static void SelectPrevItem(edict_t *ent, int itflags) { gclient_t *cl; int i, index; const gitem_t *it; cl = ent->client; if (cl->layout == LAYOUT_MENU) { PMenu_Prev(ent); return; } if (cl->chase_target) { ChasePrev(ent); cl->chase_mode = CHASE_NONE; return; } // scan for the next valid one for (i = 1; i <= ITEM_TOTAL; i++) { index = (cl->selected_item + ITEM_TOTAL - i) % ITEM_TOTAL; if (!cl->inventory[index]) continue; it = INDEX_ITEM(index); if (!it->use) continue; if (!(it->flags & itflags)) continue; cl->selected_item = index; return; } cl->selected_item = -1; }
/* ================= Cmd_WeapNext_f ================= */ static void Cmd_WeapNext_f(edict_t *ent) { gclient_t *cl; int i, index; gitem_t *it; int selected_weapon; cl = ent->client; if (!cl->weapon) return; selected_weapon = ITEM_INDEX(cl->weapon); // scan for the next valid one for (i = 1; i <= ITEM_TOTAL; i++) { index = (selected_weapon + ITEM_TOTAL - i) % ITEM_TOTAL; if (!cl->inventory[index]) continue; it = INDEX_ITEM(index); if (!it->use) continue; if (!(it->flags & IT_WEAPON)) continue; it->use(ent, it); if (cl->weapon == it) return; // successful } }
/* ================= Cmd_WeapLast_f ================= */ static void Cmd_WeapLast_f(edict_t *ent) { gclient_t *cl; int index; gitem_t *it; cl = ent->client; if (!cl->weapon || !cl->lastweapon) return; index = ITEM_INDEX(cl->lastweapon); if (!cl->inventory[index]) return; it = INDEX_ITEM(index); if (!it->use) return; if (!(it->flags & IT_WEAPON)) return; it->use(ent, it); }
/* ================= Cmd_InvDrop_f ================= */ static void Cmd_InvDrop_f(edict_t *ent) { gitem_t *it; if (ent->client->layout == LAYOUT_MENU) { PMenu_Select(ent); return; } ValidateSelectedItem(ent); if (ent->client->selected_item == -1) { gi.cprintf(ent, PRINT_HIGH, "No item to drop.\n"); return; } it = INDEX_ITEM(ent->client->selected_item); if (!it->drop) { gi.cprintf(ent, PRINT_HIGH, "Item is not dropable.\n"); return; } it->drop(ent, it); }
/*QUAKED worldspawn (0 0 0) ? Only used for the world. "sky" environment map name "skyaxis" vector axis for rotating sky "skyrotate" speed of rotation in degrees/second "sounds" music cd track number "gravity" 800 is default gravity "message" text to print at user logon */ void SP_worldspawn(edict_t *ent) { char buffer[MAX_QPATH]; ent->movetype = MOVETYPE_PUSH; ent->solid = SOLID_BSP; ent->inuse = qtrue; // since the world doesn't use G_Spawn() ent->s.modelindex = 1; // world model is always index 1 //--------------- // reserve some spots for dead player bodies for coop / deathmatch InitBodyQue(); // set configstrings for items SetItemNames(); //if (st.nextmap) // strcpy(level.nextmap, st.nextmap); // make some data visible to the server if (ent->message && ent->message[0]) { gi.configstring(CS_NAME, ent->message); } ent->message = NULL; if (st.sky && st.sky[0]) gi.configstring(CS_SKY, st.sky); else gi.configstring(CS_SKY, "unit1_"); gi.configstring(CS_SKYROTATE, va("%f", st.skyrotate)); gi.configstring(CS_SKYAXIS, va("%f %f %f", st.skyaxis[0], st.skyaxis[1], st.skyaxis[2])); gi.configstring(CS_CDTRACK, va("%i", ent->sounds)); gi.configstring(CS_MAXCLIENTS, va("%i", (int)(maxclients->value))); // status bar program gi.configstring(CS_STATUSBAR, dm_statusbar); gi.configstring(CS_OBSERVE, "SPECT"); G_HighlightStr(buffer, "SPECTATOR MODE", sizeof(buffer)); gi.configstring(CS_SPECMODE, buffer); G_HighlightStr(buffer, "Press ATTACK to join", sizeof(buffer)); gi.configstring(CS_PREGAME, buffer); //--------------- // help icon for statusbar gi.imageindex("i_help"); level.images.health = gi.imageindex("i_health"); gi.imageindex("help"); gi.imageindex("field_3"); level.images.powershield = gi.imageindex("i_powershield"); level.images.quad = gi.imageindex("p_quad"); level.images.invulnerability = gi.imageindex("p_invulnerability"); level.images.envirosuit = gi.imageindex("p_envirosuit"); level.images.rebreather = gi.imageindex("p_rebreather"); if (!st.gravity) gi.cvar_set("sv_gravity", "800"); else gi.cvar_set("sv_gravity", st.gravity); level.sounds.fry = gi.soundindex("player/fry.wav"); // standing in lava / slime level.sounds.lava_in = gi.soundindex("player/lava_in.wav"); level.sounds.burn[0] = gi.soundindex("player/burn1.wav"); level.sounds.burn[1] = gi.soundindex("player/burn2.wav"); level.sounds.drown = gi.soundindex("player/drown1.wav"); PrecacheItem(INDEX_ITEM(ITEM_BLASTER)); gi.soundindex("player/lava1.wav"); gi.soundindex("player/lava2.wav"); gi.soundindex("misc/pc_up.wav"); gi.soundindex("misc/talk1.wav"); level.sounds.secret = gi.soundindex("misc/secret.wav"); level.sounds.count = gi.soundindex("world/10_0.wav"); level.sounds.udeath = gi.soundindex("misc/udeath.wav"); gi.soundindex("items/respawn1.wav"); // sexed sounds level.sounds.death[0] = gi.soundindex("*death1.wav"); level.sounds.death[1] = gi.soundindex("*death2.wav"); level.sounds.death[2] = gi.soundindex("*death3.wav"); level.sounds.death[3] = gi.soundindex("*death4.wav"); level.sounds.fall[0] = gi.soundindex("*fall1.wav"); level.sounds.fall[1] = gi.soundindex("*fall2.wav"); level.sounds.gurp[0] = gi.soundindex("*gurp1.wav"); // drowning damage level.sounds.gurp[1] = gi.soundindex("*gurp2.wav"); level.sounds.jump = gi.soundindex("*jump1.wav"); // player jump level.sounds.pain[0][0] = gi.soundindex("*pain25_1.wav"); level.sounds.pain[0][1] = gi.soundindex("*pain25_2.wav"); level.sounds.pain[1][0] = gi.soundindex("*pain50_1.wav"); level.sounds.pain[1][1] = gi.soundindex("*pain50_2.wav"); level.sounds.pain[2][0] = gi.soundindex("*pain75_1.wav"); level.sounds.pain[2][1] = gi.soundindex("*pain75_2.wav"); level.sounds.pain[3][0] = gi.soundindex("*pain100_1.wav"); level.sounds.pain[3][1] = gi.soundindex("*pain100_2.wav"); level.sounds.rg_hum = gi.soundindex("weapons/rg_hum.wav"); level.sounds.bfg_hum = gi.soundindex("weapons/bfg_hum.wav"); // sexed models // THIS ORDER MUST MATCH THE DEFINES IN g_local.h // you can add more, max 15 gi.modelindex("#w_blaster.md2"); gi.modelindex("#w_shotgun.md2"); gi.modelindex("#w_sshotgun.md2"); gi.modelindex("#w_machinegun.md2"); gi.modelindex("#w_chaingun.md2"); gi.modelindex("#a_grenades.md2"); gi.modelindex("#w_glauncher.md2"); gi.modelindex("#w_rlauncher.md2"); gi.modelindex("#w_hyperblaster.md2"); gi.modelindex("#w_railgun.md2"); gi.modelindex("#w_bfg.md2"); //------------------- level.sounds.gasp[0] = gi.soundindex("player/gasp1.wav"); // gasping for air level.sounds.gasp[1] = gi.soundindex("player/gasp2.wav"); // head breaking surface, not gasping level.sounds.watr_in = gi.soundindex("player/watr_in.wav"); // feet hitting water level.sounds.watr_out = gi.soundindex("player/watr_out.wav"); // feet leaving water level.sounds.watr_un = gi.soundindex("player/watr_un.wav"); // head going underwater level.sounds.breath[0] = gi.soundindex("player/u_breath1.wav"); level.sounds.breath[1] = gi.soundindex("player/u_breath2.wav"); gi.soundindex("items/pkup.wav"); // bonus item pickup gi.soundindex("world/land.wav"); // landing thud gi.soundindex("misc/h2ohit1.wav"); // landing splash gi.soundindex("items/damage.wav"); gi.soundindex("items/protect.wav"); gi.soundindex("items/protect4.wav"); level.sounds.noammo = gi.soundindex("weapons/noammo.wav"); gi.soundindex("infantry/inflies1.wav"); level.sounds.xian = gi.soundindex("world/xian1.wav"); level.sounds.makron = gi.soundindex("makron/laf4.wav"); // gibs level.models.meat = gi.modelindex("models/objects/gibs/sm_meat/tris.md2"); /*level.models.arm = gi.modelindex("models/objects/gibs/arm/tris.md2"); level.models.bones[0] = gi.modelindex("models/objects/gibs/bone/tris.md2"); level.models.bones[1] = gi.modelindex("models/objects/gibs/bone2/tris.md2"); level.models.chest = gi.modelindex("models/objects/gibs/chest/tris.md2"); level.models.skull = gi.modelindex("models/objects/gibs/skull/tris.md2");*/ level.models.head = gi.modelindex("models/objects/gibs/head2/tris.md2"); // // Setup light animation tables. 'a' is total darkness, 'z' is doublebright. // // 0 normal gi.configstring(CS_LIGHTS + 0, "m"); // 1 FLICKER (first variety) gi.configstring(CS_LIGHTS + 1, "mmnmmommommnonmmonqnmmo"); // 2 SLOW STRONG PULSE gi.configstring(CS_LIGHTS + 2, "abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba"); // 3 CANDLE (first variety) gi.configstring(CS_LIGHTS + 3, "mmmmmaaaaammmmmaaaaaabcdefgabcdefg"); // 4 FAST STROBE gi.configstring(CS_LIGHTS + 4, "mamamamamama"); // 5 GENTLE PULSE 1 gi.configstring(CS_LIGHTS + 5, "jklmnopqrstuvwxyzyxwvutsrqponmlkj"); // 6 FLICKER (second variety) gi.configstring(CS_LIGHTS + 6, "nmonqnmomnmomomno"); // 7 CANDLE (second variety) gi.configstring(CS_LIGHTS + 7, "mmmaaaabcdefgmmmmaaaammmaamm"); // 8 CANDLE (third variety) gi.configstring(CS_LIGHTS + 8, "mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa"); // 9 SLOW STROBE (fourth variety) gi.configstring(CS_LIGHTS + 9, "aaaaaaaazzzzzzzz"); // 10 FLUORESCENT FLICKER gi.configstring(CS_LIGHTS + 10, "mmamammmmammamamaaamammma"); // 11 SLOW PULSE NOT FADE TO BLACK gi.configstring(CS_LIGHTS + 11, "abcdefghijklmnopqrrqponmlkjihgfedcba"); // styles 32-62 are assigned by the light program for switchable lights // 63 testing gi.configstring(CS_LIGHTS + 63, "a"); }
/* ================== Cmd_Give_f Give items to a client ================== */ static void Cmd_Give_f(edict_t *ent) { char *name; gitem_t *it; int index; int i; bool give_all; edict_t *it_ent; if (!CheckCheats(ent)) { return; } name = gi.args(); if (Q_stricmp(name, "all") == 0) give_all = true; else give_all = false; if (give_all || Q_stricmp(gi.argv(1), "health") == 0) { if (gi.argc() == 3) ent->health = atoi(gi.argv(2)); else ent->health = ent->max_health; if (!give_all) return; } if (give_all || Q_stricmp(name, "weapons") == 0) { for (i = 0; i < ITEM_TOTAL; i++) { it = INDEX_ITEM(i); if (!it->pickup) continue; if (!(it->flags & IT_WEAPON)) continue; ent->client->inventory[i] += 1; } if (!give_all) return; } if (give_all || Q_stricmp(name, "ammo") == 0) { for (i = 0; i < ITEM_TOTAL; i++) { it = INDEX_ITEM(i); if (!it->pickup) continue; if (!(it->flags & IT_AMMO)) continue; Add_Ammo(ent, it, 1000); } if (!give_all) return; } if (give_all || Q_stricmp(name, "armor") == 0) { gitem_armor_t *info; ent->client->inventory[ITEM_ARMOR_JACKET] = 0; ent->client->inventory[ITEM_ARMOR_COMBAT] = 0; it = INDEX_ITEM(ITEM_ARMOR_BODY); info = (gitem_armor_t *)it->info; ent->client->inventory[ITEM_ARMOR_BODY] = info->max_count; if (!give_all) return; } if (give_all || Q_stricmp(name, "Power Shield") == 0) { it = INDEX_ITEM(ITEM_POWER_SHIELD); it_ent = G_Spawn(); it_ent->classname = it->classname; SpawnItem(it_ent, it); if (it_ent->inuse) { Touch_Item(it_ent, ent, NULL, NULL); if (it_ent->inuse) G_FreeEdict(it_ent); } if (!give_all) return; } if (give_all) { for (i = 0; i < ITEM_TOTAL; i++) { it = INDEX_ITEM(i); if (!it->pickup) continue; if (it->flags & (IT_ARMOR | IT_WEAPON | IT_AMMO)) continue; ent->client->inventory[i] = 1; } return; } it = FindItem(name); if (!it) { name = gi.argv(1); it = FindItem(name); if (!it) { gi.cprintf(ent, PRINT_HIGH, "unknown item\n"); return; } } if (!it->pickup) { gi.cprintf(ent, PRINT_HIGH, "non-pickup item\n"); return; } index = ITEM_INDEX(it); if (it->flags & IT_AMMO) { if (gi.argc() == 3) ent->client->inventory[index] = atoi(gi.argv(2)); else ent->client->inventory[index] += it->quantity; } else { it_ent = G_Spawn(); it_ent->classname = it->classname; SpawnItem(it_ent, it); if (it_ent->inuse) { Touch_Item(it_ent, ent, NULL, NULL); if (it_ent->inuse) G_FreeEdict(it_ent); } } }