void test1() { info("this is a test\n"); infov("print %s\n", "this"); CU_ASSERT(2 * 2 == 4); }
qboolean minisentry_findtarget (edict_t *self) { edict_t *target=NULL; // don't retarget too quickly if (self->last_move_time > level.time) return false; while ((target = findclosestradius (target, self->s.origin, SENTRY_TARGET_RANGE)) != NULL) { if (!G_ValidTarget(self, target, true)) continue; if (!infov(self, target, SENTRY_FOV)) continue; self->enemy = target; self->last_move_time = level.time + 1.0; gi.sound(self, CHAN_AUTO, gi.soundindex("weapons/turrspot.wav"), 1, ATTN_NORM, 0); return true; } return false; }
void UpdateChaseCam (edict_t *ent) { int i; edict_t *old, *targ; vec3_t start, goal; vec3_t angles, forward, right; trace_t tr; qboolean eyecam=false; if (!ent->client->chase_target) return; if (!G_IsSpectator(ent)) return; //gi.dprintf("updating chase for %s\n", ent->client->pers.netname); // is our chase target no longer valid? if (!IsValidChaseTarget(ent->client->chase_target)) { old = ent->client->chase_target; ChaseNext(ent); // try to find a new chase target if (ent->client->chase_target == old) { // switch out of chase-cam mode ent->client->chase_target = NULL; ent->client->ps.pmove.pm_flags &= ~PMF_NO_PREDICTION; ent->client->ps.pmove.pm_flags &= ~PMF_DUCKED; // quit ducked. return; } } targ = ent->client->chase_target; if (PM_MonsterHasPilot(targ)) targ = targ->owner; VectorCopy(targ->s.origin, start); // use client's viewing angle if (targ->client) VectorCopy(targ->client->v_angle, angles); // use pilot's viewing angle /* else if (PM_MonsterHasPilot(targ)) { VectorCopy(targ->owner->s.origin, start); VectorCopy(targ->owner->client->v_angle, angles); } */ // use non-client's angles else VectorCopy(targ->s.angles, angles); if (ent->client->chasecam_mode) eyecam = true; // if we're chasing a non-client entity that has a valid enemy // within our sights, then modify our viewing pitch if (eyecam && !targ->client && G_ValidTarget(targ, targ->enemy, true) && infov(targ, targ->enemy, 90)) { VectorSubtract(targ->enemy->s.origin, targ->s.origin, forward); vectoangles(forward, forward); angles[PITCH] = forward[PITCH]; //gi.dprintf("pitch %d\n", (int)forward[PITCH]); } if (!eyecam) { if (angles[PITCH] > 56) angles[PITCH] = 56; if (angles[PITCH] < -56) angles[PITCH] = -56; } AngleVectors (angles, forward, right, NULL); VectorNormalize(forward); if (eyecam) { // save current player fov float fov = ent->client->ps.fov; if (targ->viewheight) start[2] += targ->viewheight; else start[2] = targ->absmax[2]-8; VectorMA(start, targ->maxs[1]+16, forward, start); // update HUD if (targ->client) ent->client->ps = targ->client->ps; else ent->client->ps.gunindex = 0; // restore player's fov (don't use target's fov) ent->client->ps.fov = fov; } else { ent->client->ps.gunindex = 0; // special conditions for upside-down minisentry if (targ->owner && (targ->mtype == M_MINISENTRY) && (targ->owner->style == SENTRY_FLIPPED)) { start[2] = targ->absmin[2]-16; } else { if (targ->viewheight) start[2] += targ->viewheight; else start[2] = targ->absmax[2]-8; VectorMA(start, targ->mins[1]-16, forward, start); } } // jump animation lifts if (!targ->groundentity) start[2] += 16; tr = gi.trace(targ->s.origin, NULL, NULL, start, targ, MASK_SOLID); VectorCopy(tr.endpos, start); if (tr.fraction < 1) { if (eyecam) VectorMA(start, -12, forward, start); else VectorMA(start, 12, forward, start); } VectorCopy(start, goal); // pad for floors and ceilings VectorCopy(goal, start); start[2] += 6; tr = gi.trace(goal, vec3_origin, vec3_origin, start, targ, MASK_SOLID); if (tr.fraction < 1) { VectorCopy(tr.endpos, goal); goal[2] -= 6; } VectorCopy(goal, start); start[2] -= 6; tr = gi.trace(goal, vec3_origin, vec3_origin, start, targ, MASK_SOLID); if (tr.fraction < 1) { VectorCopy(tr.endpos, goal); goal[2] += 6; } if (targ->deadflag) ent->client->ps.pmove.pm_type = PM_DEAD; else ent->client->ps.pmove.pm_type = PM_FREEZE; VectorCopy(goal, ent->s.origin); for (i=0 ; i<3 ; i++) { ent->client->ps.pmove.delta_angles[i] = ANGLE2SHORT(angles[i] - ent->client->resp.cmd_angles[i]); } if (targ->deadflag) { ent->client->ps.viewangles[ROLL] = 40; ent->client->ps.viewangles[PITCH] = -15; if (targ->client) ent->client->ps.viewangles[YAW] = targ->client->killer_yaw; else ent->client->ps.viewangles[YAW] = 0; } else { VectorCopy(angles, ent->client->ps.viewangles); VectorCopy(angles, ent->client->v_angle); } ent->viewheight = 0; ent->client->ps.pmove.pm_flags |= PMF_NO_PREDICTION; gi.linkentity(ent); }
void ParasiteAttack (edict_t *ent) { int damage, kick; vec3_t forward, right, start, end, offset; trace_t tr; if (debuginfo->value) gi.dprintf("%s just called ParasiteAttack()\n", ent->client->pers.userinfo); // terminate attack if (!G_EntIsAlive(ent) || (ent->parasite_frames > PARASITE_MAXFRAMES) || que_typeexists(ent->curses, CURSE_FROZEN)) { parasite_endattack(ent); return; } // calculate starting point AngleVectors (ent->client->v_angle, forward, right, NULL); VectorSet(offset, 0, 7, ent->viewheight-8); P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start); // do we already have a valid target? if (G_ValidTarget(ent, ent->parasite_target, true) && (entdist(ent, ent->parasite_target) <= PARASITE_RANGE) && infov(ent, ent->parasite_target, 90)) { VectorSubtract(ent->parasite_target->s.origin, start, forward); VectorNormalize(forward); } VectorMA(start, PARASITE_RANGE, forward, end); tr = gi.trace(start, NULL, NULL, end, ent, MASK_SHOT); // did we hit something? if (G_EntIsAlive(tr.ent) && !OnSameTeam(ent, tr.ent)) { if (ent->parasite_frames == 0) { ent->client->pers.inventory[power_cube_index] -= PARASITE_COST; gi.sound (ent, CHAN_AUTO, gi.soundindex("parasite/paratck3.wav"), 1, ATTN_NORM, 0); ent->client->ability_delay = level.time + PARASITE_DELAY; } ent->parasite_target = tr.ent; damage = 2*ent->myskills.abilities[BLOOD_SUCKER].current_level; if (tr.ent->groundentity) kick = -100; else kick = -50; T_Damage(tr.ent, ent, ent, forward, tr.endpos, tr.plane.normal, damage, kick, DAMAGE_NO_ABILITIES, MOD_PARASITE); gi.WriteByte(svc_temp_entity); gi.WriteByte(TE_PARASITE_ATTACK); gi.WriteShort(ent-g_edicts); gi.WritePosition(start); gi.WritePosition(tr.endpos); gi.multicast(ent->s.origin, MULTICAST_PVS); ent->parasite_frames++; } else if (ent->parasite_frames) parasite_endattack(ent); }
void minisentry_attack (edict_t *self) { int speed, dmg_radius; float chance; vec3_t forward, start, aim; qboolean slowed=false; minisentry_lockon(self); if (self->light_level < 1) return; // out of ammo // are we affected by holy freeze? //if (HasActiveCurse(self, AURA_HOLYFREEZE)) if (que_typeexists(self->curses, AURA_HOLYFREEZE)) slowed = true; // calculate muzzle location AngleVectors(self->s.angles, forward, NULL, NULL); VectorCopy(self->s.origin, start); if (self->owner && self->owner->style == SENTRY_FLIPPED) start[2] -= abs(self->mins[2]); else start[2] += self->maxs[2]; VectorMA(start, (self->maxs[0] + 16), forward, start); if ((level.time > self->wait) && infov(self, self->enemy, 30)) { speed = 650 + 35*self->creator->myskills.abilities[BUILD_SENTRY].current_level; MonsterAim(self, -1, speed, true, 0, aim, start); dmg_radius = self->radius_dmg; if (dmg_radius > 150) dmg_radius = 150; fire_rocket (self, start, aim, self->radius_dmg, speed, dmg_radius, self->radius_dmg); if (slowed) self->wait = level.time + 2.0; else if (self->chill_time > level.time) self->wait = level.time + (1.0 * (1 + CHILL_DEFAULT_BASE + CHILL_DEFAULT_ADDON * self->chill_level)); else self->wait = level.time + 1.0; } self->light_level--; // decrease ammo if (slowed && !(level.framenum%2)) return; // chill effect reduces attack rate/refire if (self->chill_time > level.time) { chance = 1 / (1 + CHILL_DEFAULT_BASE + CHILL_DEFAULT_ADDON * self->chill_level); if (random() > chance) return; } fire_bullet (self, start, forward, self->dmg, 2*self->dmg, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, MOD_SENTRY); gi.sound(self, CHAN_WEAPON, gi.soundindex("weapons/plaser.wav"), 1, ATTN_NORM, 0); gi.WriteByte (svc_muzzleflash); gi.WriteShort (self-g_edicts); gi.WriteByte (MZ_IONRIPPER|MZ_SILENCED); gi.multicast (start, MULTICAST_PVS); }