Any ideas for making a grappling hook?
by Alaric Karczag · in Game Design and Creative Issues · 07/12/2004 (6:47 pm) · 36 replies
I'm trying to find a way to make a harpoon. I'd like to be able to shoot an item and then drag it behind me.
ie:
fire = shoots out harpoon + rope, it hits object.
hold down button = to drag on item without shortening the rope,
release button = recoils the harpoon or drags item towards player
I've looked through the forums for any code for this...
Help would be great!
Thanks all for your help
ie:
fire = shoots out harpoon + rope, it hits object.
hold down button = to drag on item without shortening the rope,
release button = recoils the harpoon or drags item towards player
I've looked through the forums for any code for this...
Help would be great!
Thanks all for your help
About the author
#2
08/29/2004 (6:50 am)
Heh that is an old page and hasnt been updated ever, hooked14 works perfect also (in q2)
#3
08/30/2004 (6:55 pm)
Nice, and thank you for the link!
#4
08/31/2004 (4:07 am)
Your welcome , please share it, if you port it over to torque. This is on my list of todo's.
#5
09/01/2004 (4:32 am)
I made a grappling hook that lets you swing from static objects fairly realistically, but it doesnt let you pull other objects or attach yourself to moving things like vehicles or other players. I'll post it later.
#6
09/01/2004 (4:44 am)
Eric cool, i would be very interested in seeing it. No fps should be with out it. :}
#7
in player.h,
add these lines to the public section of the player class definition
PHYSICS:
in player.cc,
in the function player::updateMove, find the code that looks like this
and add this underneath it, this code is what applies the actual physics of the hook
RENDERING:
add this function to the end of player.cc
this function lets us draw a line for the grappling hook rope
NETWORK:
This part needs fixing as it's really inefficient network-wise. it gets it working though.
An ideal solution would be to predict this info on the client using a special property of a projectile
in Player::packUpdate, add these lines to the very beginning
and add these to the beginning of Player::unpackUpdate
09/02/2004 (8:49 am)
DEFINITIONS:in player.h,
add these lines to the public section of the player class definition
//EGH //grapling hook stuff
Point3F hookPos;
F32 hookLen;
void setHookPos(const VectorF& newHookPos) { hookPos = newHookPos; };
void setHookLen(const F32& newHookLen) { hookLen = newHookLen; };
void Player::renderObject(SceneState* state, SceneRenderImage* image);
//<-EGHPHYSICS:
in player.cc,
in the function player::updateMove, find the code that looks like this
// Add in force from physical zones... acc += (mAppliedForce / mMass) * TickSec; // Adjust velocity with all the move & gravity acceleration // TG: I forgot why doesn't the TickSec multiply happen here... mVelocity += acc;
and add this underneath it, this code is what applies the actual physics of the hook
//EGH: grapling hook forces
VectorF t;
t = getPosition() - hookPos;
float dist;
if( hookLen != -1 )
{
//if beyond hook length, apply force proportional to distance
dist = ((t.x * t.x) + (t.y * t.y) + (t.z * t.z));
if(dist > (hookLen*hookLen) )
{
//Con::warnf("Beyond HookLen");
mVelocity += (1000 * moveVec/ mMass) * TickSec;
//do something!
t.normalize();
F32 vMag;
vMag = mSqrt((mVelocity.x * mVelocity.x) + (mVelocity.y * mVelocity.y) + (mVelocity.z * mVelocity.z));
if(vMag != 0)
{
if(mAcos(mDot(t, mVelocity)/vMag) < 1.57)
{
mVelocity -= (mDot(t, mVelocity)/mDot(t, t)) * t ;
mVelocity.normalize();
mVelocity *= vMag;
}
}
}
else
{
//Con::warnf("Inside HookLen");
}
}
//<-EGHRENDERING:
add this function to the end of player.cc
this function lets us draw a line for the grappling hook rope
//EGH
void Player::renderObject(SceneState* state, SceneRenderImage* image)
{
Parent::renderObject(state, image);
if(hookLen != -1 )
{
//draw the rope
MatrixF xf(true);
getMountTransform(0,&xf);
Point3F pos;
xf.getColumn(3,&pos);
VectorF t;
t = getPosition() - hookPos;
float dist;
dist = mSqrt((t.x * t.x) + (t.y * t.y) + (t.z * t.z));
float zoffset;
zoffset = sqrt(hookLen*hookLen - dist*dist);
zoffset *= 1/10;
t *= 1/10;
glColor4fv(ColorF(1.0, 1.0, 1.0, 0.5));
glBegin(GL_LINE_LOOP);
MatrixF mat;
getRenderImageTransform(0, &mat);
pos = mat.getPosition();
// Draw Vertex.
/*for(int i = 0; i < 10; i++)
{
glVertex3f( hookPos.x + (t.x * i),
hookPos.y + (t.y * i),
hookPos.z + (t.z * i) + (i%2));
}*/
glVertex3f( (hookPos.x + (t.x * 5)),
(hookPos.y + (t.y * 5)),
(hookPos.z + (t.z * 5)) );
glVertex3f( pos.x,
pos.y,
pos.z);
glEnd();
}
}
//<-EGHNETWORK:
This part needs fixing as it's really inefficient network-wise. it gets it working though.
An ideal solution would be to predict this info on the client using a special property of a projectile
in Player::packUpdate, add these lines to the very beginning
//EGH stream->write(hookPos.x); // stream->write(hookPos.y); // stream->write(hookPos.z); // stream->write(hookLen); // //<-EGH
and add these to the beginning of Player::unpackUpdate
//EGH stream->read(&hookPos.x); stream->read(&hookPos.y); stream->read(&hookPos.z); stream->read(&hookLen); //<-EGH
#8
I made this before consolemethod was around so it uses the old style.
Put this above Player::consoleInit()
add these to Player::consoleInit()
09/02/2004 (8:51 am)
SCRIPT CONNECTIONS:I made this before consolemethod was around so it uses the old style.
Put this above Player::consoleInit()
//EGH
static bool cSetHookPos(SimObject *ptr, S32, const char **argv)
{
Player* obj = static_cast<Player*>(ptr);
VectorF vel(0,0,0);
dSscanf(argv[2],"%f %f %f",&vel.x,&vel.y,&vel.z);
obj->setHookPos(vel);
//obj->setControlDirty();
return true;
}
static bool cSetHookLen(SimObject *ptr, S32, const char **argv)
{
Player* obj = static_cast<Player*>(ptr);
F32 Len;
dSscanf(argv[2],"%f",&Len);
obj->setHookLen(Len);
//obj->setControlDirty();
return true;
}
//<-EGHadd these to Player::consoleInit()
//EGH
Con::addCommand("Player", "setHookPos", cSetHookPos, "obj.setHookPos(Vector)", 3, 3);
Con::addCommand("Player", "setHookLen", cSetHookLen, "obj.setHookLen(Float)", 3, 3);
//<-EGH
#9
Argh this is weak but i gotta go to work.
To get this working, all you need to do now is make a projectile called hookprojectile and add this function
then make a weapon image called hookimage and add this script function
09/02/2004 (8:55 am)
SCRIPT:Argh this is weak but i gotta go to work.
To get this working, all you need to do now is make a projectile called hookprojectile and add this function
function hookProjectile::onCollision(%this,%obj,%col,%fade,%pos,%normal)
{
//messageall(type, 'projectile collision col = %1', %col);
// Apply damage to the object all shape base objects
if (%col.getType() & ($TypeMasks::StaticObjectType | $TypeMasks::InteriorObjectType | $TypeMasks::TerrainObjectType))
{
%obj.client.player.setHookPos(%pos);
%len = vectorSub(%obj.client.player.getPosition(), %pos);
echo("hook length = ", vectorLen(%len));
%obj.client.player.setHookLen(vectorLen(%len));
}
}then make a weapon image called hookimage and add this script function
function hookImage::onFire(%this, %obj, %slot)
{
%obj.client.player.setHookLen(-1);
%projectile = %this.projectile;
// Decrement inventory ammo. The image's ammo state is update
// automatically by the ammo inventory hooks.
//%obj.decInventory(%this.ammo,1);
// Determin initial projectile velocity based on the
// gun's muzzle point and the object's current velocity
%muzzleVector = %obj.getMuzzleVector(%slot);
%objectVelocity = %obj.getVelocity();
%muzzleVelocity = VectorAdd(
VectorScale(%muzzleVector, %projectile.muzzleVelocity),
VectorScale(%objectVelocity, %projectile.velInheritFactor));
// Create the projectile object
%p = new (%this.projectileType)() {
dataBlock = %projectile;
initialVelocity = %muzzleVelocity;
initialPosition = %obj.getMuzzlePoint(%slot);
sourceObject = %obj;
sourceSlot = %slot;
client = %obj.client;
};
MissionCleanup.add(%p);
return %p;
}
#10
09/02/2004 (8:56 am)
I didnt test it but i think it works.
#11
09/02/2004 (7:00 pm)
Awesome , only one way to find out, i should get time this weekend (3day). Man that kinda gets my blood pumpin! Thanks.
#12
I'm working on my bachelors in game design, and have started building characters and building for the game.
I don't know alot about the torque programming tho.
Everyone should own the All In One book, it's a great resource for the starters out there!
Eric you will be put into the credits!
09/03/2004 (9:39 pm)
Holy crud thank you Eric! I'm new to programming and this is great!I'm working on my bachelors in game design, and have started building characters and building for the game.
I don't know alot about the torque programming tho.
Everyone should own the All In One book, it's a great resource for the starters out there!
Eric you will be put into the credits!
#13
09/20/2004 (5:23 pm)
I just tried it and I dont know if its just me but when I start the game, I see a white string from my hand that goes to the ground and I cant move. Whats going on?
#14
09/21/2004 (7:29 am)
Thats the grappling hook. Firing the hook into the air should clear it out and allow you to move
#15
05/09/2005 (11:21 am)
Anyone attempt to move this code into a new projectile class?
#16
how do I make this update from the script?
10/20/2006 (11:48 am)
Question: I tried to put in a simple "gather" action that just decrements hooklen repeatedly while you hold down the trigger, and the hookLen variable is definitely diminishing, but the player doesn't move (and the line doesn't get shorter) until I cause update move to be called again by jumping or running....how do I make this update from the script?
function HookImage::onGather(%this, %obj, %slot)
{
echo("onGather: pre-hook length = ", %obj.client.player.getHookLen());
%tt = %obj.client.player.getHookLen();
if (%tt > 0.1)
{
%tt = %tt - 0.1;
}
else
{
%tt = 0;
}
%obj.client.player.setHookLen(%tt);
echo("onGather: post-hook length = ", %obj.client.player.getHookLen());
}
#17
ok some wacky things when I implemented this:
first I get a straight white line comming out of the bottom of the player, and all the AIs
my 'w' now works as a left side step for no apparant reason at all lol
I mounted the image to the player (using just the crossbow right nowas the 'image') and nothing happens when I shoot, im sure I have overlooked something just not sure as to what.
Any ideas?
10/24/2006 (4:23 pm)
Lolok some wacky things when I implemented this:
first I get a straight white line comming out of the bottom of the player, and all the AIs
my 'w' now works as a left side step for no apparant reason at all lol
I mounted the image to the player (using just the crossbow right nowas the 'image') and nothing happens when I shoot, im sure I have overlooked something just not sure as to what.
Any ideas?
#18
02/04/2007 (12:29 am)
Anyone have this working with 1.5? Getting a bunch of errors during the compile.c:\torque\sdk\engine\game\player.cc(1621) : error C2065: 'hookPos' : undeclared identifier
c:\torque\sdk\engine\game\player.cc(1623) : error C2065: 'hookLen' : undeclared identifier
c:\torque\sdk\engine\game\player.cc(3511) : error C2228: left of '.x' must have class/struct/union
type is ''unknown-type''
c:\torque\sdk\engine\game\player.cc(3512) : error C2228: left of '.y' must have class/struct/union
type is ''unknown-type''
c:\torque\sdk\engine\game\player.cc(3513) : error C2228: left of '.z' must have class/struct/union
type is ''unknown-type''
c:\torque\sdk\engine\game\player.cc(3587) : error C2228: left of '.x' must have class/struct/union
type is ''unknown-type''
c:\torque\sdk\engine\game\player.cc(3588) : error C2228: left of '.y' must have class/struct/union
type is ''unknown-type''
c:\torque\sdk\engine\game\player.cc(3589) : error C2228: left of '.z' must have class/struct/union
type is ''unknown-type''
c:\torque\sdk\engine\game\player.cc(3825) : error C2039: 'setHookPos' : is not a member of 'Player'
c:\torque\sdk\engine\game\player.h(236) : see declaration of 'Player'
c:\torque\sdk\engine\game\player.cc(3835) : error C2039: 'setHookLen' : is not a member of 'Player'
c:\torque\sdk\engine\game\player.h(236) : see declaration of 'Player'
c:\torque\sdk\engine\game\player.cc(4381) : error C2509: 'renderObject' : member function not declared in 'Player'
c:\torque\sdk\engine\game\player.h(236) : see declaration of 'Player'
Creating browse information file...
Microsoft Browse Information Maintenance Utility Version 8.00.50727
Copyright (C) Microsoft Corporation. All rights reserved.
Build log was saved at "file://c:\Torque\SDK\engine\out.VC8.DEBUG\BuildLog.htm"
Torque Demo - 11 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 6 up-to-date, 0 skipped ==========
#19
03/12/2007 (12:38 pm)
This is basicly what ive been searching for i havent dowloaded and tested yet but i want to see if it works with 1.5 ...awsome
#20
player.h -> somewhere in a public section
FYI, it compiles with 1.5, haven't tested it in a game yet.
Initializing the hook members in the Player::Player() should also fix the "stuck when I start the game" and "white line that points down" problems I read about in this thread. But again, not tested.
Add these to the Player constructor:
hookLen = -1;
hookPos.set(0, 0, 0);
I'm sort of hoping that I can modify this easilly so that I can drag objects along with it.
04/04/2007 (12:34 pm)
Christian, you forgot the header definitions.player.h -> somewhere in a public section
//EGH //grapling hook stuff
Point3F hookPos;
F32 hookLen;
void setHookPos(const VectorF& newHookPos) { hookPos = newHookPos; };
void setHookLen(const F32& newHookLen) { hookLen = newHookLen; };
void Player::renderObject(SceneState* state, SceneRenderImage* image);
//<-EGHFYI, it compiles with 1.5, haven't tested it in a game yet.
Initializing the hook members in the Player::Player() should also fix the "stuck when I start the game" and "white line that points down" problems I read about in this thread. But again, not tested.
Add these to the Player constructor:
hookLen = -1;
hookPos.set(0, 0, 0);
I'm sort of hoping that I can modify this easilly so that I can drag objects along with it.
Torque Owner Ace
I have a src to a real grapple for quake 2 written in "c". This third party swinging grapple is loaded with all the goodies a grapple needs , ( it wont pull stuff to it though, although i like the "idea").
heres a link, maybe someone will get it done before i could.
cleverace.home.comcast.net/~cleverace/quake/hook.HTM