Author Topic: Q2 Mod Coding  (Read 4207 times)

Offline quadz

  • Loquaciously Multiloquent Member
  • ****
  • Posts: 5352
    • View Profile
  • Rated:
Q2 Mod Coding
« on: July 22, 2009, 09:15:55 PM »
Hola...

I was toying with xatrix mod a bit this afternoon, trying to make the traps able to take damage.

So far, I've only been partially successful.  They do get hit by splash (radius) damage.  But I have not been able to hit them with a gi.trace() style impact.

At present, I presume there are two probable alternatives... (1) some flags are set incorrectly so that gi.trace() is ignoring the trap entity; or (2) its bounding box is set to something so tiny I just can't hit it.

I tried setting its mins/maxs to a large box, but this only seems to affect its movement when thrown, i still can't hit it with non-splash damage.

Here is the current code, with my current (experimental) changes hilighted:

static void trap_pain (edict_t *self, edict_t *other, float kick, int damage)
{
    gi.bprintf(PRINT_HIGH, "trap_pain: dmg=%d\n", damage);
}

static void trap_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
{
    gi.bprintf(PRINT_HIGH, "trap_die: dmg=%d\n", damage);
}


void fire_trap (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed, float timer, float damage_radius, qboolean held)
{
    edict_t *trap;
    vec3_t  dir;
    vec3_t  forward, right, up;

    vectoangles (aimdir, dir);
    AngleVectors (dir, forward, right, up);

    trap = G_Spawn();
    VectorCopy (start, trap->s.origin);
    VectorScale (aimdir, speed, trap->velocity);
    VectorMA (trap->velocity, 200 + crandom() * 10.0, up, trap->velocity);
    VectorMA (trap->velocity, crandom() * 10.0, right, trap->velocity);
    VectorSet (trap->avelocity, 0, 300, 0);
    trap->movetype = MOVETYPE_BOUNCE;
    trap->solid = SOLID_BBOX;

    // %%quadz - killable traps {
    trap->svflags |= SVF_MONSTER;
    trap->clipmask = MASK_MONSTERSOLID;  // was: MASK_SHOT
    trap->deadflag = DEAD_NO;
    trap->svflags &= ~SVF_DEADMONSTER;

    trap->takedamage = DAMAGE_YES;
    trap->health = TRAP_DEFAULT_HEALTH;
    trap->pain = trap_pain;
    trap->die = trap_die;
    VectorSet(trap->mins, -64, -64, 0);  // was: (trap->mins, -4, -4, 0)
    VectorSet(trap->maxs, 64, 64, 128);  // was: (trap->maxs, 4, 4, 8)
    // %%quadz - }


    // Nick - add define
    //trap->s.modelindex = gi.modelindex ("models/weapons/z_trap/tris.md2");
    trap->s.modelindex = gi.modelindex (TRAP_MODEL);
    trap->owner = self;
    trap->nextthink = level.time + 1.0;
    trap->think = Trap_Think;
    trap->dmg = damage;
    trap->dmg_radius = damage_radius;
    trap->classname = "htrap";
    // RAFAEL 16-APR-98
    // Nick - Add define
    //trap->s.sound = gi.soundindex ("weapons/traploop.wav");
    trap->s.sound = gi.soundindex (TRAPLOOP_SOUND);
    // END 16-APR-98

    if (held)
        trap->spawnflags = 3;
    else
        trap->spawnflags = 1;
   
    if ((held) && timer <= 0.0) // If player just died (< 0 health) throw trap not explode it.
        Trap_Explode (trap);
    else
    {
        gi.linkentity (trap);
    }

    trap->timestamp = level.time + TRAP_DEFAULT_LIFETIME;
}



Anyway, figured I'd ask, in case anyone who's familiar with Q2 modding might have some tips.


Thx,

quadz

  • Insightful
    Informative
    Funny
    Nice Job / Good Work
    Rock On
    Flawless Logic
    Well-Reasoned Argument and/or Conclusion
    Demonstrates Exceptional Knowlege of the Game
    Appears Not to Comprehend Game Fundamentals
    Frag of the Week
    Frag Hall of Fame
    Jump of the Week
    Jump Hall of Fame
    Best Solution
    Wins The Internet
    Whoosh! You done missed the joke thar Cletus!
    Obvious Troll Is Obvious
    DO YOU EVEN LIFT?
    DEMO OR STFU
    Offtopic
    Flamebait
    Redundant
    Factually Challenged
    Preposterously Irrational Arguments
    Blindingly Obvious Logical Fallacies
    Absurd Misconstrual of Scientific Principles or Evidence
    Amazing Conspiracy Theory Bro
    Racist Ignoramus
"He knew all the tricks, dramatic irony, metaphor, bathos, puns, parody, litotes and... satire. He was vicious."

Offline peewee_RotA

  • Brobdingnagian Member
  • ***
  • Posts: 4152
  • Hi, I'm from the gov'ment and I'm here to help you
    • View Profile
  • Rated:
Re: Q2 Mod Coding
« Reply #1 on: July 23, 2009, 03:47:34 AM »
I'm pretty sure that:
trap->svflags &= ~SVF_DEADMONSTER;

causes it to get ignored.

Here's what ninja of comp says on the issue:
http://webadvisor.aupr.edu/noc/Othertutorials/qdevels/-%20Vulnerable%20Rockets%20.html

P.S. The min maxes that you used are the same as the SuperTank I believe. :P
« Last Edit: July 23, 2009, 03:51:47 AM by peewee_RotA »
  • Insightful
    Informative
    Funny
    Nice Job / Good Work
    Rock On
    Flawless Logic
    Well-Reasoned Argument and/or Conclusion
    Demonstrates Exceptional Knowlege of the Game
    Appears Not to Comprehend Game Fundamentals
    Frag of the Week
    Frag Hall of Fame
    Jump of the Week
    Jump Hall of Fame
    Best Solution
    Wins The Internet
    Whoosh! You done missed the joke thar Cletus!
    Obvious Troll Is Obvious
    DO YOU EVEN LIFT?
    DEMO OR STFU
    Offtopic
    Flamebait
    Redundant
    Factually Challenged
    Preposterously Irrational Arguments
    Blindingly Obvious Logical Fallacies
    Absurd Misconstrual of Scientific Principles or Evidence
    Amazing Conspiracy Theory Bro
    Racist Ignoramus
GOTO ROTAMODS (rocketgib)
GOTO ROTAMAPS (fireworks)
HappyFriar- q2server.fuzzylogicinc.com
 Tune in to the Tastycast!!!!  http://dna.zeliepa.net

Offline quadz

  • Loquaciously Multiloquent Member
  • ****
  • Posts: 5352
    • View Profile
  • Rated:
Re: Q2 Mod Coding
« Reply #2 on: July 23, 2009, 04:39:33 AM »
Thanks.

Actually there were two issues.  R1ch pointed out that the 'owner' can't shoot its own items.  But there was a further issue, that some number of frames after the trap lands, its Think routine would clear its mins,maxs size.

After working around those issues, I can now damage the trap... however, when the mins,maxs aren't cleared, one can't quite reach the trap to where it thinks it has sucked the player in.

That's where it currently stands... I'll either try messing with its clip flags so the player doesn't clip against it (if possible), or I guess i'll fudge it and add an epsilon to its kill distance...

But anyway... been fun so far...  :dohdohdoh:

quadz
  • Insightful
    Informative
    Funny
    Nice Job / Good Work
    Rock On
    Flawless Logic
    Well-Reasoned Argument and/or Conclusion
    Demonstrates Exceptional Knowlege of the Game
    Appears Not to Comprehend Game Fundamentals
    Frag of the Week
    Frag Hall of Fame
    Jump of the Week
    Jump Hall of Fame
    Best Solution
    Wins The Internet
    Whoosh! You done missed the joke thar Cletus!
    Obvious Troll Is Obvious
    DO YOU EVEN LIFT?
    DEMO OR STFU
    Offtopic
    Flamebait
    Redundant
    Factually Challenged
    Preposterously Irrational Arguments
    Blindingly Obvious Logical Fallacies
    Absurd Misconstrual of Scientific Principles or Evidence
    Amazing Conspiracy Theory Bro
    Racist Ignoramus
"He knew all the tricks, dramatic irony, metaphor, bathos, puns, parody, litotes and... satire. He was vicious."

SpawnGirl

  • Guest
Re: Q2 Mod Coding
« Reply #3 on: July 23, 2009, 05:52:28 AM »
 :'( :'( :'( :'( :'( :'( :'(

Im not agree
Before you could kill people been trapped and finally to escape
Thats funny too.

Now you dont have scape, i don know
before of thinking about that im not sure about the idea
  • Insightful
    Informative
    Funny
    Nice Job / Good Work
    Rock On
    Flawless Logic
    Well-Reasoned Argument and/or Conclusion
    Demonstrates Exceptional Knowlege of the Game
    Appears Not to Comprehend Game Fundamentals
    Frag of the Week
    Frag Hall of Fame
    Jump of the Week
    Jump Hall of Fame
    Best Solution
    Wins The Internet
    Whoosh! You done missed the joke thar Cletus!
    Obvious Troll Is Obvious
    DO YOU EVEN LIFT?
    DEMO OR STFU
    Offtopic
    Flamebait
    Redundant
    Factually Challenged
    Preposterously Irrational Arguments
    Blindingly Obvious Logical Fallacies
    Absurd Misconstrual of Scientific Principles or Evidence
    Amazing Conspiracy Theory Bro
    Racist Ignoramus

Offline peewee_RotA

  • Brobdingnagian Member
  • ***
  • Posts: 4152
  • Hi, I'm from the gov'ment and I'm here to help you
    • View Profile
  • Rated:
Re: Q2 Mod Coding
« Reply #4 on: July 23, 2009, 06:38:22 AM »
Thanks.

Actually there were two issues.  R1ch pointed out that the 'owner' can't shoot its own items.  But there was a further issue, that some number of frames after the trap lands, its Think routine would clear its mins,maxs size.

After working around those issues, I can now damage the trap... however, when the mins,maxs aren't cleared, one can't quite reach the trap to where it thinks it has sucked the player in.

That's where it currently stands... I'll either try messing with its clip flags so the player doesn't clip against it (if possible), or I guess i'll fudge it and add an epsilon to its kill distance...

But anyway... been fun so far...  :dohdohdoh:

quadz


Possible but really weird. I do something similar in Megaman quake 2 using the charged mega buster.

I'll look into it an post some code snippits latter.


But wait... shouldn't it activate that entity's touch function regardless when the player's bbox touches the trap's bbox?
« Last Edit: July 23, 2009, 06:40:00 AM by peewee_RotA »
  • Insightful
    Informative
    Funny
    Nice Job / Good Work
    Rock On
    Flawless Logic
    Well-Reasoned Argument and/or Conclusion
    Demonstrates Exceptional Knowlege of the Game
    Appears Not to Comprehend Game Fundamentals
    Frag of the Week
    Frag Hall of Fame
    Jump of the Week
    Jump Hall of Fame
    Best Solution
    Wins The Internet
    Whoosh! You done missed the joke thar Cletus!
    Obvious Troll Is Obvious
    DO YOU EVEN LIFT?
    DEMO OR STFU
    Offtopic
    Flamebait
    Redundant
    Factually Challenged
    Preposterously Irrational Arguments
    Blindingly Obvious Logical Fallacies
    Absurd Misconstrual of Scientific Principles or Evidence
    Amazing Conspiracy Theory Bro
    Racist Ignoramus
GOTO ROTAMODS (rocketgib)
GOTO ROTAMAPS (fireworks)
HappyFriar- q2server.fuzzylogicinc.com
 Tune in to the Tastycast!!!!  http://dna.zeliepa.net

Offline [BTF] Reflex

  • Loquaciously Multiloquent Member
  • ****
  • Posts: 5324
  • !
    • View Profile
  • Rated:
Re: Q2 Mod Coding
« Reply #5 on: September 02, 2009, 05:20:43 AM »
I liked the idea of rockets/grenades taking damage.

I've faked that,  firing a grenade and railing it at time of explosion :)



I've also been guilty of trying to shoot traps while trapped in them real early in my xatrix career.
Awesome to see it worked on.
  • Insightful
    Informative
    Funny
    Nice Job / Good Work
    Rock On
    Flawless Logic
    Well-Reasoned Argument and/or Conclusion
    Demonstrates Exceptional Knowlege of the Game
    Appears Not to Comprehend Game Fundamentals
    Frag of the Week
    Frag Hall of Fame
    Jump of the Week
    Jump Hall of Fame
    Best Solution
    Wins The Internet
    Whoosh! You done missed the joke thar Cletus!
    Obvious Troll Is Obvious
    DO YOU EVEN LIFT?
    DEMO OR STFU
    Offtopic
    Flamebait
    Redundant
    Factually Challenged
    Preposterously Irrational Arguments
    Blindingly Obvious Logical Fallacies
    Absurd Misconstrual of Scientific Principles or Evidence
    Amazing Conspiracy Theory Bro
    Racist Ignoramus
Sometimes I think it’s a sin when I feel like I’m winnin’ when I’m losin’ again

Offline peewee_RotA

  • Brobdingnagian Member
  • ***
  • Posts: 4152
  • Hi, I'm from the gov'ment and I'm here to help you
    • View Profile
  • Rated:
Re: Q2 Mod Coding
« Reply #6 on: November 17, 2009, 09:27:59 AM »
I never posted this like I said I would  :oops:


Better late than never lol.


Here's is Megaman's X-Buster code. If a charged plasma blast touches a player and kills it, it will reduce the damage and continue through that object. This is very tricky but works out fairly well in practice.

Code: [Select]
/*
=================
X-Buster
=================
*/
void xbuster_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
{
if (other == self->owner)
return;

if (self->owner->client)
PlayerNoise(self->owner, self->s.origin, PNOISE_IMPACT);

if (other->takedamage)
{
T_Damage (other, self, self->owner, self->velocity, self->s.origin, plane->normal, self->dmg, 1, DAMAGE_ENERGY, MOD_BUSTER);
}
else
{
gi.WriteByte (svc_temp_entity);
gi.WriteByte (TE_BLASTER);
gi.WritePosition (self->s.origin);
if (!plane)
gi.WriteDir (vec3_origin);
else
gi.WriteDir (plane->normal);
gi.multicast (self->s.origin, MULTICAST_PVS);
}

//if count was true
if (self->radius_dmg == 1)
G_FreeEdict(self); //simply destroy ent
else
remove_shot(self); //decrement shot and remove object
}

void cblaster_pass (edict_t *ent)
{
vec3_t v;
VectorCopy(ent->cutterangle, v);

VectorNormalize(v);

//restore original velocity
vectoangles(v, ent->s.angles);
VectorCopy(v, ent->movedir);
VectorScale(v, 700, ent->velocity);

//if count was true
if (ent->radius_dmg == 1)
ent->think = G_FreeEdict; //simply destroy ent
else
ent->think = remove_shot;
ent->nextthink = level.time + 1;
}

void cblaster_touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
{
vec3_t origin;
int n;

int rdam, damr;

rdam = 45;
damr = 45;

if (other == ent->owner)
return;

if (other->takedamage)
{
int newdmg;
newdmg = ent->dmg - other->health; //calculate new damage by subtracting other health from damage

T_Damage (other, ent, ent->owner, ent->velocity, ent->s.origin, plane->normal, ent->dmg, 0, 0, MOD_BUSTER);

ent->dmg = newdmg; //we did the damage so change the damage for next touch

if (ent->dmg > 0) //if there still is any dmg left then don't destroy bolt
{
ent->think = cblaster_pass;
ent->nextthink = level.time + 0.01;

//return so it doesnt get destroyed
return;
}
}



if (ent->owner->client)
PlayerNoise(ent->owner, ent->s.origin, PNOISE_IMPACT);

// calculate position for the explosion entity
VectorMA (ent->s.origin, -0.02, ent->velocity, origin);

// T_RadiusDamage(ent, ent->owner, rdam, other, damr, MOD_BLASTER);

gi.WriteByte (svc_temp_entity);
gi.WriteByte (TE_TELEPORT_EFFECT);
gi.WritePosition (origin);
gi.multicast (ent->s.origin, MULTICAST_PHS);

if (ent->radius_dmg == 1)
G_FreeEdict(ent); //simply destroy ent
else
remove_shot(ent); //decrement shot and remove object
}

void sblaster_touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
{
vec3_t origin;
int n;

int rdam, damr;

rdam = 80;
damr = 100;

if (other == ent->owner)
return;

if (other->takedamage)
{
int newdmg;
newdmg = ent->dmg - other->health; //calculate new damage by subtracting other health from damage

T_Damage (other, ent, ent->owner, ent->velocity, ent->s.origin, plane->normal, ent->dmg, 0, 0, MOD_SABRE_BLAST);

ent->dmg = newdmg; //we did the damage so change the damage for next touch

if (ent->dmg > 0) //if there still is any dmg left then don't destroy bolt
{
ent->think = cblaster_pass;
ent->nextthink = level.time + 0.01;

//return so it doesnt get destroyed
return;
}
}



if (ent->owner->client)
PlayerNoise(ent->owner, ent->s.origin, PNOISE_IMPACT);

// calculate position for the explosion entity
VectorMA (ent->s.origin, -0.02, ent->velocity, origin);

T_RadiusDamage(ent, ent->owner, rdam, other, damr, MOD_SABRE_BLAST);

gi.WriteByte (svc_temp_entity);
gi.WriteByte (TE_PLAIN_EXPLOSION);
gi.WritePosition (origin);
gi.multicast (ent->s.origin, MULTICAST_PHS);

//if count was true
if (ent->radius_dmg == 1)
G_FreeEdict(ent); //simply destroy ent
else
remove_shot(ent); //decrement shot and remove object
}


void fire_cblaster (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, int type, qboolean count)
{
edict_t *bolt;
trace_t tr;

VectorNormalize (dir);

bolt = G_Spawn();
bolt->svflags = SVF_DEADMONSTER;
VectorCopy (start, bolt->s.origin);
VectorCopy (start, bolt->s.old_origin);
vectoangles (dir, bolt->s.angles);
VectorScale (dir, speed, bolt->velocity);

//copy beginning velocity to temp variable in case we need to continue moving
VectorCopy(dir, bolt->cutterangle);

bolt->movetype = MOVETYPE_FLYMISSILE;
bolt->clipmask = MASK_SHOT;
bolt->solid = SOLID_BBOX;
VectorClear (bolt->mins);
VectorClear (bolt->maxs);
bolt->s.modelindex = gi.modelindex ("models/objects/plasma/tris.md2");
bolt->touch = xbuster_touch;
bolt->s.effects |= EF_COLOR_SHELL;

if (type == 0)
{
bolt->s.renderfx |= (RF_SHELL_RED|RF_SHELL_GREEN);
}
else if (type == 1)
{
VectorSet(bolt->mins, -2, -2, -2);
VectorSet(bolt->maxs, 2, 2, 2);
bolt->s.effects |= EF_BLASTER;
bolt->s.modelindex = gi.modelindex ("models/objects/plasma2/tris.md2");
bolt->s.renderfx |= (RF_SHELL_GREEN);
}
else if (type == -1)
{
VectorSet(bolt->mins, -8, -8, -8);
VectorSet(bolt->maxs, 8, 8, 8);

bolt->s.modelindex = gi.modelindex ("models/objects/sblast/tris.md2");
bolt->s.effects = EF_BLASTER;

bolt->touch = sblaster_touch;
}
else
{
//if we have charge upgrade and charged above 2
if (self->client->pers.enhance == ENH_CHARG && type > 2)
{
bolt->s.effects |= EF_ROCKET;
bolt->s.renderfx |= (RF_SHELL_RED);
}
else
{
bolt->s.effects |= EF_GRENADE;
bolt->s.renderfx |= (RF_SHELL_BLUE);
}

VectorSet(bolt->mins, -8, -8, -8);
VectorSet(bolt->maxs, 8, 8, 8);

bolt->s.modelindex = gi.modelindex ("models/objects/plasma3/tris.md2");
bolt->touch = cblaster_touch;
}

//if we decided not to count (blaster2 or tank)
if (!count)
{
bolt->radius_dmg = 1; //mark as not counting
bolt->think = G_FreeEdict; //set think to only remove without counting down
}
else
{
bolt->radius_dmg = 0; //mark as counting
bolt->think = remove_shot; //set think to remove shot and count down
}

bolt->owner = self;
bolt->nextthink = level.time + 3;

//for plasma type 3 damage will be used as health
bolt->dmg = damage;

bolt->classname = "bolt";
gi.linkentity (bolt);


tr = gi.trace (self->s.origin, NULL, NULL, bolt->s.origin, bolt, MASK_SHOT);
if (tr.fraction < 1.0)
{
VectorMA (bolt->s.origin, -10, dir, bolt->s.origin);
bolt->touch (bolt, tr.ent, NULL, NULL);
}
}
  • Insightful
    Informative
    Funny
    Nice Job / Good Work
    Rock On
    Flawless Logic
    Well-Reasoned Argument and/or Conclusion
    Demonstrates Exceptional Knowlege of the Game
    Appears Not to Comprehend Game Fundamentals
    Frag of the Week
    Frag Hall of Fame
    Jump of the Week
    Jump Hall of Fame
    Best Solution
    Wins The Internet
    Whoosh! You done missed the joke thar Cletus!
    Obvious Troll Is Obvious
    DO YOU EVEN LIFT?
    DEMO OR STFU
    Offtopic
    Flamebait
    Redundant
    Factually Challenged
    Preposterously Irrational Arguments
    Blindingly Obvious Logical Fallacies
    Absurd Misconstrual of Scientific Principles or Evidence
    Amazing Conspiracy Theory Bro
    Racist Ignoramus
GOTO ROTAMODS (rocketgib)
GOTO ROTAMAPS (fireworks)
HappyFriar- q2server.fuzzylogicinc.com
 Tune in to the Tastycast!!!!  http://dna.zeliepa.net

Offline peewee_RotA

  • Brobdingnagian Member
  • ***
  • Posts: 4152
  • Hi, I'm from the gov'ment and I'm here to help you
    • View Profile
  • Rated:
Re: Q2 Mod Coding
« Reply #7 on: November 17, 2009, 09:51:33 AM »
This may be more applicable:

For phase shields that make any entity pass through you:


When a player gets shot in g_combat.c and they have a phase shield:

Code: [Select]
//peewee start
//phase shield
//if target is a client
if (targ->client)
{
//if target has a phase shield and
//we are still alive
if (targ->client->pers.enhance == ENH_PHASE &&
targ->health > 0)
{
//make unable to take damage
targ->takedamage = false;
targ->solid = SOLID_NOT;

//set time limit
targ->client->pers.blast_time = level.time + 1.5;

}
}

And when the timer expires in Client Think in p_client.c
Code: [Select]
//phase shield
else if (ent->client->pers.enhance == ENH_PHASE)
{
if (ent->client->pers.blast_time < level.time)
{
//remove partially invisible
//ent->s.effects = 0;
ent->s.renderfx = 0;
ent->solid = SOLID_BBOX;

//make able to take damage again
ent->takedamage = true;
}
}
//peewee end



And then rolling cutters that pass through living objects. This is probably the strangest, trickiest , and buggiest attempt at a similar function

Code: [Select]
//------------------------------
// CUTTER
//------------------------------
void cutter_touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf);

void cutter_think (edict_t *ent)
{
//decrement time
ent->health--;

//if time runs out
if (ent->health == 0)
{
//decrement shot and remove object
remove_shot(ent);
return; //stop thinking
}
else //otherwise
ent->nextthink = level.time + 0.1; //keep thinking


//dont start spin for 0.4 seconds
if (ent->health < 26)
{
//add spin
vec3_t v, f;

v[PITCH] = ent->cutterangle[PITCH];

//if a player shot this
if (ent->owner && ent->owner->client)
{
//adjust curve for left hand
if (ent->owner->client->pers.hand == LEFT_HANDED)
v[YAW]   = ent->cutterangle[YAW] -= 25;
else
v[YAW]   = ent->cutterangle[YAW] += 25;
}
else //otherwise use the same spin
v[YAW]   = ent->cutterangle[YAW] += 25;


v[ROLL]  = ent->cutterangle[ROLL];
AngleVectors (v, f, NULL, NULL);

VectorScale(f, 650, f);
VectorCopy(f, ent->velocity);
VectorCopy(v, ent->cutterangle);
}



//if we are currently not solid
if (ent->count)
{
//decrement timer
ent->count--;

//if timer is zero
if (ent->count == 0)
{
//make it touchable again
ent->solid = SOLID_BBOX;
ent->touch = cutter_touch;
}
}
}

void cutter_pass (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
{
return;
}


void cutter_touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
{
if (other == ent->owner)
return;

if (other->takedamage)
{
//we hit someone so do damage
T_Damage (other, ent, ent->owner, ent->velocity, ent->s.origin, plane->normal, ent->dmg, 0, 0, MOD_CUTTER);

//make cutter not solid so that it will pass through players
ent->solid = SOLID_NOT;
ent->touch = cutter_pass;

//tell cutter think that we are nonsolid by starting counter
ent->count = 3;

//cutter hit so start spinning
ent->nextthink = level.time;

}
else
{
//decrement shot and remove object
remove_shot(ent);
}
}

void fire_cutter (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, qboolean charged)
{
edict_t *bolt;
trace_t tr;

VectorNormalize (dir);

bolt = G_Spawn();
bolt->svflags = SVF_DEADMONSTER;
VectorCopy (start, bolt->s.origin);
VectorCopy (start, bolt->s.old_origin);
vectoangles (dir, bolt->s.angles);
VectorScale (dir, speed, bolt->velocity);
bolt->movetype = MOVETYPE_FLYMISSILE;
bolt->clipmask = MASK_SHOT;
bolt->solid = SOLID_BBOX;
VectorClear (bolt->mins);
VectorClear (bolt->maxs);
bolt->s.modelindex = gi.modelindex ("models/objects/cutter/tris.md2");
bolt->touch = cutter_touch;

if (charged)
{
bolt->s.effects |= EF_COLOR_SHELL;
bolt->s.renderfx |= (RF_SHELL_GREEN);
}


bolt->owner = self;

bolt->count = 0; //clear notsolid counter
bolt->health = 30; //initialize health timer
bolt->nextthink = level.time + 0.1;
bolt->think = cutter_think;

bolt->s.sound = gi.soundindex ("weapons/cutter.wav");


bolt->dmg = damage;
bolt->classname = "bolt";

//copy forward before adding spin
VectorCopy(bolt->s.angles, bolt->cutterangle);
//give cutter some spin
VectorSet(bolt->avelocity,0, -2000 ,0);

gi.linkentity (bolt);


tr = gi.trace (self->s.origin, NULL, NULL, bolt->s.origin, bolt, MASK_SHOT);
if (tr.fraction < 1.0)
{
VectorMA (bolt->s.origin, -10, dir, bolt->s.origin);
bolt->touch (bolt, tr.ent, NULL, NULL);
}
}
  • Insightful
    Informative
    Funny
    Nice Job / Good Work
    Rock On
    Flawless Logic
    Well-Reasoned Argument and/or Conclusion
    Demonstrates Exceptional Knowlege of the Game
    Appears Not to Comprehend Game Fundamentals
    Frag of the Week
    Frag Hall of Fame
    Jump of the Week
    Jump Hall of Fame
    Best Solution
    Wins The Internet
    Whoosh! You done missed the joke thar Cletus!
    Obvious Troll Is Obvious
    DO YOU EVEN LIFT?
    DEMO OR STFU
    Offtopic
    Flamebait
    Redundant
    Factually Challenged
    Preposterously Irrational Arguments
    Blindingly Obvious Logical Fallacies
    Absurd Misconstrual of Scientific Principles or Evidence
    Amazing Conspiracy Theory Bro
    Racist Ignoramus
GOTO ROTAMODS (rocketgib)
GOTO ROTAMAPS (fireworks)
HappyFriar- q2server.fuzzylogicinc.com
 Tune in to the Tastycast!!!!  http://dna.zeliepa.net

 

El Box de Shoutamente

Last 10 Shouts:

Costigan_Q2

November 11, 2024, 06:41:06 AM
"Stay cozy folks.

Everything is gonna be fine."

There'll be no excuses for having TDS after January 20th, there'll be no excuses AT ALL!!!
 

|iR|Focalor

November 06, 2024, 03:28:50 AM
 

RailWolf

November 05, 2024, 03:13:44 PM
Nice :)

Tom Servo

November 04, 2024, 05:05:24 PM
The Joe Rogan Experience episode 223 that dropped a couple hours ago with Musk, they're talking about Quake lol.

Costigan_Q2

November 04, 2024, 03:37:55 PM
Stay cozy folks.

Everything is gonna be fine.
 

|iR|Focalor

October 31, 2024, 08:56:37 PM

Costigan_Q2

October 17, 2024, 06:31:53 PM
Not activated your account yet?

Activate it now! join in the fun!

Tom Servo

October 11, 2024, 03:35:36 PM
HAHAHAHAHAHA
 

|iR|Focalor

October 10, 2024, 12:19:41 PM
I don't worship the devil. Jesus is Lord, friend. He died for your sins. He will forgive you if you just ask.
 

rikwad

October 09, 2024, 07:57:21 PM
Sorry, I couldn't resist my inner asshole.

Show 50 latest
Welcome, Guest. Please login or register.
November 24, 2024, 06:27:20 AM

Login with username, password and session length