#include "g_local.h" void rocket_touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf); static void check_dodge (edict_t *self, vec3_t start, vec3_t dir, int speed) { vec3_t end; vec3_t v; trace_t tr; float eta; // easy mode only ducks one quarter the time if (skill->value == 0) { if (random() > 0.25) return; } VectorMA (start, 8192, dir, end); tr = gi.trace (start, NULL, NULL, end, self, MASK_SHOT); if ((tr.ent) && (tr.ent->svflags & SVF_MONSTER) && (tr.ent->health > 0) && (tr.ent->monsterinfo.dodge) && infront(tr.ent, self)) { VectorSubtract (tr.endpos, start, v); eta = (VectorLength(v) - tr.ent->maxs[0]) / speed; tr.ent->monsterinfo.dodge (tr.ent, self, eta); } } static void P_ProjectSource (gclient_t *client, vec3_t point, vec3_t distance, vec3_t forward, vec3_t right, vec3_t result) { vec3_t _distance; VectorCopy (distance, _distance); if (client->pers.hand == LEFT_HANDED) _distance[1] *= -1; else if (client->pers.hand == CENTER_HANDED) _distance[1] = 0; G_ProjectSource (point, _distance, forward, right, result); } static void rocket_spiral_think(edict_t *ent) { vec3_t newpos, pos; VectorSubtract(ent->s.origin, ent->pos2, pos); RotatePointAroundVector(newpos, ent->pos1, pos, 30); VectorAdd(ent->pos2, newpos, ent->s.origin); RotatePointAroundVector(ent->velocity, ent->pos1, ent->velocity, 30); ent->nextthink = level.time + FRAMETIME; } void fire_spiral_rocket (edict_t *self, vec3_t start, vec3_t dir, vec3_t pos1, int damage, int speed, float damage_radius, int radius_damage) { edict_t *rocket; rocket = G_Spawn(); VectorCopy (pos1, rocket->pos1); VectorCopy (start, rocket->pos2); VectorCopy (start, rocket->s.origin); VectorCopy (dir, rocket->movedir); vectoangles (dir, rocket->s.angles); VectorScale (dir, speed, rocket->velocity); rocket->movetype = MOVETYPE_FLYMISSILE; rocket->clipmask = MASK_SHOT; rocket->solid = SOLID_BBOX; rocket->s.effects |= EF_ROCKET; VectorClear (rocket->mins); VectorClear (rocket->maxs); rocket->s.modelindex = gi.modelindex ("models/objects/rocket/tris.md2"); rocket->owner = self; rocket->touch = rocket_touch; rocket->nextthink = level.time + FRAMETIME; rocket->think = rocket_spiral_think; rocket->dmg = damage; rocket->radius_dmg = radius_damage; rocket->dmg_radius = damage_radius; rocket->s.sound = gi.soundindex ("weapons/rockfly.wav"); rocket->classname = "rocket"; if (self->client) check_dodge (self, rocket->s.origin, dir, speed); gi.linkentity (rocket); } void fire_streak (edict_t *self, vec3_t start, vec3_t dir, int damage, int mod)//fast blaster effectively. looks good. that's it tho. //it can't hurt people but i can't get the model to go through. also fucking laggy in net play. //streakoff 1/0 to turn on / off { edict_t *bolt; trace_t tr; int speed = 3000; if (streakoff->value) return; 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/streak/tris.md2"); bolt->s.effects |= EF_SPHERETRANS; bolt->s.renderfx = RF_FULLBRIGHT; bolt->owner = self; bolt->touch = matrix_streak_touch; bolt->nextthink = level.time + 0.6; bolt->think = G_FreeEdict; bolt->dmg = 0; bolt->classname = "bullet"; bolt->s.sound = gi.soundindex ("weapons/swish.wav"); gi.linkentity (bolt); if (self->client) check_dodge (self, bolt->s.origin, dir, speed); 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); } } void matrix_streak_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)//destroy streak if it hits anything. { if (other == self->owner) return; G_FreeEdict (self); } void Matrix_SpawnDeadBullet (edict_t *self, vec3_t dir, edict_t *target) { trace_t tr; edict_t *bolt; vec3_t forward, right; vec3_t start; vec3_t offset; vec3_t end; vec3_t blag; int speed = 1; gi.sound (self, CHAN_VOICE, gi.soundindex ("buletstp.wav"), 1, ATTN_NORM, 0); VectorSubtract(target->s.origin, self->s.origin, forward); VectorMA(forward, 0.6, self->s.origin, end); VectorNormalize(forward); if(!target->velocity[0] || !target->velocity[1]) SpawnShadow(target); //if standing still dodge effect bolt = G_Spawn(); bolt->svflags = SVF_DEADMONSTER; VectorCopy (end, bolt->s.origin); VectorCopy (end, bolt->s.old_origin); VectorScale (forward, speed, bolt->velocity); vectoangles (forward, bolt->s.angles); //bolt->velocity[2] = -80; bolt->movetype = MOVETYPE_BOUNCE; bolt->clipmask = MASK_SHOT; bolt->solid = SOLID_BBOX; VectorClear (bolt->mins); VectorClear (bolt->maxs); bolt->s.modelindex = gi.modelindex ("models/objects/shell1/tris.md2"); bolt->nextthink = level.time + 1.2; bolt->think = G_FreeEdict; bolt->classname = "bolt"; gi.linkentity (bolt); //if (self->client) // check_dodge (self, bolt->s.origin, dir, speed); } void matrix_fire_rocket (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, float damage_radius, int radius_damage) { edict_t *rocketa; edict_t *rocketb; edict_t *rocketc; vec3_t dir2; float temp = -1; while (temp<0) temp = random()*1 + 1; rocketa = G_Spawn(); rocketa->randomrocket = temp; VectorCopy (self->client->v_angle, dir2); dir2[PITCH] = self->client->v_angle[PITCH] + 8; AngleVectors (dir2, dir, NULL, NULL); VectorCopy (start, rocketa->s.origin); VectorCopy (dir, rocketa->movedir); VectorCopy(rocketa->s.origin, rocketa->s.old_origin); vectoangles (dir, rocketa->s.angles); VectorScale (dir, speed, rocketa->velocity); rocketa->movetype = MOVETYPE_MATRIXROCKET; rocketa->clipmask = MASK_SHOT; rocketa->solid = SOLID_BBOX; //rocketa->s.effects |= EF_TAGTRAIL; rocketa->s.effects |= EF_GRENADE; VectorClear (rocketa->mins); VectorClear (rocketa->maxs); rocketa->s.modelindex = gi.modelindex ("models/objects/rocket/tris.md2"); rocketa->owner = self; rocketa->touch = rocket_touch; rocketa->nextthink = level.time + 8000/speed; rocketa->think = G_FreeEdict; rocketa->dmg = damage; rocketa->radius_dmg = radius_damage; rocketa->dmg_radius = damage_radius; rocketa->s.sound = gi.soundindex ("weapons/rockfly.wav"); rocketa->classname = "rocket"; if (self->client) check_dodge (self, rocketa->s.origin, dir, speed); //////////////////////////////////////////////////////// rocketb = G_Spawn(); rocketb->randomrocket = temp; dir2[PITCH] = self->client->v_angle[PITCH] - 6; dir2[YAW] = self->client->v_angle[YAW] - 6; AngleVectors (dir2, dir, NULL, NULL); VectorCopy (start, rocketb->s.origin); VectorCopy (dir, rocketb->movedir); VectorCopy(rocketb->s.origin, rocketb->s.old_origin); vectoangles (dir, rocketb->s.angles); VectorScale (dir, speed, rocketb->velocity); rocketb->movetype = MOVETYPE_MATRIXROCKET; rocketb->clipmask = MASK_SHOT; rocketb->solid = SOLID_BBOX; //rocketb->s.effects |= EF_FLAG1; rocketb->s.effects |= EF_GRENADE; VectorClear (rocketb->mins); VectorClear (rocketb->maxs); rocketb->s.modelindex = gi.modelindex ("models/objects/rocket/tris.md2"); rocketb->owner = self; rocketb->touch = rocket_touch; rocketb->nextthink = level.time + 8000/speed; rocketb->think = G_FreeEdict; rocketb->dmg = damage; rocketb->radius_dmg = radius_damage; rocketb->dmg_radius = damage_radius; rocketb->s.sound = gi.soundindex ("weapons/rockfly.wav"); rocketb->classname = "rocket"; if (self->client) check_dodge (self, rocketb->s.origin, dir, speed); ///////////////////////////////////////////////// rocketc = G_Spawn(); rocketc->randomrocket = temp; dir2[PITCH] = self->client->v_angle[PITCH] - 6; dir2[YAW] = self->client->v_angle[YAW] + 6; AngleVectors (dir2, dir, NULL, NULL); VectorCopy (start, rocketc->s.origin); VectorCopy(rocketc->s.origin, rocketc->s.old_origin); VectorCopy (dir, rocketc->movedir); vectoangles (dir, rocketc->s.angles); VectorScale (dir, speed, rocketc->velocity); rocketc->movetype = MOVETYPE_MATRIXROCKET; rocketc->clipmask = MASK_SHOT; rocketc->solid = SOLID_BBOX; //rocketc->s.effects |= EF_FLAG2; rocketc->s.effects |= EF_GRENADE; VectorClear (rocketc->mins); VectorClear (rocketc->maxs); rocketc->s.modelindex = gi.modelindex ("models/objects/rocket/tris.md2"); rocketc->owner = self; rocketc->touch = rocket_touch; rocketc->nextthink = level.time + 8000/speed; rocketc->think = G_FreeEdict; rocketc->dmg = damage; rocketc->radius_dmg = radius_damage; rocketc->dmg_radius = damage_radius; rocketc->s.sound = gi.soundindex ("weapons/rockfly.wav"); rocketc->classname = "rocket"; if (self->client) check_dodge (self, rocketa->s.origin, dir, speed); rocketb->target_ent = rocketc; rocketa->target_ent = rocketb; rocketc->target_ent = rocketa; gi.linkentity (rocketb); gi.linkentity (rocketa); gi.linkentity (rocketc); } void VectorM (float scale, vec3_t vecb, vec3_t vecc) { vecc[0] = scale*vecb[0]; vecc[1] = scale*vecb[1]; vecc[2] = scale*vecb[2]; } void Matrix_Rocket_Think (edict_t *rocket) { vec3_t accel, accel2; VectorCopy(rocket->s.origin, rocket->s.old_origin); VectorSubtract(rocket->s.origin, rocket->target_ent->s.origin, accel); if(accel[0] > 300 || accel[0] < -300 || accel[1] > 300 || accel[1] < -300 || accel[2] > 300 || accel[2] < -300) return; VectorM(-rocket->randomrocket, accel, accel); VectorAdd(accel, rocket->velocity, rocket->velocity); } void KickBack (edict_t *ent, vec3_t dir, int kick) { vec3_t kickback; //ducking stops you moving if(ent->vertbuttons<0 && ent->groundentity) { ent->client->kick_angles[0] -= kick; return; } if(ent->groundentity) kick *= 60; else kick *= 40; VectorInverse(dir); VectorScale(dir, kick, dir); VectorAdd(dir, ent->velocity, ent->velocity); } void Matrix_KnifePin (edict_t *other, edict_t *attacker, vec3_t end) { other->pinned_nextthink = level.framenum + 15; VectorCopy(end, other->pinnedpos); if(other->client) gi.centerprintf (other, "%s pinned your ass to the wall.\n", attacker->client->pers.netname); } void knife_touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) { vec3_t origin, dir, end; // int n; edict_t *dropped; edict_t *knife; // vec3_t forward, right, up; vec3_t move_angles; gitem_t *item; trace_t tr; if (other == ent->owner) return; if (surf && (surf->flags & SURF_SKY)) { G_FreeEdict (ent); return; } if (ent->owner->client) { gi.sound(ent, CHAN_WEAPON, gi.soundindex("weapons/clank.wav"), 1, ATTN_NORM, 0); PlayerNoise(ent->owner, ent->s.origin, PNOISE_IMPACT); } // calculate position for the explosion entity VectorMA (ent->s.origin, -0.02, ent->velocity, origin); //glass fx if (0 == Q_stricmp(other->classname, "func_explosive")) { // ignore it, so it can bounce return; } else // --- if (other->takedamage) { T_Damage (other, ent, ent->owner, ent->velocity, ent->s.origin, plane->normal, ent->dmg, VectorLength (ent->velocity)/5, 1, MOD_KNIFE); VectorCopy(ent->velocity, dir); VectorNormalize(dir); VectorMA(dir, VectorLength(ent->velocity) , ent->s.origin, end); tr = gi.trace(ent->s.origin, vec3_origin, vec3_origin, end, ent, MASK_SOLID); VectorMA(dir, VectorLength(ent->velocity) * tr.fraction, ent->s.origin, end); if(tr.fraction<1) Matrix_KnifePin(other, ent->owner, end); } else { dropped = G_Spawn(); item = FindItem("Gung Ho Knives"); dropped->classname = item->classname; dropped->item = item; dropped->spawnflags = DROPPED_ITEM; dropped->s.effects = 0; dropped->s.renderfx = RF_GLOW; VectorSet (dropped->mins, -15, -15, -15); VectorSet (dropped->maxs, 15, 15, 15); gi.setmodel (dropped, item->world_model); dropped->solid = SOLID_TRIGGER; dropped->movetype = MOVETYPE_TOSS; dropped->touch = Touch_Item; dropped->owner = ent; dropped->gravity = 0; vectoangles (ent->velocity, move_angles); //AngleVectors (ent->s.angles, forward, right, up); VectorCopy (ent->s.origin, dropped->s.origin); VectorCopy (move_angles, dropped->s.angles); //VectorScale (forward, 100, dropped->velocity); //dropped->velocity[2] = 300; //dropped->think = drop_make_touchable; //dropped->nextthink = level.time + 1; dropped->nextthink = level.time + 100; dropped->think = G_FreeEdict; gi.linkentity (dropped); if ( !(ent->waterlevel) ) { gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_SPARKS); gi.WritePosition (origin); gi.WriteDir (plane->normal); gi.multicast (ent->s.origin, MULTICAST_PVS); } } G_FreeEdict (ent); } void knife_throw (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed ) { edict_t *knife; // vec3_t forward, right, up; trace_t tr; knife = G_Spawn(); VectorNormalize (dir); VectorCopy (start, knife->s.origin); VectorCopy (start, knife->s.old_origin); vectoangles (dir, knife->s.angles); VectorScale (dir, speed, knife->velocity); knife->movetype = MOVETYPE_TOSS; VectorSet (knife->avelocity, 1200, 0, 0); knife->movetype = MOVETYPE_TOSS; knife->clipmask = MASK_SHOT; knife->solid = SOLID_BBOX; knife->s.effects = 0; //EF_ROTATE? VectorClear (knife->mins); VectorClear (knife->maxs); knife->s.modelindex = gi.modelindex ("models/objects/knife/tris.md2"); knife->owner = self; knife->touch = knife_touch; knife->nextthink = level.time + 8000/speed; knife->think = G_FreeEdict; knife->dmg = damage; knife->s.sound = gi.soundindex ("misc/flyloop.wav"); knife->classname = "thrown_knife"; // used by dodging monsters, skip // if (self->client) // check_dodge (self, rocket->s.origin, dir, speed); tr = gi.trace (self->s.origin, NULL, NULL, knife->s.origin, knife, MASK_SHOT); if (tr.fraction < 1.0) { VectorMA (knife->s.origin, -10, dir, knife->s.origin); knife->touch (knife, tr.ent, NULL, NULL); } gi.linkentity (knife); } void Kuml_Touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf) { if (other == ent->owner) return; if (surf && (surf->flags & SURF_SKY)) { G_FreeEdict (ent); return; } if (!other->takedamage) { T_Damage (other, ent->owner, ent->owner, vec3_origin, other->s.origin, vec3_origin, ent->dmg, 0, 0, MOD_SHOTGUN); G_FreeEdict (ent); return; } ent->enemy = other; //Grenade_Explode (ent); } //shh! secret! void fire_kuml2 (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick, int hspread, int vspread, int count, int mod) { vec3_t dir; vec3_t forward, right, up; vec3_t end; vec3_t temp; float r; float u; int i = 8; edict_t *bolt; trace_t tr; int speed = 500; bolt = G_Spawn(); vectoangles (aimdir, dir); AngleVectors (dir, forward, right, up); r = crandom()*hspread; u = crandom()*vspread; VectorMA (start, 8192, forward, end); VectorMA (end, r, right, end); VectorMA (end, u, up, end); 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_TOSS; bolt->clipmask = MASK_SHOT; bolt->solid = SOLID_BBOX; VectorClear (bolt->mins); VectorClear (bolt->maxs); bolt->s.modelindex = gi.modelindex ("models/objects/debris2/tris.md2"); bolt->s.effects |= EF_SPHERETRANS; bolt->s.renderfx = RF_FULLBRIGHT; bolt->s.skinnum = 1; bolt->owner = self; bolt->touch = Kuml_Touch; bolt->nextthink = level.time + 3; bolt->think = G_FreeEdict; bolt->dmg = 15; bolt->classname = "poopoo"; bolt->s.sound = gi.soundindex ("weapons/swish.wav"); gi.linkentity (bolt); if (self->client) check_dodge (self, bolt->s.origin, dir, speed); 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); } } void fire_kuml (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick, int hspread, int vspread, int count, int mod) { int i; edict_t *bolt; trace_t tr; int speed = 500; vec3_t dir; vec3_t forward, right, up; vec3_t end; vec3_t temp; float r; float u; for (i = 0; i < count; i++) { return fire_kuml2 (self, start, aimdir, damage, kick, hspread, vspread, count, mod); } }