Announcement

Collapse
No announcement yet.

Guided sidewinder rockets

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • #16
    The impulses aren't exactly the global cardinal directions, they are the cardinal directions in respect to the rocket. So if the rocket is heading 45 degrees east of north, and you press the impulse for left trajectory, it will go 45 degrees west of north. I still don't like it though.

    My idea for the better rocket swing reads the difference in the player's aim motion. Basically it will involve tracelining directly in front of the player everytime the .think function cycles. By stacking up a self.cnt count on the rocket, I can set an if statement such as:

    if (self.cnt*0.5 != rint(self.cnt*0.5)
    trace_endpos = self.owner.viewtrace; // new field for storing the player's aim point directly in front of him

    Basically that will write the trace_endpos to the player's field only if the .think function updates the rocket's self.cnt to an odd number. This means it will skip it every other cycle. I can then compare the self.viewtrace position to the actual position and if it is a substantial difference, then we know the player means to swing the rocket in that direction and not simply guide it.

    I have no idea how it will work just yet, I need to try it out. But it would allow you to swing in any direction just about, and without having to press a button.

    P.s. I'm glad you got some use out of trying this idea and helping me out as well. I had another rocket idea that I think is possible that I don't actually intend to use myself though. But with rift quake, from what I can tell so far, may be of interest to you. At least as another fun programming challenge if you're interested.
    Absolutely, I'm all ears man.
    'Replacement Player Models' Project

    Comment


    • #17
      I don't know if you can use modulus in QC but if you can, you could do something like this

      if(self.cnt%2)
      //code

      If you don't know, modulus works by returning the remainder from a division standpoint. Using 2 as your divisor means that the remainder can only ever be 0 or 1. 0 and 1 are also acceptable true/false values. As cnt is being incremented the condition will alternate between true and false, giving you the "every-other" situation you are trying to accomplish. If you get any problems with 0%2 and 1%2 just start the cnt at 2.

      or take your way and make it a method so you can reuse it

      Code:
      float(float num) Alt =
      {
      	if (num*0.5 == rint(num*0.5))
      		return 1;
      
      	return 0;
      };
      
      usage
      
      if(Alt(self.cnt))
      	//code
      Last edited by MadGypsy; 07-28-2014, 12:27 AM.
      http://www.nextgenquake.com

      Comment


      • #18
        Originally posted by Dutch View Post
        Absolutely, I'm all ears man.
        Ok. I was looking at the inside 3d tutorials and saw the ones for flares. It seemed like a pretty cool idea, but wouldn't have much valid use in my mod. At least not the flares by themselves.

        Since I was still thinking about the rockets, an idea popped up into my head involving both flares and the rockets.

        Heats seeking/beacon seeking rockets. The idea is that the flares/beacons could be used as normal. To give off light in dark areas and are thrown in a similar fashion to quake 2 grenades where the longer the player holds the trigger, the farther it will go. And it will stay lit for a semi-random period of time.

        Where the rockets come in is that the rockets would be drawn towards any flares reasonably within the the vicinity. The rockets would fly straight until they get within a certain radius of the flares/beacons and then curve towards them.

        I think this could add some very interesting gameplay strategy and tactics. Without making it too easy either. The player could toss the flare/beacon into an area, but would then have a limited amount of time to fire the rocket in order to make it land and explode at the point of the flare before it dies out.

        I can see this useful in both single and multi player. The player could use it in ancicipation to try to cut off an enemy and as a crowd control device to damage several enemies in a group. And of course there is the risk that the flare/beacon might go out before the rocket reaches the radius or the enemy is out of range before it hits.

        Also, in multi player, you have to worry about other player's flares/beacons possibly as there could be one closer to you when you fire it.

        Anyways, just an idea that I think could have a lot of possibility. Although, just wouldn't fit in my current mod idea, so I don't know if I would ever get around to trying to implement it. Anyways, hope you like it.

        I can see it being hard to see just how well it works without actually trying it out. It sounds fun and interesting in theory at least. (to me at least).

        P.s. I say flare/beacon and heat/beacon seeking cause heat seeking would imply it goes towards heat. Which was my original idea, but for continuity sake, I think "beacon" might fit better cause otherwise the rockets would logically go directly towards enemies, the player, and wall torches. SO I suppose they would be flares with built in signal beacons.

        Comment


        • #19
          Cool thread. It seems modding is alive and kicking.
          Scout's Journey
          Rune of Earth Magic

          Comment


          • #20
            @gypsy: I'll check and see if modulus is supported, I'm sure it wasn't back in the day but I believe Spike's compiler recognizes new math functions, it may read that just fine. Either way, good call on making it a re-usable function.

            @legend: Some of the weapons in my mod have two forms of firing: normal and alt function. I could implement this idea with a weapon that fires a flare as the alt function, and a projectile that seeks out the flare as a primary fire. The idea would be that you could launch a flare near some unsuspecting enemies, back up out of sight, and fire the projectile out so it can find the flare. In ai.qc, I could modify monster behavior so that if this were the case, they would still have no idea where you were, even after taking damage. Awesome idea dude.

            I think I will try this out soon.

            Another idea I had not long ago is an air strike weapon. I actually got this idea from playing Unreal Tournament a looong time ago, and Gears of War uses the same idea for the Hammer of Dawn. Basically, if the target is outside, you can "paint" them with a laser. If you are able to paint them consistently for 2 or 3 seconds or so, it prompts an immediate air strike, which could be artillery or a large laser. It would take some triggers to implement, as the targeted player has to be outdoors, but it would be pretty slick IMO.
            'Replacement Player Models' Project

            Comment


            • #21
              Originally posted by Dutch View Post
              @gypsy: I'll check and see if modulus is supported, I'm sure it wasn't back in the day but I believe Spike's compiler recognizes new math functions, it may read that just fine. Either way, good call on making it a re-usable function.

              @legend: Some of the weapons in my mod have two forms of firing: normal and alt function. I could implement this idea with a weapon that fires a flare as the alt function, and a projectile that seeks out the flare as a primary fire. The idea would be that you could launch a flare near some unsuspecting enemies, back up out of sight, and fire the projectile out so it can find the flare. In ai.qc, I could modify monster behavior so that if this were the case, they would still have no idea where you were, even after taking damage. Awesome idea dude.

              I think I will try this out soon.

              Another idea I had not long ago is an air strike weapon. I actually got this idea from playing Unreal Tournament a looong time ago, and Gears of War uses the same idea for the Hammer of Dawn. Basically, if the target is outside, you can "paint" them with a laser. If you are able to paint them consistently for 2 or 3 seconds or so, it prompts an immediate air strike, which could be artillery or a large laser. It would take some triggers to implement, as the targeted player has to be outdoors, but it would be pretty slick IMO.
              I would think that if the flare is launched into a group of enemies, there would be a chance that they are either drawn towards it or possibly flee. either way, you are most certainly free to do with the bare idea that you wish. I do hope you get some use out of it. I just thought it might have been worth throwing out there for others to possibly use.

              Tomorrow I hope to finally start checking out your guided rocket code and get it implemented along with some other minor modifications and maybe getting my new weapon idea sorted out too.

              Comment


              • #22
                Thanks a ton Dutch. Finally got around to playing with it and it works great. Not done yet, but here is my code. It's only slightly different from yours.

                Code:
                /*
                ==============================================================================
                
                Guided ROCKETS
                
                ==============================================================================
                */
                
                /*
                ================================
                Definitions
                
                Floats needed to carry out code.
                ================================
                */
                
                .float tracing;
                .float rocketdir;
                
                /*
                ================================
                Explosion Sprite
                
                Exploding sprite animation frame functions.
                ================================
                */
                
                void()	s_explode1	=	[0,		s_explode2] {};
                void()	s_explode2	=	[1,		s_explode3] {};
                void()	s_explode3	=	[2,		s_explode4] {};
                void()	s_explode4	=	[3,		s_explode5] {};
                void()	s_explode5	=	[4,		s_explode6] {};
                void()	s_explode6	=	[5,		SUB_Remove] {};
                
                void() BecomeExplosion =
                {
                	self.movetype = MOVETYPE_NONE;
                	self.velocity = '0 0 0';
                	self.touch = SUB_Null;
                	setmodel (self, "progs/s_explod.spr");
                	self.solid = SOLID_NOT;
                	s_explode1 ();
                };
                
                void() T_MissileTouch =
                {
                	local float	damg;
                	
                	self.owner.tracing = FALSE;
                	self.owner.rocketdir = 0;
                
                	if (other == self.owner)
                		return;		// don't explode on owner
                
                	if (pointcontents(self.origin) == CONTENT_SKY)
                	{
                		remove(self);
                		return;
                	}
                	
                	if (other.health)
                	{
                		damg = 200 + random()*20;
                		if (other.classname == "monster_shambler")
                			damg = damg * 0.5;	// mostly immune
                		T_Damage (other, self, self.owner, damg );
                	}
                	
                	// don't do radius damage to the other, because all the damage
                	// was done in the impact
                	T_RadiusDamage (self, self.owner, 120, other);
                
                //	sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
                	self.origin = self.origin - 8*normalize(self.velocity);
                
                	WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
                	WriteByte (MSG_BROADCAST, TE_EXPLOSION);
                	WriteCoord (MSG_BROADCAST, self.origin_x);
                	WriteCoord (MSG_BROADCAST, self.origin_y);
                	WriteCoord (MSG_BROADCAST, self.origin_z);
                
                	BecomeExplosion ();
                };
                
                /*
                ================================
                TrajectoryUpdate
                
                The missile's .think function.
                ================================
                */
                
                void() TrajectoryUpdate =
                {
                if (!self.owner.button0 || self.owner.deadflag != DEAD_NO)
                {	
                self.owner.tracing = FALSE;
                self.think = SUB_Remove;
                self.nextthink = time + 5;	
                return;
                }
                
                self.owner.tracing = TRUE;
                makevectors(self.owner.v_angle);
                
                if (self.owner.rocketdir == 0)
                traceline(self.owner.origin, aim(self.owner, 100000)*100000, FALSE, self.owner);
                else if (self.owner.rocketdir == 1)
                traceline(self.origin, self.origin + v_right, FALSE, self);
                else if (self.owner.rocketdir == 2)
                traceline(self.origin, self.origin - v_right, FALSE, self);
                else if (self.owner.rocketdir == 3)
                traceline(self.origin, self.origin + v_up, FALSE, self);
                else
                traceline(self.origin, self.origin - v_up, FALSE, self);
                
                self.velocity = normalize(trace_endpos - (self.origin - self.velocity))*1000;	
                self.angles = vectoangles(self.velocity);
                
                if (self.owner.rocketdir == 0)
                {
                self.think = TrajectoryUpdate;
                self.nextthink = time + 0.05;
                }
                else
                {
                self.owner.rocketdir = 0;
                self.owner.tracing = FALSE;
                self.think = SUB_Remove;
                self.nextthink = time + 5;	
                return;
                }
                };
                
                /*
                
                
                
                /*
                ================
                W_FireRocket
                ================
                */
                void() RocketThink =
                {
                	makevectors (self.owner.v_angle);
                	self.velocity = aim(self.owner, 1000);
                	self.velocity = self.velocity * 1000;
                	self.angles = vectoangles(self.velocity);
                	
                	self.nextthink = time + 0.01;
                	self.think = RocketThink;
                };
                
                void() W_FireRocket =
                {
                	local	entity missile, mpuff;
                	
                	self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
                	
                	sound (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM);
                
                	self.punchangle_x = -2;
                
                	missile = spawn ();
                	missile.owner = self;
                	missile.movetype = MOVETYPE_FLYMISSILE;
                	missile.solid = SOLID_BBOX;
                	missile.classname = "missile";
                		
                // set missile speed	
                
                	makevectors (self.v_angle);
                	missile.velocity = aim(self, 1000);
                	missile.velocity = missile.velocity * 1000;
                	missile.angles = vectoangles(missile.velocity);
                	
                	missile.touch = T_MissileTouch;
                	
                // set missile duration
                	missile.nextthink = time + 5;
                	missile.think = SUB_Remove;
                
                	setmodel (missile, "progs/missile.mdl");
                	setsize (missile, '0 0 0', '0 0 0');		
                	setorigin (missile, self.origin + v_forward*8 + '0 0 16');
                	
                	missile.velocity = aim(self, 100000);
                	missile.velocity = missile.velocity*1000;
                	missile.angles = vectoangles(missile.velocity);	
                	missile.touch = T_MissileTouch;
                
                	missile.think = TrajectoryUpdate;
                	missile.nextthink = time + 0.2;
                };
                
                /*
                The only thing I want to add are
                Needing cells to use the guiding function, but still be able to fire normal rockets if the player doesn't have any cells.

                And figure out that maneuvering thruster type of deal where the rocket swings in the opposite direction for a moment just before it goes in the intended direction.

                I might try to make it lag a little more cause I want it to move in a bit more of a curve. But it actually feels pretty good as it is, so I may leave it alone. If I did want to do that, I just have to increase the number for the

                Code:
                self.think = TrajectoryUpdate;
                self.nextthink = time + 0.05;
                part of the code right?

                I'd also like to reduce the damage slightly of the rockets when using the guided function but still keep it increase when just tapping and firing it straight. Not sure how to do that yet though.

                I'm trying to figure out which part of your code is telling it to fly straight by tapping the button and for the guiding to kick in by holding the button?

                On a related note, how does the gravity thrust for rockets work that makes it possible for players to rocket jump? Can a similar effect be coded into the weapons firing function itself or does it have to be in the code for the ammo that's being used? I want to add a rocket jump like effect to the double barreled shotgun but don't necessarily want it to happen when using the regular shotgun or the other new weapon I'm adding which also uses shotgun shells. And also don't want it to do nearly as much damage as a rocket jump would do.

                Thanks again for all the help.

                Comment


                • #23
                  You bet man.

                  There's some stuff in your code that is just filler, it isn't being called on or anything. It looks like you added a function called RocketThink? It doesn't tie into the rocket at all, but looking at the code, you don't want it to or else you will lose the tracing ability. TrajectoryUpdate() is the .think function.

                  There's also some stuff from id that is/was useless, like the commented out sound function for the explosion sound (that's handled in the engine C code for when the temporary entity TE_EXPLOSION is called).

                  To keep it clean, I would recommend taking the code I wrote and simply overwrite the old rocket code, and then make modifications to it then.

                  ================================================== =

                  To subtract cells, add

                  self.owner.cells = self.owner.cells - 1;

                  underneath self.owner.tracing = TRUE in TrajectoryUpdate(). This will subtract 20 cells per second, because TrajectoryUpdate is set to cycle every 0.05 seconds (0.05 x 20 = 1 second). You can probably set the self.nextthink = time + 0.1 without noticing too much of a difference in rocket behavior. Then it will only subtract 10 cells every second. You can also use the 'every other cycle' check gypsy and I were talking about, so that a cell will only be subtracted every other cycle of the TrajectoryUpdate .think function. This would be the correct way of implementing the 'every other cycle' check:

                  Originally posted by MadGypsy
                  float(float num) Alt =
                  {
                  if (num*0.5 == rint(num*0.5))
                  return 1;

                  return 0;
                  };

                  usage

                  if(Alt(self.cnt))
                  //code
                  ================================================== =

                  To make it lag more, I would not alter the self.nextthink float. Remember that novel I wrote about vectors a few posts back?

                  self.velocity = normalize(trace_endpos - (self.origin - self.velocity))*1000;
                  That too is in TrajectoryUpdate(). To make it lag more, write that line as this:

                  self.velocity = normalize(trace_endpos - (self.origin - self.velocity*2))*1000;

                  You can of course make that 2 any number you want. Experiment with different values until you find the rocket response you like the best.

                  ================================================== =

                  To alter the damage dealt by tracing rockets, you'll want to change it based on the tracing float of the rocket's owner.

                  In T_MissileTouch(), alter the following code by adding the orange highlighted text:

                  if (other.health)
                  {
                  if (self.owner.tracing == TRUE)
                  damg = [insert your preferred damage value];
                  else

                  damg = 200 + random()*20;
                  if (other.classname == "monster_shambler")
                  damg = damg * 0.5; // mostly immune
                  T_Damage (other, self, self.owner, damg );
                  }

                  if (self.owner.tracing == TRUE)
                  T_RadiusDamage (self, self.owner, [insert your preferred radius damage here], other);
                  else

                  T_RadiusDamage (self, self.owner, 120, other);

                  This will, however, only apply your defined damage if you are still holding the fire button to trace the rocket. Otherwise it will revert to the normal rocket damage (looks like you stepped it up to 200 for the normal damage, I believe id had it set at 100). If that's ok with you, then that should be all you have to do. If not, I can explain how to set the damage properties through the use of the rocket's classname.

                  ================================================== =====

                  In my code, all rockets start out as normal, straight-flying rockets. When you fire the rocket, it has a self.think for TrajectoryUpdate(). This think function happens at 0.2 seconds after the rocket is launched. The first lines of TrajectoryUpdate check to see if the player has let go of the fire button (!self.owner.button0 means that the owner of the rocket [you, the player] is not pressing the fire button [.button0]). It also checks to see if the player is dead or dying (self.owner.deadflag != DEAD_NO means the player is not alive). If either of these two conditions are met (the characters || are syntax for 'or') then the rocket's think function is set to SUB_Remove in five seconds, which does two things: removes the rocket 5 seconds later (usually a rocket hits something by this time, so you may have never seen this happen in-game) and it breaks the TrajectoryUpdate .think cycle (the rocket is no longer updating velocity based on the player's aim). So naturally, if you simply fire a rocket and do not keep the fire button depressed, the TrajectoryUpdate .think function is completely by-passed, and acts just like a normal rocket.

                  ================================================== =

                  Gravity thrust (rocket jump) of the player has nothing to do with the Rocket Launcher itself. It is calculated in a different QC file called fight.qc within the T_Damage() function:

                  // figure momentum add:

                  if ((inflictor != world) && (targ.movetype == MOVETYPE_WALK))
                  {
                  dir = targ.origin - (inflictor.absmin + inflictor.absmax)*0.5;
                  dir = normalize(dir);
                  targ.velocity = targ.velocity + dir*damage*8;
                  }
                  Monsters don't have this velocity change because they are not MOVETYPE_WALK. It only affects players (you could of course change this, some mods do).

                  If you've ever been hit by a Quad lightning gun or double-barreld shotgun, you'll notice the same velocity change as the rocket launcher. You could write up some code that would simulate this behavior with the shotgun, but it would be a little involved and I would need to test it before posting any solutions.

                  ==============================================

                  Hope this helps man, I don't mean to sound too technical, but this stuff is hard to explain. I'll try to straighten out anything you find vague about all that if I can.
                  'Replacement Player Models' Project

                  Comment


                  • #24
                    Thanks again Dutch.

                    The rocketthink was intended to slow down the RL's rate of fire originally I believe.
                    Thanks for the tip and I will definitely look into cleaning it up more. When it's all done, I hope to have nice clean and very commented code. (it's been driving me nuts looking at all sorts of uncommented code and trying to figure out what does what.)

                    I was originally planning on just having the guided rocket just use a fixed amount of cells per use. But your idea of using so many per second sounds a bit better. I will give it a try using the every other cycle method for 10 cells per second.

                    I would appreciate if you could explain how to control the damage through the classname like you mentioned. I would prefer that the damage gets reduced once the player activates the guided function of the rocket so it is reduced even if they let go of the trigger. Either that or the rocket explodes when they release the trigger and it only deals splash damage.

                    Yeah, the damage has been doubled for direct hits but reduces splash damage on a direct hit.

                    So far the shotgun, I would have to make it call to the T_damage somewhere in the shotgun firing code? Or to the bullets? Would that cause the player to get knocked back when firing as well? So what is the T_Damage function exactly? Just for knock back?

                    If I wanted the monsters to get knocked back when hit, I would change their movetype_step to movetype_walk?

                    Anyway, thanks yet again for all the helpful info.
                    Last edited by Legend; 07-31-2014, 01:04 AM.

                    Comment


                    • #25
                      I would appreciate if you could explain how to control the damage through the classname like you mentioned. I would prefer that the damage gets reduced once the player activates the guided function of the rocket so it is reduced even if they let go of the trigger. Either that or the rocket explodes when they release the trigger and it only deals splash damage.

                      Ok, so when you initially fire the rocket in the W_FireRocket() function, see the line that says

                      self.classname = "rocket"; ?

                      We are going to change that as soon as the rocket is being traced. Go to the TrajectoryUpdate .think function. Right above the line that reads

                      self.owner.tracing = TRUE;

                      add:

                      self.classname = "trace_rocket";

                      * Side Note: one of the toughest things for me to fully grasp was the utilization of 'self'. When the player performs a function (like calling on the W_FireRocket() function to launch a rocket), the player himself is 'self'. When we tell the rocket to perform the TrajectoryUpdate() .think function (missile.think = TrajectoryUpdate, that means within the TrajectoryUpdate() function, the missile is 'self'. That is why we must alter the player's fields in TrajectoryUpdate() as 'self.owner', because the player owns the rocket. Just remember that 'self' is always the entity that the function is for.

                      What we have done is re-define the rocket's classname if and only if the player is still holding the fire button 0.2 seconds after launching it in order to trace it.

                      Now, in T_MissileTouch(), you will add this code:
                      if (other.health)
                      {
                      if (self.classname == "trace_rocket")
                      damg = [your preferred damage value here];
                      else

                      damg = 200 + random()*20;

                      if (other.classname == "monster_shambler")
                      damg = damg * 0.5; // mostly immune
                      T_Damage (other, self, self.owner, damg );
                      }

                      // don't do radius damage to the other, because all the damage
                      // was done in the impact
                      if (self.classname == "trace_rocket")
                      T_RadiusDamage (self, self.owner, [your preferred radius damage value here], other);
                      else

                      T_RadiusDamage (self, self.owner, 120, other);
                      This will deal the appropriate damage based on the rocket's classname, which will not change after being set to "trace_rocket". If you don't trace the rocket, it will remain "rocket" as the classname.

                      If you only want to deal splash damage, you could set damg for the "trace_rocket" to 0, but that's kind of hacky (you're essentially dealing a damage value of 0 to the target). I would replace this line:

                      if (other.health)

                      with this:

                      if (other.health && self.classname == "rocket")

                      and then don't even worry about adding the classname check for the normal non-radius damage portion.

                      ================================================

                      You don't want to set the monster's movetype to MOVETYPE_WALK, because as far as I know, that movetype is intended for clients (players). I don't know what would happen if you did, maybe nothing, but I've never experimented with that.

                      Instead, just take that movetype check out of the velocity change within T_Damage() and see what happens. So it will only read as:

                      if (inflictor != world)

                      Give that a shot. It may cause bugs I'm not aware of, but that's a great way of learning: experimenting.

                      ================================================

                      For the shotgun blast...what is your intention? Should it damage the player when he 'shotgun jumps' or should it just knock him back? Should it only knock him upwards if he is shooting the ground beneath him? There is definitely a way to do it, but you gotta decide exactly how it will behave.
                      'Replacement Player Models' Project

                      Comment


                      • #26
                        Thanks Dutch. You are quite informative in your explanations and often better than most of the tutorials on inside3D.

                        I will definitely fiddle with the different damage values using the classname example tomorrow.

                        The splash damage idea would only have been if the rocket explodes without actually hitting anything when the player lets go of the trigger so there would have been to actual target it hits. I'm still not clear on if that's even possible to make a rocket explode without collision.

                        For the double shotgun, I specifically want the player to be able to point it straight at the ground and get a rocket jump like boost only with less damage. I also want the player to have a bit of a physical knock back when firing it. As it is, the player gets a critical hit bonus when firing the double shotgun right up close to an enemy in the face but is quite week cause of the spread at mid to long range. I want to make it a little harder to get those up close critical hits by making the player knock back when firing.

                        I also want to be able to use the knockback with the new weapon, but to a stronger degree. Without the rocket jump like effect though.

                        The new weapon is actually a reconfiguration of the zerstorer riot controller. A very high powered, high fire rate shotgun with a wide spread but fires with a 20 shell drum of ammo that takes the longest to auto-reload and has about a 25% chance of jamming and losing the remaining shells in the drum as well as eating up an un-jamming time slightly longer than the auto-reload does. I got most the code for this figured out other than the knock back. I basically want it top be where the player has to be careful when firing it with the back facing the edge of a platform, otherwise they may fall off from the knock back from about 4 shots.

                        The regular shotgun is simply semi auto fire with a 6 round mag. But I don't want the rocket jump effect with it either.

                        I may even change the double shotgun into a quad shotgun in order to use 4 shells instead of two and make the idea of it being so powerful and having the jump assist more feasible. Unfortunately though, I lack the modeling and skinning skills to make it a legit quad. So I'll probably stick with the double instead of quad anyways.

                        Comment


                        • #27
                          Thanks Dutch. You are quite informative in your explanations and often better than most of the tutorials on inside3D.
                          No problem dude.

                          The splash damage idea would only have been if the rocket explodes without actually hitting anything when the player lets go of the trigger so there would have been to actual target it hits. I'm still not clear on if that's even possible to make a rocket explode without collision.
                          As the rocket sits now, it will not explode on it's own without touching a surface. To do that, you can add a counter for the rocket in TrajectoryUpdate(). Beneath self.owner.tracing = TRUE;, add this:

                          self.cnt = self.cnt + 1;

                          The .cnt float is usually used as a counter, and is already a valid definition in defs.qc (.floats are simply numerical place holders for specific entities and all behave the same. They can be any number. When they are set to FALSE or TRUE, it is the same as setting them to 0 or 1. The .tracing float I made is the same thing. The convenience of having several different defined floats is simply to keep the code organized, and sometimes you will have an entity that needs several stored float values).

                          Now right above that, add the following:

                          if (self.cnt == 100)
                          {
                          self.owner.tracing = FALSE;
                          WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
                          WriteByte (MSG_BROADCAST, TE_EXPLOSION);
                          WriteCoord (MSG_BROADCAST, self.origin_x);
                          WriteCoord (MSG_BROADCAST, self.origin_y);
                          WriteCoord (MSG_BROADCAST, self.origin_z);
                          BecomeExplosion();
                          T_RadiusDamage (self, self.owner, [your preferred radius damage value here], other);
                          return;
                          }
                          This sets a timed detonation of 5 seconds after launch (0.05 seconds x 100 cnts = 5 seconds) where the traced rocket will explode in mid air and deal a radius damage, turn into the sprite animation, reset the player's .tracing value to zero, and return to skip subsequent code.

                          Now, everytime I add any new code, I launch up my mod and test it every which way possible. Catch bugs as they happen, because even then you will miss some. I'm currently out of town at the moment and I'm using my Mac, so I can't test any of that, but it should get you in the right direction. Note that normal rockets will still not detonate in mid-air, this will only apply for traced rockets. I leave it up to you to implement a similar idea to normal rockets if that's something you'd like to do.

                          For the shotgun blast, there are a few ways to implement a substantial recoil. In W_FireSuperShotgun() in weapons.qc, you could add something like:

                          self.velocity = v_forward*-300;

                          or something similar. Play with different values. What that should do is apply a velocity to the player opposite of his current aim direction. Like I said, I can't test this at the moment, but see what happens.

                          Let me know how it goes.

                          EDIT: Check out the Altar of Storms mod. There is a pretty slick quad shotgun in that mod. If anything, it will give you an idea of how to go about making one. Basic MDL modeling is a good skill to have, especially if you're making the code to go with it. The great thing about Quake is the simplicity; given some time, it is possible for just one guy to do it all (but naturally there will be one or two areas you are a lot better at than others).

                          Here's some programs you should download, in case you're not familiar. All are free and all are great.

                          * NotePad++ (good interface for coding)
                          * fteqcc (Spike's QC compiler)
                          * Fimg (create/modify Quake sprite .spr files)
                          * Wally (create Quake faithful textures using Quake's palette...I use the living hell out of this)
                          * QME (Quake Model Editor. I don't even use the paid version but it's great for organizing mdl files and making small animation tweaks...I wouldn't try to build models with it, only edit).
                          * Blender (this is an absolute must, or at least a program comparable to Blender. Learn it as soon as you can, and download the Quake MDL importer/exporter plugin)
                          * NetRadiant with MadGypsy's Virtuoso gamepack (he just made a new thread for it in the WIP section. If you plan on mapping for your mod, this is the way to do it)
                          * TexMex (create/edit WAD texture files)
                          * PakScape (access Quake's pak files)

                          Chances are you already have one or two of those. Another big recommendation I have: if your mod starts to get fancy (basically, if your mod has features beyond what Quoth has, for example), then choose your favorite Quake engine and build it exclusively for that engine. With a simpler mod like Quoth (even though it has lots of new content, it doesn't stray too far from faithful Quake), most engines will handle it similarly. But with all the 'unfaithful' features I have in my mod, I found out real quick that every engine is a little different, to such a degree that I can only guarantee it will work without a hitch on QuakeSpasm and, for the most part, DarkPlaces (having some custom sprite orientation problems on DP at the moment).
                          Last edited by Dutch; 08-02-2014, 01:09 AM.
                          'Replacement Player Models' Project

                          Comment


                          • #28
                            finally tried playing around with the shotgun recoil. I can get it working techinically. But the player just goes straight up when firing at the ground instead of up and forward when moving. I would basically like to make the player be able to use the double shotty to rocket jump without the damage. I already added proportional falling damage, so they will receive that, but just not from the initial blast itself.

                            Got the rocket going how I like it. Thanks a ton Dutch. One thing I haven't really looked at at all is making toggle-able features. LIke the rocket using cells. I like it, but not everyone would. And playing in a dmsp/q3 arena type of setting which I intend to incorporate these weapon mods into would highly depend on whether or not the map being played contains both rocket and cell ammo. I don't intend to make any maps, so if the player would not be able to use the guiding feature very often. I thought it would be good to make it so the player could toggle whether the guided rockets require cells or not.

                            I don't intend to get too fancy with it. I want to keep it so it can be played in the most basic of quake engines like directq 1.8.4 and Qbism Super8 so that way, when finished, the most amount of people can play and hopefully enjoy it. I can't run several of the fancier engines for instance cause of my laptop. I'm sure there are others in my same situation who simply cannot play on some engines.
                            Last edited by Legend; 08-05-2014, 12:58 PM.

                            Comment


                            • #29
                              So I'm on vacation (i.e. not on my PC) and my laptop took a hard drive shit yesterday, so I'm on my phone, meaning I gotta keep this short and sweet. Apologies.

                              For the shotgun blast velocity, change it to:

                              self.velocity = self.velocity - (v_forward*300);

                              I made a mistake in not adding the second self.velocity. Now it should maintain the players velocity while knocking him up when pointing down. I can't test it, so let me know what that does. Chances are we'll have to play with it some more (I still have a lot to learn as well).

                              If you want control whether cells are subtracted or not, you will have to perform a cvar check. If you plan on this mod being faithful engine compatible, then you must use an already existing cvar that original quake does not use. There are a few you can use, such as "scratch1", "temp2", "saved1", and "nomonsters".

                              Right above the cell subtraction, add:

                              If (cvar("saved1") != 0)

                              This means if the server of a match has the saved1 cvar set above 0 (or below), then cells will subtract for players tracing in the match. At least that should work, server to client relationship is still something I'm learning.
                              'Replacement Player Models' Project

                              Comment


                              • #30
                                Thanks Dutch. I got the shotty working nicely now just as I wanted.

                                btw, did you happen to look at the code in the op on the bottom link?
                                I'm trying to figure out where the information for the crital hit damage is located. I changed the clip size of the shotgun and gl, but somehow changed the critical hit factor to where it scores after only two direct hits instead of 4. But, don't see how any of the values I changed could do that since I increased the shotgun clip size from 4 to 6 and decreased the gl clip from 4 to 3. Anyway, I know you can't look at it now. Just curious if you ever did.

                                I'll try to refrain from any more non rocket related questions in this forum so it doesn't get too cluttered with other info. I may have some grenade launcher related questions in the future I post here, but that would most likely be it. I'll start a new thread for some further questions.

                                Enjoy your vacation man and thanks again.
                                Last edited by Legend; 08-05-2014, 02:05 PM.

                                Comment

                                Working...
                                X