Grapple Hook

Discuss programming in the QuakeC language.
Post Reply
CocoT
Posts: 695
Joined: Tue Dec 14, 2004 5:39 pm
Location: Belly-Gum
Contact:

Grapple Hook

Post by CocoT »

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!
Teiman
Posts: 311
Joined: Sun Jun 03, 2007 9:39 am

Re: Grapple Hook

Post by Teiman »

all grapples used to be straigforward to install :D
Quake Matt
Posts: 129
Joined: Sun Jun 05, 2005 9:59 pm

Post by Quake Matt »

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.
r00k
Posts: 1111
Joined: Sat Nov 13, 2004 10:39 pm

Post by r00k »

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;
};
CocoT
Posts: 695
Joined: Tue Dec 14, 2004 5:39 pm
Location: Belly-Gum
Contact:

Post by CocoT »

Oh, great, r00k, I'll have a look at that! :)
Thanks a lot! :wink:
Neurotic Conversions - New location: Update your bookmarks!
MauveBib
Posts: 634
Joined: Thu Nov 04, 2004 1:22 am

Post by MauveBib »

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!
Teiman
Posts: 311
Joined: Sun Jun 03, 2007 9:39 am

Post by Teiman »

Sajt
Posts: 1215
Joined: Sat Oct 16, 2004 3:39 am

Post by Sajt »

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.
Teiman
Posts: 311
Joined: Sun Jun 03, 2007 9:39 am

Post by Teiman »

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.
Post Reply