/* ============== VoteMenuKick ============== Vote menu kick change handler. */ void VoteMenuKick (edict_t *ent) { edict_t *victim; if (ent->client->pers.votemenu_values.decrease) { if (ent->client->pers.votemenu_values.kick == NULL) victim = g_edicts + game.maxclients; else victim = ent->client->pers.votemenu_values.kick - 1; while (victim > g_edicts && (!victim->inuse || victim == ent || victim->client->pers.admin)) victim--; } else { if (ent->client->pers.votemenu_values.kick == NULL) victim = g_edicts + 1; else victim = ent->client->pers.votemenu_values.kick + 1; while (victim <= g_edicts + game.maxclients && (!victim->inuse || victim == ent || victim->client->pers.admin)) victim++; } if (victim <= g_edicts + game.maxclients && victim > g_edicts) ent->client->pers.votemenu_values.kick = victim; else ent->client->pers.votemenu_values.kick = NULL; VoteMenuUpdate (ent, VOTE_MENU_KICK); PMenu_Update (ent); gi.unicast (ent, true); }
void PMenu_Prev(edict_t *ent) { pmenuhnd_t *hnd; int i; pmenu_t *p; if (!ent->client->menu) { gi.dprintf("warning: ent has no menu\n"); return; } hnd = ent->client->menu; if (hnd->cur < 0) return; // no selectable entries i = hnd->cur; p = hnd->entries + hnd->cur; do { if (i == 0) { i = hnd->num - 1; p = hnd->entries + i; } else i--, p--; if (p->SelectFunc) break; } while (i != hnd->cur); hnd->cur = i; PMenu_Update(ent); }
void PMenu_Next(edict_t *ent) { pmenuhnd_t *hnd; int i; pmenu_t *p; if (!ent->client->menu) { gi.dprintf("warning: ent has no menu\n"); return; } hnd = ent->client->menu; if (hnd->cur < 0) return; // no selectable entries i = hnd->cur; p = hnd->entries + hnd->cur; do { i++, p++; if (i == hnd->num) i = 0, p = hnd->entries; if (p->SelectFunc) break; } while (i != hnd->cur); hnd->cur = i; PMenu_Update(ent); }
/* ============== VoteMenuChat ============== Vote menu chat change handler. */ void VoteMenuChat (edict_t *ent) { // only 2 values.. no need for decreasing ent->client->pers.votemenu_values.chat = (ent->client->pers.votemenu_values.chat + 1) % 2; VoteMenuUpdate (ent, VOTE_MENU_CHAT); PMenu_Update (ent); gi.unicast (ent, true); }
/* ============== VoteMenuBFG ============== Vote menu BFG change handler. */ void VoteMenuBFG (edict_t *ent) { // only 2 values.. no need for decreasing ent->client->pers.votemenu_values.bfg = (ent->client->pers.votemenu_values.bfg + 1) % 2; VoteMenuUpdate (ent, VOTE_MENU_BFG); PMenu_Update (ent); gi.unicast (ent, true); }
/* ============== VoteMenuPowerups ============== Vote menu powerups change handler. */ void VoteMenuPowerups (edict_t *ent) { // only 2 values.. no need for decreasing ent->client->pers.votemenu_values.powerups = (ent->client->pers.votemenu_values.powerups + 1) % 2; VoteMenuUpdate (ent, VOTE_MENU_POWERUPS); PMenu_Update (ent); gi.unicast (ent, true); }
/* ============== VoteMenuBugs ============== Vote menu bugs change handler. */ void VoteMenuBugs (edict_t *ent) { if (ent->client->pers.votemenu_values.decrease) ent->client->pers.votemenu_values.bugs = (ent->client->pers.votemenu_values.bugs + 2) % 3; else ent->client->pers.votemenu_values.bugs = (ent->client->pers.votemenu_values.bugs + 1) % 3; VoteMenuUpdate (ent, VOTE_MENU_BUGS); PMenu_Update (ent); gi.unicast (ent, true); }
/* ============== VoteMenuTimelimit ============== Vote menu timelimit change handler. */ void VoteMenuTimelimit (edict_t *ent) { if (ent->client->pers.votemenu_values.decrease) ent->client->pers.votemenu_values.timelimit = ((ent->client->pers.votemenu_values.timelimit + 20) % 30) + 5; else ent->client->pers.votemenu_values.timelimit = (ent->client->pers.votemenu_values.timelimit % 30) + 5; VoteMenuUpdate (ent, VOTE_MENU_TIMELIMIT); PMenu_Update (ent); gi.unicast (ent, true); }
/* ============== VoteMenuGameMode ============== Vote menu gamemode change handler. */ void VoteMenuGameMode (edict_t *ent) { if (ent->client->pers.votemenu_values.decrease) ent->client->pers.votemenu_values.gamemode = (ent->client->pers.votemenu_values.gamemode + 2) % 3; else ent->client->pers.votemenu_values.gamemode = (ent->client->pers.votemenu_values.gamemode + 1) % 3; VoteMenuUpdate (ent, VOTE_MENU_GAMEMODE); PMenu_Update (ent); gi.unicast (ent, 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 = (pmenuhnd_t*)G_Malloc(sizeof(*hnd)); hnd->arg = arg; hnd->entries = (struct pmenu_s*)G_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 = G_CopyString(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_Update(ent); gi.unicast (ent, true); return hnd; // Knightmare added }
/* ============== VoteMenuOvertime ============== Vote menu overtime change handler. */ void VoteMenuOvertime (edict_t *ent) { if (ent->client->pers.votemenu_values.decrease) { // we need to cycle from 5 down to -1 ent->client->pers.votemenu_values.overtime = ((ent->client->pers.votemenu_values.overtime + 7) %7) - 1; } else { // we need to cycle from -1 up to 5 ent->client->pers.votemenu_values.overtime = ((ent->client->pers.votemenu_values.overtime + 2) % 7) - 1; } VoteMenuUpdate (ent, VOTE_MENU_OVERTIME); PMenu_Update (ent); gi.unicast (ent, true); }
void PMenu_Prev(edict_t *ent) { pmenuhnd_t *hnd; int i; pmenu_t *p; if (!ent->client->menu) { gi.dprintf(DEVELOPER_MSG_GAME, "warning: ent has no menu\n"); return; } hnd = ent->client->menu; if (hnd->cur < 0) { return; /* no selectable entries */ } i = hnd->cur; p = hnd->entries + hnd->cur; do { if (i == 0) { i = hnd->num - 1; p = hnd->entries + i; } else { i--, p--; } if (p->SelectFunc) { break; } } while (i != hnd->cur); hnd->cur = i; PMenu_Update(ent); }
void PMenu_Open(edict_t *ent, pmenu_t *entries, int cur, int num) { pmenuhnd_t *hnd; pmenu_t *p; int i; if (!ent->client) return; if (ent->client->menu) { gi.dprintf("warning, ent already has a menu\n"); PMenu_Close(ent); } hnd = malloc(sizeof(*hnd)); hnd->entries = entries; 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; if(!(ent->svflags & SVF_MONSTER)) { PMenu_Update(ent); gi.unicast (ent, true); } }
/* ============== VoteMenuConfig ============== Vote menu config change handler. */ void VoteMenuConfig (edict_t *ent) { int cfg_count; int cfg_index; cfg_index = ent->client->pers.votemenu_values.cfg_index; if (tdm_configlist == NULL) return; for (cfg_count = 0; tdm_configlist[cfg_count] != NULL; cfg_count++); if (ent->client->pers.votemenu_values.decrease) cfg_index--; else cfg_index++; // don't show "---" twice if user decreased value at the start if (cfg_index == -2) cfg_index = cfg_count - 1; // jump from the start of the list to the end else if (cfg_index < 0) cfg_index = cfg_count; // jump from the end of the list to the start else if (cfg_index > cfg_count) cfg_index = 0; //memset (ent->client->pers.votemenu_values.map, '\0', strlen (ent->client->pers.votemenu_values.map)); // we reached the end of maplist.. show '---' if (tdm_configlist[cfg_index] == NULL) strcpy (ent->client->pers.votemenu_values.config, "---"); else strcpy (ent->client->pers.votemenu_values.config, tdm_configlist[cfg_index]); ent->client->pers.votemenu_values.cfg_index = cfg_index; VoteMenuUpdate (ent, VOTE_MENU_CONFIG); PMenu_Update (ent); gi.unicast (ent, true); }
/* ============== VoteMenuMap ============== Vote menu map change handler. */ void VoteMenuMap (edict_t *ent) { int map_count; int map_index; map_index = ent->client->pers.votemenu_values.map_index; if (tdm_maplist == NULL) return; for (map_count = 0; tdm_maplist[map_count] != NULL; map_count++); if (ent->client->pers.votemenu_values.decrease) map_index--; else map_index++; // don't show "---" twice if user decreased value at the start if (map_index == -2) map_index = map_count - 1; // jump from the start of the list to the end else if (map_index < 0) map_index = map_count; // jump from the end of the list to the start else if (map_index > map_count) map_index = 0; //memset (ent->client->pers.votemenu_values.map, '\0', strlen (ent->client->pers.votemenu_values.map)); // we reached the end of maplist.. show '---' if (tdm_maplist[map_index] == NULL) strcpy (ent->client->pers.votemenu_values.map, "---"); else strcpy (ent->client->pers.votemenu_values.map, tdm_maplist[map_index]); ent->client->pers.votemenu_values.map_index = map_index; VoteMenuUpdate (ent, VOTE_MENU_MAP); PMenu_Update (ent); gi.unicast (ent, true); }
/* ================= ClientEndServerFrame Called for each player at the end of the server frame and right after spawning ================= */ void ClientEndServerFrame (edict_t * ent) { float bobtime; int i; //char player_name[30]; //char temp[40]; // int damage; // zucc for bleeding current_player = ent; current_client = ent->client; //AQ2:TNG - Slicer : Stuffs the client x seconds after he enters the server, needed for Video check if (ent->client->resp.checktime[0] <= level.time) { ent->client->resp.checktime[0] = level.time + video_checktime->value; if (video_check->value || video_check_lockpvs->value || video_check_glclear->value || darkmatch->value) stuffcmd (ent, "%!fc $vid_ref\n"); if (video_force_restart->value && video_check->value && !ent->client->resp.checked) { stuffcmd (ent, "vid_restart\n"); ent->client->resp.checked = true; } } if (ent->client->resp.checktime[1] <= level.time) { ent->client->resp.checktime[1] = level.time + video_checktime->value; ent->client->resp.checktime[2] = level.time + 1; if (video_check->value || video_check_lockpvs->value || video_check_glclear->value || darkmatch->value) { if (ent->client->resp.vidref && Q_stricmp(ent->client->resp.vidref, "soft")) stuffcmd (ent, "%cpsi $gl_modulate $gl_lockpvs $gl_clear $gl_dynamic $gl_driver\n"); } } if (ent->client->resp.checktime[2] <= level.time) { // ent->client->resp.checktime[2] = level.time + video_checktime->value; if (video_check->value || video_check_lockpvs->value || video_check_glclear->value || darkmatch->value) { if (ent->client->resp.vidref && Q_stricmp(ent->client->resp.vidref, "soft")) VideoCheckClient (ent); } } if(pause_time) { G_SetStats (ent); return; } //FIREBLADE - Unstick avoidance stuff. if (ent->solid == SOLID_TRIGGER && !lights_camera_action) { edict_t *overlap; if ((overlap = FindOverlap (ent, NULL)) == NULL) { ent->solid = SOLID_BBOX; gi.linkentity (ent); RemoveFromTransparentList (ent); } else { do { if (overlap->solid == SOLID_BBOX) { overlap->solid = SOLID_TRIGGER; gi.linkentity (overlap); AddToTransparentList (overlap); } overlap = FindOverlap (ent, overlap); } while (overlap != NULL); } } //FIREBLADE // // 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 || ent->solid == SOLID_NOT) { bobmove = 0; current_client->bobtime = 0; // start at beginning of cycle again } else if (ent->groundentity) { // so bobbing only cycles when on ground if (xyspeed > 210) bobmove = 0.25; else if (xyspeed > 100) bobmove = 0.125; else bobmove = 0.0625; } bobtime = (current_client->bobtime += bobmove); if (current_client->ps.pmove.pm_flags & PMF_DUCKED) bobtime *= 4; bobcycle = (int) bobtime; bobfracsin = fabs (sin (bobtime * M_PI)); // detect hitting the floor P_FallingDamage (ent); // zucc handle any bleeding damage here Do_Bleeding (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); G_SetStats (ent); //FIREBLADE for (i = 1; i <= maxclients->value; i++) { int stats_copy; edict_t *e = g_edicts + i; if (!ent->inuse || e->client->chase_mode == 0 || e->client->chase_target != ent) continue; for (stats_copy = 0; stats_copy < MAX_STATS; stats_copy++) { if (stats_copy >= STAT_TEAM_HEADER && stats_copy <= STAT_TEAM2_SCORE) continue; // protect these if (stats_copy >= STAT_TEAM3_PIC && stats_copy <= STAT_TEAM3_SCORE) continue; // protect these if (stats_copy == STAT_LAYOUTS || stats_copy == STAT_ID_VIEW) continue; // protect these if (stats_copy == STAT_SNIPER_ICON && e->client->chase_mode != 2) continue; // only show sniper lens when in chase mode 2 if (stats_copy == STAT_FRAGS) continue; e->client->ps.stats[stats_copy] = ent->client->ps.stats[stats_copy]; } //FB e->client->ps.stats[STAT_LAYOUTS] = 1; //FB break; } //FIREBLADE 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); // zucc - clear the open door command ent->client->doortoggle = 0; if (ent->client->push_timeout > 0) ent->client->push_timeout--; /* else { ent->client->attacker = NULL; ent->client->attacker_mod = MOD_BLEEDING; } */ if (ent->client->reload_attempts > 0) { if (((ent->client->latched_buttons | ent->client->buttons) & BUTTON_ATTACK) && canFire(ent)) { ent->client->reload_attempts = 0; } else { Cmd_Reload_f (ent); } } if (ent->client->weapon_attempts > 0) Cmd_Weapon_f (ent); // if the scoreboard is up, update it if (ent->client->showscores && !(level.framenum & 31)) { //FIREBLADE if (ent->client->menu) { PMenu_Update (ent); } else //FIREBLADE DeathmatchScoreboardMessage (ent, ent->enemy); gi.unicast (ent, false); } //FIREBLADE if(!pause_time) RadioThink (ent); //FIREBLADE }