std::string InventoryState::_handItemSummary (GameItemObject* hand) { std::stringstream ss; if (hand) { ss << hand->name() << "\n"; // is it weapon if (hand->subtype() == GameObject::TYPE_ITEM_WEAPON) { auto weapon = dynamic_cast<GameWeaponItemObject*>(hand); ss << "Dmg: " << weapon->damageMin() << "-" << weapon->damageMax() << " "; ss << "Rng: " << weapon->rangePrimary(); // has it ammo? if (weapon->ammoType() != 0) { ss << "\nAmmo: /" << weapon->ammoCapacity() << " "; auto ammo = GameObjectFactory::createObject(weapon->ammoPID()); ss << ammo->name(); } } } else { ss << "No item\nUnarmed dmg:"; } return ss.str(); }
/* ============== CG_CheckAmmo If the ammo has gone low enough to generate the warning, play a sound ============== */ void CG_CheckAmmo( void ) { int i; int total; int previous; int weapons; // see about how many seconds of ammo we have remaining weapons = cg.snap->ps.stats[ STAT_WEAPONS ]; total = 0; for ( i = WP_MACHINEGUN ; i < WP_NUM_WEAPONS ; i++ ) { if ( ! ( weapons & ( 1 << i ) ) ) { continue; } switch ( i ) { case WP_ROCKET_LAUNCHER: case WP_GRENADE_LAUNCHER: case WP_RAILGUN: case WP_SHOTGUN: case WP_SHOTRAIL: #ifdef MISSIONPACK case WP_PROX_LAUNCHER: #endif total += cg.snap->ps.ammo[ammoType(i)] * 1000; break; default: total += cg.snap->ps.ammo[ammoType(i)] * 200; break; } if ( total >= 5000 ) { cg.lowAmmoWarning = 0; return; } } previous = cg.lowAmmoWarning; if ( total == 0 ) { cg.lowAmmoWarning = 2; } else { cg.lowAmmoWarning = 1; } // play a sound on transitions if ( cg.lowAmmoWarning != previous ) { trap_S_StartLocalSound( cgs.media.noAmmoSound, CHAN_LOCAL_SOUND ); } }
/* ================ BG_CanItemBeGrabbed Returns false if the item should not be picked up. This needs to be the same for client side prediction and server use. ================ */ qboolean BG_CanItemBeGrabbed( int gametype, const entityState_t *ent, const playerState_t *ps ) { gitem_t *item; #ifdef MISSIONPACK int upperBound; #endif if ( ent->modelindex < 1 || ent->modelindex >= bg_numItems ) { Com_Error( ERR_DROP, "BG_CanItemBeGrabbed: index out of range" ); } item = &bg_itemlist[ent->modelindex]; switch( item->giType ) { case IT_WEAPON: return qtrue; // weapons are always picked up case IT_AMMO: if ( ps->ammo[ ammoType(item->giTag) ] >= 200 ) { return qfalse; // can't hold any more } return qtrue; case IT_ARMOR: #ifdef MISSIONPACK if( bg_itemlist[ps->stats[STAT_PERSISTANT_POWERUP]].giTag == PW_SCOUT ) { return qfalse; } // we also clamp armor to the maxhealth for handicapping if( bg_itemlist[ps->stats[STAT_PERSISTANT_POWERUP]].giTag == PW_GUARD ) { upperBound = ps->stats[STAT_MAX_HEALTH]; } else { upperBound = ps->stats[STAT_MAX_HEALTH] * 2; } if ( ps->stats[STAT_ARMOR] >= upperBound ) { return qfalse; } #else if ( ps->stats[STAT_ARMOR] >= ps->stats[STAT_MAX_HEALTH] * 2 ) { return qfalse; } #endif return qtrue; case IT_HEALTH: // small and mega healths will go over the max, otherwise // don't pick up if already at max #ifdef MISSIONPACK if( bg_itemlist[ps->stats[STAT_PERSISTANT_POWERUP]].giTag == PW_GUARD ) { upperBound = ps->stats[STAT_MAX_HEALTH]; } else #endif if ( item->quantity == 5 || item->quantity == 100 ) { if ( ps->stats[STAT_HEALTH] >= ps->stats[STAT_MAX_HEALTH] * 2 ) { return qfalse; } return qtrue; } if ( ps->stats[STAT_HEALTH] >= ps->stats[STAT_MAX_HEALTH] ) { return qfalse; } return qtrue; case IT_POWERUP: return qtrue; // powerups are always picked up #ifdef MISSIONPACK case IT_PERSISTANT_POWERUP: // can only hold one item at a time if ( ps->stats[STAT_PERSISTANT_POWERUP] ) { return qfalse; } // check team only if( ( ent->generic1 & 2 ) && ( ps->persistant[PERS_TEAM] != TEAM_RED ) ) { return qfalse; } if( ( ent->generic1 & 4 ) && ( ps->persistant[PERS_TEAM] != TEAM_BLUE ) ) { return qfalse; } return qtrue; #endif case IT_TEAM: // team items, such as flags #ifdef MISSIONPACK if( gametype == GT_1FCTF ) { // neutral flag can always be picked up if( item->giTag == PW_NEUTRALFLAG ) { return qtrue; } if (ps->persistant[PERS_TEAM] == TEAM_RED) { if (item->giTag == PW_BLUEFLAG && ps->powerups[PW_NEUTRALFLAG] ) { return qtrue; } } else if (ps->persistant[PERS_TEAM] == TEAM_BLUE) { if (item->giTag == PW_REDFLAG && ps->powerups[PW_NEUTRALFLAG] ) { return qtrue; } } } #endif if( gametype == GT_CTF ) { // ent->modelindex2 is non-zero on items if they are dropped // we need to know this because we can pick up our dropped flag (and return it) // but we can't pick up our flag at base if (ps->persistant[PERS_TEAM] == TEAM_RED) { if (item->giTag == PW_BLUEFLAG || (item->giTag == PW_REDFLAG && ent->modelindex2) || (item->giTag == PW_REDFLAG && ps->powerups[PW_BLUEFLAG]) ) return qtrue; } else if (ps->persistant[PERS_TEAM] == TEAM_BLUE) { if (item->giTag == PW_REDFLAG || (item->giTag == PW_BLUEFLAG && ent->modelindex2) || (item->giTag == PW_BLUEFLAG && ps->powerups[PW_REDFLAG]) ) return qtrue; } } #ifdef MISSIONPACK if( gametype == GT_HARVESTER ) { return qtrue; } #endif return qfalse; case IT_HOLDABLE: // can only hold one item at a time if ( ps->stats[STAT_HOLDABLE_ITEM] ) { return qfalse; } return qtrue; case IT_BAD: Com_Error( ERR_DROP, "BG_CanItemBeGrabbed: IT_BAD" ); default: #ifndef Q3_VM #ifndef NDEBUG // bk0001204 Com_Printf("BG_CanItemBeGrabbed: unknown enum %d\n", item->giType ); #endif #endif break; } return qfalse; }
std::string BasePart::describe() const { std::stringstream ss; ss << "Base: " << name() << ", Bullet type: " << static_cast<int>(ammoType()); return ss.str(); }