bool CWeapon::SwitchAmmoType( u32 flags ) { if ( IsPending() || OnClient() ) return false; if ( !(flags & CMD_START) ) return false; u8 l_newType = m_ammoType; bool b1, b2; do { l_newType = u8( (u32(l_newType+1)) % m_ammoTypes.size() ); b1 = (l_newType != m_ammoType); b2 = unlimited_ammo() ? false : ( !m_pInventory->GetAny( m_ammoTypes[l_newType].c_str() ) ); } while( b1 && b2 ); if ( l_newType != m_ammoType ) { m_set_next_ammoType_on_reload = l_newType; if ( OnServer() ) { Reload(); } } return true; }
bool CWeaponMagazined::TryReload() { if (m_pCurrentInventory) { if (TryToGetAmmo(m_ammoType) || unlimited_ammo() || (IsMisfire() && iAmmoElapsed)) { m_bPending = true; SwitchState(eReload); return true; } for (u32 i = 0; i < m_ammoTypes.size(); ++i) { if (TryToGetAmmo(i)) { m_ammoType = i; m_bPending = true; SwitchState(eReload); return true; } } } SwitchState(eIdle); return false; }
void CWeaponMagazined::GetBriefInfo(xr_string& str_name, xr_string& icon_sect_name, xr_string& str_count) { int AE = GetAmmoElapsed(); int AC = GetAmmoCurrent(); if (AE == 0 || 0 == m_magazine.size()) icon_sect_name = *m_ammoTypes[m_ammoType]; else icon_sect_name = *m_ammoTypes[m_magazine.back().m_LocalAmmoType]; string256 sItemName; strcpy_s(sItemName, *CStringTable().translate(pSettings->r_string(icon_sect_name.c_str(), "inv_name_short"))); if (HasFireModes()) strcat_s(sItemName, GetCurrentFireModeStr()); str_name = sItemName; { if (!unlimited_ammo()) sprintf_s(sItemName, "%d/%d", AE, AC - AE); else sprintf_s(sItemName, "%d/--", AE); str_count = sItemName; } }
void CWeaponMagazined::UnloadMagazine(bool spawn_ammo) { xr_map<LPCSTR, u16> l_ammo; while (!m_magazine.empty()) { CCartridge &l_cartridge = m_magazine.back(); xr_map<LPCSTR, u16>::iterator l_it; for (l_it = l_ammo.begin(); l_ammo.end() != l_it; ++l_it) { if (!xr_strcmp(*l_cartridge.m_ammoSect, l_it->first)) { ++(l_it->second); break; } } if (l_it == l_ammo.end()) l_ammo[*l_cartridge.m_ammoSect] = 1; m_magazine.pop_back(); --iAmmoElapsed; } VERIFY((u32)iAmmoElapsed == m_magazine.size()); if (!spawn_ammo) return; xr_map<LPCSTR, u16>::iterator l_it; for (l_it = l_ammo.begin(); l_ammo.end() != l_it; ++l_it) { CWeaponAmmo *l_pA = smart_cast<CWeaponAmmo*>(m_pCurrentInventory->GetAny(l_it->first)); if (l_pA) { u16 l_free = l_pA->m_boxSize - l_pA->m_boxCurr; l_pA->m_boxCurr = l_pA->m_boxCurr + (l_free < l_it->second ? l_free : l_it->second); l_it->second = l_it->second - (l_free < l_it->second ? l_free : l_it->second); } if (l_it->second && !unlimited_ammo()) SpawnAmmo(l_it->second, l_it->first); } }
bool CWeaponMagazined::TryReload() { if(m_pInventory) { m_pAmmo = smart_cast<CWeaponAmmo*>(m_pInventory->GetAny(*m_ammoTypes[m_ammoType] )); if(IsMisfire() && iAmmoElapsed) { m_bPending = true; SwitchState(eReload); return true; } if(m_pAmmo || unlimited_ammo()) { m_bPending = true; SwitchState(eReload); return true; } else for(u32 i = 0; i < m_ammoTypes.size(); ++i) { m_pAmmo = smart_cast<CWeaponAmmo*>(m_pInventory->GetAny( *m_ammoTypes[i] )); if(m_pAmmo) { m_ammoType = i; m_bPending = true; SwitchState(eReload); return true; } } } SwitchState(eIdle); return false; }
void CWeaponMagazined::ReloadMagazine() { m_dwAmmoCurrentCalcFrame = 0; //устранить осечку при перезарядке if (IsMisfire()) bMisfire = false; //переменная блокирует использование //только разных типов патронов // static bool l_lockType = false; if (!m_bLockType) { m_ammoName = NULL; m_pAmmo = NULL; } if (!m_pCurrentInventory) return; if (m_set_next_ammoType_on_reload != u32(-1)){ m_ammoType = m_set_next_ammoType_on_reload; m_set_next_ammoType_on_reload = u32(-1); } if (!unlimited_ammo()) { //попытаться найти в инвентаре патроны текущего типа #if defined(AMMO_FROM_BELT) if (ParentIsActor()) m_pAmmo = smart_cast<CWeaponAmmo*>(m_pCurrentInventory->GetAmmoOnBelt(*m_ammoTypes[m_ammoType])); else m_pAmmo = smart_cast<CWeaponAmmo*>(m_pCurrentInventory->GetAny(*m_ammoTypes[m_ammoType])); #else m_pAmmo = smart_cast<CWeaponAmmo*>(m_pCurrentInventory->GetAny(*m_ammoTypes[m_ammoType])); #endif if (!m_pAmmo && !m_bLockType) { for (u32 i = 0; i < m_ammoTypes.size(); ++i) { //проверить патроны всех подходящих типов #if defined(AMMO_FROM_BELT) if (ParentIsActor()) m_pAmmo = smart_cast<CWeaponAmmo*>(m_pCurrentInventory->GetAmmoOnBelt(*m_ammoTypes[i])); else m_pAmmo = smart_cast<CWeaponAmmo*>(m_pCurrentInventory->GetAny(*m_ammoTypes[i])); #else m_pAmmo = smart_cast<CWeaponAmmo*>(m_pCurrentInventory->GetAny(*m_ammoTypes[i])); #endif if (m_pAmmo) { m_ammoType = i; break; } } } } else m_ammoType = m_ammoType; //нет патронов для перезарядки if (!m_pAmmo && !unlimited_ammo()) return; //разрядить магазин, если загружаем патронами другого типа if (!m_bLockType && !m_magazine.empty() && (!m_pAmmo || xr_strcmp(m_pAmmo->cNameSect(), *m_magazine.back().m_ammoSect))) UnloadMagazine(); VERIFY((u32)iAmmoElapsed == m_magazine.size()); if (m_DefaultCartridge.m_LocalAmmoType != m_ammoType) m_DefaultCartridge.Load(*m_ammoTypes[m_ammoType], u8(m_ammoType)); CCartridge l_cartridge = m_DefaultCartridge; while (iAmmoElapsed < iMagazineSize) { if (!unlimited_ammo()) { if (!m_pAmmo->Get(l_cartridge)) break; } ++iAmmoElapsed; l_cartridge.m_LocalAmmoType = u8(m_ammoType); m_magazine.push_back(l_cartridge); } m_ammoName = (m_pAmmo) ? m_pAmmo->m_nameShort : NULL; VERIFY((u32)iAmmoElapsed == m_magazine.size()); //выкинуть коробку патронов, если она пустая if (m_pAmmo && !m_pAmmo->m_boxCurr && OnServer()) m_pAmmo->SetDropManual(TRUE); if (iMagazineSize > iAmmoElapsed) { m_bLockType = true; ReloadMagazine(); m_bLockType = false; } VERIFY((u32)iAmmoElapsed == m_magazine.size()); }