Forum

Grapple Hook

Discuss programming in the QuakeC language.

Moderator: InsideQC Admins

Grapple Hook

Postby CocoT » Sun Jun 24, 2007 10:49 pm

Do you guys know of any good grapple hook code that could easily be implemented into a mod? :)
I know there is one on I3D (the laser one), but was wondering if there was any other grapple-related code around. :wink:
Neurotic Conversions - New location: Update your bookmarks!
User avatar
CocoT
 
Posts: 695
Joined: Tue Dec 14, 2004 5:39 pm
Location: Belly-Gum

Re: Grapple Hook

Postby Teiman » Mon Jun 25, 2007 8:26 am

all grapples used to be straigforward to install :D
Teiman
 
Posts: 309
Joined: Sun Jun 03, 2007 9:39 am

Postby Quake Matt » Mon Jun 25, 2007 12:03 pm

I'm working on rope physics for Gyro that make for a pretty decent grappling hook, even if it's better for swinging than it is for climbing. It's still experimental code that might not make it into the next release, but I can post what I've got if that'd help.
User avatar
Quake Matt
 
Posts: 129
Joined: Sun Jun 05, 2005 9:59 pm

Postby r00k » Mon Jun 25, 2007 5:10 pm

This is code that i adapted from the 3wave hook...
u might need to tweak to fit in your mod...


Code: Select all

void () LinkPos =
{
   //R00k added
   local vector dir;
   dir = self.owner.origin - (self.owner.owner.origin + '0 0 16'); 
     self.angles = vectoangles(dir);

   makevectors (self.enemy.angles);
   setorigin (self, self.owner.origin + ( ( ( self.enemy.origin + (v_up * 16 * (!self.enemy.button2)) + (v_forward * 16) ) - self.owner.origin ) * ( self.weapon ) ) );
   self.nextthink = (time + sys_ticrate);
};

void () HookVanish =
{
   self.owner.hook_out = FALSE;

   do
   {
      if ((self.classname == "hook_chain_link") || (self.classname == "hook_entity"))//sanity check
      {
         remove (self);
      }
      self = self.hookentity;
   } while (self);
};

void () UnHookPlayer =
{
   local entity unhook_self;

   if (self.hook_out)
   {
      unhook_self = self;
      self = self.hookentity;
      HookVanish ();
      self = unhook_self;
   }
};

void () HookPull =
{
   local vector vel;
   local float v;

   if ((!self.owner.button0 && self.owner.weapon == IT_HOOK) || (self.owner.teleport_time > time ) || (self.owner.deadflag) || (gameover))
   {
      HookVanish();
      return;
   }
   
   if (self.enemy.style & CTF_OBSERVER)
   {
      HookVanish();
      return;
   }
   
   if (self.enemy.takedamage)
   {
      if (!teamplay || self.enemy.team != self.owner.team)
      {
         if (!CanDamage(self.enemy, self.owner,"hook"))
         {
            HookVanish();
            return;
         }
         sound (self, CHAN_WEAPON, "blob/land1.wav", 1, ATTN_NORM);
         self.enemy.deathtype = "hook";

         //T_Damage (self.enemy, self, self.owner, 1);
         //at lower ticrates the hook damage is updated too fast
         //default 200a+100h = 30 seconds to death by hook
         self.hookdmg = (self.hookdmg + (sys_ticrate/0.1));

         if (self.hookdmg >= 1)
         {
            T_Damage (self.enemy, self, self.owner, 1);
            if (self.enemy.classname == "player")
            {
               SpawnBlood (self.origin, self.velocity, 10);
            }
            self.hookdmg = 0.00;
         }

         makevectors (self.v_angle);
      }

      if (self.enemy.solid == SOLID_SLIDEBOX)
      {
         self.velocity = self.enemy.velocity;
         setorigin (self, self.enemy.origin + self.enemy.mins + (self.enemy.size * 0.5));
      }
      else
      {
         self.velocity = self.enemy.velocity;
      }
   }
   else
   {
      self.velocity = self.enemy.velocity;
   }
   if (self.enemy.solid == SOLID_NOT)
   {
      HookVanish();
      return;
   }

   makevectors (self.owner.angles);
   vel = self.origin - ( self.owner.origin + (v_up * 16 * (!self.owner.button2)) + (v_forward * 16));

   v = vlen (vel);

   if ( v > 100 )
   {
      vel = (normalize(vel) * 850);
   }
   else
   {
      if (v <= 100)
      {
         vel = ((normalize(vel) * v) * 10);
      }
   }
      
   self.owner.velocity = vel;

   self.dest = self.owner.origin;
   self.nextthink = (time + sys_ticrate);
};

void () T_HookTouch =
{
   if ((other != self.owner))
   {
      if ((pointcontents (self.origin) == CONTENT_SKY) || (gameover))
      {
         HookVanish ();
         return;
      }
      else
      {
         if ((other.solid == SOLID_SLIDEBOX))
         {
            if ((other.team == self.owner.team) && (teamplay))
            {
               self.owner.attack_finished = (time + 0.5);
               HookVanish ();
               return;
            }
            other.axhitme = 1; // make axe noise
         }

         if (other.takedamage)
         {
            T_Damage (other, self, self.owner, 10 );
            //R00k fixed bleeding buttons/triggers
            if (other.classname == "player")
            {
               SpawnBlood (self.origin, self.velocity, 10);
            }
            else
            {   //R00k: hook hits triggers, just show sparks
               WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
               WriteByte (MSG_BROADCAST, TE_GUNSHOT);
               WriteCoord (MSG_BROADCAST, self.origin_x);
               WriteCoord (MSG_BROADCAST, self.origin_y);
               WriteCoord (MSG_BROADCAST, self.origin_z);
            }
         }
         else
         {
            sound (self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM);
            self.avelocity = '0 0 0';
         }

         if (self.owner.button0)
         {
            if (other.solid == SOLID_SLIDEBOX)
            {
               setorigin (self, other.origin + other.mins + (other.size * 0.5));
               //self.velocity = '0 0 0';               
               self.velocity = other.velocity;
            }
            else
            {
               self.velocity = other.velocity;
            }

            self.weapon = other.nextthink - time;

            self.style = 2;
            self.enemy = other;
            self.owner.ltime = (time + 0.5);
            self.nextthink = (time + sys_ticrate);
            self.think = HookPull;
            self.touch = SUB_Null;            
         }
         else
         {
            self.nextthink = (time + sys_ticrate);
            self.think     = HookVanish;
         }
      }
   }
};

void () Hook_Check =
{
   if ((!self.owner.button0 && self.owner.weapon == IT_HOOK) || (self.owner.deadflag) || (gameover))
   {
      HookVanish ();
      return;
   }
   
   if (self)
   {
      self.nextthink = time + sys_ticrate;
      self.think = Hook_Check;
   }
};

void () W_FireHook =
{
   local entity hook;
   local float linknum;
   local entity link;
   local entity prevlink;

   self.hook_out    = TRUE;
   hook       = spawn ();
   hook.classname  = "hook_entity";
   hook.owner    = self;
   self.hookentity = hook;
   hook.movetype    = MOVETYPE_FLY;
   hook.solid    = SOLID_BBOX;
   makevectors (self.v_angle);
   hook.velocity    = 1200 * aim(self, 1200);
   hook.angles    = vectoangles (hook.velocity);
   hook.avelocity    = '0 0 -500';
   hook.touch    = T_HookTouch;
   //hook.nextthink  = (time + 5);   //This will never occur on any current CTF map..
   //hook.think     = HookVanish;
   hook.nextthink    = time + 0.5;//instead lets check if we let off the button in mid-flight! eh?
   hook.think    = Hook_Check;

   setmodel (hook, "progs/v_spike.mdl");

   setsize (hook, '0 0 0', '0 0 0');
   setorigin (hook, self.origin + (v_forward*16) + '0 0 16' );

   sound (self, CHAN_WEAPON, "hknight/hit.wav", 1, ATTN_NORM);

   linknum = 5;
   prevlink = world;
   while (linknum)
   {
      link = spawn ();
      link.classname = "hook_chain_link";
      link.hookentity = prevlink;
      prevlink = link;
      link.owner = hook;
      link.enemy = self;
      link.weapon = (linknum / 6); //was 0.25);
      link.movetype = MOVETYPE_NOCLIP;
      link.solid = SOLID_NOT;
      link.angles = vectoangles(hook.velocity);
      setmodel (link, "progs/s_spike.mdl");
      setsize (link, '0 0 0', '0 0 0');
      makevectors (self.angles);
      setorigin (link, hook.origin + (((self.origin + (v_up * 16 * (!self.button2)) + (v_forward * 16)) - hook.origin) * (link.weapon)));
      link.nextthink  = (time + sys_ticrate);
      link.think      = LinkPos;
      linknum         = linknum - 1;
   }
   hook.hookentity = link;
};
r00k
 
Posts: 1110
Joined: Sat Nov 13, 2004 10:39 pm

Postby CocoT » Mon Jun 25, 2007 8:44 pm

Oh, great, r00k, I'll have a look at that! :)
Thanks a lot! :wink:
Neurotic Conversions - New location: Update your bookmarks!
User avatar
CocoT
 
Posts: 695
Joined: Tue Dec 14, 2004 5:39 pm
Location: Belly-Gum

Postby MauveBib » Tue Jun 26, 2007 10:13 pm

I have a decent swinging grappling hook in my old Mandible mod...

http://elf.planetquake.gamespy.com/mandible.shtml

Can't remember where I nicked it from. It's damn good though. If you like it I can send you the code.

It replaces the axe in the mod if you want to try it out. IIRC O and P are bound to shorten and lengthen the rope.
Apathy Now!
User avatar
MauveBib
 
Posts: 634
Joined: Thu Nov 04, 2004 1:22 am

Postby Teiman » Wed Jun 27, 2007 7:26 am

Teiman
 
Posts: 309
Joined: Sun Jun 03, 2007 9:39 am

Postby Sajt » Wed Jun 27, 2007 7:53 am

That grappling hook isn't very useful. Except as a weapon, seeing as how it can gib a shambler in one hit :D
Last edited by Sajt on Wed Jun 27, 2007 10:14 am, edited 1 time in total.
F. A. Špork, an enlightened nobleman and a great patron of art, had a stately Baroque spa complex built on the banks of the River Labe.
Sajt
 
Posts: 1215
Joined: Sat Oct 16, 2004 3:39 am

Postby Teiman » Wed Jun 27, 2007 10:05 am

Von Neumman drones are a interesting sci-fi concept

http://en.wikipedia.org/wiki/Mantrid
http://en.wikipedia.org/wiki/Self-repli ... n_probes_2
http://www.physicspost.com/articles.php ... 113&page=4

The idea is to create a drone that can create clones if himself. And let then run wild on the universe, consuming all the existing stuff on the long run.
Teiman
 
Posts: 309
Joined: Sun Jun 03, 2007 9:39 am


Return to QuakeC Programming

Who is online

Users browsing this forum: No registered users and 1 guest