bool CSDKBot::ThinkMedRange() { CBasePlayer* pEnemy = m_PlayerSearchInfo.CloseEnemy(); CBasePlayer* pEnemySecond = m_PlayerSearchInfo.CloseEnemySecond(); bool bForceForward = false; if (pEnemy && pEnemySecond) { Vector lookTarget; lookTarget = LerpVector(pEnemy->Weapon_ShootPosition(), pEnemySecond->Weapon_ShootPosition(), 0.3); LookAt(lookTarget, m_pDifficult->m_flMeleeTurnLerp - 0.1, 5.f); //move more aggressively forward if the second enemy is far away if (m_PlayerSearchInfo.CloseEnemyDist() + 400 < m_PlayerSearchInfo.CloseEnemySecondDist()) { bForceForward = true; m_curCmd.buttons |= IN_FORWARD; } } else if (pEnemy) { Vector lookTarget; lookTarget = pEnemy->Weapon_ShootPosition(); LookAt(lookTarget, m_pDifficult->m_flMeleeTurnLerp - 0.1, 5.f); CBasePlayer* pFriend = m_PlayerSearchInfo.CloseFriend(); if (pFriend) { vec_t friendCombatRange = (pFriend->GetAbsOrigin() - pEnemy->GetAbsOrigin()).Length(); if (friendCombatRange < HELP_START_RANGE) bForceForward = true; } } if (gpGlobals->curtime > m_flNextStrafeTime) { float randomStrafe = bot_randfloat(); if (randomStrafe < 0.4f) { m_curCmd.buttons |= IN_LEFT; m_curCmd.buttons &= ~IN_RIGHT; } else if (randomStrafe < 0.8f) { m_curCmd.buttons &= ~IN_LEFT; m_curCmd.buttons |= IN_RIGHT; } else { m_curCmd.buttons &= ~IN_LEFT; m_curCmd.buttons &= ~IN_RIGHT; } //we're more likely to go forward if we're being forced to if (bot_randfloat() < 0.4f || (bForceForward && bot_randfloat() < 0.8f)) { m_curCmd.buttons |= IN_FORWARD; } else if (!bForceForward) { m_curCmd.buttons &= ~IN_FORWARD; } m_flNextStrafeTime += RandomFloat(0.1f, 1.4f); } return true; }
bool CSDKBot::ThinkLongRange() { m_curCmd.buttons |= IN_FORWARD; Vector lookTarget; CBasePlayer* pEnemy = m_PlayerSearchInfo.CloseEnemy(); CFlag* pFlag = m_PlayerSearchInfo.CloseEnemyFlagVisible(); //if there's a flag move towards the flag as well if (pEnemy && pFlag) { lookTarget = LerpVector(pFlag->GetAbsOrigin(), pEnemy->Weapon_ShootPosition(), 0.3f); } else if (pEnemy) { lookTarget = pEnemy->Weapon_ShootPosition(); } LookAt(lookTarget, 0.6f, 5.f); TeammateGoAround(true); return true; }
static void NQD_LerpPlayerinfo (float f) { if (cl.intermission) { // just stay there return; } if (nq_player_teleported) { VectorCopy (nq_mvelocity[0], cl.simvel); VectorCopy (nq_mviewangles[0], cl.viewangles); if (cls.demoplayback) VectorCopy (nq_mviewangles[0], cl.simangles); return; } LerpVector (nq_mvelocity[1], nq_mvelocity[0], f, cl.simvel); if (cls.demoplayback) { LerpAngles (nq_mviewangles[1], nq_mviewangles[0], f, cl.simangles); VectorCopy (cl.simangles, cl.viewangles); } }
// for .qwd demo playback static void CL_LerpMove (float msgtime) { static int lastsequence = 0; static vec3_t lerp_angles[3]; static vec3_t lerp_origin[3]; static float lerp_times[3]; static qbool nolerp[2]; static float demo_latency = 0.01; float frac; float simtime; int i; int from, to; if (cl_nolerp.value) return; if (cls.netchan.outgoing_sequence < lastsequence) { // reset lastsequence = -1; lerp_times[0] = -1; demo_latency = 0.01; } if (cls.netchan.outgoing_sequence > lastsequence) { lastsequence = cls.netchan.outgoing_sequence; // move along lerp_times[2] = lerp_times[1]; lerp_times[1] = lerp_times[0]; lerp_times[0] = msgtime; VectorCopy (lerp_origin[1], lerp_origin[2]); VectorCopy (lerp_origin[0], lerp_origin[1]); VectorCopy (cl.simorg, lerp_origin[0]); VectorCopy (lerp_angles[1], lerp_angles[2]); VectorCopy (lerp_angles[0], lerp_angles[1]); VectorCopy (cl.simangles, lerp_angles[0]); nolerp[1] = nolerp[0]; nolerp[0] = false; for (i = 0; i < 3; i++) if (fabs(lerp_origin[0][i] - lerp_origin[1][i]) > 40) break; if (i < 3) nolerp[0] = true; // a teleport or something } simtime = cls.realtime - demo_latency; // adjust latency if (simtime > lerp_times[0]) { // Com_DPrintf ("HIGH clamp\n"); demo_latency = cls.realtime - lerp_times[0]; } else if (simtime < lerp_times[2]) { // Com_DPrintf (" low clamp\n"); demo_latency = cls.realtime - lerp_times[2]; } else { // drift towards ideal latency float ideal_latency = (lerp_times[0] - lerp_times[2]) * 0.6; if (demo_latency > ideal_latency) demo_latency = max(demo_latency - cls.frametime * 0.1, ideal_latency); } // decide where to lerp from if (simtime > lerp_times[1]) { from = 1; to = 0; } else { from = 2; to = 1; } if (nolerp[to]) return; frac = (simtime - lerp_times[from]) / (lerp_times[to] - lerp_times[from]); frac = bound (0, frac, 1); LerpVector (lerp_origin[from], lerp_origin[to], frac, cl.simorg); LerpAngles (lerp_angles[from], lerp_angles[to], frac, cl.simangles); }
/* ================ R_RecursiveClipBPoly Clip a bmodel poly down the world bsp tree ================ */ static void R_RecursiveClipBPoly(bedge_t *pedges, mnode_t *pnode, mface_t *psurf) { bedge_t *psideedges[2], *pnextedge, *ptedge; int i, side, lastside; float dist, frac, lastdist; cplane_t *splitplane, tplane; mvertex_t *pvert, *plastvert, *ptvert; mnode_t *pn; int area; psideedges[0] = psideedges[1] = NULL; makeclippededge = qfalse; // transform the BSP plane into model space // FIXME: cache these? splitplane = pnode->plane; tplane.dist = -PlaneDiff(r_entorigin, splitplane); tplane.normal[0] = DotProduct(entity_rotation[0], splitplane->normal); tplane.normal[1] = DotProduct(entity_rotation[1], splitplane->normal); tplane.normal[2] = DotProduct(entity_rotation[2], splitplane->normal); // clip edges to BSP plane for (; pedges; pedges = pnextedge) { pnextedge = pedges->pnext; // set the status for the last point as the previous point // FIXME: cache this stuff somehow? plastvert = pedges->v[0]; lastdist = PlaneDiff(plastvert->point, &tplane); if (lastdist > 0) lastside = 0; else lastside = 1; pvert = pedges->v[1]; dist = PlaneDiff(pvert->point, &tplane); if (dist > 0) side = 0; else side = 1; if (side != lastside) { // clipped if (numbverts >= MAX_BMODEL_VERTS) return; // generate the clipped vertex frac = lastdist / (lastdist - dist); ptvert = &pbverts[numbverts++]; LerpVector(plastvert->point, pvert->point, frac, ptvert->point); // split into two edges, one on each side, and remember entering // and exiting points // FIXME: share the clip edge by having a winding direction flag? if (numbedges >= (MAX_BMODEL_EDGES - 1)) { Com_Printf("Out of edges for bmodel\n"); return; } ptedge = &pbedges[numbedges]; ptedge->pnext = psideedges[lastside]; psideedges[lastside] = ptedge; ptedge->v[0] = plastvert; ptedge->v[1] = ptvert; ptedge = &pbedges[numbedges + 1]; ptedge->pnext = psideedges[side]; psideedges[side] = ptedge; ptedge->v[0] = ptvert; ptedge->v[1] = pvert; numbedges += 2; if (side == 0) { // entering for front, exiting for back pfrontenter = ptvert; makeclippededge = qtrue; } else { pfrontexit = ptvert; makeclippededge = qtrue; } } else { // add the edge to the appropriate side pedges->pnext = psideedges[side]; psideedges[side] = pedges; } } // if anything was clipped, reconstitute and add the edges along the clip // plane to both sides (but in opposite directions) if (makeclippededge) { if (numbedges >= (MAX_BMODEL_EDGES - 2)) { Com_Error(ERR_DROP, "Out of edges for bmodel"); } ptedge = &pbedges[numbedges]; ptedge->pnext = psideedges[0]; psideedges[0] = ptedge; ptedge->v[0] = pfrontexit; ptedge->v[1] = pfrontenter; ptedge = &pbedges[numbedges + 1]; ptedge->pnext = psideedges[1]; psideedges[1] = ptedge; ptedge->v[0] = pfrontenter; ptedge->v[1] = pfrontexit; numbedges += 2; } // draw or recurse further for (i = 0; i < 2; i++) { if (psideedges[i]) { // draw if we've reached a non-solid leaf, done if all that's left is a // solid leaf, and continue down the tree if it's not a leaf pn = pnode->children[i]; // we're done with this branch if the node or leaf isn't in the PVS if (pn->visframe == r_visframecount) { if (!pn->plane) { mleaf_t *pl = (mleaf_t *)pn; if (pl->contents != CONTENTS_SOLID) { if (r_newrefdef.areabits) { area = pl->area; if (!Q_IsBitSet(r_newrefdef.areabits, area)) continue; // not visible } r_currentbkey = pl->key; R_RenderBmodelFace(psideedges[i], psurf); } } else { R_RecursiveClipBPoly(psideedges[i], pnode->children[i], psurf); } } } } }
/* =============== CL_AddPacketEntities =============== */ static void CL_AddPacketEntities(void) { entity_t ent; entity_state_t *s1; float autorotate; int i; int pnum; centity_t *cent; int autoanim; clientinfo_t *ci; unsigned int effects, renderfx; // bonus items rotate at a fixed rate autorotate = anglemod(cl.time * 0.1f); // brush models can auto animate their frames autoanim = 2 * cl.time / 1000; memset(&ent, 0, sizeof(ent)); for (pnum = 0; pnum < cl.frame.numEntities; pnum++) { i = (cl.frame.firstEntity + pnum) & PARSE_ENTITIES_MASK; s1 = &cl.entityStates[i]; cent = &cl_entities[s1->number]; effects = s1->effects; renderfx = s1->renderfx; // set frame if (effects & EF_ANIM01) ent.frame = autoanim & 1; else if (effects & EF_ANIM23) ent.frame = 2 + (autoanim & 1); else if (effects & EF_ANIM_ALL) ent.frame = autoanim; else if (effects & EF_ANIM_ALLFAST) ent.frame = cl.time / 100; else ent.frame = s1->frame; // quad and pent can do different things on client if (effects & EF_PENT) { effects &= ~EF_PENT; effects |= EF_COLOR_SHELL; renderfx |= RF_SHELL_RED; } if (effects & EF_QUAD) { effects &= ~EF_QUAD; effects |= EF_COLOR_SHELL; renderfx |= RF_SHELL_BLUE; } //====== // PMM if (effects & EF_DOUBLE) { effects &= ~EF_DOUBLE; effects |= EF_COLOR_SHELL; renderfx |= RF_SHELL_DOUBLE; } if (effects & EF_HALF_DAMAGE) { effects &= ~EF_HALF_DAMAGE; effects |= EF_COLOR_SHELL; renderfx |= RF_SHELL_HALF_DAM; } // pmm //====== // optionally remove the glowing effect if (cl_noglow->integer) renderfx &= ~RF_GLOW; ent.oldframe = cent->prev.frame; ent.backlerp = 1.0 - cl.lerpfrac; if (renderfx & RF_FRAMELERP) { // step origin discretely, because the frames // do the animation properly VectorCopy(cent->current.origin, ent.origin); VectorCopy(cent->current.old_origin, ent.oldorigin); // FIXME } else if (renderfx & RF_BEAM) { // interpolate start and end points for beams LerpVector(cent->prev.origin, cent->current.origin, cl.lerpfrac, ent.origin); LerpVector(cent->prev.old_origin, cent->current.old_origin, cl.lerpfrac, ent.oldorigin); } else { if (s1->number == cl.frame.clientNum + 1) { // use predicted origin VectorCopy(cl.playerEntityOrigin, ent.origin); VectorCopy(cl.playerEntityOrigin, ent.oldorigin); } else { // interpolate origin LerpVector(cent->prev.origin, cent->current.origin, cl.lerpfrac, ent.origin); VectorCopy(ent.origin, ent.oldorigin); } #if USE_FPS // run alias model animation if (cent->prev_frame != s1->frame) { int delta = cl.time - cent->anim_start; float frac; if (delta > BASE_FRAMETIME) { Com_DDPrintf("[%d] anim end %d: %d --> %d\n", cl.time, s1->number, cent->prev_frame, s1->frame); cent->prev_frame = s1->frame; frac = 1; } else if (delta > 0) { frac = delta * BASE_1_FRAMETIME; Com_DDPrintf("[%d] anim run %d: %d --> %d [%f]\n", cl.time, s1->number, cent->prev_frame, s1->frame, frac); } else { frac = 0; } ent.oldframe = cent->prev_frame; ent.backlerp = 1.0 - frac; } #endif } if ((effects & EF_GIB) && !cl_gibs->integer) { goto skip; } // create a new entity // tweak the color of beams if (renderfx & RF_BEAM) { // the four beam colors are encoded in 32 bits of skinnum (hack) ent.alpha = 0.30; ent.skinnum = (s1->skinnum >> ((rand() % 4) * 8)) & 0xff; ent.model = 0; } else { // set skin if (s1->modelindex == 255) {
/* ================ R_ClipEdge ================ */ void R_ClipEdge(mvertex_t *pv0, mvertex_t *pv1, clipplane_t *clip) { float d0, d1, f; mvertex_t clipvert; for (; clip; clip = clip->next) { d0 = DotProduct(pv0->point, clip->normal) - clip->dist; d1 = DotProduct(pv1->point, clip->normal) - clip->dist; if (d0 >= 0) { // point 0 is unclipped if (d1 >= 0) { // both points are unclipped continue; } // only point 1 is clipped // we don't cache clipped edges cacheoffset = CLIPPED_NOT_CACHED; f = d0 / (d0 - d1); LerpVector(pv0->point, pv1->point, f, clipvert.point); if (clip->leftedge) { r_leftclipped = qtrue; r_leftexit = clipvert; } else if (clip->rightedge) { r_rightclipped = qtrue; r_rightexit = clipvert; } R_ClipEdge(pv0, &clipvert, clip->next); return; } else { // point 0 is clipped if (d1 < 0) { // both points are clipped // we do cache fully clipped edges if (!r_leftclipped) cacheoffset = FULLY_CLIPPED_CACHED | (r_framecount & FRAMECOUNT_MASK); return; } // only point 0 is clipped r_lastvertvalid = qfalse; // we don't cache partially clipped edges cacheoffset = CLIPPED_NOT_CACHED; f = d0 / (d0 - d1); LerpVector(pv0->point, pv1->point, f, clipvert.point); if (clip->leftedge) { r_leftclipped = qtrue; r_leftenter = clipvert; } else if (clip->rightedge) { r_rightclipped = qtrue; r_rightenter = clipvert; } R_ClipEdge(&clipvert, pv1, clip->next); return; } } // add the edge R_EmitEdge(pv0, pv1); }