diff --git a/ext/Client/venice-spectator/ui.lua b/ext/Client/venice-spectator/ui.lua index 237ccb9..4e6ad1a 100644 --- a/ext/Client/venice-spectator/ui.lua +++ b/ext/Client/venice-spectator/ui.lua @@ -314,12 +314,12 @@ function SpectatorUI:OnUpdate(p_Delta, p_SimulationDelta) self.m_InitialTimer = self.m_InitialTimer - p_Delta return end - - for i = 1, self.m_KillCount do - if self.m_Kills[i]['delta'] ~= nil then - self.m_Kills[i]['delta'] = self.m_Kills[i]['delta'] - p_Delta - end - end + + for i = 1, self.m_KillCount do + if self.m_Kills[i] ~= nil and self.m_Kills[i]['delta'] ~= nil then + self.m_Kills[i]['delta'] = self.m_Kills[i]['delta'] - p_Delta + end + end if not self.m_PlayerStats then self.m_PlayerStats = true @@ -342,26 +342,76 @@ function SpectatorUI:OnUpdate(p_Delta, p_SimulationDelta) end local s_ObjectiveIndex = 1 + local s_ObjectiveCounter = 1 + + local gameMode = SharedUtils:GetCurrentGameMode() + if gameMode == nil then + -- while maploading this can be nil + return + elseif gameMode:match("Conquest") or gameMode:match("Superiority") or gameMode == "Domination0" or gameMode == "Scavenger0" then + + local s_TicketIterator = EntityManager:GetIterator('ClientTicketCounterEntity') + + local s_NeedsTeamUpdate = false + + if s_TicketIterator ~= nil then + local s_Entity = s_TicketIterator:Next() + + while s_Entity ~= nil do + local s_TicketCounter = TicketCounterEntity(s_Entity) + + if self.m_Tickets[s_TicketCounter.team] ~= s_TicketCounter.ticketCount then + self.m_Tickets[s_TicketCounter.team] = s_TicketCounter.ticketCount + s_NeedsTeamUpdate = true + end - local s_TicketIterator = EntityManager:GetIterator('TicketCounterEntity') - - local s_NeedsTeamUpdate = false - - if s_TicketIterator ~= nil then - local s_Entity = s_TicketIterator:Next() - - while s_Entity ~= nil do - local s_TicketCounter = TicketCounterEntity(s_Entity) + s_Entity = s_TicketIterator:Next() + end + end + + elseif gameMode:match("Rush") then + + local s_TicketIterator = EntityManager:GetIterator('ClientLifeCounterEntity') + + local s_NeedsTeamUpdate = false + + if s_TicketIterator ~= nil then + local s_Entity = s_TicketIterator:Next() + + while s_Entity ~= nil do + local s_TicketCounter = LifeCounterEntity(s_Entity) + + if self.m_Tickets[LifeCounterEntityData(s_TicketCounter.data).teamId] ~= s_TicketCounter.lifeCounter then + self.m_Tickets[LifeCounterEntityData(s_TicketCounter.data).teamId] = s_TicketCounter.lifeCounter + s_NeedsTeamUpdate = true + end - if self.m_Tickets[s_TicketCounter.team] ~= s_TicketCounter.ticketCount then - self.m_Tickets[s_TicketCounter.team] = s_TicketCounter.ticketCount - s_NeedsTeamUpdate = true + s_Entity = s_TicketIterator:Next() end + end + + elseif gameMode:match("TeamDeathMatch") or gameMode == "SquadDeathMatch0" then + + local s_TicketIterator = EntityManager:GetIterator('ClientKillCounterEntity') + + local s_NeedsTeamUpdate = false + + if s_TicketIterator ~= nil then + local s_Entity = s_TicketIterator:Next() + + while s_Entity ~= nil do + local s_TicketCounter = KillCounterEntity(s_Entity) + + if self.m_Tickets[KillCounterEntityData(s_TicketCounter.data).teamId] ~= s_TicketCounter.killCount then + self.m_Tickets[KillCounterEntityData(s_TicketCounter.data).teamId] = s_TicketCounter.killCount + s_NeedsTeamUpdate = true + end - s_Entity = s_TicketIterator:Next() + s_Entity = s_TicketIterator:Next() + end end + end - if s_NeedsTeamUpdate then local s_Teams = {} @@ -375,11 +425,18 @@ function SpectatorUI:OnUpdate(p_Delta, p_SimulationDelta) self:SendUIAction(SET_TEAM_NAME, { team = 2, name = self.m_TeamNames[2] }) end - local s_Iterator = EntityManager:GetIterator('CapturePointEntity') - - if s_Iterator ~= nil then + local s_Iterator = EntityManager:GetIterator('ClientCapturePointEntity') + + if s_Iterator ~= nil then local s_Entity = s_Iterator:Next() + local s_AddObjectives = false + + if s_Entity == nil then + -- if we don't find any CapturePointEntity in the beginning we clear our objectives + self:SendUIAction(CLEAR_OBJECTIVES, {}) + end + while s_Entity ~= nil do local s_CaptureEntity = CapturePointEntity(s_Entity) @@ -392,23 +449,44 @@ function SpectatorUI:OnUpdate(p_Delta, p_SimulationDelta) if not s_CaptureEntity.controlled then s_Team = TeamId.TeamNeutral end - + local s_Label = s_CaptureEntity.name s_Label = s_Label:gsub('ID_H_US_', '') s_Label = s_Label:gsub('ID_H_RU_', '') - + + -- Order the CapturePoints alphabetic + if s_Label == "A" then + s_ObjectiveIndex = 1 + elseif s_Label == "B" then + s_ObjectiveIndex = 2 + elseif s_Label == "C" then + s_ObjectiveIndex = 3 + elseif s_Label == "D" then + s_ObjectiveIndex = 4 + elseif s_Label == "E" then + s_ObjectiveIndex = 5 + elseif s_Label == "F" then + s_ObjectiveIndex = 6 + elseif s_Label == "G" then + s_ObjectiveIndex = 7 + elseif s_Label == "H" then + s_ObjectiveIndex = 8 + elseif s_Label == "I" then + s_ObjectiveIndex = 9 + elseif s_Label == "J" then + s_ObjectiveIndex = 10 + elseif s_Label == "K" then + s_ObjectiveIndex = 11 + elseif s_Label == "L" then + s_ObjectiveIndex = 12 + end + local s_Transform = s_CaptureEntity.transform.trans if self.m_Objectives[s_ObjectiveIndex] == nil then - self:SendUIAction(ADD_OBJECTIVE, { - objective = { - label = s_Label, - currentTeam = s_Team, - contested = s_Contested, - position = { s_Transform.x, s_Transform.y, s_Transform.z } - } - }) - + + s_AddObjectives = true + elseif self.m_Objectives[s_ObjectiveIndex]['label'] ~= s_Label or self.m_Objectives[s_ObjectiveIndex]['currentTeam'] ~= s_Team or self.m_Objectives[s_ObjectiveIndex]['contested'] ~= s_Contested then @@ -430,20 +508,36 @@ function SpectatorUI:OnUpdate(p_Delta, p_SimulationDelta) position = { s_Transform.x, s_Transform.y, s_Transform.z } } - s_ObjectiveIndex = s_ObjectiveIndex + 1 + s_ObjectiveCounter = s_ObjectiveCounter + 1 end s_Entity = s_Iterator:Next() end + + -- Add the Objectives here so the order is correct + if s_AddObjectives == true then + + self:SendUIAction(CLEAR_OBJECTIVES, {}) + for s_ObjectiveIndex,m_Objective in pairs(self.m_Objectives) do + + self:SendUIAction(ADD_OBJECTIVE, { + objective = { + label = m_Objective.label, + currentTeam = m_Objective.currentTeam, + contested = m_Objective.contested, + position = m_Objective.position + } + }) + end + end + s_AddObjectives = false + end -- Refresh all objectives if there are now less. - if s_ObjectiveIndex > 1 and self.m_Objectives[s_ObjectiveIndex] ~= nil then + if s_ObjectiveCounter > 1 and self.m_Objectives[s_ObjectiveCounter] ~= nil then self:SendUIAction(CLEAR_OBJECTIVES, {}) - - for i = 1, s_ObjectiveIndex - 1 do - self:SendUIAction(ADD_OBJECTIVE, { objective = self.m_Objectives[i] }) - end + self.m_Objectives = {} end @@ -504,7 +598,7 @@ function SpectatorUI:OnUpdate(p_Delta, p_SimulationDelta) local s_NewKillCount = 0 for i = 1, s_KillCount do - if self.m_Kills[i]['delta'] <= 0 then + if self.m_Kills[i] ~= nil and self.m_Kills[i]['delta'] ~= nil and self.m_Kills[i]['delta'] <= 0 then self.m_Kills[i] = nil s_UpdateKills = true else @@ -562,6 +656,10 @@ function SpectatorUI:OnUpdate(p_Delta, p_SimulationDelta) end function SpectatorUI:ShouldUpdatePlayer(p_OldData, p_NewData) + if p_OldData == nil then + return true + end + if p_OldData['team'] ~= p_NewData['team'] then return true end @@ -694,19 +792,22 @@ function SpectatorUI:GetPlayerData(p_Player) local s_WeaponsComponent = s_Soldier.weaponsComponent if s_WeaponsComponent ~= nil then - s_PlayerData['currentWeapon'] = s_WeaponsComponent.currentWeaponIndex + s_PlayerData['currentWeapon'] = s_WeaponsComponent.currentWeaponSlot - for i = 1, s_WeaponsComponent.weaponCount do + for i,s_Weapon in pairs(s_WeaponsComponent.weapons) do s_PlayerData['weapons'][i] = {} - local s_Weapon = s_WeaponsComponent:GetWeapon(i - 1) - + if s_Weapon ~= nil then local s_SoldierWeaponData = SoldierWeaponData(s_Weapon.data) - local s_SoldierWeaponBlueprint = SoldierWeaponBlueprint(s_SoldierWeaponData.soldierWeaponBlueprint) - s_PlayerData['weapons'][i]['name'] = s_SoldierWeaponBlueprint.name or s_Weapon.name -- Old: GetWeaponEntityNameByIndex - s_PlayerData['weapons'][i]['displayName'] = s_Weapon.name -- Old: GetWeaponNameByIndex - s_PlayerData['weapons'][i]['ammo'] = s_Weapon.primaryAmmo - s_PlayerData['weapons'][i]['ammoMags'] = s_Weapon.secondaryAmmo + local s_SoldierWeaponBlueprint = s_SoldierWeaponData.soldierWeaponBlueprint + if s_SoldierWeaponBlueprint ~= nil then + s_SoldierWeaponBlueprint = SoldierWeaponBlueprint(s_SoldierWeaponBlueprint) + end + s_PlayerData['weapons'][i]['name'] = s_SoldierWeaponBlueprint.name or s_Weapon.name -- Old: GetWeaponEntityNameByIndex + s_PlayerData['weapons'][i]['displayName'] = s_Weapon.name -- Old: GetWeaponNameByIndex + s_PlayerData['weapons'][i]['ammo'] = s_Weapon.primaryAmmo + s_PlayerData['weapons'][i]['ammoMags'] = s_Weapon.secondaryAmmo + end end @@ -725,4 +826,4 @@ function SpectatorUI:GetPlayerData(p_Player) return s_PlayerData end -return SpectatorUI \ No newline at end of file +return SpectatorUI diff --git a/ext/Client/venice-spectator/vanilla-ui.lua b/ext/Client/venice-spectator/vanilla-ui.lua index df69b4a..7814ca3 100644 --- a/ext/Client/venice-spectator/vanilla-ui.lua +++ b/ext/Client/venice-spectator/vanilla-ui.lua @@ -4,6 +4,7 @@ function SpectatorVanillaUI:__init() -- Install our hooks. -- TODO: Re-enable push screen hook when our UI is ready. self.m_UIPushScreenHook = Hooks:Install('UI:PushScreen', 420, self, self.OnPushScreen) + self.m_UICreateKillMessageHook = Hooks:Install('UI:CreateKillMessage', 420, self, self.OnCreateKillMessage) end function SpectatorVanillaUI:OnUpdate(p_Delta, p_SimDelta) @@ -12,7 +13,7 @@ end function SpectatorVanillaUI:OnPushScreen(p_Hook, p_Screen, p_GraphPriority, p_ParentGraph) if SpectatorManager:GetCameraMode() == SpectatorCameraMode.Disabled then - p_Hook:Next() + --p_Hook:Next() return end @@ -28,7 +29,7 @@ function SpectatorVanillaUI:OnPushScreen(p_Hook, p_Screen, p_GraphPriority, p_Pa s_Screen.name ~= "UI/Flow/Screen/SpawnScreen" and s_Screen.name ~= "UI/Flow/Screen/SpawnScreenTicketCounterTDMScreen" and s_Screen.name ~= "UI/Flow/Screen/HudTDMScreen" then - p_Hook:Next() + --p_Hook:Next() return end @@ -73,4 +74,12 @@ function SpectatorVanillaUI:OnPushScreen(p_Hook, p_Screen, p_GraphPriority, p_Pa p_Hook:Pass(s_Screen, p_GraphPriority, p_ParentGraph) end -return SpectatorVanillaUI \ No newline at end of file +function SpectatorVanillaUI:OnCreateKillMessage(p_Hook) + if SpectatorManager:GetCameraMode() == SpectatorCameraMode.Disabled then + return + end + -- Block the kill feed + p_Hook:Return() +end + +return SpectatorVanillaUI diff --git a/mod.json b/mod.json index 5a3c92f..085e113 100644 --- a/mod.json +++ b/mod.json @@ -3,7 +3,10 @@ "Authors": [ "Venice Unleashed" ], "Description": "Venice Unleashed Spectator Functionality", "URL": "http://veniceunleashed.net", - "Version": "1.1", + "Version": "1.2.1", "HasWebUI": true, - "HasVeniceEXT": true -} \ No newline at end of file + "HasVeniceEXT": true , + "Dependencies": { + "veniceext": "^1.0.3" + } +} diff --git a/ui/assets/scss/components/_player-card.scss b/ui/assets/scss/components/_player-card.scss index 275ae5d..792267f 100644 --- a/ui/assets/scss/components/_player-card.scss +++ b/ui/assets/scss/components/_player-card.scss @@ -75,18 +75,37 @@ } .item-container { + display: flex; overflow: hidden; + justify-content: space-between; line-height: 1.4814vh; font-size: 1.4814vh; font-family: puristasemibold; - img { - max-width: 20%; + + .img-container { + $vh-sz: 2vh; + $px-sz: 16px; + + display: flex; + align-items: center; + justify-content: center; + width: $vh-sz; + min-width: $px-sz; + height: $vh-sz; + min-height: $px-sz; margin: 0.740vh 0; + overflow: hidden; + + img { + width: 100%; + display: block; + transform: scale(4); + } } + span { margin: 0.740vh 0; - float: right; } } } @@ -95,7 +114,10 @@ } .score-container { - height: 0; + height: 4vh; + display: flex; + align-items: center; + justify-content: center; width: 64.81vh; margin: 0.370vh auto 0; text-align: center; @@ -106,22 +128,21 @@ transition: height 250ms ease-in-out, border-bottom-width 250ms ease-in-out; .score-item { - display: inline-block; - vertical-align: middle; - margin: 0.5555vh 1.3888vh 0.6767vh; + display: flex; + align-items: center; + margin: 0 1.4vh; color: #e6e6e6; - h1 { - display: inline-block; - vertical-align: bottom; - font-size: 1.1111vh; - margin-right: 0.9259vh; + div.label { + display: block; + font-size: 1.1vh; + margin-right: 0.9vh; text-transform: uppercase; } - span { - vertical-align: bottom; - font-size: 1.48148vh; + div.value { + display: block; + font-size: 1.4vh; } } } diff --git a/ui/src/components/Killfeed/Kill.js b/ui/src/components/Killfeed/Kill.js index 1f232fc..6fa0085 100644 --- a/ui/src/components/Killfeed/Kill.js +++ b/ui/src/components/Killfeed/Kill.js @@ -7,14 +7,19 @@ export default class Kill extends Component { const { killer, killed, weapon } = this.props; - let killerClass = killer !== null ? 'player-name killer team-' + killer.team : ''; - let killerName = killer !== null ? killer.name : ''; + let killerClass = killer ? 'player-name killer ' : ''; + killerClass = killer && killer.team ? killerClass + 'team-' + killer.team : killerClass + let killerName = killer ? killer.name : ''; - let killedClass = 'player-name killed team-' + killed.team; + let killedClass = 'player-name killed '; + killedClass = killed && killed.team ? killedClass + 'team-' + killed.team : killedClass; let weaponParts = weapon.split('/'); let weaponName = weaponParts[weaponParts.length - 1]; + // return a dummy div (probably null should work too) + if (!killed || !killerName) return (
) + return (
{killerName} diff --git a/ui/src/components/MatchBar/ObjectiveBar.js b/ui/src/components/MatchBar/ObjectiveBar.js index 8953c26..7bbf23a 100644 --- a/ui/src/components/MatchBar/ObjectiveBar.js +++ b/ui/src/components/MatchBar/ObjectiveBar.js @@ -15,8 +15,8 @@ export default class ObjectiveBar extends Component for (let i = 0; i < objectives.length; ++i) { - let objective = this.props.objective || {}; - let nextObjective = nextProps.objective || {}; + let objective = objectives[i] || {}; + let nextObjective = nextObjectives[i] || {}; if (objective.currentTeam !== nextObjective.currentTeam || objective.contested !== nextObjective.contested || diff --git a/ui/src/components/MatchBar/TeamSide.js b/ui/src/components/MatchBar/TeamSide.js index 9ca011a..a1bf8ed 100644 --- a/ui/src/components/MatchBar/TeamSide.js +++ b/ui/src/components/MatchBar/TeamSide.js @@ -8,6 +8,7 @@ export default class TeamSide extends Component { shouldComponentUpdate(nextProps) { + if(!this.props || !nextProps) return false let team = this.props.team || {}; let nextTeam = nextProps.team || {}; diff --git a/ui/src/components/PlayerCard/EquipmentItem.js b/ui/src/components/PlayerCard/EquipmentItem.js index f27e722..f8b9a9c 100644 --- a/ui/src/components/PlayerCard/EquipmentItem.js +++ b/ui/src/components/PlayerCard/EquipmentItem.js @@ -53,10 +53,13 @@ export default class EquipmentItem extends Component displayName = 'Slot ' + slot; } - let weaponImage = require('../../../assets/img/no-equipment.png'); + let weaponImage = 'fb://UI/Art/Persistence/WeaponAccessory/NoSelection'; + + + if (!this.state.error && weaponName !== null) { + weaponImage = Utils.getWeaponName(weaponName); + } - if (!this.state.error && weaponName !== null) - weaponImage = require('../../../assets/img/weapons/' + weaponName + '.png'); // TODO: Use frostbite asset. return ( @@ -77,7 +80,7 @@ export default class EquipmentItem extends Component return (

Slot {weaponSlot + 1}

- +
) } diff --git a/ui/src/components/PlayerCard/InfoContainer.js b/ui/src/components/PlayerCard/InfoContainer.js index a2609ab..83df4b2 100644 --- a/ui/src/components/PlayerCard/InfoContainer.js +++ b/ui/src/components/PlayerCard/InfoContainer.js @@ -26,10 +26,28 @@ export default class InfoContainer extends Component // Gather equipment. let equipment = []; + console.log(player) + console.log(player.weapons) + + if(player.weapons === null || (Object.keys(player.weapons).length === 0 && player.weapons.constructor === Object)) { + return ( +
+ +
+ ); + } + + // TODO: Add in-vehicle logic. equipment.push(); equipment.push(); - equipment.push(); + + if(Object.keys(player.weapons[2]).length === 0 && player.weapons[2].constructor === Object) { + equipment.push(); + } else { + equipment.push(); + } + equipment.push(); return ( diff --git a/ui/src/components/PlayerCard/ScoreItem.js b/ui/src/components/PlayerCard/ScoreItem.js index 849a069..4691164 100644 --- a/ui/src/components/PlayerCard/ScoreItem.js +++ b/ui/src/components/PlayerCard/ScoreItem.js @@ -15,8 +15,8 @@ export default class ScoreItem extends Component return (
-

{label}

- {value} +
{label}
+
{value}
); } diff --git a/ui/src/components/PlayerCard/StatItem.js b/ui/src/components/PlayerCard/StatItem.js index 8e9242e..937e4f9 100644 --- a/ui/src/components/PlayerCard/StatItem.js +++ b/ui/src/components/PlayerCard/StatItem.js @@ -1,6 +1,8 @@ import React, { Component } from 'react' import PropTypes from 'prop-types'; +import Utils from '../../util/Utils' + export default class StatItem extends Component { shouldComponentUpdate(nextProps) @@ -23,7 +25,9 @@ export default class StatItem extends Component

{label}

- +
+ +
{leftLabel + ' / ' + rightLabel}
diff --git a/ui/src/components/SquadBlock/PlayerWeapon.js b/ui/src/components/SquadBlock/PlayerWeapon.js index 7a29cbd..ca851e8 100644 --- a/ui/src/components/SquadBlock/PlayerWeapon.js +++ b/ui/src/components/SquadBlock/PlayerWeapon.js @@ -28,8 +28,8 @@ export default class PlayerWeapon extends Component // TODO: Use frostbite asset. return (
- +
); } -} \ No newline at end of file +} diff --git a/ui/src/index.js b/ui/src/index.js index 97902a0..b6208f1 100644 --- a/ui/src/index.js +++ b/ui/src/index.js @@ -28,4 +28,4 @@ if (process.env.NODE_ENV !== 'production') require('./test/spam'); } -console.log("Test"); \ No newline at end of file +console.log("Test"); diff --git a/ui/src/reducers/team.js b/ui/src/reducers/team.js index 4749682..b44a1d0 100644 --- a/ui/src/reducers/team.js +++ b/ui/src/reducers/team.js @@ -27,6 +27,8 @@ export default function team(state = initialState, action) case SET_TEAM_NAME: { + if(!action) + return state; if (action.team >= state.teams.length) return state; diff --git a/ui/src/util/Utils.js b/ui/src/util/Utils.js index 0fce30d..b1ccbd5 100644 --- a/ui/src/util/Utils.js +++ b/ui/src/util/Utils.js @@ -5,251 +5,265 @@ export default class Utils switch (name) { case '870': - return 'remington'; + return 'fb://UI/Art/Persistence/Weapons/Remington'; case 'a91': - return 'a91'; + return 'fb://UI/Art/Persistence/Weapons/A91'; case 'acr': - return 'xp2_acr'; + return 'fb://UI/Art/Persistence/Weapons/XP2_ACR'; case 'aek971': - return 'aek97'; + return 'fb://UI/Art/Persistence/Weapons/AEK97'; case 'aek971_m320_he': - return 'm320'; + return 'fb://UI/Art/Persistence/Weapons/M320'; case 'aek971_m320_lvg': - return 'm320_lvg'; + return 'fb://UI/Art/Persistence/Weapons/M320_LVG'; case 'aek971_m320_shg': - return 'm320_sg'; + return 'fb://UI/Art/Persistence/Weapons/M320_SG'; case 'aek971_m320_smk': - return 'm320_smk'; + return 'fb://UI/Art/Persistence/Weapons/M320_SMK'; case 'ak74m': - return 'ak74m'; + return 'fb://UI/Art/Persistence/Weapons/AK74M'; case 'ak74m_us': - return 'ak74m'; + return 'fb://UI/Art/Persistence/Weapons/AK74M'; case 'aks74u': - return 'aks74u'; + return 'fb://UI/Art/Persistence/Weapons/AKS74U'; case 'aks74u_us': - return 'aks74u'; + return 'fb://UI/Art/Persistence/Weapons/AKS74U'; case 'an94': - return 'an94'; + return 'fb://UI/Art/Persistence/Weapons/AN94'; case 'asval': - return 'asval'; + return 'fb://UI/Art/Persistence/Weapons/ASVal'; case 'crossbow_scoped_cobra': - return 'xp4_crossbowkobra'; + case 'xp4_crossbow_prototype': + return 'fb://UI/Art/Persistence/Weapons/XP4_CrossbowKobra'; case 'crossbow_scoped_riflescope': - return 'xp4_crossbowriflescope'; + return 'fb://UI/Art/Persistence/Weapons/XP4_CrossbowRifleScope'; case 'dao-12': - return 'dao12'; + return 'fb://UI/Art/Persistence/Weapons/DAO12'; case 'f2000': - return 'f2000'; + return 'fb://UI/Art/Persistence/Weapons/F2000'; case 'famas': - return 'xp1_famas'; + return 'fb://UI/Art/Persistence/Weapons/XP1_FAMAS'; case 'fgm148': - return 'javelin'; + return 'fb://UI/Art/Persistence/Weapons/Javelin'; case 'fim92': - return 'stinger'; + case 'fim92a': + return 'fb://UI/Art/Persistence/Weapons/Stinger'; case 'g36c': - return 'g36c'; + return 'fb://UI/Art/Persistence/Weapons/G36C'; case 'g3a3': - return 'g3'; + return 'fb://UI/Art/Persistence/Weapons/G3'; case 'glock17': - return 'glock17'; + return 'fb://UI/Art/Persistence/Weapons/Glock17'; case 'glock17_silenced': - return 'glock17silenced'; + return 'fb://UI/Art/Persistence/Weapons/Glock17Silenced'; case 'glock18': - return 'glock18'; + return 'fb://UI/Art/Persistence/Weapons/Glock18'; case 'glock18_silenced': - return 'glock18silenced'; + return 'fb://UI/Art/Persistence/Weapons/Glock18Silenced'; case 'hk417': - return 'xp2_hk417'; + return 'fb://UI/Art/Persistence/Weapons/XP2_HK417'; case 'hk53': - return 'xp1_hk53'; + return 'fb://UI/Art/Persistence/Weapons/XP1_HK53'; case 'jackhammer': - return 'xp1_jackhammer'; + return 'fb://UI/Art/Persistence/Weapons/XP1_JACKHAMMER'; case 'jng90': - return 'xp2_jng90'; + return 'fb://UI/Art/Persistence/Weapons/XP2_JNG90'; case 'kh2002': - return 'kh2002'; + return 'fb://UI/Art/Persistence/Weapons/KH2002'; case 'knife': - return 'knife'; + return 'fb://UI/Art/Persistence/Weapons/Knife'; case 'knife_razor': - return 'combatknife'; + return 'fb://UI/Art/Persistence/Weapons/CombatKnife'; case 'l85a2': - return 'xp1_l85a2'; + return 'fb://UI/Art/Persistence/Weapons/XP1_L85A2'; case 'l86': - return 'xp2_l86'; + return 'fb://UI/Art/Persistence/Weapons/XP2_L86'; case 'l96': - return 'xp1_l96'; + return 'fb://UI/Art/Persistence/Weapons/XP1_L96'; case 'lsat': - return 'xp2_lsat'; + return 'fb://UI/Art/Persistence/Weapons/XP2_LSAT'; case 'm1014': - return 'm1014'; + return 'fb://UI/Art/Persistence/Weapons/M1014'; case 'm16a4': - return 'm16a4'; + return 'fb://UI/Art/Persistence/Weapons/M16A4'; case 'm16a4_ru': - return 'm16a4'; + return 'fb://UI/Art/Persistence/Weapons/M16A4'; case 'm16_burst': - return 'm16a4'; + return 'fb://UI/Art/Persistence/Weapons/M16A4'; case 'm1911_lit': - return 'm1911flashlight'; + return 'fb://UI/Art/Persistence/Weapons/M1911Flashlight'; case 'm1911': - return 'm1911'; + return 'fb://UI/Art/Persistence/Weapons/M1911'; case 'm1911_silenced': - return 'm1911silenced'; + return 'fb://UI/Art/Persistence/Weapons/M1911Silenced'; case 'm1911_tactical': - return 'm1911tactical'; + return 'fb://UI/Art/Persistence/Weapons/M1911Tactical'; case 'm240': - return 'm240'; + return 'fb://UI/Art/Persistence/Weapons/M240'; case 'm249': - return 'm249'; + return 'fb://UI/Art/Persistence/Weapons/M249'; case 'm26mass_flechette': - return 'm26mass_flechette'; + return 'fb://UI/Art/Persistence/Weapons/M26Mass_flechette'; case 'm26mass_frag': - return 'm26mass_frag'; + return 'fb://UI/Art/Persistence/Weapons/M26Mass_frag'; case 'm26mass': - return 'm26mass'; + return 'fb://UI/Art/Persistence/Weapons/M26Mass'; case 'm26mass_slug': - return 'm26mass_slug'; + return 'fb://UI/Art/Persistence/Weapons/M26Mass_slug'; case 'm27iar': - return 'm27'; + return 'fb://UI/Art/Persistence/Weapons/M27'; case 'm320_he': - return 'm320'; + case 'm320': + return 'fb://UI/Art/Persistence/Weapons/M320'; case 'm320_lvg': - return 'm320_lvg'; + return 'fb://UI/Art/Persistence/Weapons/M320_LVG'; case 'm320_shg': - return 'm320_sg'; + return 'fb://UI/Art/Persistence/Weapons/M320_SG'; case 'm320_smk': - return 'm320_smk'; + return 'fb://UI/Art/Persistence/Weapons/M320_SMK'; case 'm39ebr': - return 'm39ebr'; + return 'fb://UI/Art/Persistence/Weapons/M39EBR'; case 'm39ebr_posh': - return 'm39ebr'; + return 'fb://UI/Art/Persistence/Weapons/M39EBR'; case 'm40a5': - return 'm40a5'; + return 'fb://UI/Art/Persistence/Weapons/M40A5'; case 'm416': - return 'm416'; + return 'fb://UI/Art/Persistence/Weapons/M416'; case 'm4a1': - return 'm4a1'; + return 'fb://UI/Art/Persistence/Weapons/M4A1'; case 'm4a1_ru': - return 'm4a1'; + return 'fb://UI/Art/Persistence/Weapons/M4A1'; case 'm4': - return 'm4a1'; + return 'fb://UI/Art/Persistence/Weapons/M4A1'; case 'm60': - return 'm60'; + return 'fb://UI/Art/Persistence/Weapons/M60'; case 'm93r': - return 'm93r'; + return 'fb://UI/Art/Persistence/Weapons/M93R'; case 'm98b': - return 'm98'; + return 'fb://UI/Art/Persistence/Weapons/M98'; case 'm9': - return 'm9'; + return 'fb://UI/Art/Persistence/Weapons/M9'; case 'm9_ru': - return 'm9'; + return 'fb://UI/Art/Persistence/Weapons/M9'; case 'm9_silenced': - return 'm9silenced'; + return 'fb://UI/Art/Persistence/Weapons/M9Silenced'; case 'm9_tacticallight': - return 'm9flashlight'; + return 'fb://UI/Art/Persistence/Weapons/M9Flashlight'; case 'magpulpdr': - return 'pdr'; + case 'magpul_pdr': + return 'fb://UI/Art/Persistence/Weapons/PDR'; case 'mg36': - return 'xp1_mg36'; + return 'fb://UI/Art/Persistence/Weapons/XP1_MG36'; case 'mk11': - return 'mk11'; + return 'fb://UI/Art/Persistence/Weapons/MK11'; case 'mk11_ru': - return 'mk11'; + return 'fb://UI/Art/Persistence/Weapons/MK11'; case 'mp412rex': - return 'rex'; + return 'fb://UI/Art/Persistence/Weapons/REX'; case 'mp443': - return 'mp443'; + return 'fb://UI/Art/Persistence/Weapons/MP443'; case 'mp443_silenced': - return 'mp443silenced'; + return 'fb://UI/Art/Persistence/Weapons/MP443Silenced'; case 'mp443_tacticallight': - return 'mp443flashlight'; + return 'fb://UI/Art/Persistence/Weapons/MP443Flashlight'; case 'mp443_us': - return 'mp443'; + return 'fb://UI/Art/Persistence/Weapons/MP443'; case 'mp5k': - return 'xp2_mp5k'; + return 'fb://UI/Art/Persistence/Weapons/xp2_mp5k'; case 'mp7': - return 'mp7'; + return 'fb://UI/Art/Persistence/Weapons/mp7'; case 'mtar': - return 'xp2_mtar'; + return 'fb://UI/Art/Persistence/Weapons/xp2_mtar'; case 'p90': - return 'p90'; + return 'fb://UI/Art/Persistence/Weapons/p90'; case 'pecheneg': - return 'pecheneg'; + return 'fb://UI/Art/Persistence/Weapons/pecheneg'; case 'pp-19': - return 'xp1_pp19'; + return 'fb://UI/Art/Persistence/Weapons/xp1_pp19'; case 'pp2000': - return 'pp2000'; + return 'fb://UI/Art/Persistence/Weapons/pp2000'; case 'qbb-95': - return 'xp1_qbb95'; + return 'fb://UI/Art/Persistence/Weapons/xp1_qbb95'; case 'qbu-88_sniper': - return 'xp1_qbu88'; + return 'fb://UI/Art/Persistence/Weapons/xp1_qbu88'; case 'qbz-95b': - return 'xp1_qbz95b'; + return 'fb://UI/Art/Persistence/Weapons/xp1_qbz95b'; case 'rpg7': - return 'rpg7'; + return 'fb://UI/Art/Persistence/Weapons/rpg7'; case 'rpk-74m': - return 'rpk'; + return 'fb://UI/Art/Persistence/Weapons/rpk'; case 'rpk-74m_us': - return 'rpk'; + return 'fb://UI/Art/Persistence/Weapons/rpk'; case 'sa18igla': - return 'igla'; + return 'fb://UI/Art/Persistence/Weapons/igla'; case 'saiga_20k': - return 'saiga12'; + return 'fb://UI/Art/Persistence/Weapons/saiga12'; case 'scar-h': - return 'scarh'; + return 'fb://UI/Art/Persistence/Weapons/scarh'; case 'scar-l': - return 'xp2_scarl'; + return 'fb://UI/Art/Persistence/Weapons/xp2_scarl'; case 'sg553lb': - return 'sg553'; + return 'fb://UI/Art/Persistence/Weapons/sg553'; case 'sks': - return 'sks'; + return 'fb://UI/Art/Persistence/Weapons/sks'; case 'smaw': - return 'smaw'; + return 'fb://UI/Art/Persistence/Weapons/smaw'; case 'spas12': - return 'xp2_spas12'; + return 'fb://UI/Art/Persistence/Weapons/xp2_spas12'; case 'steyraug': - return 'xp2_steyraug'; + return 'fb://UI/Art/Persistence/Weapons/xp2_steyraug'; case 'sv98': - return 'sv98'; + return 'fb://UI/Art/Persistence/Weapons/sv98'; case 'svd': - return 'svd'; + return 'fb://UI/Art/Persistence/Weapons/svd'; case 'svd_us': - return 'svd'; + return 'fb://UI/Art/Persistence/Weapons/svd'; case 'taurus44_scoped': - return 'taurus44scoped'; + return 'fb://UI/Art/Persistence/Weapons/taurus44scoped'; case 'taurus44': - return 'taurus44'; + return 'fb://UI/Art/Persistence/Weapons/taurus44'; case 'type88': - return 'type88'; + return 'fb://UI/Art/Persistence/Weapons/type88'; case 'ump45': - return 'ump'; + return 'fb://UI/Art/Persistence/Weapons/ump'; case 'usas-12': - return 'usas12'; + return 'fb://UI/Art/Persistence/Weapons/usas12'; case 'ammobag': - return 'ammobag'; + return 'fb://UI/Art/Persistence/KitItem/ammobag'; case 'c4': - return 'c4'; + return 'fb://UI/Art/Persistence/KitItem/c4'; case 'claymore': - return 'claymore'; + return 'fb://UI/Art/Persistence/KitItem/claymore'; + case 'defibrillator': case 'defib': - return 'defib'; + return 'fb://UI/Art/Persistence/KitItem/defib'; case 'eodbot': - return 'oedbot'; + case 'eodbot_pda': + return 'fb://UI/Art/Persistence/KitItem/oedbot'; case 'm15': - return 'mine'; + return 'fb://UI/Art/Persistence/KitItem/mine'; case 'm224': - return 'mortar'; + return 'fb://UI/Art/Persistence/KitItem/mortar'; case 'mav': - return 'mav'; - case 'medkit': - return 'medkit'; + case 'mav_pda': + return 'fb://UI/Art/Persistence/KitItem/mav'; + case 'medicbag': + return 'fb://UI/Art/Persistence/KitItem/medkit'; + case 'radio_beacon': case 'radiobeacon': - return 'radiobeacon'; + return 'fb://UI/Art/Persistence/KitItem/radiobeacon'; case 'repairtool': - return 'repairtool'; + return 'fb://UI/Art/Persistence/KitItem/repairtool'; case 'soflam': - return 'soflam'; + case 'soflam_pda': + return 'fb://UI/Art/Persistence/KitItem/soflam'; + case 't-ugs': case 'ugs': - return 'tugs'; + return 'fb://UI/Art/Persistence/KitItem/tugs'; + case 'ammo': + return 'fb://UI/Art/Persistence/Specializations/Clips'; + case 'grenades': + return 'fb://UI/Art/Persistence/Weapons/Grenade'; default: return name; }