void PMenu_Update(edict_t *ent){ if(!ent->client->menu){ gi.dprintf("warning: ent has no menu\n"); return; } if(level.time - ent->client->menutime >= 1.0){ // been a second or more since last update, update now PMenu_Do_Update(ent); gi.unicast(ent, true); ent->client->menutime = level.time; ent->client->menudirty = false; } ent->client->menutime = level.time + 0.2; ent->client->menudirty = true; }
// Note that the pmenu entries are duplicated // this is so that a static set of pmenu entries can be used // for multiple clients and changed without interference // note that arg will be freed when the menu is closed, it must be allocated memory pmenuhnd_t *PMenu_Open(edict_t *ent, pmenu_t *entries, int cur, int num, void *arg) { pmenuhnd_t *hnd; pmenu_t *p; int i; if (!ent->client) return NULL; if (ent->client->menu) { gi.dprintf("warning, ent already has a menu\n"); PMenu_Close(ent); } hnd = malloc(sizeof(*hnd)); hnd->arg = arg; hnd->entries = malloc(sizeof(pmenu_t) * num); memcpy(hnd->entries, entries, sizeof(pmenu_t) * num); // duplicate the strings since they may be from static memory for (i = 0; i < num; i++) if (entries[i].text) hnd->entries[i].text = strdup(entries[i].text); hnd->num = num; if (cur < 0 || !entries[cur].SelectFunc) { for (i = 0, p = entries; i < num; i++, p++) if (p->SelectFunc) break; } else i = cur; if (i >= num) hnd->cur = -1; else hnd->cur = i; ent->client->showscores = true; ent->client->inmenu = true; ent->client->menu = hnd; PMenu_Do_Update(ent); gi.unicast (ent, true); return hnd; }
void ClientEndServerFrame (edict_t *ent) { float bobtime; int i; current_player = ent; current_client = ent->client; // // If the origin or velocity have changed since ClientThink(), // update the pmove values. This will happen when the client // is pushed by a bmodel or kicked by an explosion. // // If it wasn't updated here, the view position would lag a frame // behind the body position when pushed -- "sinking into plats" // for (i=0 ; i<3 ; i++) { current_client->ps.pmove.origin[i] = ent->s.origin[i]*8.0; current_client->ps.pmove.velocity[i] = ent->velocity[i]*8.0; } // // If the end of unit layout is displayed, don't give // the player any normal movement attributes // if (level.intermissiontime) { // FIXME: add view drifting here? current_client->ps.blend[3] = 0; current_client->ps.fov = 90; G_SetStats (ent); return; } AngleVectors (ent->client->v_angle, forward, right, up); // burn from lava, etc P_WorldEffects (); // // set model angles from view angles so other things in // the world can tell which direction you are looking // if (ent->client->v_angle[PITCH] > 180) ent->s.angles[PITCH] = (-360 + ent->client->v_angle[PITCH])/3; else ent->s.angles[PITCH] = ent->client->v_angle[PITCH]/3; ent->s.angles[YAW] = ent->client->v_angle[YAW]; ent->s.angles[ROLL] = 0; ent->s.angles[ROLL] = SV_CalcRoll (ent->s.angles, ent->velocity)*4; // // calculate speed and cycle to be used for // all cyclic walking effects // xyspeed = sqrt(ent->velocity[0]*ent->velocity[0] + ent->velocity[1]*ent->velocity[1]); if (xyspeed < 5) { bobmove = 0; current_client->bobtime = 0; // start at beginning of cycle again } //Kngightmare- exception for wading else if (ent->groundentity || ent->waterlevel == 2) { // so bobbing only cycles when on ground if (xyspeed > 450) // Knightmare added bobmove = 0.50; else if (xyspeed > 210) bobmove = 0.25; else if (!ent->groundentity && ent->waterlevel == 2 && xyspeed > 100) bobmove = 0.45; else if (xyspeed > 100) bobmove = 0.125; else if (!ent->groundentity && ent->waterlevel == 2) bobmove = 0.325; else bobmove = 0.0625; } bobtime = (current_client->bobtime += bobmove); if (current_client->ps.pmove.pm_flags & PMF_DUCKED) bobtime *= 4; bobcycle = (int)bobtime; // Lazarus: vehicle drivers don't bob if(ent->vehicle) bobfracsin = 0.; else bobfracsin = fabs(sin(bobtime*M_PI)); // detect hitting the floor P_FallingDamage (ent); // Lazarus: detect hitting walls P_SlamDamage (ent); // apply all the damage taken this frame P_DamageFeedback (ent); // determine the view offsets SV_CalcViewOffset (ent); // determine the gun offsets SV_CalcGunOffset (ent); // determine the full screen color blend // must be after viewoffset, so eye contents can be // accurately determined // FIXME: with client prediction, the contents // should be determined by the client SV_CalcBlend (ent); // chase cam stuff if (ent->client->resp.spectator) G_SetSpectatorStats(ent); //ZOID else //if (!ent->client->chase_target) //ZOID G_SetStats (ent); G_CheckChaseStats(ent); G_SetClientEvent (ent); G_SetClientEffects (ent); G_SetClientSound (ent); G_SetClientFrame (ent); VectorCopy (ent->velocity, ent->client->oldvelocity); VectorCopy (ent->client->ps.viewangles, ent->client->oldviewangles); // clear weapon kicks VectorClear (ent->client->kick_origin); VectorClear (ent->client->kick_angles); // if the scoreboard is up, update it if (!(level.framenum & 31)) { if (ent->client->showscores) { if (ent->client->menu) { // PMenu_Update(ent); PMenu_Do_Update(ent); ent->client->menudirty = false; ent->client->menutime = level.time; } else if (ent->client->textdisplay) Text_Update(ent); else DeathmatchScoreboardMessage (ent, ent->enemy); gi.unicast (ent, false); } else if(ent->client->whatsit) WhatsIt(ent); } // tpp if (ent->client->chasetoggle == 1) CheckChasecam_Viewent(ent); // end tpp }