Laser Grapple

Inside3D
 • Front Page
 • Articles
 • Downloads
 • Forums
 • Hosting
 • Help Wanted
 • Interviews
 • Reviews
 • Staff

 
Allied Sites
 - AI Cafe
 - Bot Epidemic
 - Dark Places
 - Flat Earth
 - FrikBot
 - Ghoulish Art
 - Kilbert3D
 - Quake Info Pool
 - QSG: Quake Standards
 - Rusted Fork
 - Stroggs Gone Mad
 - More...
 
Quake
 - Getting Started
 - QuakeC Specs v1.0
 - QuakeC Tutorials
 - Quake Mod Index
 
Quake II
 - Getting Started
 - dll Sourcecode
 - Coding Tutorials
 
.dll Central
 - Getting Started
 - Learning
 - dll Primer
 - dll in C
 - dll in Delphi
 - Compilers
 
Jedi Knight
 - Getting Started
 - COG Specs
 - Sound Specs
 - Tutorials
 
Level Editing
 - Tutorials/Tips
 
 
Telefragged!!!
Created By: Tux
eMail: tux@admdev.com
Difficulty Scale: Medium


Well, I actually did it, my beam hook tutorial, with the sound and models included.

Step 1.

First, prepare your mod directory. Create the following directory structure.

quake/moddir/sound/hook/grfire.wav
quake/moddir/sound/hook/grhit.wav
quake/moddir/sound/hook/grreset.wav
quake/moddir/progs/null.spr
quake/moddir/progs/bolt.mdl
Get these files from this zip tuthook.zip.

Step 2.

Add tuthook.qc to progs.src above weapons.qc

Step 3.

Next, go into weapons.qc and copy the following code into the precache function near the beginning of the file:

precache_sound("hook/grfire.wav");
precache_sound("hook/grhit.wav");
precache_sound("hook/grreset.wav");
precache_model("progs/null.spr");


Step 4.

Next go to client.qc and add this line to the end of the "PlayerPreThink" function:

CheckRope();


Step 5.

Then, add these lines to defs.qc:

.entity hook;
.float hooking;
Next go to weapons.qc and add the following lines to the Impulse check near the end of the file.

if (self.impulse == 24)
	FireHook ();
if (self.impulse == 25)
	BreakHook ();

Step 6.

Add all the below code to a new file called tuthook.qc (or use the tuthook.qc from the zip)

void () DrawBeam = 
{
   local vector org;
   org = (self.origin) + '0 0 16';
   WriteByte(MSG_BROADCAST, SVC_TEMPENTITY);
   WriteByte(MSG_BROADCAST, TE_LIGHTNING1);
   WriteEntity(MSG_BROADCAST, world);
   WriteCoord(MSG_BROADCAST, org_x);
   WriteCoord(MSG_BROADCAST, org_y);
   WriteCoord(MSG_BROADCAST, org_z);
   WriteCoord(MSG_BROADCAST, self.hook.origin_x);
   WriteCoord(MSG_BROADCAST, self.hook.origin_y);
   WriteCoord(MSG_BROADCAST, self.hook.origin_z);	
};

void() pull =
{
		if (self.owner.hooking == 1)
		{
		self.owner.velocity = normalize(self.origin - self.owner.origin);
		self.owner.velocity = self.owner.velocity * 500;
		self.think = pull;
		self.nextthink = time + 0.1;
		}
		else
		{
		self.owner.hooking = 0;
		remove(self);
		sound (self.owner, CHAN_WEAPON, "grapple/grreset.wav", 1, ATTN_NORM);
		}	
};

void() hookdamage =
{
if (self.enemy.health)
{
	self.owner.velocity = normalize(self.origin - self.owner.origin);
	self.owner.velocity = self.owner.velocity * 500;
	
	T_Damage(self.enemy, self, self.owner, 2);

	self.origin = self.enemy.origin;
	self.think = hookdamage;
	self.nextthink = time + 0.1;
}
else
{
	self.owner.hooking = 0;
	remove(self);
	sound (self.owner, CHAN_WEAPON, "grapple/grreset.wav", 1, ATTN_NORM);	
}
};

void() PullHook =
{
	if (other == self.owner)
		return;

	if (other == world) // Pull
	{
			self.solid = SOLID_NOT;
			self.movetype = MOVETYPE_NONE;
			self.think = pull;
			self.nextthink = time;
      }
	if (other.takedamage && other.health)
	{
			self.think = hookdamage;
			self.enemy = other;
			self.solid = SOLID_NOT;
			self.nextthink = time;
	}
	sound (self.owner, CHAN_WEAPON, "grapple/grhit.wav", 1, ATTN_NORM);	
	
};


void() BreakHook =
{
	if (self.hooking == 1)
	{
	remove(self.hook);
	self.hooking = 0;
	sound (self, CHAN_WEAPON, "grapple/grreset.wav", 1, ATTN_NORM);	
	}
};

void () FireHook =
{
	local entity hooky;
	hooky = spawn();
	setorigin(hooky, self.origin + self.view_ofs);
	setmodel(hooky, "progs/null.spr");
	setsize (hooky, '0 0 0', '0 0 0');
	hooky.solid = SOLID_BBOX;
	hooky.movetype = MOVETYPE_FLYMISSILE;
	makevectors(self.v_angle);
	self.aiment = hooky;
	hooky.velocity = v_forward * 1500;
	hooky.owner = self;
	self.hook = hooky;
	hooky.classname = "hookend";
	self.hooking = 1;
	hooky.touch = PullHook;
	//hooky.cansplash = 1; // If my splash tutorial is installed, uncomment this line
	sound (self, CHAN_WEAPON, "grapple/grfire.wav", 1, ATTN_NORM);	
};

void() CheckRope =
{
	if (self.hooking == 1 && self.hook.classname == "hookend")
	{
		DrawBeam ();
	}

};
The mod is now ready for compile. For the hook to work with a single button, make an autoexec.cfg file that contains these lines:

alias +hook "impulse 24"
alias -hook "impulse 25"
bind  +hook







The Inside3D content and design is copyrighted by the Inside3D team, and may not be re-produced or copied without proper consent. All rights reserved. Any work credited to any author not part of InsideQC is copyrighted by that author. If you have any feedback, suggestions or flames please send it in to the author. Inside3D is hosted by telefragged and the design was originated by project-9.