diff --git a/AUTHORS b/AUTHORS index 17937d8a1..ef969e5ec 100644 --- a/AUTHORS +++ b/AUTHORS @@ -12,6 +12,7 @@ veteran29 # CONTRIBUTORS AkiKay +arc ArtOfWar arc Badger 2-3 @@ -37,4 +38,5 @@ Smith TepacheLoco TraceSnowOwl TWYuanYu +Worst Case Scenario (WCS) Team Zelik diff --git a/addons/all_in_one/addon.gproj b/addons/all_in_one/addon.gproj index f01a44421..586bdee82 100755 --- a/addons/all_in_one/addon.gproj +++ b/addons/all_in_one/addon.gproj @@ -3,7 +3,7 @@ GameProject { GUID "60C4E0B49618CC62" TITLE "ACE All in One" Dependencies { - "58D0FB3206B6F859" "60C4CE4888FF4621" "60E573C9B04CC408" "5DBD560C5148E1DA" "5EB744C5F42E0800" "60C53A9372ED3964" "606C369BAC3F6CC3" "60C4C12DAE90727B" "65860252A17554C7" "6214CEA5DA92BFF3" "60EAEA0389DB3CC2" "611CB1D409001EB0" "61B7763A8AEB53B7" "646D52AF8BB3FF15" "61226BB18D360BDD" "64475DC102F2BDA4" "62F802951CC8A37E" "68EAA4976497C46A" + "58D0FB3206B6F859" "60C4CE4888FF4621" "60E573C9B04CC408" "5DBD560C5148E1DA" "5EB744C5F42E0800" "60C53A9372ED3964" "606C369BAC3F6CC3" "60C4C12DAE90727B" "65860252A17554C7" "6214CEA5DA92BFF3" "60EAEA0389DB3CC2" "611CB1D409001EB0" "61B7763A8AEB53B7" "646D52AF8BB3FF15" "61226BB18D360BDD" "64475DC102F2BDA4" "62F802951CC8A37E" "68EAA4976497C46A" "68FD5E6A9F921F30" "667D049B9D9A0883" } Configurations { GameProjectConfig PC { diff --git a/addons/all_in_one/dev.gproj b/addons/all_in_one/dev.gproj index 8aba89395..19555029b 100644 --- a/addons/all_in_one/dev.gproj +++ b/addons/all_in_one/dev.gproj @@ -3,7 +3,7 @@ GameProject { GUID "65AD7BE594439A52" TITLE "ACE All in One Dev" Dependencies { - "58D0FB3206B6F859" "65AD7D0D9941A380" "65AD7C139EB4C1A1" "65AD7C379CBD394D" "65AD7BCC9F6B3B4E" "65AD7CF69FAF1FDD" "65AD7D2E9866FA6E" "6586079789278413" "65B343F799FB521B" "65AD7D4F994EA327" "65AD7CE59E8DB349" "65AD7D4099944EBD" "65AD7D1E9EEAFA53" "65AD7C249E4ECDFB" "65AD7CB89F219E38" "65AD7C75826B46C6" "65AD7CD09CAEC4E2" "68EAA4B96976D557" + "58D0FB3206B6F859" "65AD7D0D9941A380" "65AD7C139EB4C1A1" "65AD7C379CBD394D" "65AD7BCC9F6B3B4E" "65AD7CF69FAF1FDD" "65AD7D2E9866FA6E" "6586079789278413" "65B343F799FB521B" "65AD7D4F994EA327" "65AD7CE59E8DB349" "65AD7D4099944EBD" "65AD7D1E9EEAFA53" "65AD7C249E4ECDFB" "65AD7CB89F219E38" "65AD7C75826B46C6" "65AD7CD09CAEC4E2" "65B8EA178A3E94E3" "664AFDC993C9CE1A" "667B230F9505C8BA" "68EAA4B96976D557" } Configurations { GameProjectConfig PC { diff --git a/addons/core/Configs/ControlHints/AvailableActions.conf b/addons/core/Configs/ControlHints/AvailableActions.conf index e70c2b7cb..0260f9526 100644 --- a/addons/core/Configs/ControlHints/AvailableActions.conf +++ b/addons/core/Configs/ControlHints/AvailableActions.conf @@ -9,5 +9,18 @@ SCR_AvailableActionsDisplay { m_sAction "ACE_StopCarrying" m_sName "#ACE-UserAction_Release" } + SCR_AvailableActionContext "{6639110D6FBCBCA5}" { + m_aConditions { + SCR_CharacterIsInVehicleCondition "{6639110CC6062CC5}" { + m_bIsTurret 1 + } + SCR_IsCharacterADSCondition "{6639110BA0507D42}" { + m_bNegateCondition 1 + } + } + m_sTag "ACE_INSPECT_TURRET" + m_sAction "CharacterInspect" + m_sName "#ACE-ControlsHint_InspectTurret" + } } } \ No newline at end of file diff --git a/addons/core/Language/ACE_localization.cs_cz.conf b/addons/core/Language/ACE_localization.cs_cz.conf index 2dc44d8b1..9caaedf4c 100755 --- a/addons/core/Language/ACE_localization.cs_cz.conf +++ b/addons/core/Language/ACE_localization.cs_cz.conf @@ -1,11 +1,13 @@ StringTableRuntime { Ids { "ACE-Acronym" + "ACE-ControlsHint_InspectTurret" "ACE-Emotes_Emote_Pushups_Name" "ACE-Emotes_Emote_Salute_Name" "ACE-Emotes_Emote_SitOnFloor_Name" "ACE-Item_Banana_Description" "ACE-Item_Banana_Name" + "ACE-RadialMenu_ChangeMagazine" "ACE-UserAction_Carry" "ACE-UserAction_Carrying" "ACE-UserAction_LoadCarried" @@ -16,11 +18,13 @@ StringTableRuntime { } Texts { "ACE" + "Inspect Turret" "Push-ups" "Salute" "Sit on the floor" "Zdravá dávka draslíku!" "Banán" + "Change mangazine" "Nést" "Nošení" "Load carried:" diff --git a/addons/core/Language/ACE_localization.de_de.conf b/addons/core/Language/ACE_localization.de_de.conf index 08c0c9480..c58927625 100755 --- a/addons/core/Language/ACE_localization.de_de.conf +++ b/addons/core/Language/ACE_localization.de_de.conf @@ -1,11 +1,13 @@ StringTableRuntime { Ids { "ACE-Acronym" + "ACE-ControlsHint_InspectTurret" "ACE-Emotes_Emote_Pushups_Name" "ACE-Emotes_Emote_Salute_Name" "ACE-Emotes_Emote_SitOnFloor_Name" "ACE-Item_Banana_Description" "ACE-Item_Banana_Name" + "ACE-RadialMenu_ChangeMagazine" "ACE-UserAction_Carry" "ACE-UserAction_Carrying" "ACE-UserAction_LoadCarried" @@ -16,11 +18,13 @@ StringTableRuntime { } Texts { "ACE" + "Geschütz untersuchen" "Liegestützen" "Salutieren" "Auf den Boden sitzen" "Gesundes Kalium!" "Banane" + "Magazin wechseln" "Tragen" "Am Tragen" "Getragener laden:" diff --git a/addons/core/Language/ACE_localization.en_us.conf b/addons/core/Language/ACE_localization.en_us.conf index 90d322075..5fda08be5 100755 --- a/addons/core/Language/ACE_localization.en_us.conf +++ b/addons/core/Language/ACE_localization.en_us.conf @@ -1,11 +1,13 @@ StringTableRuntime { Ids { "ACE-Acronym" + "ACE-ControlsHint_InspectTurret" "ACE-Emotes_Emote_Pushups_Name" "ACE-Emotes_Emote_Salute_Name" "ACE-Emotes_Emote_SitOnFloor_Name" "ACE-Item_Banana_Description" "ACE-Item_Banana_Name" + "ACE-RadialMenu_ChangeMagazine" "ACE-UserAction_Carry" "ACE-UserAction_Carrying" "ACE-UserAction_LoadCarried" @@ -16,11 +18,13 @@ StringTableRuntime { } Texts { "ACE" + "Inspect Turret" "Push-ups" "Salute" "Sit on the floor" "Healthy potassium!" "Banana" + "Change mangazine" "Carry" "Carrying" "Load carried:" diff --git a/addons/core/Language/ACE_localization.es_es.conf b/addons/core/Language/ACE_localization.es_es.conf index ca03d5681..c25f278b4 100755 --- a/addons/core/Language/ACE_localization.es_es.conf +++ b/addons/core/Language/ACE_localization.es_es.conf @@ -1,11 +1,13 @@ StringTableRuntime { Ids { "ACE-Acronym" + "ACE-ControlsHint_InspectTurret" "ACE-Emotes_Emote_Pushups_Name" "ACE-Emotes_Emote_Salute_Name" "ACE-Emotes_Emote_SitOnFloor_Name" "ACE-Item_Banana_Description" "ACE-Item_Banana_Name" + "ACE-RadialMenu_ChangeMagazine" "ACE-UserAction_Carry" "ACE-UserAction_Carrying" "ACE-UserAction_LoadCarried" @@ -16,11 +18,13 @@ StringTableRuntime { } Texts { "ACE" + "Inspect Turret" "Lagartijas" "Saludo militar" "Sentarse en el suelo" "¡Potasio saludable!" "Plátano" + "Change mangazine" "Llevar" "Arrastrar" "Cargar paciente:" diff --git a/addons/core/Language/ACE_localization.fr_fr.conf b/addons/core/Language/ACE_localization.fr_fr.conf index f0849141d..bcac17643 100755 --- a/addons/core/Language/ACE_localization.fr_fr.conf +++ b/addons/core/Language/ACE_localization.fr_fr.conf @@ -1,11 +1,13 @@ StringTableRuntime { Ids { "ACE-Acronym" + "ACE-ControlsHint_InspectTurret" "ACE-Emotes_Emote_Pushups_Name" "ACE-Emotes_Emote_Salute_Name" "ACE-Emotes_Emote_SitOnFloor_Name" "ACE-Item_Banana_Description" "ACE-Item_Banana_Name" + "ACE-RadialMenu_ChangeMagazine" "ACE-UserAction_Carry" "ACE-UserAction_Carrying" "ACE-UserAction_LoadCarried" @@ -16,11 +18,13 @@ StringTableRuntime { } Texts { "ACE" + "Inspect Turret" "Faire des pompes" "Salut militaire" "Asseyez-vous par terre" "Potassium bon pour la santé !" "Banane" + "Change mangazine" "Porter" "Porter" "Charge transportée" diff --git a/addons/core/Language/ACE_localization.it_it.conf b/addons/core/Language/ACE_localization.it_it.conf index 76048b834..ab7a9d110 100755 --- a/addons/core/Language/ACE_localization.it_it.conf +++ b/addons/core/Language/ACE_localization.it_it.conf @@ -1,11 +1,13 @@ StringTableRuntime { Ids { "ACE-Acronym" + "ACE-ControlsHint_InspectTurret" "ACE-Emotes_Emote_Pushups_Name" "ACE-Emotes_Emote_Salute_Name" "ACE-Emotes_Emote_SitOnFloor_Name" "ACE-Item_Banana_Description" "ACE-Item_Banana_Name" + "ACE-RadialMenu_ChangeMagazine" "ACE-UserAction_Carry" "ACE-UserAction_Carrying" "ACE-UserAction_LoadCarried" @@ -16,11 +18,13 @@ StringTableRuntime { } Texts { "ACE" + "Inspect Turret" "Flessioni" "Saluto militare" "Sedersi per terra" "Potassio sano!" "Banana" + "Change mangazine" "Trasporta" "Trascina" "Carica trasportato:" diff --git a/addons/core/Language/ACE_localization.ja_jp.conf b/addons/core/Language/ACE_localization.ja_jp.conf index 4c3414db8..e40638756 100755 --- a/addons/core/Language/ACE_localization.ja_jp.conf +++ b/addons/core/Language/ACE_localization.ja_jp.conf @@ -1,11 +1,13 @@ StringTableRuntime { Ids { "ACE-Acronym" + "ACE-ControlsHint_InspectTurret" "ACE-Emotes_Emote_Pushups_Name" "ACE-Emotes_Emote_Salute_Name" "ACE-Emotes_Emote_SitOnFloor_Name" "ACE-Item_Banana_Description" "ACE-Item_Banana_Name" + "ACE-RadialMenu_ChangeMagazine" "ACE-UserAction_Carry" "ACE-UserAction_Carrying" "ACE-UserAction_LoadCarried" @@ -16,11 +18,13 @@ StringTableRuntime { } Texts { "ACE" + "Inspect Turret" "Push-ups" "Salute" "Sit on the floor" "Healthy potassium!" "Banana" + "Change mangazine" "運ぶ" "Carrying" "Load carried:" diff --git a/addons/core/Language/ACE_localization.ko_kr.conf b/addons/core/Language/ACE_localization.ko_kr.conf index e2a1bb76c..f7f81ab09 100755 --- a/addons/core/Language/ACE_localization.ko_kr.conf +++ b/addons/core/Language/ACE_localization.ko_kr.conf @@ -1,11 +1,13 @@ StringTableRuntime { Ids { "ACE-Acronym" + "ACE-ControlsHint_InspectTurret" "ACE-Emotes_Emote_Pushups_Name" "ACE-Emotes_Emote_Salute_Name" "ACE-Emotes_Emote_SitOnFloor_Name" "ACE-Item_Banana_Description" "ACE-Item_Banana_Name" + "ACE-RadialMenu_ChangeMagazine" "ACE-UserAction_Carry" "ACE-UserAction_Carrying" "ACE-UserAction_LoadCarried" @@ -16,11 +18,13 @@ StringTableRuntime { } Texts { "ACE" + "Inspect Turret" "팔굽혀펴기" "경례" "바닥에 앉기" "건강한 칼륨덩어리입니다!" "바나나" + "Change mangazine" "업기" "업는 중" "업힌 사람 싣기:" diff --git a/addons/core/Language/ACE_localization.pl_pl.conf b/addons/core/Language/ACE_localization.pl_pl.conf index f25e5bc26..091573044 100755 --- a/addons/core/Language/ACE_localization.pl_pl.conf +++ b/addons/core/Language/ACE_localization.pl_pl.conf @@ -1,11 +1,13 @@ StringTableRuntime { Ids { "ACE-Acronym" + "ACE-ControlsHint_InspectTurret" "ACE-Emotes_Emote_Pushups_Name" "ACE-Emotes_Emote_Salute_Name" "ACE-Emotes_Emote_SitOnFloor_Name" "ACE-Item_Banana_Description" "ACE-Item_Banana_Name" + "ACE-RadialMenu_ChangeMagazine" "ACE-UserAction_Carry" "ACE-UserAction_Carrying" "ACE-UserAction_LoadCarried" @@ -16,11 +18,13 @@ StringTableRuntime { } Texts { "ACE" + "Inspect Turret" "Push-ups" "Salute" "Sit on the floor" "Healthy potassium!" "Banana" + "Change mangazine" "Nieś" "Carrying" "Load carried:" diff --git a/addons/core/Language/ACE_localization.pt_br.conf b/addons/core/Language/ACE_localization.pt_br.conf index 0efaf0423..7fa27d5ae 100755 --- a/addons/core/Language/ACE_localization.pt_br.conf +++ b/addons/core/Language/ACE_localization.pt_br.conf @@ -1,11 +1,13 @@ StringTableRuntime { Ids { "ACE-Acronym" + "ACE-ControlsHint_InspectTurret" "ACE-Emotes_Emote_Pushups_Name" "ACE-Emotes_Emote_Salute_Name" "ACE-Emotes_Emote_SitOnFloor_Name" "ACE-Item_Banana_Description" "ACE-Item_Banana_Name" + "ACE-RadialMenu_ChangeMagazine" "ACE-UserAction_Carry" "ACE-UserAction_Carrying" "ACE-UserAction_LoadCarried" @@ -16,11 +18,13 @@ StringTableRuntime { } Texts { "ACE" + "Inspect Turret" "Flexões" "Comprimeto militar" "Sentar no chão" "Potássio saudável!" "Banana" + "Change mangazine" "Carregar" "Levar" "Carregar paciente:" diff --git a/addons/core/Language/ACE_localization.ru_ru.conf b/addons/core/Language/ACE_localization.ru_ru.conf index 53e0a6d48..541b86176 100755 --- a/addons/core/Language/ACE_localization.ru_ru.conf +++ b/addons/core/Language/ACE_localization.ru_ru.conf @@ -1,11 +1,13 @@ StringTableRuntime { Ids { "ACE-Acronym" + "ACE-ControlsHint_InspectTurret" "ACE-Emotes_Emote_Pushups_Name" "ACE-Emotes_Emote_Salute_Name" "ACE-Emotes_Emote_SitOnFloor_Name" "ACE-Item_Banana_Description" "ACE-Item_Banana_Name" + "ACE-RadialMenu_ChangeMagazine" "ACE-UserAction_Carry" "ACE-UserAction_Carrying" "ACE-UserAction_LoadCarried" @@ -16,11 +18,13 @@ StringTableRuntime { } Texts { "ACE" + "Inspect Turret" "Push-ups" "Salute" "Sit on the floor" "Здоровый калий!" "Банан" + "Change mangazine" "Перенести" "Перенос" "Load carried:" diff --git a/addons/core/Language/ACE_localization.st b/addons/core/Language/ACE_localization.st index ce8c46e01..203e604b1 100644 --- a/addons/core/Language/ACE_localization.st +++ b/addons/core/Language/ACE_localization.st @@ -20,6 +20,14 @@ StringTable { Author "kexanone" LastChanged "kexanone" } + CustomStringTableItem "{6639110B40CE8693}" { + Id "ACE-ControlsHint_InspectTurret" + Target_en_us "Inspect Turret" + Target_de_de "Geschütz untersuchen" + Modified 1715082397 + Author "Kexanone" + LastChanged "Kexanone" + } CustomStringTableItem "{64771570B1AFAB10}" { Id "ACE-Emotes_Emote_Pushups_Name" Target_en_us "Push-ups" @@ -96,6 +104,14 @@ StringTable { Author "kexanone" LastChanged "Martian" } + CustomStringTableItem "{663A2182DD1E0961}" { + Id "ACE-RadialMenu_ChangeMagazine" + Target_en_us "Change mangazine" + Target_de_de "Magazin wechseln" + Modified 1715088550 + Author "Kexanone" + LastChanged "Kexanone" + } CustomStringTableItem "{5DDEFB51C773DDD9}" { Id "ACE-UserAction_Carry" Target_en_us "Carry" diff --git a/addons/core/Language/ACE_localization.uk_ua.conf b/addons/core/Language/ACE_localization.uk_ua.conf index aebafbce8..91e069ae3 100755 --- a/addons/core/Language/ACE_localization.uk_ua.conf +++ b/addons/core/Language/ACE_localization.uk_ua.conf @@ -1,11 +1,13 @@ StringTableRuntime { Ids { "ACE-Acronym" + "ACE-ControlsHint_InspectTurret" "ACE-Emotes_Emote_Pushups_Name" "ACE-Emotes_Emote_Salute_Name" "ACE-Emotes_Emote_SitOnFloor_Name" "ACE-Item_Banana_Description" "ACE-Item_Banana_Name" + "ACE-RadialMenu_ChangeMagazine" "ACE-UserAction_Carry" "ACE-UserAction_Carrying" "ACE-UserAction_LoadCarried" @@ -16,11 +18,13 @@ StringTableRuntime { } Texts { "ACE" + "Inspect Turret" "Push-ups" "Salute" "Sit on the floor" "Здоровий калій!" "Банан" + "Change mangazine" "Перенести" "Перенесення" "Load carried:" diff --git a/addons/core/Language/ACE_localization.zh_cn.conf b/addons/core/Language/ACE_localization.zh_cn.conf index b3390c589..8028d6b11 100755 --- a/addons/core/Language/ACE_localization.zh_cn.conf +++ b/addons/core/Language/ACE_localization.zh_cn.conf @@ -1,11 +1,13 @@ StringTableRuntime { Ids { "ACE-Acronym" + "ACE-ControlsHint_InspectTurret" "ACE-Emotes_Emote_Pushups_Name" "ACE-Emotes_Emote_Salute_Name" "ACE-Emotes_Emote_SitOnFloor_Name" "ACE-Item_Banana_Description" "ACE-Item_Banana_Name" + "ACE-RadialMenu_ChangeMagazine" "ACE-UserAction_Carry" "ACE-UserAction_Carrying" "ACE-UserAction_LoadCarried" @@ -16,11 +18,13 @@ StringTableRuntime { } Texts { "ACE" + "Inspect Turret" "伏地挺身" "敬禮" "席地而坐" "香蕉含鉀量高,腎功能不良者應諮詢醫生後食用" "香蕉" + "Change mangazine" "背負" "背負中" "將隨行單位移進載具" diff --git a/addons/core/Prefabs/Characters/Core/DefaultPlayerController.et b/addons/core/Prefabs/Characters/Core/DefaultPlayerController.et index 00cb1d0b6..40b2d6cf9 100644 --- a/addons/core/Prefabs/Characters/Core/DefaultPlayerController.et +++ b/addons/core/Prefabs/Characters/Core/DefaultPlayerController.et @@ -2,6 +2,26 @@ SCR_PlayerController { ID "1A9BA6BEFA06E3B1" components { ACE_RadialMenuComponent "{654944904311E33E}" { + m_aRadialMenuControllers { + ACE_TurretInspectionRadialMenuController "{6639115DCE6E270A}" { + m_RMControls SCR_RadialMenuControllerInputs "{6639115DFE9AF907}" { + m_sOpenAction "CharacterInspect" + m_bCloseOnReleaseOpen 0 + m_bPerformOnClose 0 + m_bCloseOnPerform 1 + m_bShowWhileUnconcious 0 + } + m_Data SCR_SelectionMenuData "{66391157A21808AD}" { + m_aEntries { + ACE_SelectTurretMagazineRadialMenuCategoryEntry "{66391150EC4B09C7}" { + Name "#ACE-RadialMenu_ChangeMagazine" + Icon "{3262679C50EF4F01}UI/Textures/Icons/icons_wrapperUI.imageset" + IconSetName "magazine" + } + } + } + } + } } } } \ No newline at end of file diff --git a/addons/core/Prefabs/Vehicles/Helicopters/Mi8MT/VehParts/WeapSystems/Mi8MT_PKMT_mount_front.et b/addons/core/Prefabs/Vehicles/Helicopters/Mi8MT/VehParts/WeapSystems/Mi8MT_PKMT_mount_front.et new file mode 100644 index 000000000..f8ec0686e --- /dev/null +++ b/addons/core/Prefabs/Vehicles/Helicopters/Mi8MT/VehParts/WeapSystems/Mi8MT_PKMT_mount_front.et @@ -0,0 +1,7 @@ +Turret : "{419D5A88C92E2540}Prefabs/Vehicles/Helicopters/Mi8MT/VehParts/WeapSystems/Mi8MT_PKMT_mount_base.et" { + ID "51ACD0965653D003" + components { + SCR_TurretControllerComponent "{51ACD09C61C183E4}" { + } + } +} \ No newline at end of file diff --git a/addons/core/Prefabs/Vehicles/Helicopters/Mi8MT/VehParts/WeapSystems/Mi8MT_PKMT_mount_front.et.meta b/addons/core/Prefabs/Vehicles/Helicopters/Mi8MT/VehParts/WeapSystems/Mi8MT_PKMT_mount_front.et.meta new file mode 100644 index 000000000..e0e63a6d4 --- /dev/null +++ b/addons/core/Prefabs/Vehicles/Helicopters/Mi8MT/VehParts/WeapSystems/Mi8MT_PKMT_mount_front.et.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{0147F3C32DF990FF}Prefabs/Vehicles/Helicopters/Mi8MT/VehParts/WeapSystems/Mi8MT_PKMT_mount_front.et" + Configurations { + EntityTemplateResourceClass PC { + } + EntityTemplateResourceClass XBOX_ONE : PC { + } + EntityTemplateResourceClass XBOX_SERIES : PC { + } + EntityTemplateResourceClass PS4 : PC { + } + EntityTemplateResourceClass PS5 : PC { + } + EntityTemplateResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/core/Prefabs/Vehicles/Helicopters/Mi8MT/VehParts/WeapSystems/Mi8MT_PKMT_mount_rear.et b/addons/core/Prefabs/Vehicles/Helicopters/Mi8MT/VehParts/WeapSystems/Mi8MT_PKMT_mount_rear.et new file mode 100644 index 000000000..f8ec0686e --- /dev/null +++ b/addons/core/Prefabs/Vehicles/Helicopters/Mi8MT/VehParts/WeapSystems/Mi8MT_PKMT_mount_rear.et @@ -0,0 +1,7 @@ +Turret : "{419D5A88C92E2540}Prefabs/Vehicles/Helicopters/Mi8MT/VehParts/WeapSystems/Mi8MT_PKMT_mount_base.et" { + ID "51ACD0965653D003" + components { + SCR_TurretControllerComponent "{51ACD09C61C183E4}" { + } + } +} \ No newline at end of file diff --git a/addons/core/Prefabs/Vehicles/Helicopters/Mi8MT/VehParts/WeapSystems/Mi8MT_PKMT_mount_rear.et.meta b/addons/core/Prefabs/Vehicles/Helicopters/Mi8MT/VehParts/WeapSystems/Mi8MT_PKMT_mount_rear.et.meta new file mode 100644 index 000000000..a9dd567ba --- /dev/null +++ b/addons/core/Prefabs/Vehicles/Helicopters/Mi8MT/VehParts/WeapSystems/Mi8MT_PKMT_mount_rear.et.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{F75F5379C0F568C4}Prefabs/Vehicles/Helicopters/Mi8MT/VehParts/WeapSystems/Mi8MT_PKMT_mount_rear.et" + Configurations { + EntityTemplateResourceClass PC { + } + EntityTemplateResourceClass XBOX_ONE : PC { + } + EntityTemplateResourceClass XBOX_SERIES : PC { + } + EntityTemplateResourceClass PS4 : PC { + } + EntityTemplateResourceClass PS5 : PC { + } + EntityTemplateResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/core/Prefabs/Vehicles/Helicopters/UH1H/VehParts/WeapSystems/UH1H_M60D_gunner_left.et b/addons/core/Prefabs/Vehicles/Helicopters/UH1H/VehParts/WeapSystems/UH1H_M60D_gunner_left.et new file mode 100644 index 000000000..f2b1cb14a --- /dev/null +++ b/addons/core/Prefabs/Vehicles/Helicopters/UH1H/VehParts/WeapSystems/UH1H_M60D_gunner_left.et @@ -0,0 +1,7 @@ +Turret : "{398D01C541761153}Prefabs/Vehicles/Helicopters/UH1H/VehParts/WeapSystems/UH1H_M60D_gunner_base.et" { + ID "51ACD0965653D003" + components { + SCR_TurretControllerComponent "{51ACD09C61C183E4}" { + } + } +} \ No newline at end of file diff --git a/addons/core/Prefabs/Vehicles/Helicopters/UH1H/VehParts/WeapSystems/UH1H_M60D_gunner_left.et.meta b/addons/core/Prefabs/Vehicles/Helicopters/UH1H/VehParts/WeapSystems/UH1H_M60D_gunner_left.et.meta new file mode 100644 index 000000000..86c105426 --- /dev/null +++ b/addons/core/Prefabs/Vehicles/Helicopters/UH1H/VehParts/WeapSystems/UH1H_M60D_gunner_left.et.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{273A9AE09880628E}Prefabs/Vehicles/Helicopters/UH1H/VehParts/WeapSystems/UH1H_M60D_gunner_left.et" + Configurations { + EntityTemplateResourceClass PC { + } + EntityTemplateResourceClass XBOX_ONE : PC { + } + EntityTemplateResourceClass XBOX_SERIES : PC { + } + EntityTemplateResourceClass PS4 : PC { + } + EntityTemplateResourceClass PS5 : PC { + } + EntityTemplateResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/core/Prefabs/Vehicles/Helicopters/UH1H/VehParts/WeapSystems/UH1H_M60D_gunner_right.et b/addons/core/Prefabs/Vehicles/Helicopters/UH1H/VehParts/WeapSystems/UH1H_M60D_gunner_right.et new file mode 100644 index 000000000..f2b1cb14a --- /dev/null +++ b/addons/core/Prefabs/Vehicles/Helicopters/UH1H/VehParts/WeapSystems/UH1H_M60D_gunner_right.et @@ -0,0 +1,7 @@ +Turret : "{398D01C541761153}Prefabs/Vehicles/Helicopters/UH1H/VehParts/WeapSystems/UH1H_M60D_gunner_base.et" { + ID "51ACD0965653D003" + components { + SCR_TurretControllerComponent "{51ACD09C61C183E4}" { + } + } +} \ No newline at end of file diff --git a/addons/core/Prefabs/Vehicles/Helicopters/UH1H/VehParts/WeapSystems/UH1H_M60D_gunner_right.et.meta b/addons/core/Prefabs/Vehicles/Helicopters/UH1H/VehParts/WeapSystems/UH1H_M60D_gunner_right.et.meta new file mode 100644 index 000000000..3d1ac11e4 --- /dev/null +++ b/addons/core/Prefabs/Vehicles/Helicopters/UH1H/VehParts/WeapSystems/UH1H_M60D_gunner_right.et.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{7F99E6708A781708}Prefabs/Vehicles/Helicopters/UH1H/VehParts/WeapSystems/UH1H_M60D_gunner_right.et" + Configurations { + EntityTemplateResourceClass PC { + } + EntityTemplateResourceClass XBOX_ONE : PC { + } + EntityTemplateResourceClass XBOX_SERIES : PC { + } + EntityTemplateResourceClass PS4 : PC { + } + EntityTemplateResourceClass PS5 : PC { + } + EntityTemplateResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/core/Prefabs/Vehicles/Wheeled/BTR70/VehParts/Turret/BTR70_Turret.et b/addons/core/Prefabs/Vehicles/Wheeled/BTR70/VehParts/Turret/BTR70_Turret.et new file mode 100644 index 000000000..64a03b971 --- /dev/null +++ b/addons/core/Prefabs/Vehicles/Wheeled/BTR70/VehParts/Turret/BTR70_Turret.et @@ -0,0 +1,7 @@ +Turret : "{4AD877DEA242E512}Prefabs/Weapons/Core/Turret_Base.et" { + ID "51ACD0965653D003" + components { + SCR_TurretControllerComponent "{51ACD09C61C183E4}" { + } + } +} \ No newline at end of file diff --git a/addons/core/Prefabs/Vehicles/Wheeled/BTR70/VehParts/Turret/BTR70_Turret.et.meta b/addons/core/Prefabs/Vehicles/Wheeled/BTR70/VehParts/Turret/BTR70_Turret.et.meta new file mode 100644 index 000000000..6be4567ea --- /dev/null +++ b/addons/core/Prefabs/Vehicles/Wheeled/BTR70/VehParts/Turret/BTR70_Turret.et.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{66596659FB0F645B}Prefabs/Vehicles/Wheeled/BTR70/VehParts/Turret/BTR70_Turret.et" + Configurations { + EntityTemplateResourceClass PC { + } + EntityTemplateResourceClass XBOX_ONE : PC { + } + EntityTemplateResourceClass XBOX_SERIES : PC { + } + EntityTemplateResourceClass PS4 : PC { + } + EntityTemplateResourceClass PS5 : PC { + } + EntityTemplateResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/core/Prefabs/Vehicles/Wheeled/LAV25/VehParts/Turret/LAV25_turret_base.et b/addons/core/Prefabs/Vehicles/Wheeled/LAV25/VehParts/Turret/LAV25_turret_base.et new file mode 100644 index 000000000..64a03b971 --- /dev/null +++ b/addons/core/Prefabs/Vehicles/Wheeled/LAV25/VehParts/Turret/LAV25_turret_base.et @@ -0,0 +1,7 @@ +Turret : "{4AD877DEA242E512}Prefabs/Weapons/Core/Turret_Base.et" { + ID "51ACD0965653D003" + components { + SCR_TurretControllerComponent "{51ACD09C61C183E4}" { + } + } +} \ No newline at end of file diff --git a/addons/core/Prefabs/Vehicles/Wheeled/LAV25/VehParts/Turret/LAV25_turret_base.et.meta b/addons/core/Prefabs/Vehicles/Wheeled/LAV25/VehParts/Turret/LAV25_turret_base.et.meta new file mode 100644 index 000000000..585a68cdc --- /dev/null +++ b/addons/core/Prefabs/Vehicles/Wheeled/LAV25/VehParts/Turret/LAV25_turret_base.et.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{DF5979FDE2682F70}Prefabs/Vehicles/Wheeled/LAV25/VehParts/Turret/LAV25_turret_base.et" + Configurations { + EntityTemplateResourceClass PC { + } + EntityTemplateResourceClass XBOX_ONE : PC { + } + EntityTemplateResourceClass XBOX_SERIES : PC { + } + EntityTemplateResourceClass PS4 : PC { + } + EntityTemplateResourceClass PS5 : PC { + } + EntityTemplateResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/core/Prefabs/Vehicles/Wheeled/M998/VehParts/M1025_gun_mount.et b/addons/core/Prefabs/Vehicles/Wheeled/M998/VehParts/M1025_gun_mount.et new file mode 100644 index 000000000..64a03b971 --- /dev/null +++ b/addons/core/Prefabs/Vehicles/Wheeled/M998/VehParts/M1025_gun_mount.et @@ -0,0 +1,7 @@ +Turret : "{4AD877DEA242E512}Prefabs/Weapons/Core/Turret_Base.et" { + ID "51ACD0965653D003" + components { + SCR_TurretControllerComponent "{51ACD09C61C183E4}" { + } + } +} \ No newline at end of file diff --git a/addons/core/Prefabs/Vehicles/Wheeled/M998/VehParts/M1025_gun_mount.et.meta b/addons/core/Prefabs/Vehicles/Wheeled/M998/VehParts/M1025_gun_mount.et.meta new file mode 100644 index 000000000..1ed224900 --- /dev/null +++ b/addons/core/Prefabs/Vehicles/Wheeled/M998/VehParts/M1025_gun_mount.et.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{8C68C54F9C50A9AF}Prefabs/Vehicles/Wheeled/M998/VehParts/M1025_gun_mount.et" + Configurations { + EntityTemplateResourceClass PC { + } + EntityTemplateResourceClass XBOX_ONE : PC { + } + EntityTemplateResourceClass XBOX_SERIES : PC { + } + EntityTemplateResourceClass PS4 : PC { + } + EntityTemplateResourceClass PS5 : PC { + } + EntityTemplateResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/core/scripts/Game/ACE_Core/Character/SCR_CharacterCommandHandlerComponent.c b/addons/core/scripts/Game/ACE_Core/Character/SCR_CharacterCommandHandlerComponent.c new file mode 100644 index 000000000..5786a08dd --- /dev/null +++ b/addons/core/scripts/Game/ACE_Core/Character/SCR_CharacterCommandHandlerComponent.c @@ -0,0 +1,52 @@ +//------------------------------------------------------------------------------------------------ +//! Add flag for enabling/disable HandleWeaponFire +modded class SCR_CharacterCommandHandlerComponent : CharacterCommandHandlerComponent +{ + protected bool m_bACE_CanHandleWeaponFire = true; + protected bool m_bACE_ForceWeaponFire = false; + + //------------------------------------------------------------------------------------------------ + override bool HandleWeaponFire(CharacterInputContext pInputCtx, float pDt, int pCurrentCommandID) + { + super.HandleWeaponFire(pInputCtx, pDt, pCurrentCommandID); + + if (!m_bACE_CanHandleWeaponFire) + return false; + + if (m_bACE_ForceWeaponFire) + { + if (pInputCtx.WeaponIsRaised()) + pInputCtx.SetWeaponPullTrigger(true); + + m_bACE_ForceWeaponFire = false; + } + + return HandleWeaponFireDefault(pInputCtx, pDt, pCurrentCommandID); + } + + //------------------------------------------------------------------------------------------------ + void ACE_SetCanHandleWeaponFire(bool canHandle) + { + Rpc(RplDo_ACE_SetCanHandleWeaponFireOwner, canHandle); + } + + //------------------------------------------------------------------------------------------------ + [RplRpc(RplChannel.Reliable, RplRcver.Owner)] + protected void RplDo_ACE_SetCanHandleWeaponFireOwner(bool canHandle) + { + m_bACE_CanHandleWeaponFire = canHandle; + } + + //------------------------------------------------------------------------------------------------ + void ACE_ForceWeaponFire() + { + Rpc(RplDo_ACE_ForceWeaponFireOwner); + } + + //------------------------------------------------------------------------------------------------ + [RplRpc(RplChannel.Reliable, RplRcver.Owner)] + protected void RplDo_ACE_ForceWeaponFireOwner() + { + m_bACE_ForceWeaponFire = true; + } +} diff --git a/addons/core/scripts/Game/ACE_Core/Character/SCR_CharacterControllerComponent.c b/addons/core/scripts/Game/ACE_Core/Character/SCR_CharacterControllerComponent.c index d28735ca1..112f08c3e 100644 --- a/addons/core/scripts/Game/ACE_Core/Character/SCR_CharacterControllerComponent.c +++ b/addons/core/scripts/Game/ACE_Core/Character/SCR_CharacterControllerComponent.c @@ -115,4 +115,20 @@ modded class SCR_CharacterControllerComponent : CharacterControllerComponent return false; } + + //------------------------------------------------------------------------------------------------ + void ACE_PlaySoundEvent(ACE_ECharacterSoundEvent id) + { + Rpc(RpcDo_ACE_PlaySoundEventBroadcast, id); + + if (!System.IsConsoleApp()) + RpcDo_ACE_PlaySoundEventBroadcast(id); + } + + //------------------------------------------------------------------------------------------------ + [RplRpc(RplChannel.Reliable, RplRcver.Broadcast)] + protected void RpcDo_ACE_PlaySoundEventBroadcast(ACE_ECharacterSoundEvent id) + { + m_CharacterSoundComponent.SoundEvent(typename.EnumToString(ACE_ECharacterSoundEvent, id)); + } } diff --git a/addons/core/scripts/Game/ACE_Core/Components/SCR_TurretControllerComponent.c b/addons/core/scripts/Game/ACE_Core/Components/SCR_TurretControllerComponent.c new file mode 100644 index 000000000..2f95f83bb --- /dev/null +++ b/addons/core/scripts/Game/ACE_Core/Components/SCR_TurretControllerComponent.c @@ -0,0 +1,91 @@ +//------------------------------------------------------------------------------------------------ +modded class SCR_TurretControllerComponent : TurretControllerComponent +{ + protected bool m_bACE_InitDone = false; + protected IEntity m_pACE_NextMagazine = null; + + protected static const int ATTEMPT_TIMEOUT = 100; + protected static const int MAX_ATTEMPTS = 10; + + //------------------------------------------------------------------------------------------------ + void ACE_ReloadWeaponWith(notnull IEntity magazine) + { + RplComponent magazineRpl = RplComponent.Cast(magazine.FindComponent(RplComponent)); + if (!magazineRpl) + return; + + Rpc(RpcDo_ACE_ReloadWeaponWithOwner, magazineRpl.Id()); + } + + //------------------------------------------------------------------------------------------------ + [RplRpc(RplChannel.Reliable, RplRcver.Owner)] + protected void RpcDo_ACE_ReloadWeaponWithOwner(RplId magazineID) + { + if (!m_bACE_InitDone) + ACE_Init(); + + RplComponent magazineRpl = RplComponent.Cast(Replication.FindItem(magazineID)); + if (!magazineRpl) + return; + + m_pACE_NextMagazine = magazineRpl.GetEntity(); + // Has to be put on callqueue, as instant execution would fail + GetGame().GetCallqueue().Call(GetGame().GetInputManager().SetActionValue, "TurretReload", 1); + } + + //------------------------------------------------------------------------------------------------ + protected void ACE_Init() + { + EventHandlerManagerComponent eventHandler = EventHandlerManagerComponent.Cast(GetOwner().FindComponent(EventHandlerManagerComponent)); + if (!eventHandler) + return; + + eventHandler.RegisterScriptHandler("OnTurretReload", this, ACE_OnWeaponReload); + m_bACE_InitDone = true; + } + + //------------------------------------------------------------------------------------------------ + protected void ACE_OnWeaponReload(BaseWeaponComponent weapon, bool finished, TurretControllerComponent turretController) + { + if (!finished || !m_pACE_NextMagazine) + return; + + RplComponent magazineRpl = RplComponent.Cast(m_pACE_NextMagazine.FindComponent(RplComponent)); + if (!magazineRpl) + return; + + Rpc(RpcDo_ACE_ForceReloadWeaponWithServer, magazineRpl.Id(), 0); + m_pACE_NextMagazine = null; + } + + //------------------------------------------------------------------------------------------------ + //! Instantly reloads weapon with the given magazine + [RplRpc(RplChannel.Reliable, RplRcver.Server)] + protected void RpcDo_ACE_ForceReloadWeaponWithServer(RplId magazineID, int iAttempt) + { + // Check if occupied, as DoReloadWeaponWith crashes otherwise + BaseCompartmentSlot compartment = GetCompartmentSlot(); + if (!compartment || !compartment.IsOccupied()) + return; + + RplComponent magazineRpl = RplComponent.Cast(Replication.FindItem(magazineID)); + if (!magazineRpl) + return; + + IEntity magazine = magazineRpl.GetEntity(); + if (!magazine) + return; + + if (DoReloadWeaponWith(magazine)) + return; + + if (++iAttempt >= MAX_ATTEMPTS) + { + Debug.Error("Maximum number of attempts exceeded!"); + return; + } + + // Reschedule getting out if it failed, for instance, when called while still reloading + GetGame().GetCallqueue().CallLater(RpcDo_ACE_ForceReloadWeaponWithServer, ATTEMPT_TIMEOUT, false, magazineID, iAttempt); + } +} diff --git a/addons/core/scripts/Game/ACE_Core/Global/ACE_AutoRegModel.c b/addons/core/scripts/Game/ACE_Core/Global/ACE_AutoRegModel.c new file mode 100644 index 000000000..c0d874966 --- /dev/null +++ b/addons/core/scripts/Game/ACE_Core/Global/ACE_AutoRegModel.c @@ -0,0 +1,27 @@ +//------------------------------------------------------------------------------------------------ +//! Auto regressive model of order 1 +//! Useful for generating auto-correlated noise +class ACE_AutoRegModel : Managed +{ + protected float m_fRho; + protected float m_fSigmaEps; + protected float m_fPoint; + + //------------------------------------------------------------------------------------------------ + //! \param[in] rho Auto regression coefficient + //! \param[in] sigma Standard deviation of the noise + void ACE_AutoRegModel(float rho, float sigma) + { + m_fRho = rho; + m_fSigmaEps = sigma * Math.Sqrt(1.0 - Math.Pow(m_fRho, 2)); + m_fPoint = Math.RandomGaussFloat(sigma, 0.0); + } + + //------------------------------------------------------------------------------------------------ + //! \return next point in series + float SamplePoint() + { + m_fPoint = m_fRho * m_fPoint + Math.RandomGaussFloat(m_fSigmaEps, 0.0); + return m_fPoint; + } +} \ No newline at end of file diff --git a/addons/core/scripts/Game/ACE_Core/Global/ACE_BaseContainerTools.c b/addons/core/scripts/Game/ACE_Core/Global/ACE_BaseContainerTools.c new file mode 100644 index 000000000..f6f0498fe --- /dev/null +++ b/addons/core/scripts/Game/ACE_Core/Global/ACE_BaseContainerTools.c @@ -0,0 +1,37 @@ +//------------------------------------------------------------------------------------------------ +class ACE_BaseContainerTools +{ + //------------------------------------------------------------------------------------------------ + //! Same as ACE_BaseContainerTools::FindComponentSource, but also works for searching + //! child components of a IEntityComponentSource + static IEntityComponentSource FindComponentSource(BaseContainer container, typename componentClass) + { + if (!container) + return null; + + BaseContainerList list = container.GetObjectArray("components"); + + for (int i = 0; i < list.Count(); ++i) + { + BaseContainer component = list.Get(i); + if (component.GetClassName().ToType().IsInherited(componentClass)) + return component; + } + + return null; + } + + //------------------------------------------------------------------------------------------------ + static SCR_EditableEntityUIInfo GetEditableEntityUIInfo(BaseContainer container) + { + IEntitySource entitySource = container.ToEntitySource(); + if (!entitySource) + return null; + + IEntityComponentSource editableEntitySource = SCR_EditableEntityComponentClass.GetEditableEntitySource(entitySource); + if (!editableEntitySource) + return null; + + return SCR_EditableEntityComponentClass.GetInfo(editableEntitySource); + } +} diff --git a/addons/core/scripts/Game/ACE_Core/Global/ACE_BulletTools.c b/addons/core/scripts/Game/ACE_Core/Global/ACE_BulletTools.c new file mode 100644 index 000000000..9db116398 --- /dev/null +++ b/addons/core/scripts/Game/ACE_Core/Global/ACE_BulletTools.c @@ -0,0 +1,90 @@ +//------------------------------------------------------------------------------------------------ +class ACE_BulletTools +{ + //------------------------------------------------------------------------------------------------ + //! Return default bullet resource names of a muzzle + static array GetDefaultResourceNamesFromMuzzle(BaseMuzzleComponent muzzle) + { + ResourceName magazineOrProjectilePrefabName = muzzle.GetDefaultMagazineOrProjectileName(); + if (magazineOrProjectilePrefabName.IsEmpty()) + { + BaseMagazineComponent magazine = muzzle.GetMagazine(); + if (!magazine) + return {}; + + magazineOrProjectilePrefabName = magazine.GetOwner().GetPrefabData().GetPrefabName(); + } + + array bulletPrefabNames = GetResourceNamesFromMagazine(magazineOrProjectilePrefabName); + if (bulletPrefabNames) + return bulletPrefabNames; + + return {magazineOrProjectilePrefabName}; + } + + //------------------------------------------------------------------------------------------------ + //! Return all bullet resource names of a magazine + static array GetResourceNamesFromMagazine(ResourceName magazinePrefabName) + { + Resource magazineRes = Resource.Load(magazinePrefabName); + if (!magazineRes.IsValid()) + return null; + + BaseContainer mazagineSource = magazineRes.GetResource().ToBaseContainer(); + if (!mazagineSource) + return null; + + IEntityComponentSource magazineComponentSource = ACE_BaseContainerTools.FindComponentSource(mazagineSource, BaseMagazineComponent); + if (!magazineComponentSource) + return null; + + ResourceName ammoConfigName; + magazineComponentSource.Get("AmmoConfig", ammoConfigName); + + Resource ammoConfigRes = Resource.Load(ammoConfigName); + if (!ammoConfigRes.IsValid()) + return null; + + BaseContainer ammonConfigSrc = ammoConfigRes.GetResource().ToBaseContainer(); + if (!ammonConfigSrc) + return null; + + array ammoNames = {}; + ammonConfigSrc.Get("AmmoResourceArray", ammoNames); + return ammoNames; + } + + //------------------------------------------------------------------------------------------------ + //! Return mass of bullet + static float GetMass(ResourceName bulletPrefabName) + { + return GetFloatProperty(bulletPrefabName, "Mass"); + } + + //------------------------------------------------------------------------------------------------ + //! Return initial speed of bullet + static float GetInitialSpeed(ResourceName bulletPrefabName) + { + return GetFloatProperty(bulletPrefabName, "InitSpeed"); + } + + //------------------------------------------------------------------------------------------------ + protected static float GetFloatProperty(ResourceName bulletPrefabName, string propertyName) + { + Resource bulletRes = Resource.Load(bulletPrefabName); + if (!bulletRes.IsValid()) + return 0; + + IEntitySource bulletSource = bulletRes.GetResource().ToEntitySource(); + if (!bulletSource) + return 0; + + IEntityComponentSource shellMovementSource = ACE_BaseContainerTools.FindComponentSource(bulletSource, ShellMoveComponent); + if (!shellMovementSource) + return 0; + + float value; + shellMovementSource.Get(propertyName, value); + return value; + } +} diff --git a/addons/core/scripts/Game/ACE_Core/Global/ACE_PhysicalConstants.c b/addons/core/scripts/Game/ACE_Core/Global/ACE_PhysicalConstants.c index 44df9d31e..4e844a85a 100644 --- a/addons/core/scripts/Game/ACE_Core/Global/ACE_PhysicalConstants.c +++ b/addons/core/scripts/Game/ACE_Core/Global/ACE_PhysicalConstants.c @@ -3,7 +3,11 @@ class ACE_PhysicalConstants { // Constants static const float R = 8.3144626; // Universal gas constant [J / (K * mol)] + static const float STANDARD_AMBIENT_TEMPERATURE = 298.15; // [K] + static const float STEFAN_BOLTZMANN = 5.6703744e-8; // [W / (m^2 * K^4)] // Conversions static const float KPA2MMHG = 7.5006168; // kPa to mmHg + static const float ZERO_CELSIUS = 273.15; // 0 °C in K + static const float MPS2KNOTS = 1.94384449; // m/s to knots } diff --git a/addons/core/scripts/Game/ACE_Core/Global/ACE_WeatherHelper.c b/addons/core/scripts/Game/ACE_Core/Global/ACE_WeatherHelper.c new file mode 100644 index 000000000..2036e1b31 --- /dev/null +++ b/addons/core/scripts/Game/ACE_Core/Global/ACE_WeatherHelper.c @@ -0,0 +1,18 @@ +//------------------------------------------------------------------------------------------------ +class ACE_WeatherHelper +{ + //------------------------------------------------------------------------------------------------ + static float GetAirTemperatureForEntity(IEntity entity) + { + ChimeraWorld world = GetGame().GetWorld(); + if (!world) + return ACE_PhysicalConstants.STANDARD_AMBIENT_TEMPERATURE; + + TimeAndWeatherManagerEntity weatherManager = world.GetTimeAndWeatherManager(); + if (!weatherManager) + return ACE_PhysicalConstants.STANDARD_AMBIENT_TEMPERATURE; + + float altitude = entity.GetOrigin()[1]; + return weatherManager.ACE_GetAirTemperature(altitude); + } +} diff --git a/addons/core/scripts/Game/ACE_Core/RadialMenus/TurretInspection/ACE_SelectTurretMagazineRadialMenuCategoryEntry.c b/addons/core/scripts/Game/ACE_Core/RadialMenus/TurretInspection/ACE_SelectTurretMagazineRadialMenuCategoryEntry.c new file mode 100644 index 000000000..cfe7d1b6b --- /dev/null +++ b/addons/core/scripts/Game/ACE_Core/RadialMenus/TurretInspection/ACE_SelectTurretMagazineRadialMenuCategoryEntry.c @@ -0,0 +1,65 @@ +//------------------------------------------------------------------------------------------------ +[BaseContainerProps(configRoot: true), SCR_BaseContainerCustomTitleUIInfo("Name")] +class ACE_SelectTurretMagazineRadialMenuCategoryEntry : ACE_SelectionMenuCategoryEntry +{ + //------------------------------------------------------------------------------------------------ + override protected void OnPerform() + { + m_aEntries.Clear(); + + SCR_ChimeraCharacter char = SCR_ChimeraCharacter.Cast(SCR_PlayerController.GetLocalControlledEntity()); + if (!char) + return; + + SCR_CompartmentAccessComponent compartmentAccess = SCR_CompartmentAccessComponent.Cast(char.GetCompartmentAccessComponent()); + if (!compartmentAccess) + return; + + TurretCompartmentSlot turretCompartment = TurretCompartmentSlot.Cast(compartmentAccess.GetCompartment()); + if (!turretCompartment) + return; + + BaseWeaponManagerComponent weaponManager = BaseWeaponManagerComponent.Cast(turretCompartment.GetOwner().FindComponent(BaseWeaponManagerComponent)); + if (!weaponManager) + return; + + BaseWeaponComponent weapon = weaponManager.GetCurrentWeapon(); + if (!weapon) + return; + + BaseMuzzleComponent muzzle = weapon.GetCurrentMuzzle(); + if (!muzzle) + return; + + IEntity vehicle = turretCompartment.GetVehicle(); + if (!vehicle) + return; + + InventoryStorageManagerComponent storageManager = InventoryStorageManagerComponent.Cast(vehicle.FindComponent(InventoryStorageManagerComponent)); + if (!storageManager) + return; + + SCR_MagazinePredicate searchPredicate = new SCR_MagazinePredicate(); + searchPredicate.magWellType = muzzle.GetMagazineWell().Type(); + + array items = {}; + storageManager.FindItems(items, searchPredicate); + SCR_Sorting.HeapSort(items, false); + + // Make sure we only add each + set uniquePrefabDataSet = new set(); + + foreach (IEntity item : items) + { + EntityPrefabData prefabData = item.GetPrefabData(); + if (!prefabData) + continue; + + if (uniquePrefabDataSet.Find(prefabData) >= 0) + continue; + + m_aEntries.Insert(new ACE_SelectTurretMagazineRadialMenuEntry(item)); + uniquePrefabDataSet.Insert(prefabData); + } + } +} diff --git a/addons/core/scripts/Game/ACE_Core/RadialMenus/TurretInspection/ACE_SelectTurretMagazineRadialMenuEntry.c b/addons/core/scripts/Game/ACE_Core/RadialMenus/TurretInspection/ACE_SelectTurretMagazineRadialMenuEntry.c new file mode 100644 index 000000000..1803c4f1f --- /dev/null +++ b/addons/core/scripts/Game/ACE_Core/RadialMenus/TurretInspection/ACE_SelectTurretMagazineRadialMenuEntry.c @@ -0,0 +1,27 @@ +//------------------------------------------------------------------------------------------------ +//! Creates radial menu entry for the item passed to constructor +[BaseContainerProps(configRoot: true), SCR_BaseContainerCustomTitleUIInfo("Name")] +class ACE_SelectTurretMagazineRadialMenuEntry : ACE_SelectItemRadialMenuEntry +{ + //------------------------------------------------------------------------------------------------ + override protected void OnPerform() + { + SCR_ChimeraCharacter char = SCR_ChimeraCharacter.Cast(SCR_PlayerController.GetLocalControlledEntity()); + if (!char) + return; + + SCR_CompartmentAccessComponent compartmentAccess = SCR_CompartmentAccessComponent.Cast(char.GetCompartmentAccessComponent()); + if (!compartmentAccess) + return; + + TurretCompartmentSlot turretCompartment = TurretCompartmentSlot.Cast(compartmentAccess.GetCompartment()); + if (!turretCompartment) + return; + + SCR_TurretControllerComponent turretController = SCR_TurretControllerComponent.Cast(turretCompartment.GetOwner().FindComponent(SCR_TurretControllerComponent)); + if (!turretController) + return; + + turretController.ACE_ReloadWeaponWith(m_pItem); + } +} diff --git a/addons/core/scripts/Game/ACE_Core/RadialMenus/TurretInspection/ACE_TurretInspectionRadialMenuController.c b/addons/core/scripts/Game/ACE_Core/RadialMenus/TurretInspection/ACE_TurretInspectionRadialMenuController.c new file mode 100644 index 000000000..ec8421983 --- /dev/null +++ b/addons/core/scripts/Game/ACE_Core/RadialMenus/TurretInspection/ACE_TurretInspectionRadialMenuController.c @@ -0,0 +1,18 @@ +//------------------------------------------------------------------------------------------------ +[BaseContainerProps(configRoot: true)] +class ACE_TurretInspectionRadialMenuController : ACE_RadialMenuController +{ + //------------------------------------------------------------------------------------------------ + override void OnInputOpen() + { + ChimeraCharacter char = ChimeraCharacter.Cast(SCR_PlayerController.GetLocalControlledEntity()); + if (!char) + return; + + CompartmentAccessComponent compartmentAccess = char.GetCompartmentAccessComponent(); + if (!compartmentAccess || !TurretCompartmentSlot.Cast(compartmentAccess.GetCompartment())) + return; + + super.OnInputOpen(); + } +} diff --git a/addons/core/scripts/Game/ACE_Core/Sounds/ACE_ECharacterSoundEvent.c b/addons/core/scripts/Game/ACE_Core/Sounds/ACE_ECharacterSoundEvent.c new file mode 100644 index 000000000..7284bab59 --- /dev/null +++ b/addons/core/scripts/Game/ACE_Core/Sounds/ACE_ECharacterSoundEvent.c @@ -0,0 +1,4 @@ +//------------------------------------------------------------------------------------------------ +enum ACE_ECharacterSoundEvent +{ +} diff --git a/addons/core/scripts/GameCode/ACE_Core/World/TimeAndWeatherManagerEntity.c b/addons/core/scripts/GameCode/ACE_Core/World/TimeAndWeatherManagerEntity.c new file mode 100644 index 000000000..d320418e8 --- /dev/null +++ b/addons/core/scripts/GameCode/ACE_Core/World/TimeAndWeatherManagerEntity.c @@ -0,0 +1,130 @@ +//------------------------------------------------------------------------------------------------ +modded class TimeAndWeatherManagerEntity : BaseTimeAndWeatherManagerEntity +{ + protected ResourceName m_sACE_WeatherStatesConfigName; + protected float m_fACE_UpdateFrequency; // One update per x seconds + protected float m_fACE_UpdateTimer; // [s] + + [RplProp()] + protected float m_fACE_CurrentAirTemperature = ACE_PhysicalConstants.STANDARD_AMBIENT_TEMPERATURE; // Default value to prevent instant freezing + + static const float ACE_AVERAGE_DAYS_PER_YEAR = 365.2425; // in days + static const float ACE_AVERAGE_DAYS_PER_MONTH = ACE_AVERAGE_DAYS_PER_YEAR / 12; // in days + static const float ACE_TEMPERATURE_LAPSE_RATE = -0.0065; // [K/m] + + //------------------------------------------------------------------------------------------------ + protected void TimeAndWeatherManagerEntity(IEntitySource src, IEntity parent) + { + src.Get("Update Frequency", m_fACE_UpdateFrequency); + src.Get("WeatherStateMachine", m_sACE_WeatherStatesConfigName); + } + + //------------------------------------------------------------------------------------------------ + override void EOnFrame(IEntity owner, float timeSlice) + { + super.EOnFrame(owner, timeSlice); + + if (!Replication.IsServer()) + return; + + m_fACE_UpdateTimer -= timeSlice; + if (m_fACE_UpdateTimer > 0) + return; + + ACE_UpdateWeather(m_fACE_UpdateFrequency - m_fACE_UpdateTimer); + m_fACE_UpdateTimer = m_fACE_UpdateFrequency; + } + + //------------------------------------------------------------------------------------------------ + //! TODO: Replaced with BaseWeatherManagerEntity::UpdateWeather once it gets overridable + void ACE_UpdateWeather(float timeSlice); + + //------------------------------------------------------------------------------------------------ + //! Return current air temperature in Kelvin + //! \param[in] altitude Meters above sea level + //! \return temperature + float ACE_GetAirTemperature(float altitude = 0) + { + return m_fACE_CurrentAirTemperature + ACE_TEMPERATURE_LAPSE_RATE * altitude; + } + + //------------------------------------------------------------------------------------------------ + //! Return overcast value in the interval [0, 2] for the weather state + float ACE_GetOvercastForState(notnull WeatherState state) + { + Resource res = Resource.Load(m_sACE_WeatherStatesConfigName); + if (!res.IsValid()) + return 0; + + BaseContainer stateMachineSrc = res.GetResource().ToBaseContainer(); + BaseContainerList states = stateMachineSrc.GetObjectArray("States"); + BaseContainer stateSrc = states.Get(state.GetStateID()); + BaseContainer variantSrc = stateSrc.GetObject(string.Format("WeatherVariant%1", state.GetStartVariantIndex())); + BaseContainer weatherItems = variantSrc.GetObject("WeatherItems"); + array cloudParams; + Print(weatherItems.Get("CloudsParams", cloudParams)); + + for (int i = 0; i < cloudParams.Count(); i += 5) + { + // 55 -> ConverageModifier + if (cloudParams[i] == 55) + return cloudParams[i+4]; + } + + return 0; + } + + //------------------------------------------------------------------------------------------------ + //! Adds offset in days to date + //! \param[inout] year Year of the date to update + //! \param[inout] month Month of the date to update + //! \param[inout] day Day of the date to update + //! \param[in] offset Offset in days (can be negative) + void ACE_AddDaysToDate(inout int year, inout int month, inout int day, int offset) + { + int sign = offset.Sign(); + + while (offset != 0) + { + day += sign; + offset -= sign; + + if (!CheckValidDate(year, month, day)) + { + if (sign > 0) + { + if (month != 12) + { + month += 1; + } + else + { + month = 1; + year += 1; + } + + day = 1; + } + else + { + day = 31; + + if (month == 1) + { + month = 12; + year -= 1; + } + else + { + month -= 1; + } + + while (!CheckValidDate(year, month, day)) + { + day -= 1; + } + } + } + } + } +} diff --git a/addons/facepaint/Configs/EntityCatalog/FIA/InventoryItems_EntityCatalog_FIA.conf b/addons/facepaint/Configs/EntityCatalog/FIA/InventoryItems_EntityCatalog_FIA.conf new file mode 100644 index 000000000..b919c388e --- /dev/null +++ b/addons/facepaint/Configs/EntityCatalog/FIA/InventoryItems_EntityCatalog_FIA.conf @@ -0,0 +1,17 @@ +SCR_EntityCatalogMultiList { + m_aMultiLists { + SCR_EntityCatalogMultiListEntry "{5C630E453BCB39DC}" { + m_aEntities { + SCR_EntityCatalogInventoryItem "{65270736038395D9}" { + m_sEntityPrefab "{28FA34E692783ACB}Prefabs/Items/ACE_Facepaint_01_USSR.et" + m_aEntityDataList { + SCR_ArsenalItem "{62F30440549B386D}" { + m_eItemType EQUIPMENT + m_iSupplyCost 0 + } + } + } + } + } + } +} diff --git a/addons/facepaint/Configs/EntityCatalog/FIA/InventoryItems_EntityCatalog_FIA.conf.meta b/addons/facepaint/Configs/EntityCatalog/FIA/InventoryItems_EntityCatalog_FIA.conf.meta new file mode 100644 index 000000000..7d8f7d436 --- /dev/null +++ b/addons/facepaint/Configs/EntityCatalog/FIA/InventoryItems_EntityCatalog_FIA.conf.meta @@ -0,0 +1,19 @@ +MetaFileClass { + Name "{E908001749419691}Configs/EntityCatalog/FIA/InventoryItems_EntityCatalog_FIA.conf" + Configurations { + CONFResourceClass PC { + } + CONFResourceClass XBOX_ONE : PC { + } + CONFResourceClass XBOX_SERIES : PC { + } + CONFResourceClass PS4 : PC { + } + CONFResourceClass PS5 : PC { + } + CONFResourceClass HEADLESS : PC { + } + CONFResourceClass Xbox : PC { + } + } +} \ No newline at end of file diff --git a/addons/facepaint/Configs/EntityCatalog/UK/UK_InventoryItems.conf b/addons/facepaint/Configs/EntityCatalog/UK/UK_InventoryItems.conf new file mode 100644 index 000000000..25783af62 --- /dev/null +++ b/addons/facepaint/Configs/EntityCatalog/UK/UK_InventoryItems.conf @@ -0,0 +1,17 @@ +SCR_EntityCatalogMultiList { + m_aMultiLists { + SCR_EntityCatalogMultiListEntry "{62DD3B2896AEA994}" { + m_aEntities { + SCR_EntityCatalogInventoryItem "{68EB10F5497121E7}" { + m_sEntityPrefab "{1642314A5C9B5C13}Prefabs/Items/ACE_Facepaint_01_UK.et" + m_aEntityDataList { + SCR_ArsenalItem "{62F30440549B386D}" { + m_eItemType EQUIPMENT + m_iSupplyCost 0 + } + } + } + } + } + } +} \ No newline at end of file diff --git a/addons/facepaint/Configs/EntityCatalog/UK/UK_InventoryItems.conf.meta b/addons/facepaint/Configs/EntityCatalog/UK/UK_InventoryItems.conf.meta new file mode 100644 index 000000000..02e380f8e --- /dev/null +++ b/addons/facepaint/Configs/EntityCatalog/UK/UK_InventoryItems.conf.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{0B5165A21961B72F}Configs/EntityCatalog/UK/UK_InventoryItems.conf" + Configurations { + CONFResourceClass PC { + } + CONFResourceClass XBOX_ONE : PC { + } + CONFResourceClass XBOX_SERIES : PC { + } + CONFResourceClass PS4 : PC { + } + CONFResourceClass PS5 : PC { + } + CONFResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/facepaint/Configs/EntityCatalog/US/InventoryItems_EntityCatalog_US.conf b/addons/facepaint/Configs/EntityCatalog/US/InventoryItems_EntityCatalog_US.conf new file mode 100644 index 000000000..03b82074f --- /dev/null +++ b/addons/facepaint/Configs/EntityCatalog/US/InventoryItems_EntityCatalog_US.conf @@ -0,0 +1,17 @@ +SCR_EntityCatalogMultiList { + m_aMultiLists { + SCR_EntityCatalogMultiListEntry "{5C68AD59F0753ABE}" { + m_aEntities { + SCR_EntityCatalogInventoryItem "{65270736F5B33C47}" { + m_sEntityPrefab "{B3F2B47340817ED6}Prefabs/Items/ACE_Facepaint_01_US.et" + m_aEntityDataList { + SCR_ArsenalItem "{62F30440549B386D}" { + m_eItemType EQUIPMENT + m_iSupplyCost 0 + } + } + } + } + } + } +} diff --git a/addons/facepaint/Configs/EntityCatalog/US/InventoryItems_EntityCatalog_US.conf.meta b/addons/facepaint/Configs/EntityCatalog/US/InventoryItems_EntityCatalog_US.conf.meta new file mode 100644 index 000000000..7c752023a --- /dev/null +++ b/addons/facepaint/Configs/EntityCatalog/US/InventoryItems_EntityCatalog_US.conf.meta @@ -0,0 +1,19 @@ +MetaFileClass { + Name "{5F7EC52FC40A03E2}Configs/EntityCatalog/US/InventoryItems_EntityCatalog_US.conf" + Configurations { + CONFResourceClass PC { + } + CONFResourceClass XBOX_ONE : PC { + } + CONFResourceClass XBOX_SERIES : PC { + } + CONFResourceClass PS4 : PC { + } + CONFResourceClass PS5 : PC { + } + CONFResourceClass HEADLESS : PC { + } + CONFResourceClass Xbox : PC { + } + } +} \ No newline at end of file diff --git a/addons/facepaint/Configs/EntityCatalog/USSR/InventoryItems_EntityCatalog_USSR.conf b/addons/facepaint/Configs/EntityCatalog/USSR/InventoryItems_EntityCatalog_USSR.conf new file mode 100644 index 000000000..a75392eb4 --- /dev/null +++ b/addons/facepaint/Configs/EntityCatalog/USSR/InventoryItems_EntityCatalog_USSR.conf @@ -0,0 +1,17 @@ +SCR_EntityCatalogMultiList { + m_aMultiLists { + SCR_EntityCatalogMultiListEntry "{5C68AD5F7414CA4A}" { + m_aEntities { + SCR_EntityCatalogInventoryItem "{65270736CC1B1935}" { + m_sEntityPrefab "{28FA34E692783ACB}Prefabs/Items/ACE_Facepaint_01_USSR.et" + m_aEntityDataList { + SCR_ArsenalItem "{62F30440549B386D}" { + m_eItemType EQUIPMENT + m_iSupplyCost 0 + } + } + } + } + } + } +} diff --git a/addons/facepaint/Configs/EntityCatalog/USSR/InventoryItems_EntityCatalog_USSR.conf.meta b/addons/facepaint/Configs/EntityCatalog/USSR/InventoryItems_EntityCatalog_USSR.conf.meta new file mode 100644 index 000000000..b243b658d --- /dev/null +++ b/addons/facepaint/Configs/EntityCatalog/USSR/InventoryItems_EntityCatalog_USSR.conf.meta @@ -0,0 +1,19 @@ +MetaFileClass { + Name "{C53421647C3D0D2E}Configs/EntityCatalog/USSR/InventoryItems_EntityCatalog_USSR.conf" + Configurations { + CONFResourceClass PC { + } + CONFResourceClass XBOX_ONE : PC { + } + CONFResourceClass XBOX_SERIES : PC { + } + CONFResourceClass PS4 : PC { + } + CONFResourceClass PS5 : PC { + } + CONFResourceClass HEADLESS : PC { + } + CONFResourceClass Xbox : PC { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Assets/Weapons/MachineGuns/M249/Data/M249_Body_1.emat b/addons/overheating/Assets/Weapons/MachineGuns/M249/Data/M249_Body_1.emat new file mode 100644 index 000000000..e571c303d --- /dev/null +++ b/addons/overheating/Assets/Weapons/MachineGuns/M249/Data/M249_Body_1.emat @@ -0,0 +1,9 @@ +MatPBRBasic : "{758946B2EC5F1439}Assets/Weapons/MachineGuns/M249/Data/M249_Body_1.emat" { + Emissive 0 0 0 1 + EmissiveAbsoluteLV 0 + EmissiveMap "{3175FE13B1FC2769}Assets/Weapons/MachineGuns/M249/Data/M249_Body_1_EM.edds" + Refs { + "Emissive" + "ACE_Overheating_BarrelGlowEffectComponent.m_vColor" + } +} \ No newline at end of file diff --git a/addons/overheating/Assets/Weapons/MachineGuns/M249/Data/M249_Body_1.emat.meta b/addons/overheating/Assets/Weapons/MachineGuns/M249/Data/M249_Body_1.emat.meta new file mode 100644 index 000000000..4476d1662 --- /dev/null +++ b/addons/overheating/Assets/Weapons/MachineGuns/M249/Data/M249_Body_1.emat.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{758946B2EC5F1439}Assets/Weapons/MachineGuns/M249/Data/M249_Body_1.emat" + Configurations { + EMATResourceClass PC { + } + EMATResourceClass XBOX_ONE : PC { + } + EMATResourceClass XBOX_SERIES : PC { + } + EMATResourceClass PS4 : PC { + } + EMATResourceClass PS5 : PC { + } + EMATResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Assets/Weapons/MachineGuns/M249/Data/M249_Body_1_EM.edds b/addons/overheating/Assets/Weapons/MachineGuns/M249/Data/M249_Body_1_EM.edds new file mode 100644 index 000000000..d362478d3 Binary files /dev/null and b/addons/overheating/Assets/Weapons/MachineGuns/M249/Data/M249_Body_1_EM.edds differ diff --git a/addons/overheating/Assets/Weapons/MachineGuns/M249/Data/M249_Body_1_EM.edds.meta b/addons/overheating/Assets/Weapons/MachineGuns/M249/Data/M249_Body_1_EM.edds.meta new file mode 100644 index 000000000..eff13c1a7 --- /dev/null +++ b/addons/overheating/Assets/Weapons/MachineGuns/M249/Data/M249_Body_1_EM.edds.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{3175FE13B1FC2769}Assets/Weapons/MachineGuns/M249/Data/M249_Body_1_EM.edds" + Configurations { + PNGResourceClass PC : "{EAB5DE3219F9CBA8}Configs/System/ResourceTypes/PC/TextureColorMap.conf" { + } + PNGResourceClass XBOX_ONE : "{91D862F89991BFBE}Configs/System/ResourceTypes/XBOX_ONE/TextureColorMap.conf" { + } + PNGResourceClass XBOX_SERIES : "{5FEAED1642ECE679}Configs/System/ResourceTypes/XBOX_SERIES/TextureColorMap.conf" { + } + PNGResourceClass PS4 : "{12273E1A0928F0C4}Configs/System/ResourceTypes/PS4/TextureColorMap.conf" { + } + PNGResourceClass PS5 : "{531A0D167B1ABD97}Configs/System/ResourceTypes/PS5/TextureColorMap.conf" { + } + PNGResourceClass HEADLESS : "{BEAF5CD0C438676E}Configs/System/ResourceTypes/HEADLESS/TextureColorMap.conf" { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Assets/Weapons/MachineGuns/M249/Data/M249_Body_1_EM.png b/addons/overheating/Assets/Weapons/MachineGuns/M249/Data/M249_Body_1_EM.png new file mode 100644 index 000000000..c668ddfd0 Binary files /dev/null and b/addons/overheating/Assets/Weapons/MachineGuns/M249/Data/M249_Body_1_EM.png differ diff --git a/addons/overheating/Assets/Weapons/MachineGuns/M60/Data/M60_Body2.emat b/addons/overheating/Assets/Weapons/MachineGuns/M60/Data/M60_Body2.emat new file mode 100644 index 000000000..628e179bd --- /dev/null +++ b/addons/overheating/Assets/Weapons/MachineGuns/M60/Data/M60_Body2.emat @@ -0,0 +1,8 @@ +MatPBRBasic : "{51F0B466B57B2722}Assets/Weapons/MachineGuns/M60/Data/M60_Body2.emat" { + Emissive 0 0 0 1 + EmissiveAbsoluteLV 0 + EmissiveMap "{E65ED29824A4834C}Assets/Weapons/MachineGuns/M60/Data/M60_Body2_EM.edds" + Refs { + "Emissive" "ACE_Overheating_BarrelGlowEffectComponent.m_vColor" + } +} \ No newline at end of file diff --git a/addons/overheating/Assets/Weapons/MachineGuns/M60/Data/M60_Body2.emat.meta b/addons/overheating/Assets/Weapons/MachineGuns/M60/Data/M60_Body2.emat.meta new file mode 100644 index 000000000..dda5301cb --- /dev/null +++ b/addons/overheating/Assets/Weapons/MachineGuns/M60/Data/M60_Body2.emat.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{51F0B466B57B2722}Assets/Weapons/MachineGuns/M60/Data/M60_Body2.emat" + Configurations { + EMATResourceClass PC { + } + EMATResourceClass XBOX_ONE : PC { + } + EMATResourceClass XBOX_SERIES : PC { + } + EMATResourceClass PS4 : PC { + } + EMATResourceClass PS5 : PC { + } + EMATResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Assets/Weapons/MachineGuns/M60/Data/M60_Body2_EM.edds b/addons/overheating/Assets/Weapons/MachineGuns/M60/Data/M60_Body2_EM.edds new file mode 100644 index 000000000..f527a632f Binary files /dev/null and b/addons/overheating/Assets/Weapons/MachineGuns/M60/Data/M60_Body2_EM.edds differ diff --git a/addons/overheating/Assets/Weapons/MachineGuns/M60/Data/M60_Body2_EM.edds.meta b/addons/overheating/Assets/Weapons/MachineGuns/M60/Data/M60_Body2_EM.edds.meta new file mode 100644 index 000000000..7e82ddbee --- /dev/null +++ b/addons/overheating/Assets/Weapons/MachineGuns/M60/Data/M60_Body2_EM.edds.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{E65ED29824A4834C}Assets/Weapons/MachineGuns/M60/Data/M60_Body2_EM.edds" + Configurations { + PNGResourceClass PC : "{EAB5DE3219F9CBA8}Configs/System/ResourceTypes/PC/TextureColorMap.conf" { + } + PNGResourceClass XBOX_ONE : "{91D862F89991BFBE}Configs/System/ResourceTypes/XBOX_ONE/TextureColorMap.conf" { + } + PNGResourceClass XBOX_SERIES : "{5FEAED1642ECE679}Configs/System/ResourceTypes/XBOX_SERIES/TextureColorMap.conf" { + } + PNGResourceClass PS4 : "{12273E1A0928F0C4}Configs/System/ResourceTypes/PS4/TextureColorMap.conf" { + } + PNGResourceClass PS5 : "{531A0D167B1ABD97}Configs/System/ResourceTypes/PS5/TextureColorMap.conf" { + } + PNGResourceClass HEADLESS : "{BEAF5CD0C438676E}Configs/System/ResourceTypes/HEADLESS/TextureColorMap.conf" { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Assets/Weapons/MachineGuns/M60/Data/M60_Body2_EM.png b/addons/overheating/Assets/Weapons/MachineGuns/M60/Data/M60_Body2_EM.png new file mode 100644 index 000000000..c087e6a6e Binary files /dev/null and b/addons/overheating/Assets/Weapons/MachineGuns/M60/Data/M60_Body2_EM.png differ diff --git a/addons/overheating/Assets/Weapons/MachineGuns/PKM/Data/PKM_body_3.emat b/addons/overheating/Assets/Weapons/MachineGuns/PKM/Data/PKM_body_3.emat new file mode 100644 index 000000000..d684b7e9e --- /dev/null +++ b/addons/overheating/Assets/Weapons/MachineGuns/PKM/Data/PKM_body_3.emat @@ -0,0 +1,9 @@ +MatPBRBasic : "{E86D1DE592A111CD}Assets/Weapons/MachineGuns/PKM/Data/PKM_body_3.emat" { + Emissive 0 0 0 1 + EmissiveAbsoluteLV 0 + EmissiveMap "{EB2407FB92571226}Assets/Weapons/MachineGuns/PKM/Data/PKM_body_3_EM.edds" + Refs { + "Emissive" + "ACE_Overheating_BarrelGlowEffectComponent.m_vColor" + } +} \ No newline at end of file diff --git a/addons/overheating/Assets/Weapons/MachineGuns/PKM/Data/PKM_body_3.emat.meta b/addons/overheating/Assets/Weapons/MachineGuns/PKM/Data/PKM_body_3.emat.meta new file mode 100644 index 000000000..7bb24b22b --- /dev/null +++ b/addons/overheating/Assets/Weapons/MachineGuns/PKM/Data/PKM_body_3.emat.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{E86D1DE592A111CD}Assets/Weapons/MachineGuns/PKM/Data/PKM_body_3.emat" + Configurations { + EMATResourceClass PC { + } + EMATResourceClass XBOX_ONE : PC { + } + EMATResourceClass XBOX_SERIES : PC { + } + EMATResourceClass PS4 : PC { + } + EMATResourceClass PS5 : PC { + } + EMATResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Assets/Weapons/MachineGuns/PKM/Data/PKM_body_3_EM.edds b/addons/overheating/Assets/Weapons/MachineGuns/PKM/Data/PKM_body_3_EM.edds new file mode 100644 index 000000000..999609467 Binary files /dev/null and b/addons/overheating/Assets/Weapons/MachineGuns/PKM/Data/PKM_body_3_EM.edds differ diff --git a/addons/overheating/Assets/Weapons/MachineGuns/PKM/Data/PKM_body_3_EM.edds.meta b/addons/overheating/Assets/Weapons/MachineGuns/PKM/Data/PKM_body_3_EM.edds.meta new file mode 100644 index 000000000..b9e6c3d99 --- /dev/null +++ b/addons/overheating/Assets/Weapons/MachineGuns/PKM/Data/PKM_body_3_EM.edds.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{EB2407FB92571226}Assets/Weapons/MachineGuns/PKM/Data/PKM_body_3_EM.edds" + Configurations { + PNGResourceClass PC : "{EAB5DE3219F9CBA8}Configs/System/ResourceTypes/PC/TextureColorMap.conf" { + } + PNGResourceClass XBOX_ONE : "{91D862F89991BFBE}Configs/System/ResourceTypes/XBOX_ONE/TextureColorMap.conf" { + } + PNGResourceClass XBOX_SERIES : "{5FEAED1642ECE679}Configs/System/ResourceTypes/XBOX_SERIES/TextureColorMap.conf" { + } + PNGResourceClass PS4 : "{12273E1A0928F0C4}Configs/System/ResourceTypes/PS4/TextureColorMap.conf" { + } + PNGResourceClass PS5 : "{531A0D167B1ABD97}Configs/System/ResourceTypes/PS5/TextureColorMap.conf" { + } + PNGResourceClass HEADLESS : "{BEAF5CD0C438676E}Configs/System/ResourceTypes/HEADLESS/TextureColorMap.conf" { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Assets/Weapons/MachineGuns/PKM/Data/PKM_body_3_EM.png b/addons/overheating/Assets/Weapons/MachineGuns/PKM/Data/PKM_body_3_EM.png new file mode 100644 index 000000000..68a17a10a Binary files /dev/null and b/addons/overheating/Assets/Weapons/MachineGuns/PKM/Data/PKM_body_3_EM.png differ diff --git a/addons/overheating/Assets/Weapons/MachineGuns/RPK74/Data/RPK74_Buttstock_Barrel.emat b/addons/overheating/Assets/Weapons/MachineGuns/RPK74/Data/RPK74_Buttstock_Barrel.emat new file mode 100644 index 000000000..ec738f6e1 --- /dev/null +++ b/addons/overheating/Assets/Weapons/MachineGuns/RPK74/Data/RPK74_Buttstock_Barrel.emat @@ -0,0 +1,9 @@ +MatPBRBasic : "{94099BC5F7D821FA}Assets/Weapons/MachineGuns/RPK74/Data/RPK74_Buttstock_Barrel.emat" { + Emissive 0 0 0 1 + EmissiveAbsoluteLV 0 + EmissiveMap "{272E422231C3937B}Assets/Weapons/MachineGuns/RPK74/Data/RPK74_Buttstock_EM.edds" + Refs { + "Emissive" + "ACE_Overheating_BarrelGlowEffectComponent.m_vColor" + } +} \ No newline at end of file diff --git a/addons/overheating/Assets/Weapons/MachineGuns/RPK74/Data/RPK74_Buttstock_Barrel.emat.meta b/addons/overheating/Assets/Weapons/MachineGuns/RPK74/Data/RPK74_Buttstock_Barrel.emat.meta new file mode 100644 index 000000000..84e5c1271 --- /dev/null +++ b/addons/overheating/Assets/Weapons/MachineGuns/RPK74/Data/RPK74_Buttstock_Barrel.emat.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{94099BC5F7D821FA}Assets/Weapons/MachineGuns/RPK74/Data/RPK74_Buttstock_Barrel.emat" + Configurations { + EMATResourceClass PC { + } + EMATResourceClass XBOX_ONE : PC { + } + EMATResourceClass XBOX_SERIES : PC { + } + EMATResourceClass PS4 : PC { + } + EMATResourceClass PS5 : PC { + } + EMATResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Assets/Weapons/MachineGuns/RPK74/Data/RPK74_Buttstock_EM.edds b/addons/overheating/Assets/Weapons/MachineGuns/RPK74/Data/RPK74_Buttstock_EM.edds new file mode 100644 index 000000000..bb58e4773 Binary files /dev/null and b/addons/overheating/Assets/Weapons/MachineGuns/RPK74/Data/RPK74_Buttstock_EM.edds differ diff --git a/addons/overheating/Assets/Weapons/MachineGuns/RPK74/Data/RPK74_Buttstock_EM.edds.meta b/addons/overheating/Assets/Weapons/MachineGuns/RPK74/Data/RPK74_Buttstock_EM.edds.meta new file mode 100644 index 000000000..6026df41f --- /dev/null +++ b/addons/overheating/Assets/Weapons/MachineGuns/RPK74/Data/RPK74_Buttstock_EM.edds.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{272E422231C3937B}Assets/Weapons/MachineGuns/RPK74/Data/RPK74_Buttstock_EM.edds" + Configurations { + PNGResourceClass PC : "{EAB5DE3219F9CBA8}Configs/System/ResourceTypes/PC/TextureColorMap.conf" { + } + PNGResourceClass XBOX_ONE : "{91D862F89991BFBE}Configs/System/ResourceTypes/XBOX_ONE/TextureColorMap.conf" { + } + PNGResourceClass XBOX_SERIES : "{5FEAED1642ECE679}Configs/System/ResourceTypes/XBOX_SERIES/TextureColorMap.conf" { + } + PNGResourceClass PS4 : "{12273E1A0928F0C4}Configs/System/ResourceTypes/PS4/TextureColorMap.conf" { + } + PNGResourceClass PS5 : "{531A0D167B1ABD97}Configs/System/ResourceTypes/PS5/TextureColorMap.conf" { + } + PNGResourceClass HEADLESS : "{BEAF5CD0C438676E}Configs/System/ResourceTypes/HEADLESS/TextureColorMap.conf" { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Assets/Weapons/MachineGuns/RPK74/Data/RPK74_Buttstock_EM.png b/addons/overheating/Assets/Weapons/MachineGuns/RPK74/Data/RPK74_Buttstock_EM.png new file mode 100644 index 000000000..420ec1ad5 Binary files /dev/null and b/addons/overheating/Assets/Weapons/MachineGuns/RPK74/Data/RPK74_Buttstock_EM.png differ diff --git a/addons/overheating/Assets/Weapons/MachineGuns/UK59/Data/UK59_Metal.emat b/addons/overheating/Assets/Weapons/MachineGuns/UK59/Data/UK59_Metal.emat new file mode 100644 index 000000000..be644b0c7 --- /dev/null +++ b/addons/overheating/Assets/Weapons/MachineGuns/UK59/Data/UK59_Metal.emat @@ -0,0 +1,9 @@ +MatPBRBasic : "{1A0A72CFC5D87FD5}Assets/Weapons/MachineGuns/UK59/Data/UK59_Metal.emat" { + Emissive 0 0 0 1 + EmissiveAbsoluteLV 0 + EmissiveMap "{C4DBC19EEF7DC6CE}Assets/Weapons/MachineGuns/UK59/Data/UK59_Metal_EM.edds" + Refs { + "Emissive" + "ACE_Overheating_BarrelGlowEffectComponent.m_vColor" + } +} \ No newline at end of file diff --git a/addons/overheating/Assets/Weapons/MachineGuns/UK59/Data/UK59_Metal.emat.meta b/addons/overheating/Assets/Weapons/MachineGuns/UK59/Data/UK59_Metal.emat.meta new file mode 100644 index 000000000..cb589bd89 --- /dev/null +++ b/addons/overheating/Assets/Weapons/MachineGuns/UK59/Data/UK59_Metal.emat.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{1A0A72CFC5D87FD5}Assets/Weapons/MachineGuns/UK59/Data/UK59_Metal.emat" + Configurations { + EMATResourceClass PC { + } + EMATResourceClass XBOX_ONE : PC { + } + EMATResourceClass XBOX_SERIES : PC { + } + EMATResourceClass PS4 : PC { + } + EMATResourceClass PS5 : PC { + } + EMATResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Assets/Weapons/MachineGuns/UK59/Data/UK59_Metal_EM.edds b/addons/overheating/Assets/Weapons/MachineGuns/UK59/Data/UK59_Metal_EM.edds new file mode 100644 index 000000000..17b6d00f6 Binary files /dev/null and b/addons/overheating/Assets/Weapons/MachineGuns/UK59/Data/UK59_Metal_EM.edds differ diff --git a/addons/overheating/Assets/Weapons/MachineGuns/UK59/Data/UK59_Metal_EM.edds.meta b/addons/overheating/Assets/Weapons/MachineGuns/UK59/Data/UK59_Metal_EM.edds.meta new file mode 100644 index 000000000..666ad32f4 --- /dev/null +++ b/addons/overheating/Assets/Weapons/MachineGuns/UK59/Data/UK59_Metal_EM.edds.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{C4DBC19EEF7DC6CE}Assets/Weapons/MachineGuns/UK59/Data/UK59_Metal_EM.edds" + Configurations { + PNGResourceClass PC : "{EAB5DE3219F9CBA8}Configs/System/ResourceTypes/PC/TextureColorMap.conf" { + } + PNGResourceClass XBOX_ONE : "{91D862F89991BFBE}Configs/System/ResourceTypes/XBOX_ONE/TextureColorMap.conf" { + } + PNGResourceClass XBOX_SERIES : "{5FEAED1642ECE679}Configs/System/ResourceTypes/XBOX_SERIES/TextureColorMap.conf" { + } + PNGResourceClass PS4 : "{12273E1A0928F0C4}Configs/System/ResourceTypes/PS4/TextureColorMap.conf" { + } + PNGResourceClass PS5 : "{531A0D167B1ABD97}Configs/System/ResourceTypes/PS5/TextureColorMap.conf" { + } + PNGResourceClass HEADLESS : "{BEAF5CD0C438676E}Configs/System/ResourceTypes/HEADLESS/TextureColorMap.conf" { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Assets/Weapons/MachineGuns/UK59/Data/UK59_Metal_EM.png b/addons/overheating/Assets/Weapons/MachineGuns/UK59/Data/UK59_Metal_EM.png new file mode 100644 index 000000000..325324cae Binary files /dev/null and b/addons/overheating/Assets/Weapons/MachineGuns/UK59/Data/UK59_Metal_EM.png differ diff --git a/addons/overheating/Configs/ACE/Settings.conf b/addons/overheating/Configs/ACE/Settings.conf new file mode 100644 index 000000000..326771be5 --- /dev/null +++ b/addons/overheating/Configs/ACE/Settings.conf @@ -0,0 +1,6 @@ +ACE_SettingsConfig { + m_aInitialModSettings { + ACE_Overheating_Settings "{65FA13A496B871DE}" { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Configs/ACE/Settings.conf.meta b/addons/overheating/Configs/ACE/Settings.conf.meta new file mode 100644 index 000000000..094ecd2fc --- /dev/null +++ b/addons/overheating/Configs/ACE/Settings.conf.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{A305FEB7400A2965}Configs/ACE/Settings.conf" + Configurations { + CONFResourceClass PC { + } + CONFResourceClass XBOX_ONE : PC { + } + CONFResourceClass XBOX_SERIES : PC { + } + CONFResourceClass PS4 : PC { + } + CONFResourceClass PS5 : PC { + } + CONFResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Configs/ControlHints/AvailableActions.conf b/addons/overheating/Configs/ControlHints/AvailableActions.conf new file mode 100644 index 000000000..e25fc46ff --- /dev/null +++ b/addons/overheating/Configs/ControlHints/AvailableActions.conf @@ -0,0 +1,20 @@ +SCR_AvailableActionsDisplay { + m_aActions { + SCR_AvailableActionContext "{65F8F244026F937A}" { + m_aConditions { + SCR_WeaponSwitchAvailableCondition "{65F8F24469FAD5BB}" { + m_bNegateCondition 1 + } + SCR_IsCharacterInControlCondition "{65F8F244466D284F}" { + } + SCR_CharacterHasWeaponCondition "{65F8F2445B2C7F78}" { + } + ACE_Overheating_IsCharacterWeaponJammedCondition "{65F8F245D2A12F78}" { + } + } + m_sTag "ACE_OVERHEATING_CLEAR_JAM" + m_sAction "ACE_Overheating_ClearJam" + m_sName "#ACE_Overheating_TryClearWeaponJam" + } + } +} \ No newline at end of file diff --git a/addons/overheating/Configs/ControlHints/AvailableActions.conf.meta b/addons/overheating/Configs/ControlHints/AvailableActions.conf.meta new file mode 100644 index 000000000..e2d93a217 --- /dev/null +++ b/addons/overheating/Configs/ControlHints/AvailableActions.conf.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{80CC0413DDBDFCB9}Configs/ControlHints/AvailableActions.conf" + Configurations { + CONFResourceClass PC { + } + CONFResourceClass XBOX_ONE : PC { + } + CONFResourceClass XBOX_SERIES : PC { + } + CONFResourceClass PS4 : PC { + } + CONFResourceClass PS5 : PC { + } + CONFResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Configs/Notifications/Notifications.conf b/addons/overheating/Configs/Notifications/Notifications.conf new file mode 100644 index 000000000..234ded9c7 --- /dev/null +++ b/addons/overheating/Configs/Notifications/Notifications.conf @@ -0,0 +1,11 @@ +SCR_NotificationConfig { + m_aNotificationDisplayData { + SCR_NotificationNumber "{65FD7BA7A6345097}" { + m_NotificationKey ACE_OVERHEATING_BARREL_TEMPERATURE_RESULT + m_info SCR_UINotificationInfo "{621737CBF77F9D73}" { + Name "#ACE_Overheating-Notification_BARREL_TEMPERATURE_RESULT" + m_cNotificationColor WARNING + } + } + } +} \ No newline at end of file diff --git a/addons/overheating/Configs/Notifications/Notifications.conf.meta b/addons/overheating/Configs/Notifications/Notifications.conf.meta new file mode 100644 index 000000000..204ebf460 --- /dev/null +++ b/addons/overheating/Configs/Notifications/Notifications.conf.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{7134157CA6B1FA8E}Configs/Notifications/Notifications.conf" + Configurations { + CONFResourceClass PC { + } + CONFResourceClass XBOX_ONE : PC { + } + CONFResourceClass XBOX_SERIES : PC { + } + CONFResourceClass PS4 : PC { + } + CONFResourceClass PS5 : PC { + } + CONFResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Configs/System/chimeraInputCommon.conf b/addons/overheating/Configs/System/chimeraInputCommon.conf new file mode 100644 index 000000000..271709d24 --- /dev/null +++ b/addons/overheating/Configs/System/chimeraInputCommon.conf @@ -0,0 +1,25 @@ +ActionManager { + Contexts { + ActionContext CharacterWeaponContext { + Actions { + Action ACE_Overheating_ClearJam { + InputSource InputSourceSum "{65BCC654900533B2}" { + Sources { + InputSourceCombo "{65BCC6548E864D1B}" { + FilterPreset "select" + Sources { + InputSourceValue "{65BCC654860B4CEF}" { + Input "keyboard:KC_LSHIFT" + } + InputSourceValue "{65BCC6548723F58D}" { + Input "keyboard:KC_R" + } + } + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/addons/overheating/Configs/System/chimeraInputCommon.conf.meta b/addons/overheating/Configs/System/chimeraInputCommon.conf.meta new file mode 100644 index 000000000..f1e7b1a2d --- /dev/null +++ b/addons/overheating/Configs/System/chimeraInputCommon.conf.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{795184CF9AD764DB}Configs/System/chimeraInputCommon.conf" + Configurations { + CONFResourceClass PC { + } + CONFResourceClass XBOX_ONE : PC { + } + CONFResourceClass XBOX_SERIES : PC { + } + CONFResourceClass PS4 : PC { + } + CONFResourceClass PS5 : PC { + } + CONFResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Configs/System/keyBindingMenu.conf b/addons/overheating/Configs/System/keyBindingMenu.conf new file mode 100644 index 000000000..e0a036d0a --- /dev/null +++ b/addons/overheating/Configs/System/keyBindingMenu.conf @@ -0,0 +1,17 @@ +SCR_KeyBindingMenuConfig { + m_KeyBindingCategories { + SCR_KeyBindingCategory "{60C72E6BAD884638}" { + m_KeyBindingEntries { + SCR_KeyBindingEntry "{65BCC6553BE16CD0}" { + m_sActionName "separator" + m_sDisplayName "#ACE_Overheating-AddonName" + } + SCR_KeyBindingEntry "{65BCC6553B77AFDE}" { + m_sActionName "ACE_Overheating_ClearJam" + m_sDisplayName "#ACE_Overheating_TryClearWeaponJam" + m_sPreset "select" + } + } + } + } +} \ No newline at end of file diff --git a/addons/overheating/Configs/System/keyBindingMenu.conf.meta b/addons/overheating/Configs/System/keyBindingMenu.conf.meta new file mode 100644 index 000000000..f54af760a --- /dev/null +++ b/addons/overheating/Configs/System/keyBindingMenu.conf.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{4EE7794C9A3F11EF}Configs/System/keyBindingMenu.conf" + Configurations { + CONFResourceClass PC { + } + CONFResourceClass XBOX_ONE : PC { + } + CONFResourceClass XBOX_SERIES : PC { + } + CONFResourceClass PS4 : PC { + } + CONFResourceClass PS5 : PC { + } + CONFResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Configs/Systems/ChimeraSystemsConfig.conf b/addons/overheating/Configs/Systems/ChimeraSystemsConfig.conf new file mode 100644 index 000000000..f253c1137 --- /dev/null +++ b/addons/overheating/Configs/Systems/ChimeraSystemsConfig.conf @@ -0,0 +1,20 @@ +SystemSettings : "{45C53F06BA17238D}configs/Systems/SystemsConfig.conf" { + Systems { + ACE_Overheating_JammingSystem "{65B91DED60157A6D}" { + SystemPoints 0 + } + ACE_Overheating_BarrelTemperatureSystem "{65FC23CDE82BDA1A}" { + SystemLocation Server + SystemPoints 0 + m_pScheduler ACE_Overheating_BarrelTemperature_JobScheduler "{65FC23CDEC9A64A4}" { + m_fObjectUpdateTimeoutMS 5000 + } + } + ACE_Overheating_AmmoTemperatureSystem "{65FCED513A877491}" { + SystemLocation Server + SystemPoints 0 + m_pScheduler ACE_Overheating_AmmoTemperature_JobScheduler "{65FCED513EE0EF6B}" { + } + } + } +} \ No newline at end of file diff --git a/addons/overheating/Configs/Systems/ChimeraSystemsConfig.conf.meta b/addons/overheating/Configs/Systems/ChimeraSystemsConfig.conf.meta new file mode 100644 index 000000000..06c5eb99e --- /dev/null +++ b/addons/overheating/Configs/Systems/ChimeraSystemsConfig.conf.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{86E953538A28A98D}Configs/Systems/ChimeraSystemsConfig.conf" + Configurations { + CONFResourceClass PC { + } + CONFResourceClass XBOX_ONE : PC { + } + CONFResourceClass XBOX_SERIES : PC { + } + CONFResourceClass PS4 : PC { + } + CONFResourceClass PS5 : PC { + } + CONFResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Language/ACE_Overheating_localization.cs_cz.conf b/addons/overheating/Language/ACE_Overheating_localization.cs_cz.conf new file mode 100644 index 000000000..14fd55913 --- /dev/null +++ b/addons/overheating/Language/ACE_Overheating_localization.cs_cz.conf @@ -0,0 +1,18 @@ +StringTableRuntime { + Ids { + "ACE_Overheating-AddonName" + "ACE_Overheating-CheckBarrelTemperaturAction" + "ACE_Overheating-CoolBarrelInWaterAction" + "ACE_Overheating-Notification_BARREL_TEMPERATURE_RESULT" + "ACE_Overheating-SwapBarrelAction" + "ACE_Overheating_TryClearWeaponJam" + } + Texts { + "Overheating" + "Check barrel temperature" + "Cool barrel in water" + "You find a barrel temperature of %1 °C" + "Swap barrel" + "Try clear weapon jam" + } +} \ No newline at end of file diff --git a/addons/overheating/Language/ACE_Overheating_localization.cs_cz.conf.meta b/addons/overheating/Language/ACE_Overheating_localization.cs_cz.conf.meta new file mode 100644 index 000000000..29b88f1cf --- /dev/null +++ b/addons/overheating/Language/ACE_Overheating_localization.cs_cz.conf.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{F730DD92BED7819F}Language/ACE_Overheating_localization.cs_cz.conf" + Configurations { + CONFResourceClass PC { + } + CONFResourceClass XBOX_ONE : PC { + } + CONFResourceClass XBOX_SERIES : PC { + } + CONFResourceClass PS4 : PC { + } + CONFResourceClass PS5 : PC { + } + CONFResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Language/ACE_Overheating_localization.de_de.conf b/addons/overheating/Language/ACE_Overheating_localization.de_de.conf new file mode 100644 index 000000000..6c8db8b0e --- /dev/null +++ b/addons/overheating/Language/ACE_Overheating_localization.de_de.conf @@ -0,0 +1,18 @@ +StringTableRuntime { + Ids { + "ACE_Overheating-AddonName" + "ACE_Overheating-CheckBarrelTemperaturAction" + "ACE_Overheating-CoolBarrelInWaterAction" + "ACE_Overheating-Notification_BARREL_TEMPERATURE_RESULT" + "ACE_Overheating-SwapBarrelAction" + "ACE_Overheating_TryClearWeaponJam" + } + Texts { + "Overheating" + "Lauftemperatur überprüfen" + "Lauf im Wasser kühlen" + "Die Lauftemperatur liegt bei %1 °C" + "Lauf austauschen" + "Versuche Waffenstörung zu beheben" + } +} \ No newline at end of file diff --git a/addons/overheating/Language/ACE_Overheating_localization.de_de.conf.meta b/addons/overheating/Language/ACE_Overheating_localization.de_de.conf.meta new file mode 100644 index 000000000..ec2dadbda --- /dev/null +++ b/addons/overheating/Language/ACE_Overheating_localization.de_de.conf.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{224EC7A1AD7490BF}Language/ACE_Overheating_localization.de_de.conf" + Configurations { + CONFResourceClass PC { + } + CONFResourceClass XBOX_ONE : PC { + } + CONFResourceClass XBOX_SERIES : PC { + } + CONFResourceClass PS4 : PC { + } + CONFResourceClass PS5 : PC { + } + CONFResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Language/ACE_Overheating_localization.en_us.conf b/addons/overheating/Language/ACE_Overheating_localization.en_us.conf new file mode 100644 index 000000000..14fd55913 --- /dev/null +++ b/addons/overheating/Language/ACE_Overheating_localization.en_us.conf @@ -0,0 +1,18 @@ +StringTableRuntime { + Ids { + "ACE_Overheating-AddonName" + "ACE_Overheating-CheckBarrelTemperaturAction" + "ACE_Overheating-CoolBarrelInWaterAction" + "ACE_Overheating-Notification_BARREL_TEMPERATURE_RESULT" + "ACE_Overheating-SwapBarrelAction" + "ACE_Overheating_TryClearWeaponJam" + } + Texts { + "Overheating" + "Check barrel temperature" + "Cool barrel in water" + "You find a barrel temperature of %1 °C" + "Swap barrel" + "Try clear weapon jam" + } +} \ No newline at end of file diff --git a/addons/overheating/Language/ACE_Overheating_localization.en_us.conf.meta b/addons/overheating/Language/ACE_Overheating_localization.en_us.conf.meta new file mode 100644 index 000000000..769250504 --- /dev/null +++ b/addons/overheating/Language/ACE_Overheating_localization.en_us.conf.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{7CBE4DEAC78795BE}Language/ACE_Overheating_localization.en_us.conf" + Configurations { + CONFResourceClass PC { + } + CONFResourceClass XBOX_ONE : PC { + } + CONFResourceClass XBOX_SERIES : PC { + } + CONFResourceClass PS4 : PC { + } + CONFResourceClass PS5 : PC { + } + CONFResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Language/ACE_Overheating_localization.es_es.conf b/addons/overheating/Language/ACE_Overheating_localization.es_es.conf new file mode 100644 index 000000000..14fd55913 --- /dev/null +++ b/addons/overheating/Language/ACE_Overheating_localization.es_es.conf @@ -0,0 +1,18 @@ +StringTableRuntime { + Ids { + "ACE_Overheating-AddonName" + "ACE_Overheating-CheckBarrelTemperaturAction" + "ACE_Overheating-CoolBarrelInWaterAction" + "ACE_Overheating-Notification_BARREL_TEMPERATURE_RESULT" + "ACE_Overheating-SwapBarrelAction" + "ACE_Overheating_TryClearWeaponJam" + } + Texts { + "Overheating" + "Check barrel temperature" + "Cool barrel in water" + "You find a barrel temperature of %1 °C" + "Swap barrel" + "Try clear weapon jam" + } +} \ No newline at end of file diff --git a/addons/overheating/Language/ACE_Overheating_localization.es_es.conf.meta b/addons/overheating/Language/ACE_Overheating_localization.es_es.conf.meta new file mode 100644 index 000000000..408b8f438 --- /dev/null +++ b/addons/overheating/Language/ACE_Overheating_localization.es_es.conf.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{B9F200632985FEA1}Language/ACE_Overheating_localization.es_es.conf" + Configurations { + CONFResourceClass PC { + } + CONFResourceClass XBOX_ONE : PC { + } + CONFResourceClass XBOX_SERIES : PC { + } + CONFResourceClass PS4 : PC { + } + CONFResourceClass PS5 : PC { + } + CONFResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Language/ACE_Overheating_localization.fr_fr.conf b/addons/overheating/Language/ACE_Overheating_localization.fr_fr.conf new file mode 100644 index 000000000..14fd55913 --- /dev/null +++ b/addons/overheating/Language/ACE_Overheating_localization.fr_fr.conf @@ -0,0 +1,18 @@ +StringTableRuntime { + Ids { + "ACE_Overheating-AddonName" + "ACE_Overheating-CheckBarrelTemperaturAction" + "ACE_Overheating-CoolBarrelInWaterAction" + "ACE_Overheating-Notification_BARREL_TEMPERATURE_RESULT" + "ACE_Overheating-SwapBarrelAction" + "ACE_Overheating_TryClearWeaponJam" + } + Texts { + "Overheating" + "Check barrel temperature" + "Cool barrel in water" + "You find a barrel temperature of %1 °C" + "Swap barrel" + "Try clear weapon jam" + } +} \ No newline at end of file diff --git a/addons/overheating/Language/ACE_Overheating_localization.fr_fr.conf.meta b/addons/overheating/Language/ACE_Overheating_localization.fr_fr.conf.meta new file mode 100644 index 000000000..42fa6aa1a --- /dev/null +++ b/addons/overheating/Language/ACE_Overheating_localization.fr_fr.conf.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{025AF554CF061DA3}Language/ACE_Overheating_localization.fr_fr.conf" + Configurations { + CONFResourceClass PC { + } + CONFResourceClass XBOX_ONE : PC { + } + CONFResourceClass XBOX_SERIES : PC { + } + CONFResourceClass PS4 : PC { + } + CONFResourceClass PS5 : PC { + } + CONFResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Language/ACE_Overheating_localization.it_it.conf b/addons/overheating/Language/ACE_Overheating_localization.it_it.conf new file mode 100644 index 000000000..14fd55913 --- /dev/null +++ b/addons/overheating/Language/ACE_Overheating_localization.it_it.conf @@ -0,0 +1,18 @@ +StringTableRuntime { + Ids { + "ACE_Overheating-AddonName" + "ACE_Overheating-CheckBarrelTemperaturAction" + "ACE_Overheating-CoolBarrelInWaterAction" + "ACE_Overheating-Notification_BARREL_TEMPERATURE_RESULT" + "ACE_Overheating-SwapBarrelAction" + "ACE_Overheating_TryClearWeaponJam" + } + Texts { + "Overheating" + "Check barrel temperature" + "Cool barrel in water" + "You find a barrel temperature of %1 °C" + "Swap barrel" + "Try clear weapon jam" + } +} \ No newline at end of file diff --git a/addons/overheating/Language/ACE_Overheating_localization.it_it.conf.meta b/addons/overheating/Language/ACE_Overheating_localization.it_it.conf.meta new file mode 100644 index 000000000..a28317c87 --- /dev/null +++ b/addons/overheating/Language/ACE_Overheating_localization.it_it.conf.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{82467A6062249E5A}Language/ACE_Overheating_localization.it_it.conf" + Configurations { + CONFResourceClass PC { + } + CONFResourceClass XBOX_ONE : PC { + } + CONFResourceClass XBOX_SERIES : PC { + } + CONFResourceClass PS4 : PC { + } + CONFResourceClass PS5 : PC { + } + CONFResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Language/ACE_Overheating_localization.ja_jp.conf b/addons/overheating/Language/ACE_Overheating_localization.ja_jp.conf new file mode 100644 index 000000000..14fd55913 --- /dev/null +++ b/addons/overheating/Language/ACE_Overheating_localization.ja_jp.conf @@ -0,0 +1,18 @@ +StringTableRuntime { + Ids { + "ACE_Overheating-AddonName" + "ACE_Overheating-CheckBarrelTemperaturAction" + "ACE_Overheating-CoolBarrelInWaterAction" + "ACE_Overheating-Notification_BARREL_TEMPERATURE_RESULT" + "ACE_Overheating-SwapBarrelAction" + "ACE_Overheating_TryClearWeaponJam" + } + Texts { + "Overheating" + "Check barrel temperature" + "Cool barrel in water" + "You find a barrel temperature of %1 °C" + "Swap barrel" + "Try clear weapon jam" + } +} \ No newline at end of file diff --git a/addons/overheating/Language/ACE_Overheating_localization.ja_jp.conf.meta b/addons/overheating/Language/ACE_Overheating_localization.ja_jp.conf.meta new file mode 100644 index 000000000..6c288e275 --- /dev/null +++ b/addons/overheating/Language/ACE_Overheating_localization.ja_jp.conf.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{925DC7F25C55AEF1}Language/ACE_Overheating_localization.ja_jp.conf" + Configurations { + CONFResourceClass PC { + } + CONFResourceClass XBOX_ONE : PC { + } + CONFResourceClass XBOX_SERIES : PC { + } + CONFResourceClass PS4 : PC { + } + CONFResourceClass PS5 : PC { + } + CONFResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Language/ACE_Overheating_localization.ko_kr.conf b/addons/overheating/Language/ACE_Overheating_localization.ko_kr.conf new file mode 100644 index 000000000..14fd55913 --- /dev/null +++ b/addons/overheating/Language/ACE_Overheating_localization.ko_kr.conf @@ -0,0 +1,18 @@ +StringTableRuntime { + Ids { + "ACE_Overheating-AddonName" + "ACE_Overheating-CheckBarrelTemperaturAction" + "ACE_Overheating-CoolBarrelInWaterAction" + "ACE_Overheating-Notification_BARREL_TEMPERATURE_RESULT" + "ACE_Overheating-SwapBarrelAction" + "ACE_Overheating_TryClearWeaponJam" + } + Texts { + "Overheating" + "Check barrel temperature" + "Cool barrel in water" + "You find a barrel temperature of %1 °C" + "Swap barrel" + "Try clear weapon jam" + } +} \ No newline at end of file diff --git a/addons/overheating/Language/ACE_Overheating_localization.ko_kr.conf.meta b/addons/overheating/Language/ACE_Overheating_localization.ko_kr.conf.meta new file mode 100644 index 000000000..72af33167 --- /dev/null +++ b/addons/overheating/Language/ACE_Overheating_localization.ko_kr.conf.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{32E3EF5ECF78ADCE}Language/ACE_Overheating_localization.ko_kr.conf" + Configurations { + CONFResourceClass PC { + } + CONFResourceClass XBOX_ONE : PC { + } + CONFResourceClass XBOX_SERIES : PC { + } + CONFResourceClass PS4 : PC { + } + CONFResourceClass PS5 : PC { + } + CONFResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Language/ACE_Overheating_localization.pl_pl.conf b/addons/overheating/Language/ACE_Overheating_localization.pl_pl.conf new file mode 100644 index 000000000..14fd55913 --- /dev/null +++ b/addons/overheating/Language/ACE_Overheating_localization.pl_pl.conf @@ -0,0 +1,18 @@ +StringTableRuntime { + Ids { + "ACE_Overheating-AddonName" + "ACE_Overheating-CheckBarrelTemperaturAction" + "ACE_Overheating-CoolBarrelInWaterAction" + "ACE_Overheating-Notification_BARREL_TEMPERATURE_RESULT" + "ACE_Overheating-SwapBarrelAction" + "ACE_Overheating_TryClearWeaponJam" + } + Texts { + "Overheating" + "Check barrel temperature" + "Cool barrel in water" + "You find a barrel temperature of %1 °C" + "Swap barrel" + "Try clear weapon jam" + } +} \ No newline at end of file diff --git a/addons/overheating/Language/ACE_Overheating_localization.pl_pl.conf.meta b/addons/overheating/Language/ACE_Overheating_localization.pl_pl.conf.meta new file mode 100644 index 000000000..8ad9a7d84 --- /dev/null +++ b/addons/overheating/Language/ACE_Overheating_localization.pl_pl.conf.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{6E9249A4719731B2}Language/ACE_Overheating_localization.pl_pl.conf" + Configurations { + CONFResourceClass PC { + } + CONFResourceClass XBOX_ONE : PC { + } + CONFResourceClass XBOX_SERIES : PC { + } + CONFResourceClass PS4 : PC { + } + CONFResourceClass PS5 : PC { + } + CONFResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Language/ACE_Overheating_localization.pt_br.conf b/addons/overheating/Language/ACE_Overheating_localization.pt_br.conf new file mode 100644 index 000000000..14fd55913 --- /dev/null +++ b/addons/overheating/Language/ACE_Overheating_localization.pt_br.conf @@ -0,0 +1,18 @@ +StringTableRuntime { + Ids { + "ACE_Overheating-AddonName" + "ACE_Overheating-CheckBarrelTemperaturAction" + "ACE_Overheating-CoolBarrelInWaterAction" + "ACE_Overheating-Notification_BARREL_TEMPERATURE_RESULT" + "ACE_Overheating-SwapBarrelAction" + "ACE_Overheating_TryClearWeaponJam" + } + Texts { + "Overheating" + "Check barrel temperature" + "Cool barrel in water" + "You find a barrel temperature of %1 °C" + "Swap barrel" + "Try clear weapon jam" + } +} \ No newline at end of file diff --git a/addons/overheating/Language/ACE_Overheating_localization.pt_br.conf.meta b/addons/overheating/Language/ACE_Overheating_localization.pt_br.conf.meta new file mode 100644 index 000000000..c54dba3a5 --- /dev/null +++ b/addons/overheating/Language/ACE_Overheating_localization.pt_br.conf.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{BBE5D3684A69FB08}Language/ACE_Overheating_localization.pt_br.conf" + Configurations { + CONFResourceClass PC { + } + CONFResourceClass XBOX_ONE : PC { + } + CONFResourceClass XBOX_SERIES : PC { + } + CONFResourceClass PS4 : PC { + } + CONFResourceClass PS5 : PC { + } + CONFResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Language/ACE_Overheating_localization.ru_ru.conf b/addons/overheating/Language/ACE_Overheating_localization.ru_ru.conf new file mode 100644 index 000000000..14fd55913 --- /dev/null +++ b/addons/overheating/Language/ACE_Overheating_localization.ru_ru.conf @@ -0,0 +1,18 @@ +StringTableRuntime { + Ids { + "ACE_Overheating-AddonName" + "ACE_Overheating-CheckBarrelTemperaturAction" + "ACE_Overheating-CoolBarrelInWaterAction" + "ACE_Overheating-Notification_BARREL_TEMPERATURE_RESULT" + "ACE_Overheating-SwapBarrelAction" + "ACE_Overheating_TryClearWeaponJam" + } + Texts { + "Overheating" + "Check barrel temperature" + "Cool barrel in water" + "You find a barrel temperature of %1 °C" + "Swap barrel" + "Try clear weapon jam" + } +} \ No newline at end of file diff --git a/addons/overheating/Language/ACE_Overheating_localization.ru_ru.conf.meta b/addons/overheating/Language/ACE_Overheating_localization.ru_ru.conf.meta new file mode 100644 index 000000000..bb1e0f1b8 --- /dev/null +++ b/addons/overheating/Language/ACE_Overheating_localization.ru_ru.conf.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{EEA4C7C0D7109E7E}Language/ACE_Overheating_localization.ru_ru.conf" + Configurations { + CONFResourceClass PC { + } + CONFResourceClass XBOX_ONE : PC { + } + CONFResourceClass XBOX_SERIES : PC { + } + CONFResourceClass PS4 : PC { + } + CONFResourceClass PS5 : PC { + } + CONFResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Language/ACE_Overheating_localization.st b/addons/overheating/Language/ACE_Overheating_localization.st new file mode 100644 index 000000000..c07552f45 --- /dev/null +++ b/addons/overheating/Language/ACE_Overheating_localization.st @@ -0,0 +1,63 @@ +StringTable { + ItemClassName "CustomStringTableItem" + Items { + CustomStringTableItem "{65F8ED3623FB5254}" { + Id "ACE_Overheating-AddonName" + Target_en_us "Overheating" + Targer_ko_kr "과열" + Modified 1710813523 + Author "Kexanone" + LastChanged "Psycool" + } + CustomStringTableItem "{65FD7BA74803598A}" { + Id "ACE_Overheating-CheckBarrelTemperaturAction" + Target_en_us "Check barrel temperature" + Target_de_de "Lauftemperatur überprüfen" + Target_zh_cn "檢查槍管溫度" + Targer_ko_kr "총열 온도 확인하기" + Modified 1711151729 + Author "Kexanone" + LastChanged "Psycool" + } + CustomStringTableItem "{65FE31FFE04C16AE}" { + Id "ACE_Overheating-CoolBarrelInWaterAction" + Target_en_us "Cool barrel in water" + Target_de_de "Lauf im Wasser kühlen" + Target_zh_cn "用水冷卻槍管" + Targer_ko_kr "물로 총열 식히기" + Modified 1711200065 + Author "Kexanone" + LastChanged "Psycool" + } + CustomStringTableItem "{65FD7BA71F3FB178}" { + Id "ACE_Overheating-Notification_BARREL_TEMPERATURE_RESULT" + Target_en_us "You find a barrel temperature of %1 °C" + Target_de_de "Die Lauftemperatur liegt bei %1 °C" + Target_zh_cn "你測得槍管溫度為 %1 °C" + Targer_ko_kr "총열 온도가 %1°C임을 알아냈습니다" + Modified 1711152715 + Author "Kexanone" + LastChanged "Psycool" + } + CustomStringTableItem "{65FD7BBCC39DF357}" { + Id "ACE_Overheating-SwapBarrelAction" + Target_en_us "Swap barrel" + Target_de_de "Lauf austauschen" + Target_zh_cn "更換槍管" + Targer_ko_kr "총열 교체" + Modified 1711153953 + Author "Kexanone" + LastChanged "Psycool" + } + CustomStringTableItem "{65F8ED365BE1FB1F}" { + Id "ACE_Overheating_TryClearWeaponJam" + Target_en_us "Try clear weapon jam" + Target_de_de "Versuche Waffenstörung zu beheben" + Target_zh_cn "嘗試排除卡彈" + Targer_ko_kr "무기 격발불량 해결 시도하기" + Modified 1710813896 + Author "Kexanone" + LastChanged "Psycool" + } + } +} diff --git a/addons/overheating/Language/ACE_Overheating_localization.st.meta b/addons/overheating/Language/ACE_Overheating_localization.st.meta new file mode 100644 index 000000000..85b0be3b6 --- /dev/null +++ b/addons/overheating/Language/ACE_Overheating_localization.st.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{BE8A6751C19A49EC}Language/ACE_Overheating_localization.st" + Configurations { + StringTableResourceClass PC { + } + StringTableResourceClass XBOX_ONE : PC { + } + StringTableResourceClass XBOX_SERIES : PC { + } + StringTableResourceClass PS4 : PC { + } + StringTableResourceClass PS5 : PC { + } + StringTableResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Language/ACE_Overheating_localization.uk_ua.conf b/addons/overheating/Language/ACE_Overheating_localization.uk_ua.conf new file mode 100644 index 000000000..14fd55913 --- /dev/null +++ b/addons/overheating/Language/ACE_Overheating_localization.uk_ua.conf @@ -0,0 +1,18 @@ +StringTableRuntime { + Ids { + "ACE_Overheating-AddonName" + "ACE_Overheating-CheckBarrelTemperaturAction" + "ACE_Overheating-CoolBarrelInWaterAction" + "ACE_Overheating-Notification_BARREL_TEMPERATURE_RESULT" + "ACE_Overheating-SwapBarrelAction" + "ACE_Overheating_TryClearWeaponJam" + } + Texts { + "Overheating" + "Check barrel temperature" + "Cool barrel in water" + "You find a barrel temperature of %1 °C" + "Swap barrel" + "Try clear weapon jam" + } +} \ No newline at end of file diff --git a/addons/overheating/Language/ACE_Overheating_localization.uk_ua.conf.meta b/addons/overheating/Language/ACE_Overheating_localization.uk_ua.conf.meta new file mode 100644 index 000000000..3de580366 --- /dev/null +++ b/addons/overheating/Language/ACE_Overheating_localization.uk_ua.conf.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{64FC9236BB3E202B}Language/ACE_Overheating_localization.uk_ua.conf" + Configurations { + CONFResourceClass PC { + } + CONFResourceClass XBOX_ONE : PC { + } + CONFResourceClass XBOX_SERIES : PC { + } + CONFResourceClass PS4 : PC { + } + CONFResourceClass PS5 : PC { + } + CONFResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Language/ACE_Overheating_localization.zh_cn.conf b/addons/overheating/Language/ACE_Overheating_localization.zh_cn.conf new file mode 100644 index 000000000..707b11860 --- /dev/null +++ b/addons/overheating/Language/ACE_Overheating_localization.zh_cn.conf @@ -0,0 +1,18 @@ +StringTableRuntime { + Ids { + "ACE_Overheating-AddonName" + "ACE_Overheating-CheckBarrelTemperaturAction" + "ACE_Overheating-CoolBarrelInWaterAction" + "ACE_Overheating-Notification_BARREL_TEMPERATURE_RESULT" + "ACE_Overheating-SwapBarrelAction" + "ACE_Overheating_TryClearWeaponJam" + } + Texts { + "Overheating" + "檢查槍管溫度" + "用水冷卻槍管" + "你測得槍管溫度為 %1 °C" + "更換槍管" + "嘗試排除卡彈" + } +} \ No newline at end of file diff --git a/addons/overheating/Language/ACE_Overheating_localization.zh_cn.conf.meta b/addons/overheating/Language/ACE_Overheating_localization.zh_cn.conf.meta new file mode 100644 index 000000000..06588ec1a --- /dev/null +++ b/addons/overheating/Language/ACE_Overheating_localization.zh_cn.conf.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{BE4CFC0B829EF036}Language/ACE_Overheating_localization.zh_cn.conf" + Configurations { + CONFResourceClass PC { + } + CONFResourceClass XBOX_ONE : PC { + } + CONFResourceClass XBOX_SERIES : PC { + } + CONFResourceClass PS4 : PC { + } + CONFResourceClass PS5 : PC { + } + CONFResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Prefabs/Weapons/Attachments/Muzzle/ACE_Overheating_HelperAttachment.et b/addons/overheating/Prefabs/Weapons/Attachments/Muzzle/ACE_Overheating_HelperAttachment.et new file mode 100644 index 000000000..1c3601a00 --- /dev/null +++ b/addons/overheating/Prefabs/Weapons/Attachments/Muzzle/ACE_Overheating_HelperAttachment.et @@ -0,0 +1,7 @@ +GenericEntity { + ID "663201D392ACB012" + components { + Hierarchy "{68D8F8184715C9E3}" { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Prefabs/Weapons/Attachments/Muzzle/ACE_Overheating_HelperAttachment.et.meta b/addons/overheating/Prefabs/Weapons/Attachments/Muzzle/ACE_Overheating_HelperAttachment.et.meta new file mode 100644 index 000000000..48c45bfe0 --- /dev/null +++ b/addons/overheating/Prefabs/Weapons/Attachments/Muzzle/ACE_Overheating_HelperAttachment.et.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{D4B8C629F3D4A322}Prefabs/Weapons/Core/Attachment_Base.et" + Configurations { + EntityTemplateResourceClass PC { + } + EntityTemplateResourceClass XBOX_ONE : PC { + } + EntityTemplateResourceClass XBOX_SERIES : PC { + } + EntityTemplateResourceClass PS4 : PC { + } + EntityTemplateResourceClass PS5 : PC { + } + EntityTemplateResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Prefabs/Weapons/Core/Handgun_Base.et b/addons/overheating/Prefabs/Weapons/Core/Handgun_Base.et new file mode 100644 index 000000000..4bcbd5958 --- /dev/null +++ b/addons/overheating/Prefabs/Weapons/Core/Handgun_Base.et @@ -0,0 +1,40 @@ +GenericEntity : "{E1F14DB52DBFBC57}Prefabs/Weapons/Core/Weapon_Base.et" { + ID "0000000000000001" + components { + SCR_WeaponStatsManagerComponent "{663325CC35683F01}" { + } + WeaponComponent "{CFBAA4B706BA66E8}" { + components { + MuzzleComponent "{50F64C45E7271D47}" { + components { + ACE_Overheating_BarrelComponent "{65B9755A1DB21A31}" { + m_fBarrelDiameter 0.01315 + m_cJamChanceTemperatureCurve { + 0.273 0.003 0.58 0.024 0.734 0.06 0.811 0.18 0.888 0.45 + } + m_cMuzzleDispersionFactorTemperatureCurve { + 0.231 0 0.466 0.033 0.722 0.147 1 0.333 + } + } + ACE_Overheating_HelperAttachmentComponent "{663325CC2662FC79}" { + AttachmentSlot InventoryStorageSlot AttachmentSlot { + Prefab "{D4B8C629F3D4A322}Prefabs/Weapons/Attachments/Muzzle/ACE_Overheating_HelperAttachment.et" + } + AttachmentType AttachmentMuzzle "{663325CC780482BB}" { + } + } + } + } + } + } + ActionsManagerComponent "{A29AE67FF4D82B0F}" { + ActionContexts { + UserActionContext "{65FD7BB84A032CC3}" { + Position PointInfo "{65FD7BB846651587}" { + Offset 0 0 0.05 + } + } + } + } + } +} \ No newline at end of file diff --git a/addons/overheating/Prefabs/Weapons/Core/Handgun_Base.et.meta b/addons/overheating/Prefabs/Weapons/Core/Handgun_Base.et.meta new file mode 100644 index 000000000..a73a7b710 --- /dev/null +++ b/addons/overheating/Prefabs/Weapons/Core/Handgun_Base.et.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{EE7028E9DF49763A}Prefabs/Weapons/Core/Handgun_Base.et" + Configurations { + EntityTemplateResourceClass PC { + } + EntityTemplateResourceClass XBOX_ONE : PC { + } + EntityTemplateResourceClass XBOX_SERIES : PC { + } + EntityTemplateResourceClass PS4 : PC { + } + EntityTemplateResourceClass PS5 : PC { + } + EntityTemplateResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Prefabs/Weapons/Core/LongRangeRifle_Base.et b/addons/overheating/Prefabs/Weapons/Core/LongRangeRifle_Base.et new file mode 100644 index 000000000..afd9bf7d1 --- /dev/null +++ b/addons/overheating/Prefabs/Weapons/Core/LongRangeRifle_Base.et @@ -0,0 +1,7 @@ +GenericEntity : "{911D6C8DC7BA2D63}Prefabs/Weapons/Core/Rifle_Base.et" { + ID "5260C45AAAA407F4" + components { + SCR_WeaponStatsManagerComponent "{6292D2E74B58E94A}" { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Prefabs/Weapons/Core/LongRangeRifle_Base.et.meta b/addons/overheating/Prefabs/Weapons/Core/LongRangeRifle_Base.et.meta new file mode 100644 index 000000000..002b0f748 --- /dev/null +++ b/addons/overheating/Prefabs/Weapons/Core/LongRangeRifle_Base.et.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{F9E6107C47C1B088}Prefabs/Weapons/Core/LongRangeRifle_Base.et" + Configurations { + EntityTemplateResourceClass PC { + } + EntityTemplateResourceClass XBOX_ONE : PC { + } + EntityTemplateResourceClass XBOX_SERIES : PC { + } + EntityTemplateResourceClass PS4 : PC { + } + EntityTemplateResourceClass PS5 : PC { + } + EntityTemplateResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Prefabs/Weapons/Core/MachineGun_Base.et b/addons/overheating/Prefabs/Weapons/Core/MachineGun_Base.et new file mode 100644 index 000000000..1d9247029 --- /dev/null +++ b/addons/overheating/Prefabs/Weapons/Core/MachineGun_Base.et @@ -0,0 +1,50 @@ +GenericEntity : "{E1F14DB52DBFBC57}Prefabs/Weapons/Core/Weapon_Base.et" { + ID "0000000000000001" + components { + SCR_WeaponStatsManagerComponent "{663325CDA83F057C}" { + } + WeaponComponent "{CFBAA4B706BA66E8}" { + components { + MuzzleComponent "{50F64C4591CD7AA6}" { + components { + ACE_Overheating_BarrelComponent "{65B9755AADB68C43}" { + m_fBarrelMassFraction 0.32 + m_fBarrelDiameter 0.02275 + m_fHeatingScale 0.508 + m_cJamChanceTemperatureCurve { + 0.273 0.003 0.58 0.024 0.734 0.06 0.811 0.18 0.888 0.45 + } + m_cMuzzleDispersionFactorTemperatureCurve { + 0.231 0 0.466 0.033 0.722 0.147 1 0.333 + } + } + ACE_Overheating_BarrelGlowEffectComponent "{663325CC8AC05C84}" { + } + ACE_Overheating_HelperAttachmentComponent "{663325CD0C04AE29}" { + AttachmentSlot InventoryStorageSlot AttachmentSlot { + Prefab "{D4B8C629F3D4A322}Prefabs/Weapons/Attachments/Muzzle/ACE_Overheating_HelperAttachment.et" + } + AttachmentType AttachmentMuzzle "{663325CD3874732E}" { + } + } + } + } + } + } + ActionsManagerComponent "{A29AE67FF4D82B0F}" { + additionalActions { + ACE_Overheating_SwapBarrelUserAction "{65FD7BBC6DE92331}" { + ParentContextList { + "ace_barrel" + } + UIInfo SCR_ActionUIInfo "{65FD7BBD881AC491}" { + Name "#ACE_Overheating-SwapBarrelAction" + m_sIconName "repair" + } + Duration 15 + "Sort Priority" 10 + } + } + } + } +} \ No newline at end of file diff --git a/addons/overheating/Prefabs/Weapons/Core/MachineGun_Base.et.meta b/addons/overheating/Prefabs/Weapons/Core/MachineGun_Base.et.meta new file mode 100644 index 000000000..53064035c --- /dev/null +++ b/addons/overheating/Prefabs/Weapons/Core/MachineGun_Base.et.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{F54F6C453A8CB478}Prefabs/Weapons/Core/MachineGun_Base.et" + Configurations { + EntityTemplateResourceClass PC { + } + EntityTemplateResourceClass XBOX_ONE : PC { + } + EntityTemplateResourceClass XBOX_SERIES : PC { + } + EntityTemplateResourceClass PS4 : PC { + } + EntityTemplateResourceClass PS5 : PC { + } + EntityTemplateResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Prefabs/Weapons/Core/Rifle_Base.et b/addons/overheating/Prefabs/Weapons/Core/Rifle_Base.et new file mode 100644 index 000000000..c25ac672c --- /dev/null +++ b/addons/overheating/Prefabs/Weapons/Core/Rifle_Base.et @@ -0,0 +1,28 @@ +GenericEntity : "{E1F14DB52DBFBC57}Prefabs/Weapons/Core/Weapon_Base.et" { + ID "CFBAA4B725411E45" + components { + WeaponComponent "{CFBAA4B706BA66E8}" { + components { + MuzzleComponent "{CA6BE4D6B867541F}" { + components { + ACE_Overheating_BarrelComponent "{65B9755B8CB25ED7}" { + m_cJamChanceTemperatureCurve { + 0.273 0.003 0.58 0.024 0.734 0.06 0.811 0.18 0.888 0.45 + } + m_cMuzzleDispersionFactorTemperatureCurve { + 0.231 0 0.466 0.033 0.722 0.147 1 0.333 + } + } + ACE_Overheating_HelperAttachmentComponent "{663325CC5D5AE7BF}" { + AttachmentSlot InventoryStorageSlot AttachmentSlot { + Prefab "{D4B8C629F3D4A322}Prefabs/Weapons/Attachments/Muzzle/ACE_Overheating_HelperAttachment.et" + } + AttachmentType AttachmentMuzzle "{663325CC4B126A7F}" { + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/addons/overheating/Prefabs/Weapons/Core/Rifle_Base.et.meta b/addons/overheating/Prefabs/Weapons/Core/Rifle_Base.et.meta new file mode 100644 index 000000000..30e312d59 --- /dev/null +++ b/addons/overheating/Prefabs/Weapons/Core/Rifle_Base.et.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{911D6C8DC7BA2D63}Prefabs/Weapons/Core/Rifle_Base.et" + Configurations { + EntityTemplateResourceClass PC { + } + EntityTemplateResourceClass XBOX_ONE : PC { + } + EntityTemplateResourceClass XBOX_SERIES : PC { + } + EntityTemplateResourceClass PS4 : PC { + } + EntityTemplateResourceClass PS5 : PC { + } + EntityTemplateResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Prefabs/Weapons/Core/Weapon_Base.et b/addons/overheating/Prefabs/Weapons/Core/Weapon_Base.et new file mode 100644 index 000000000..7918d3a98 --- /dev/null +++ b/addons/overheating/Prefabs/Weapons/Core/Weapon_Base.et @@ -0,0 +1,46 @@ +GenericEntity { + ID "CFBAA4B725411E45" + components { + ActionsManagerComponent "{A29AE67FF4D82B0F}" { + ActionContexts { + UserActionContext "{65FD7BB84A032CC3}" { + UIInfo SCR_ActionContextUIInfo "{65FD7BB9D1A1D0C8}" : "{970293F8561231D4}Configs/UI/NearbyInteractionContext/NearbyContextWeapons.conf" { + } + ContextName "ace_barrel" + Position PointInfo "{65FD7BB846651587}" { + PivotID "barrel_chamber" + Offset 0 0 0.1 + } + Radius 0.1 + } + } + additionalActions { + ACE_Overheating_CheckWeaponUserAction "{65FD7BB8D8AC4036}" { + ParentContextList { + "ace_barrel" + } + UIInfo SCR_ActionUIInfo "{65FD7BB8D62B3C0A}" { + Name "#ACE_Overheating-CheckBarrelTemperaturAction" + m_sIconName "search" + } + Duration 0.3 + m_eNotificationType ACE_OVERHEATING_BARREL_TEMPERATURE_RESULT + } + ACE_Overheating_CoolBarrelInWaterUserAction "{65FE31F84DF090BD}" { + ParentContextList { + "ace_barrel" + } + UIInfo SCR_ActionUIInfo "{65FE31F841A31425}" { + Name "#ACE_Overheating-CoolBarrelInWaterAction" + m_sInteractionIcon "{B9199157B90D6216}UI/Textures/InventoryIcons/Medical/Medical-icons.imageset" + m_sInteractionGlowIcon "{E4B841462701A4D7}UI/Textures/InventoryIcons/Medical/Medical-icons-glow.imageset" + m_sIconName "Blood_UI" + } + Duration 1 + PerformPerFrame 1 + "Sort Priority" 5 + } + } + } + } +} \ No newline at end of file diff --git a/addons/overheating/Prefabs/Weapons/Core/Weapon_Base.et.meta b/addons/overheating/Prefabs/Weapons/Core/Weapon_Base.et.meta new file mode 100644 index 000000000..9f8d4f3bc --- /dev/null +++ b/addons/overheating/Prefabs/Weapons/Core/Weapon_Base.et.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{E1F14DB52DBFBC57}Prefabs/Weapons/Core/Weapon_Base.et" + Configurations { + EntityTemplateResourceClass PC { + } + EntityTemplateResourceClass XBOX_ONE : PC { + } + EntityTemplateResourceClass XBOX_SERIES : PC { + } + EntityTemplateResourceClass PS4 : PC { + } + EntityTemplateResourceClass PS5 : PC { + } + EntityTemplateResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Prefabs/Weapons/Handguns/M9/Handgun_M9_base.et b/addons/overheating/Prefabs/Weapons/Handguns/M9/Handgun_M9_base.et new file mode 100644 index 000000000..15eb8a719 --- /dev/null +++ b/addons/overheating/Prefabs/Weapons/Handguns/M9/Handgun_M9_base.et @@ -0,0 +1,16 @@ +GenericEntity : "{EE7028E9DF49763A}Prefabs/Weapons/Core/Handgun_Base.et" { + ID "CFBAA4B725411E45" + components { + WeaponComponent "{CFBAA4B706BA66E8}" { + components { + MuzzleComponent "{50F64C45E7271D47}" { + components { + ACE_Overheating_BarrelComponent "{65B9755A1DB21A31}" { + m_fBarrelDiameter 0.01371 + } + } + } + } + } + } +} \ No newline at end of file diff --git a/addons/overheating/Prefabs/Weapons/Handguns/M9/Handgun_M9_base.et.meta b/addons/overheating/Prefabs/Weapons/Handguns/M9/Handgun_M9_base.et.meta new file mode 100644 index 000000000..2e4aa4368 --- /dev/null +++ b/addons/overheating/Prefabs/Weapons/Handguns/M9/Handgun_M9_base.et.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{809488C4984AC087}Prefabs/Weapons/Handguns/M9/Handgun_M9_base.et" + Configurations { + EntityTemplateResourceClass PC { + } + EntityTemplateResourceClass XBOX_ONE : PC { + } + EntityTemplateResourceClass XBOX_SERIES : PC { + } + EntityTemplateResourceClass PS4 : PC { + } + EntityTemplateResourceClass PS5 : PC { + } + EntityTemplateResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Prefabs/Weapons/MachineGuns/M249/MG_M249_base.et b/addons/overheating/Prefabs/Weapons/MachineGuns/M249/MG_M249_base.et new file mode 100644 index 000000000..e858a3255 --- /dev/null +++ b/addons/overheating/Prefabs/Weapons/MachineGuns/M249/MG_M249_base.et @@ -0,0 +1,18 @@ +GenericEntity : "{F54F6C453A8CB478}Prefabs/Weapons/Core/MachineGun_Base.et" { + ID "CFBAA4B725411E45" + components { + WeaponComponent "{CFBAA4B706BA66E8}" { + components { + MuzzleComponent "{50F64C4591CD7AA6}" { + components { + ACE_Overheating_BarrelComponent "{65B9755AADB68C43}" { + m_fBarrelMassFraction 0.461 + m_fBarrelDiameter 0.01872 + m_fHeatingScale 1 + } + } + } + } + } + } +} \ No newline at end of file diff --git a/addons/overheating/Prefabs/Weapons/MachineGuns/M249/MG_M249_base.et.meta b/addons/overheating/Prefabs/Weapons/MachineGuns/M249/MG_M249_base.et.meta new file mode 100644 index 000000000..9eed8371e --- /dev/null +++ b/addons/overheating/Prefabs/Weapons/MachineGuns/M249/MG_M249_base.et.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{599A1E833BEF3A43}Prefabs/Weapons/MachineGuns/M249/MG_M249_base.et" + Configurations { + EntityTemplateResourceClass PC { + } + EntityTemplateResourceClass XBOX_ONE : PC { + } + EntityTemplateResourceClass XBOX_SERIES : PC { + } + EntityTemplateResourceClass PS4 : PC { + } + EntityTemplateResourceClass PS5 : PC { + } + EntityTemplateResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Prefabs/Weapons/MachineGuns/M60/MG_M60_base.et b/addons/overheating/Prefabs/Weapons/MachineGuns/M60/MG_M60_base.et new file mode 100644 index 000000000..9b6a31214 --- /dev/null +++ b/addons/overheating/Prefabs/Weapons/MachineGuns/M60/MG_M60_base.et @@ -0,0 +1,18 @@ +GenericEntity : "{F54F6C453A8CB478}Prefabs/Weapons/Core/MachineGun_Base.et" { + ID "CFBAA4B725411E45" + components { + WeaponComponent "{CFBAA4B706BA66E8}" { + components { + MuzzleComponent "{50F64C4591CD7AA6}" { + components { + ACE_Overheating_BarrelComponent "{65B9755AADB68C43}" { + m_fBarrelMassFraction 0.36 + m_fBarrelDiameter 0.01828 + m_fHeatingScale 0.731 + } + } + } + } + } + } +} \ No newline at end of file diff --git a/addons/overheating/Prefabs/Weapons/MachineGuns/M60/MG_M60_base.et.meta b/addons/overheating/Prefabs/Weapons/MachineGuns/M60/MG_M60_base.et.meta new file mode 100644 index 000000000..004488d3d --- /dev/null +++ b/addons/overheating/Prefabs/Weapons/MachineGuns/M60/MG_M60_base.et.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{6E42C85D9FC0CA5D}Prefabs/Weapons/MachineGuns/M60/MG_M60_base.et" + Configurations { + EntityTemplateResourceClass PC { + } + EntityTemplateResourceClass XBOX_ONE : PC { + } + EntityTemplateResourceClass XBOX_SERIES : PC { + } + EntityTemplateResourceClass PS4 : PC { + } + EntityTemplateResourceClass PS5 : PC { + } + EntityTemplateResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Prefabs/Weapons/MachineGuns/RPK74/MG_RPK74_base.et b/addons/overheating/Prefabs/Weapons/MachineGuns/RPK74/MG_RPK74_base.et new file mode 100644 index 000000000..7fc19222b --- /dev/null +++ b/addons/overheating/Prefabs/Weapons/MachineGuns/RPK74/MG_RPK74_base.et @@ -0,0 +1,18 @@ +GenericEntity : "{F54F6C453A8CB478}Prefabs/Weapons/Core/MachineGun_Base.et" { + ID "CFBAA4B725411E45" + components { + WeaponComponent "{CFBAA4B706BA66E8}" { + components { + MuzzleComponent "{50F64C4591CD7AA6}" { + components { + ACE_Overheating_BarrelComponent "{65B9755AADB68C43}" { + m_fBarrelMassFraction 0.55 + m_fBarrelDiameter 0.01476 + m_fHeatingScale 1 + } + } + } + } + } + } +} \ No newline at end of file diff --git a/addons/overheating/Prefabs/Weapons/MachineGuns/RPK74/MG_RPK74_base.et.meta b/addons/overheating/Prefabs/Weapons/MachineGuns/RPK74/MG_RPK74_base.et.meta new file mode 100644 index 000000000..ba9d881d4 --- /dev/null +++ b/addons/overheating/Prefabs/Weapons/MachineGuns/RPK74/MG_RPK74_base.et.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{3BFBE9145E9C40B9}Prefabs/Weapons/MachineGuns/RPK74/MG_RPK74_base.et" + Configurations { + EntityTemplateResourceClass PC { + } + EntityTemplateResourceClass XBOX_ONE : PC { + } + EntityTemplateResourceClass XBOX_SERIES : PC { + } + EntityTemplateResourceClass PS4 : PC { + } + EntityTemplateResourceClass PS5 : PC { + } + EntityTemplateResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Prefabs/Weapons/Rifles/M14/Rifle_M21_base.et b/addons/overheating/Prefabs/Weapons/Rifles/M14/Rifle_M21_base.et new file mode 100644 index 000000000..28355cec7 --- /dev/null +++ b/addons/overheating/Prefabs/Weapons/Rifles/M14/Rifle_M21_base.et @@ -0,0 +1,16 @@ +GenericEntity : "{F9E6107C47C1B088}Prefabs/Weapons/Core/LongRangeRifle_Base.et" { + ID "5254ACCA959048B9" + components { + WeaponComponent "{CFBAA4B706BA66E8}" { + components { + MuzzleComponent "{CA6BE4D6B867541F}" { + components { + ACE_Overheating_BarrelComponent "{65B9755B8CB25ED7}" { + m_fBarrelDiameter 0.01442 + } + } + } + } + } + } +} \ No newline at end of file diff --git a/addons/overheating/Prefabs/Weapons/Rifles/M14/Rifle_M21_base.et.meta b/addons/overheating/Prefabs/Weapons/Rifles/M14/Rifle_M21_base.et.meta new file mode 100644 index 000000000..697d45f15 --- /dev/null +++ b/addons/overheating/Prefabs/Weapons/Rifles/M14/Rifle_M21_base.et.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{3FB5275A6505B323}Prefabs/Weapons/Rifles/M14/Rifle_M21_base.et" + Configurations { + EntityTemplateResourceClass PC { + } + EntityTemplateResourceClass XBOX_ONE : PC { + } + EntityTemplateResourceClass XBOX_SERIES : PC { + } + EntityTemplateResourceClass PS4 : PC { + } + EntityTemplateResourceClass PS5 : PC { + } + EntityTemplateResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Prefabs/Weapons/Rifles/M16/Rifle_M16A2_base.et b/addons/overheating/Prefabs/Weapons/Rifles/M16/Rifle_M16A2_base.et new file mode 100644 index 000000000..9d3501d4e --- /dev/null +++ b/addons/overheating/Prefabs/Weapons/Rifles/M16/Rifle_M16A2_base.et @@ -0,0 +1,16 @@ +GenericEntity : "{911D6C8DC7BA2D63}Prefabs/Weapons/Core/Rifle_Base.et" { + ID "CFBAA4B725411E45" + components { + WeaponComponent "{CFBAA4B706BA66E8}" { + components { + MuzzleComponent "{CA6BE4D6B867541F}" { + components { + ACE_Overheating_BarrelComponent "{65B9755B8CB25ED7}" { + m_fBarrelDiameter 0.01799 + } + } + } + } + } + } +} \ No newline at end of file diff --git a/addons/overheating/Prefabs/Weapons/Rifles/M16/Rifle_M16A2_base.et.meta b/addons/overheating/Prefabs/Weapons/Rifles/M16/Rifle_M16A2_base.et.meta new file mode 100644 index 000000000..936f1916c --- /dev/null +++ b/addons/overheating/Prefabs/Weapons/Rifles/M16/Rifle_M16A2_base.et.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{C63227C0E70EA62E}Prefabs/Weapons/Rifles/M16/Rifle_M16A2_base.et" + Configurations { + EntityTemplateResourceClass PC { + } + EntityTemplateResourceClass XBOX_ONE : PC { + } + EntityTemplateResourceClass XBOX_SERIES : PC { + } + EntityTemplateResourceClass PS4 : PC { + } + EntityTemplateResourceClass PS5 : PC { + } + EntityTemplateResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Prefabs/Weapons/Rifles/SVD/Rifle_SVD_base.et b/addons/overheating/Prefabs/Weapons/Rifles/SVD/Rifle_SVD_base.et new file mode 100644 index 000000000..986e9e9ba --- /dev/null +++ b/addons/overheating/Prefabs/Weapons/Rifles/SVD/Rifle_SVD_base.et @@ -0,0 +1,16 @@ +GenericEntity : "{F9E6107C47C1B088}Prefabs/Weapons/Core/LongRangeRifle_Base.et" { + ID "525494E72B1E90FD" + components { + WeaponComponent "{CFBAA4B706BA66E8}" { + components { + MuzzleComponent "{CA6BE4D6B867541F}" { + components { + ACE_Overheating_BarrelComponent "{65B9755B8CB25ED7}" { + m_fBarrelDiameter 0.01599 + } + } + } + } + } + } +} \ No newline at end of file diff --git a/addons/overheating/Prefabs/Weapons/Rifles/SVD/Rifle_SVD_base.et.meta b/addons/overheating/Prefabs/Weapons/Rifles/SVD/Rifle_SVD_base.et.meta new file mode 100644 index 000000000..565818581 --- /dev/null +++ b/addons/overheating/Prefabs/Weapons/Rifles/SVD/Rifle_SVD_base.et.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{A3E183EB5A2F3A38}Prefabs/Weapons/Rifles/SVD/Rifle_SVD_base.et" + Configurations { + EntityTemplateResourceClass PC { + } + EntityTemplateResourceClass XBOX_ONE : PC { + } + EntityTemplateResourceClass XBOX_SERIES : PC { + } + EntityTemplateResourceClass PS4 : PC { + } + EntityTemplateResourceClass PS5 : PC { + } + EntityTemplateResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Prefabs/World/Game/UISoundEntity.et b/addons/overheating/Prefabs/World/Game/UISoundEntity.et new file mode 100644 index 000000000..9c9b929bf --- /dev/null +++ b/addons/overheating/Prefabs/World/Game/UISoundEntity.et @@ -0,0 +1,10 @@ +SCR_UISoundEntity { + ID "52EAE81F331179B8" + components { + SimpleSoundComponent "{52EAE81FCD04D30C}" { + Filenames + { + "{1ABE61EA39D00553}Sounds/Weapons/Machineguns/ACE_Overheating_BarrelActions.acp" + } + } + } +} \ No newline at end of file diff --git a/addons/overheating/Prefabs/World/Game/UISoundEntity.et.meta b/addons/overheating/Prefabs/World/Game/UISoundEntity.et.meta new file mode 100644 index 000000000..cbf628b8f --- /dev/null +++ b/addons/overheating/Prefabs/World/Game/UISoundEntity.et.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{292486B7CA9C67BE}Prefabs/World/Game/UISoundEntity.et" + Configurations { + EntityTemplateResourceClass PC { + } + EntityTemplateResourceClass XBOX_ONE : PC { + } + EntityTemplateResourceClass XBOX_SERIES : PC { + } + EntityTemplateResourceClass PS4 : PC { + } + EntityTemplateResourceClass PS5 : PC { + } + EntityTemplateResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Sounds/Weapons/Machineguns/ACE_Overheating_BarrelActions.acp b/addons/overheating/Sounds/Weapons/Machineguns/ACE_Overheating_BarrelActions.acp new file mode 100644 index 000000000..c1fd70cc1 --- /dev/null +++ b/addons/overheating/Sounds/Weapons/Machineguns/ACE_Overheating_BarrelActions.acp @@ -0,0 +1,101 @@ +AudioClass { + sounds { + SoundClass "4105" { + id 4105 + name "ACE_OVERHEATING_SOUND_SWAP_BARREL" + version 5 + tl -274.261 -188.87 + ins { + ConnectionsClass "con:64" { + id 64 + links { + ConnectionClass "2052:65" { + id 2052 + port 65 + } + } + } + } + outState 5131 + outStatePort 26631 + eventNoRepeatTimeMSec 1000 + } + SoundClass "7177" { + id 7177 + name "ACE_OVERHEATING_SOUND_COOL_BARREL" + version 5 + tl -281.13 -57.935 + ins { + ConnectionsClass "con:64" { + id 64 + links { + ConnectionClass "6148:65" { + id 6148 + port 65 + } + } + } + } + outState 5131 + outStatePort 26631 + eventNoRepeatTimeMSec 1000 + } + } + mixers { + MixerClass "5131" { + id 5131 + name "OutputState" + version 4 + tl -55 -188 + res "{AF08E302CF8BA2E6}Sounds/FinalMix_UI_Music.afm" + ins { + ConnectionsClass "con:26631" { + id 26631 + links { + ConnectionClass "4105:65" { + id 4105 + port 65 + } + ConnectionClass "7177:65" { + id 7177 + port 65 + } + } + } + } + pi { + 2 0 + } + inputs { + "Music" "UI" + } + } + } + banks_local { + BankLocalClass "2052" { + id 2052 + name "BarrelSwap" + version 7 + tl -497 -187 + Volume -8 + Samples { + AudioBankSampleClass "ACE_Overheating_BarrelSwap.wav" { + Filename "{AD75581D6865B7B9}Sounds/Weapons/Machineguns/Samples/ACE_Overheating_BarrelSwap.wav" + } + } + } + BankLocalClass "6148" { + id 6148 + name "BarrelCooling" + version 7 + tl -502.87 -55.065 + Volume -10 + Samples { + AudioBankSampleClass "ACE_Overheating_BarrelSwap.wav" { + Filename "{6C43E01394A6190E}Sounds/Weapons/Machineguns/Samples/ACE_Overheating_BarrelCooling.wav" + } + } + } + } + version 2 +} \ No newline at end of file diff --git a/addons/overheating/Sounds/Weapons/Machineguns/ACE_Overheating_BarrelActions.acp.meta b/addons/overheating/Sounds/Weapons/Machineguns/ACE_Overheating_BarrelActions.acp.meta new file mode 100644 index 000000000..64d906d23 --- /dev/null +++ b/addons/overheating/Sounds/Weapons/Machineguns/ACE_Overheating_BarrelActions.acp.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{1ABE61EA39D00553}Sounds/Weapons/Machineguns/ACE_Overheating_BarrelActions.acp" + Configurations { + AudioProjectResourceClass PC { + } + AudioProjectResourceClass XBOX_ONE : PC { + } + AudioProjectResourceClass XBOX_SERIES : PC { + } + AudioProjectResourceClass PS4 : PC { + } + AudioProjectResourceClass PS5 : PC { + } + AudioProjectResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Sounds/Weapons/Machineguns/Samples/ACE_Overheating_BarrelCooling.wav b/addons/overheating/Sounds/Weapons/Machineguns/Samples/ACE_Overheating_BarrelCooling.wav new file mode 100644 index 000000000..ce7de15ea Binary files /dev/null and b/addons/overheating/Sounds/Weapons/Machineguns/Samples/ACE_Overheating_BarrelCooling.wav differ diff --git a/addons/overheating/Sounds/Weapons/Machineguns/Samples/ACE_Overheating_BarrelCooling.wav.meta b/addons/overheating/Sounds/Weapons/Machineguns/Samples/ACE_Overheating_BarrelCooling.wav.meta new file mode 100644 index 000000000..4c26c0a3e --- /dev/null +++ b/addons/overheating/Sounds/Weapons/Machineguns/Samples/ACE_Overheating_BarrelCooling.wav.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{6C43E01394A6190E}Sounds/Weapons/Machineguns/Samples/water_on_hot_metal_quench_sizzle_smooth_tail_compact.wav" + Configurations { + WAVResourceClass PC : "{F72B05D02F3F135E}Configs/System/ResourceTypes/PC/Sound.conf" { + } + WAVResourceClass XBOX_ONE : "{A0776163143143AC}Configs/System/ResourceTypes/XBOX_ONE/Sound.conf" { + } + WAVResourceClass XBOX_SERIES : "{382981CA1FC1C8DB}Configs/System/ResourceTypes/XBOX_SERIES/Sound.conf" { + } + WAVResourceClass PS4 : "{89EB939911B4C093}Configs/System/ResourceTypes/PS4/Sound.conf" { + } + WAVResourceClass PS5 : "{A584A3B556D4A981}Configs/System/ResourceTypes/PS5/Sound.conf" { + } + WAVResourceClass HEADLESS : "{D63592CA950AF3A8}Configs/System/ResourceTypes/HEADLESS/Sound.conf" { + } + } +} \ No newline at end of file diff --git a/addons/overheating/Sounds/Weapons/Machineguns/Samples/ACE_Overheating_BarrelSwap.wav b/addons/overheating/Sounds/Weapons/Machineguns/Samples/ACE_Overheating_BarrelSwap.wav new file mode 100644 index 000000000..dc303bdbb Binary files /dev/null and b/addons/overheating/Sounds/Weapons/Machineguns/Samples/ACE_Overheating_BarrelSwap.wav differ diff --git a/addons/overheating/Sounds/Weapons/Machineguns/Samples/ACE_Overheating_BarrelSwap.wav.meta b/addons/overheating/Sounds/Weapons/Machineguns/Samples/ACE_Overheating_BarrelSwap.wav.meta new file mode 100644 index 000000000..071ce276c --- /dev/null +++ b/addons/overheating/Sounds/Weapons/Machineguns/Samples/ACE_Overheating_BarrelSwap.wav.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{AD75581D6865B7B9}Sounds/Weapons/Machineguns/Samples/ACE_Overheating_BarrelSwap.wav" + Configurations { + WAVResourceClass PC : "{F72B05D02F3F135E}Configs/System/ResourceTypes/PC/Sound.conf" { + } + WAVResourceClass XBOX_ONE : "{A0776163143143AC}Configs/System/ResourceTypes/XBOX_ONE/Sound.conf" { + } + WAVResourceClass XBOX_SERIES : "{382981CA1FC1C8DB}Configs/System/ResourceTypes/XBOX_SERIES/Sound.conf" { + } + WAVResourceClass PS4 : "{89EB939911B4C093}Configs/System/ResourceTypes/PS4/Sound.conf" { + } + WAVResourceClass PS5 : "{A584A3B556D4A981}Configs/System/ResourceTypes/PS5/Sound.conf" { + } + WAVResourceClass HEADLESS : "{D63592CA950AF3A8}Configs/System/ResourceTypes/HEADLESS/Sound.conf" { + } + } +} \ No newline at end of file diff --git a/addons/overheating/addon.gproj b/addons/overheating/addon.gproj new file mode 100644 index 000000000..3cbb1bf53 --- /dev/null +++ b/addons/overheating/addon.gproj @@ -0,0 +1,83 @@ +GameProject { + ID "ACE_Overheating" + GUID "68FD5E6A9F921F30" + TITLE "ACE Overheating" + Dependencies { + "65AD7D0D9941A380" "58D0FB3206B6F859" + } + Configurations { + GameProjectConfig PC { + WidgetManagerSettings WidgetManagerSettings "{AC4BE58770485E02}" { + StringTables { + StringTableDefinition "{65F8ED3634DB0237}" { + StringTableSource "{BE8A6751C19A49EC}Language/ACE_Overheating_localization.st" + Languages { + LanguageDefinition "{65F8ED362AAB8E4D}" { + Code "cs_cz" + StringTableRuntime "{F730DD92BED7819F}Language/ACE_Overheating_localization.cs_cz.conf" + } + LanguageDefinition "{65F8ED362AAB8DF3}" { + Code "de_de" + StringTableRuntime "{224EC7A1AD7490BF}Language/ACE_Overheating_localization.de_de.conf" + } + LanguageDefinition "{65F8ED362AAB8DE2}" { + Code "en_us" + StringTableRuntime "{7CBE4DEAC78795BE}Language/ACE_Overheating_localization.en_us.conf" + } + LanguageDefinition "{65F8ED362AAB8DD3}" { + Code "es_es" + StringTableRuntime "{B9F200632985FEA1}Language/ACE_Overheating_localization.es_es.conf" + } + LanguageDefinition "{65F8ED362AAB8DC2}" { + Code "fr_fr" + StringTableRuntime "{025AF554CF061DA3}Language/ACE_Overheating_localization.fr_fr.conf" + } + LanguageDefinition "{65F8ED362AAB8D37}" { + Code "it_it" + StringTableRuntime "{82467A6062249E5A}Language/ACE_Overheating_localization.it_it.conf" + } + LanguageDefinition "{65F8ED362AAB8D21}" { + Code "ja_jp" + StringTableRuntime "{925DC7F25C55AEF1}Language/ACE_Overheating_localization.ja_jp.conf" + } + LanguageDefinition "{65F8ED362AAB8D10}" { + Code "ko_kr" + StringTableRuntime "{32E3EF5ECF78ADCE}Language/ACE_Overheating_localization.ko_kr.conf" + } + LanguageDefinition "{65F8ED362AAB8D01}" { + Code "pl_pl" + StringTableRuntime "{6E9249A4719731B2}Language/ACE_Overheating_localization.pl_pl.conf" + } + LanguageDefinition "{65F8ED362AAB8D0D}" { + Code "pt_br" + StringTableRuntime "{BBE5D3684A69FB08}Language/ACE_Overheating_localization.pt_br.conf" + } + LanguageDefinition "{65F8ED362AAB8CDF}" { + Code "ru_ru" + StringTableRuntime "{EEA4C7C0D7109E7E}Language/ACE_Overheating_localization.ru_ru.conf" + } + LanguageDefinition "{65F8ED362AAB8C32}" { + Code "uk_ua" + StringTableRuntime "{64FC9236BB3E202B}Language/ACE_Overheating_localization.uk_ua.conf" + } + LanguageDefinition "{65F8ED362AAB8C3C}" { + Code "zh_cn" + StringTableRuntime "{BE4CFC0B829EF036}Language/ACE_Overheating_localization.zh_cn.conf" + } + } + } + } + } + } + GameProjectConfig XBOX_ONE { + } + GameProjectConfig XBOX_SERIES { + } + GameProjectConfig PS4 { + } + GameProjectConfig PS5 { + } + GameProjectConfig HEADLESS { + } + } +} diff --git a/addons/overheating/dev.gproj b/addons/overheating/dev.gproj new file mode 100644 index 000000000..958a50519 --- /dev/null +++ b/addons/overheating/dev.gproj @@ -0,0 +1,83 @@ +GameProject { + ID "ACE_Overheating_Dev" + GUID "65B8EA178A3E94E3" + TITLE "ACE Overheating Dev" + Dependencies { + "65AD7D0D9941A380" "58D0FB3206B6F859" + } + Configurations { + GameProjectConfig PC { + WidgetManagerSettings WidgetManagerSettings "{AC4BE58770485E02}" { + StringTables { + StringTableDefinition "{65F8ED3634DB0237}" { + StringTableSource "{BE8A6751C19A49EC}Language/ACE_Overheating_localization.st" + Languages { + LanguageDefinition "{65F8ED362AAB8E4D}" { + Code "cs_cz" + StringTableRuntime "{F730DD92BED7819F}Language/ACE_Overheating_localization.cs_cz.conf" + } + LanguageDefinition "{65F8ED362AAB8DF3}" { + Code "de_de" + StringTableRuntime "{224EC7A1AD7490BF}Language/ACE_Overheating_localization.de_de.conf" + } + LanguageDefinition "{65F8ED362AAB8DE2}" { + Code "en_us" + StringTableRuntime "{7CBE4DEAC78795BE}Language/ACE_Overheating_localization.en_us.conf" + } + LanguageDefinition "{65F8ED362AAB8DD3}" { + Code "es_es" + StringTableRuntime "{B9F200632985FEA1}Language/ACE_Overheating_localization.es_es.conf" + } + LanguageDefinition "{65F8ED362AAB8DC2}" { + Code "fr_fr" + StringTableRuntime "{025AF554CF061DA3}Language/ACE_Overheating_localization.fr_fr.conf" + } + LanguageDefinition "{65F8ED362AAB8D37}" { + Code "it_it" + StringTableRuntime "{82467A6062249E5A}Language/ACE_Overheating_localization.it_it.conf" + } + LanguageDefinition "{65F8ED362AAB8D21}" { + Code "ja_jp" + StringTableRuntime "{925DC7F25C55AEF1}Language/ACE_Overheating_localization.ja_jp.conf" + } + LanguageDefinition "{65F8ED362AAB8D10}" { + Code "ko_kr" + StringTableRuntime "{32E3EF5ECF78ADCE}Language/ACE_Overheating_localization.ko_kr.conf" + } + LanguageDefinition "{65F8ED362AAB8D01}" { + Code "pl_pl" + StringTableRuntime "{6E9249A4719731B2}Language/ACE_Overheating_localization.pl_pl.conf" + } + LanguageDefinition "{65F8ED362AAB8D0D}" { + Code "pt_br" + StringTableRuntime "{BBE5D3684A69FB08}Language/ACE_Overheating_localization.pt_br.conf" + } + LanguageDefinition "{65F8ED362AAB8CDF}" { + Code "ru_ru" + StringTableRuntime "{EEA4C7C0D7109E7E}Language/ACE_Overheating_localization.ru_ru.conf" + } + LanguageDefinition "{65F8ED362AAB8C32}" { + Code "uk_ua" + StringTableRuntime "{64FC9236BB3E202B}Language/ACE_Overheating_localization.uk_ua.conf" + } + LanguageDefinition "{65F8ED362AAB8C3C}" { + Code "zh_cn" + StringTableRuntime "{BE4CFC0B829EF036}Language/ACE_Overheating_localization.zh_cn.conf" + } + } + } + } + } + } + GameProjectConfig XBOX_ONE { + } + GameProjectConfig XBOX_SERIES { + } + GameProjectConfig PS4 { + } + GameProjectConfig PS5 { + } + GameProjectConfig HEADLESS { + } + } +} \ No newline at end of file diff --git a/addons/overheating/license.txt b/addons/overheating/license.txt new file mode 100644 index 000000000..6ebf24cf1 --- /dev/null +++ b/addons/overheating/license.txt @@ -0,0 +1,18 @@ +ACE Anvil - An experimental realism mod for Arma Reforger +Copyright (C) 2024 acemod + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +When publishing a derivative of this product you may not use a name that +might create the impression that your version is an official release. + +A full copy of this license can be found at the following address: +https://github.com/acemod/ACE-Anvil/blob/master/LICENSE. diff --git a/addons/overheating/scripts/Game/ACE_Overheating/Character/SCR_CharacterControllerComponent.c b/addons/overheating/scripts/Game/ACE_Overheating/Character/SCR_CharacterControllerComponent.c new file mode 100644 index 000000000..288f06327 --- /dev/null +++ b/addons/overheating/scripts/Game/ACE_Overheating/Character/SCR_CharacterControllerComponent.c @@ -0,0 +1,64 @@ +//------------------------------------------------------------------------------------------------ +modded class SCR_CharacterControllerComponent : CharacterControllerComponent +{ + //------------------------------------------------------------------------------------------------ + protected override void OnControlledByPlayer(IEntity owner, bool controlled) + { + super.OnControlledByPlayer(owner, controlled); + + if (controlled && owner == SCR_PlayerController.GetLocalControlledEntity()) + GetGame().GetInputManager().AddActionListener("ACE_Overheating_ClearJam", EActionTrigger.DOWN, ACE_Overheating_ClearJamAction); + else + GetGame().GetInputManager().RemoveActionListener("ACE_Overheating_ClearJam", EActionTrigger.DOWN, ACE_Overheating_ClearJamAction); + } + + //------------------------------------------------------------------------------------------------ + protected void ACE_Overheating_ClearJamAction(float value = 0.0, EActionTrigger trigger = 0) + { + ChimeraCharacter ownerChar = ChimeraCharacter.Cast(GetOwner()); + if (!ownerChar) + return; + + BaseWeaponManagerComponent weaponManager = ownerChar.GetWeaponManager(); + if (!weaponManager) + return; + + BaseWeaponComponent weapon = weaponManager.GetCurrentWeapon(); + if (!weapon) + return; + + ACE_Overheating_TryClearJam(weapon); + } + + //------------------------------------------------------------------------------------------------ + void ACE_Overheating_TryClearJam(notnull BaseWeaponComponent weapon, BaseMuzzleComponent muzzle = null) + { + ACE_Overheating_BarrelComponent barrel; + if (muzzle) + barrel = ACE_Overheating_BarrelComponent.FromMuzzle(muzzle); + else + barrel = ACE_Overheating_BarrelComponent.FromWeapon(weapon); + + ACE_Overheating_WeaponAnimContext context = new ACE_Overheating_WeaponAnimContext(ChimeraCharacter.Cast(GetOwner()), weapon, barrel); + if (context.IsReloading()) + return; + + ACE_FrameJobSystem system = ACE_FrameJobSystem.GetInstance(); + if (!system) + return; + + ACE_Overheating_WeaponAnimMachine stateMachine = new ACE_Overheating_WeaponAnimMachine(); + stateMachine.SetContext(context); + stateMachine.AddState(new ACE_Overheating_RemoveMagState(ACE_Overheating_EWeaponAnimStateID.REMOVE_MAGAZINE)); + stateMachine.AddState(new ACE_Overheating_RackBoltState(ACE_Overheating_EWeaponAnimStateID.RACK_BOLT)); + stateMachine.AddTransition(new ACE_Overheating_RemoveMagCompleted(ACE_Overheating_EWeaponAnimStateID.REMOVE_MAGAZINE, ACE_Overheating_EWeaponAnimStateID.RACK_BOLT)); + stateMachine.AddTransition(new ACE_Overheating_RemoveMagFailed(ACE_Overheating_EWeaponAnimStateID.REMOVE_MAGAZINE, ACE_Overheating_EWeaponAnimStateID.STOP)); + stateMachine.AddTransition(new ACE_Overheating_RackBoltCompleted(ACE_Overheating_EWeaponAnimStateID.RACK_BOLT, ACE_Overheating_EWeaponAnimStateID.STOP)); + system.Register(stateMachine, ESystemPoint.PostFixedFrame); + } +} + +//------------------------------------------------------------------------------------------------ +class ACE_Overheating_WeaponAnimMachine : ACE_FSM_Machine +{ +} diff --git a/addons/overheating/scripts/Game/ACE_Overheating/Components/Weapons/ACE_Overheating_BarrelComponent.c b/addons/overheating/scripts/Game/ACE_Overheating/Components/Weapons/ACE_Overheating_BarrelComponent.c new file mode 100644 index 000000000..7ada2340a --- /dev/null +++ b/addons/overheating/scripts/Game/ACE_Overheating/Components/Weapons/ACE_Overheating_BarrelComponent.c @@ -0,0 +1,491 @@ +//------------------------------------------------------------------------------------------------ +//! Shared data across all instances of a prefab +class ACE_Overheating_BarrelComponentClass : ScriptComponentClass +{ + // Default: Specific heat capacity of steel + [Attribute(defvalue: "0.466", desc: "Specific heat capacity of the barrel [J / (g * K)]", category: "Barrel")] + protected float m_fBarrelSpecificHeatCapacity; + + // Default: Emissivity of oxidized steel + [Attribute(defvalue: "0.85", desc: "Emissivity of the barrel surface", category: "Barrel")] + protected float m_fBarrelEmissivity; + + // Default: 0.550 (Value from ACE3) + // M60 (MG_M60_base.et): 3.74 / 10.4 = 0.360 (Spare barrel mass (literature value) divided by total mass (ingame value)) + // M249 (MG_M249_base.et): 3.178 / 6.9 = 0.461 + // PKM (MachineGun_Base.et): 2.4 / 7.5 = 0.32 + [Attribute(defvalue: "0.55", desc: "Ratio between barrel mass and total mass of the weapon", category: "Barrel")] + protected float m_fBarrelMassFraction; + + // Default (Measured value from AK74_body.xob): 0.01476 + // M60: 0.01828 + [Attribute(defvalue: "0.01476", desc: "Outer diameter of the barrel [m]. ", precision: 5, category: "Barrel")] + protected float m_fBarrelDiameter; + + [Attribute(defvalue: "barrel_chamber", desc: "Name of the bone for the chamber")] + protected string m_sChamberBoneName; + + [Attribute(defvalue: "chamber", desc: "If m_sChamberBoneName does not exist, it searches for the first bone that contains this pattern")] + protected string m_sFallbackChamberBoneNamePattern; + + [Attribute(defvalue: "barrel_muzzle", desc: "Name of the bone for the muzzle")] + protected string m_sMuzzleBoneName; + + [Attribute(defvalue: "muzzle", desc: "If m_sMuzzleBoneName does not exist, it searches for the first bone that contains this pattern")] + protected string m_sFallbackMuzzleBoneNamePattern; + + // M60 (MachineGun_Base.et): 0.731 (Fitted together with m_fBaseHeatTransferCoefficient, such that cook-off progress will exactly reach 1.0 and then stop progressing for the next bullet and T_barrel_final=35°C when firing 100 RPM for 2 minutes and then cease fire for 15 minutes) + // M249 (MG_M249_base.et): 1.000 + // PKM (MachineGun_Base.et): 0.508 (Calculated scale to get similar heat transfer per shot as M60) + [Attribute(defvalue: "1", desc: "Heat transferred to the barrel is given by this scale times the kinetic energy of the bullet.")] + protected float m_fHeatingScale; + + [Attribute(uiwidget: UIWidgets.GraphDialog, desc: "Probability to jam vs temperature [K]", params: "1300 0.1 0 0")] + protected ref Curve m_cJamChanceTemperatureCurve; + + // Additional temperature-dependent muzzle dispersion factor f + // ----------------------------------------------------------- + // Base dispersion cone diameter gets multiplied by (1 + f) + // + // Formula: f = tan(a + da(T)) / tan(a) - 1 + // First-order Taylor approximation for small angles: f ≈ da(T) / a + // where a is base dispersion angle and da(T) is the additional temperature-dependent dispersion + // + // Using Reforger's M16A4 base dispersion: Cone height = 400 m; Cone diameter = 0.4 m => a ≈ 0.5 mrad + // and ACE3 additional dispersion: 0 mils at 0 °C, 0.5 mils at 333°C, 2.2 mils at 666 °C, 5 mils at 1000 °C + // => Additional dispersion factors: 0.0 at 0 °C, 1.0 at 333°C, 4.4 at 666 °C, 10.0 at 1000 °C + [Attribute(uiwidget: UIWidgets.GraphDialog, desc: "Additional muzzle dispersion factor vs temperature [K]", params: "1300 30 0 0")] + protected ref Curve m_cMuzzleDispersionFactorTemperatureCurve; + + protected bool m_bInitDone = false; + protected float m_fHeatPerShot; + protected float m_fBarrelHeatCapacity; + protected float m_fBarrelSurfaceArea; + protected float m_fBulletMass; + + // Fallbacks for misconfigured weapons + protected static const float FALLBACK_BARREL_MASS = 1.0; // kg + protected static const float FALLBACK_BARREL_LENGTH = 0.5; // m + protected static const float FALLBACK_BULLET_MASS = 0.004; // kg + protected static const float FALLBACK_INITIAL_BULLET_SPEED = 930; // m/s + + //------------------------------------------------------------------------------------------------ + //! Calculate derived quantities + void Init(IEntity instanceOwner) + { + if (m_bInitDone) + return; + + MuzzleComponent muzzle = MuzzleComponent.Cast(instanceOwner.FindComponent(MuzzleComponent)); + if (!muzzle) + return; + + float initialBulletSpeed; + GetBulletProperties(muzzle, m_fBulletMass, initialBulletSpeed); + // Heat produced by a shot is the initial kinetic energy of the bullet times a heating scale + m_fHeatPerShot = m_fHeatingScale * 0.5 * m_fBulletMass * Math.Pow(initialBulletSpeed, 2); + m_fBarrelHeatCapacity = m_fBarrelSpecificHeatCapacity * ComputeBarrelMass(instanceOwner) * 1000; // 1000 for kg to g + m_fBarrelSurfaceArea = Math.PI * m_fBarrelDiameter * ComputeBarrelLength(instanceOwner); + m_bInitDone = true; + } + + //------------------------------------------------------------------------------------------------ + //! Estimates mass of the barrel in kg + protected float ComputeBarrelMass(IEntity weapon) + { + SCR_WeaponAttachmentsStorageComponent weaponStorage = SCR_WeaponAttachmentsStorageComponent.Cast(weapon.FindComponent(SCR_WeaponAttachmentsStorageComponent)); + if (!weaponStorage) + { + Debug.Error(string.Format("\"%1\" has no SCR_WeaponAttachmentsStorageComponent.", weapon.GetPrefabData().GetPrefabName())); + return FALLBACK_BARREL_MASS; + } + + SCR_ItemAttributeCollection attributes = SCR_ItemAttributeCollection.Cast(weaponStorage.GetAttributes()); + if (!attributes) + { + Debug.Error(string.Format("\"%1\" has no SCR_ItemAttributeCollection.", weapon.GetPrefabData().GetPrefabName())); + return FALLBACK_BARREL_MASS; + } + + float mass = m_fBarrelMassFraction * attributes.GetWeight(); + if (mass <= 0) + { + Debug.Error(string.Format("\"%1\" has no mass.", weapon.GetPrefabData().GetPrefabName())); + mass = FALLBACK_BARREL_MASS; + } + + return mass; + } + + //------------------------------------------------------------------------------------------------ + //! Calculated from barrel memory points in meters + protected float ComputeBarrelLength(IEntity weapon) + { + Animation weaponAnim = weapon.GetAnimation(); + if (!weaponAnim) + { + Debug.Error(string.Format("\"%1\" has no Animation.", weapon.GetPrefabData().GetPrefabName())); + return FALLBACK_BARREL_LENGTH; + } + + TNodeId chamberBoneID = FindBoneID(weaponAnim, m_sChamberBoneName, m_sFallbackChamberBoneNamePattern); + TNodeId muzzleBoneID = FindBoneID(weaponAnim, m_sMuzzleBoneName, m_sFallbackMuzzleBoneNamePattern); + vector chamberTransform[4], muzzleTransform[4]; + weaponAnim.GetBoneLocalMatrix(chamberBoneID, chamberTransform); + weaponAnim.GetBoneLocalMatrix(muzzleBoneID, muzzleTransform); + + float length = vector.Distance(chamberTransform[3], muzzleTransform[3]); + if (length <= 0) + { + Debug.Error(string.Format("Could not determine barrel length for \"%1\".", weapon.GetPrefabData().GetPrefabName())); + length = FALLBACK_BARREL_LENGTH; + } + + return length; + } + + //------------------------------------------------------------------------------------------------ + //! Gets bone ID for a weapon + //! Returns bone ID for defaultBoneName if it exists + //! Otherwise searches for fallbackPattern and returns the first match + protected TNodeId FindBoneID(Animation weaponAnim, string defaultBoneName, string fallbackPattern) + { + TNodeId boneID = weaponAnim.GetBoneIndex(defaultBoneName); + if (boneID >= 0) + return boneID; + + array boneNames = {}; + weaponAnim.GetBoneNames(boneNames); + + foreach (string name : boneNames) + { + name.ToLower(); + if (name.Contains(fallbackPattern)) + return weaponAnim.GetBoneIndex(name); + } + + return -1; + } + + //------------------------------------------------------------------------------------------------ + //! Retrieves initial speed and mass for bullet in first magazine + protected void GetBulletProperties(MuzzleComponent muzzle, out float bulletMass, out float initialBulletSpeed) + { + ResourceName firstBulletPrefabName; + + array bulletPrefabNames = ACE_BulletTools.GetDefaultResourceNamesFromMuzzle(muzzle); + if (bulletPrefabNames.IsEmpty()) + { + Debug.Error(string.Format("\"%1\" has no default bullets.", muzzle.GetOwner().GetPrefabData().GetPrefabName())); + firstBulletPrefabName = ""; + } + else + { + firstBulletPrefabName = bulletPrefabNames[0]; + } + + bulletMass = ACE_BulletTools.GetMass(firstBulletPrefabName); + if (bulletMass <= 0) + { + Debug.Error(string.Format("\"%1\" has no mass.", firstBulletPrefabName)); + bulletMass = FALLBACK_BULLET_MASS; + } + + initialBulletSpeed = ACE_BulletTools.GetInitialSpeed(firstBulletPrefabName); + if (initialBulletSpeed <= 0) + { + Debug.Error(string.Format("\"%1\" has no initial speed.", firstBulletPrefabName)); + initialBulletSpeed = FALLBACK_INITIAL_BULLET_SPEED; + } + } + + //------------------------------------------------------------------------------------------------ + //! Returns heat capacity of the barrel in J / K + float GetBarrelHeatCapacity() + { + return m_fBarrelHeatCapacity; + } + + //------------------------------------------------------------------------------------------------ + //! Returns the emissivity of the barrel surface for radiative heat loss + float GetBarrelEmissivity() + { + return m_fBarrelEmissivity; + } + + //------------------------------------------------------------------------------------------------ + //! Returns outer surface area of the barrel in m^2 + float GetBarrelSurfaceArea() + { + return m_fBarrelSurfaceArea; + } + + //------------------------------------------------------------------------------------------------ + //! Returns outer diameter of the barrel in m + float GetBarrelDiameter() + { + return m_fBarrelDiameter; + } + + //------------------------------------------------------------------------------------------------ + //! Returns mass of bullet in kg + float GetBulletMass() + { + return m_fBulletMass; + } + + //------------------------------------------------------------------------------------------------ + //! Returns the heat transferred to the barrel per shot in J + float GetHeatPerShot() + { + return m_fHeatPerShot; + } + + //------------------------------------------------------------------------------------------------ + float ComputeJamChance(float temperature) + { + return Math3D.Curve(ECurveType.CurveProperty2D, temperature, m_cJamChanceTemperatureCurve)[1]; + } + + //------------------------------------------------------------------------------------------------ + float ComputeAdditionalMuzzleDispersionFactor(float temperature) + { + return Math3D.Curve(ECurveType.CurveProperty2D, temperature, m_cMuzzleDispersionFactorTemperatureCurve)[1]; + } +} + +//------------------------------------------------------------------------------------------------ +class ACE_Overheating_BarrelComponent : ScriptComponent +{ + [RplProp(onRplName: "OnStateChanged")] + protected bool m_bIsJammed = false; + + [RplProp()] + protected float m_fClearJamFailureChance = 0.1; + + protected float m_fBarrelTemperature; + protected float m_fAmmoTemperature; + protected float m_fCookOffProgress; + protected float m_fCookOffProgressScale; + protected float m_fLastTemperatureTimestamp; + protected int m_iHeatCounter; + protected float m_fJamChance; + + protected MuzzleComponent m_pMuzzle; + protected ACE_Overheating_BarrelComponentClass m_pData; + + //------------------------------------------------------------------------------------------------ + static ACE_Overheating_BarrelComponent FromWeapon(IEntity weapon) + { + if (!weapon) + return null; + + return ACE_Overheating_BarrelComponent.FromWeapon(BaseWeaponComponent.Cast(weapon.FindComponent(BaseWeaponComponent))); + } + + //------------------------------------------------------------------------------------------------ + static ACE_Overheating_BarrelComponent FromWeapon(BaseWeaponComponent weapon) + { + if (!weapon) + return null; + + return ACE_Overheating_BarrelComponent.FromMuzzle(weapon.GetCurrentMuzzle()); + } + + //------------------------------------------------------------------------------------------------ + static ACE_Overheating_BarrelComponent FromMuzzle(BaseMuzzleComponent muzzle) + { + if (!muzzle) + return null; + + return ACE_Overheating_BarrelComponent.Cast(muzzle.FindComponent(ACE_Overheating_BarrelComponent)); + } + + //------------------------------------------------------------------------------------------------ + override protected void OnPostInit(IEntity owner) + { + super.OnPostInit(owner); + SetEventMask(owner, EntityEvent.INIT); + } + + //------------------------------------------------------------------------------------------------ + override protected void EOnInit(IEntity owner) + { + super.EOnInit(owner); + + if (!GetGame().InPlayMode()) + return; + + WeaponComponent weapon = WeaponComponent.Cast(owner.FindComponent(WeaponComponent)); + if (!weapon) + return; + + m_pMuzzle = MuzzleComponent.Cast(weapon.FindComponent(MuzzleComponent)); + + // Server side init + RplComponent rpl = RplComponent.Cast(owner.FindComponent(RplComponent)); + if (rpl && rpl.IsProxy()) + return; + + m_pData = ACE_Overheating_BarrelComponentClass.Cast(GetComponentData(owner)); + m_pData.Init(owner); + + ACE_Overheating_Settings settings = ACE_SettingsHelperT.GetModSettings(); + if (settings) + m_fClearJamFailureChance = settings.m_fClearJamFailureChance; + + float airTemperature = ACE_WeatherHelper.GetAirTemperatureForEntity(GetOwner()); + m_fBarrelTemperature = airTemperature; + m_fAmmoTemperature = airTemperature; + m_fJamChance = m_pData.ComputeJamChance(m_fBarrelTemperature); + InitCookOffCookOffProgressScale(); + Replication.BumpMe(); + } + + //------------------------------------------------------------------------------------------------ + void SetState(bool isJammed) + { + if (!isJammed) + m_pMuzzle.ClearChamber(m_pMuzzle.GetCurrentBarrelIndex()); + + m_bIsJammed = isJammed; + OnStateChanged(); + Replication.BumpMe(); + } + + //------------------------------------------------------------------------------------------------ + bool IsJammed() + { + return m_bIsJammed; + } + + //------------------------------------------------------------------------------------------------ + protected void OnStateChanged() + { + ACE_Overheating_JammingSystem system = ACE_Overheating_JammingSystem.GetInstance(); + if (system) + system.OnJamStateChanged(this, m_bIsJammed); + } + + //------------------------------------------------------------------------------------------------ + MuzzleComponent GetMuzzle() + { + return m_pMuzzle; + } + + //------------------------------------------------------------------------------------------------ + void SetBarrelTemperature(float temperature) + { + m_fBarrelTemperature = temperature; + } + + //------------------------------------------------------------------------------------------------ + float GetBarrelTemperature() + { + return m_fBarrelTemperature; + } + + //------------------------------------------------------------------------------------------------ + void SetAmmoTemperature(float temperature) + { + m_fAmmoTemperature = temperature; + } + + //------------------------------------------------------------------------------------------------ + float GetAmmoTemperature() + { + return m_fAmmoTemperature; + } + + //------------------------------------------------------------------------------------------------ + float GetCookOffProgress() + { + return m_fCookOffProgress; + } + + //------------------------------------------------------------------------------------------------ + void SetCookOffProgress(float value) + { + m_fCookOffProgress = value; + } + + //------------------------------------------------------------------------------------------------ + void InitCookOffCookOffProgressScale() + { + m_fCookOffProgressScale = Math.RandomGaussFloat(0.078541632, 1); + } + + //------------------------------------------------------------------------------------------------ + float GetCookOffProgressScale() + { + return m_fCookOffProgressScale; + } + + //------------------------------------------------------------------------------------------------ + void SetLastTemperatureTimestamp(float timestamp) + { + m_fLastTemperatureTimestamp = timestamp; + } + + //------------------------------------------------------------------------------------------------ + float GetLastTemperatureTimestamp() + { + return m_fLastTemperatureTimestamp; + } + + //------------------------------------------------------------------------------------------------ + //! Increments the heat counter by one fired bullet + void IncremenHeatCounter() + { + ++m_iHeatCounter; + } + + //------------------------------------------------------------------------------------------------ + //! Returns the accumulated heat and resets the heat counter + float PopAccumulatedHeat() + { + float heat = m_pData.GetHeatPerShot() * m_iHeatCounter; + m_iHeatCounter = 0; + return heat; + } + + //------------------------------------------------------------------------------------------------ + ACE_Overheating_BarrelComponentClass GetData() + { + return m_pData; + } + + //------------------------------------------------------------------------------------------------ + void SetJamChance(float probability) + { + m_fJamChance = probability; + } + + //------------------------------------------------------------------------------------------------ + float GetJamChance() + { + return m_fJamChance; + } + + //------------------------------------------------------------------------------------------------ + float GetClearJamFailureChance() + { + return m_fClearJamFailureChance; + } + +#ifdef ENABLE_DIAG + protected float m_fHeatTransferCoefficient; + + //------------------------------------------------------------------------------------------------ + void SetHeatTransferCoefficient(float coefficient) + { + m_fHeatTransferCoefficient = coefficient; + } + + //------------------------------------------------------------------------------------------------ + float GetHeatTransferCoefficient() + { + return m_fHeatTransferCoefficient; + } +#endif +} diff --git a/addons/overheating/scripts/Game/ACE_Overheating/Diag/ArmaReforgerScripted.c b/addons/overheating/scripts/Game/ACE_Overheating/Diag/ArmaReforgerScripted.c new file mode 100644 index 000000000..7dfe72d36 --- /dev/null +++ b/addons/overheating/scripts/Game/ACE_Overheating/Diag/ArmaReforgerScripted.c @@ -0,0 +1,141 @@ +#ifdef ENABLE_DIAG +//------------------------------------------------------------------------------------------------ +modded class ArmaReforgerScripted : ChimeraGame +{ + protected bool m_bACE_Overheating_PreviousJamState = false; + protected bool m_bACE_Overheating_PreviousJamSetting = false; + protected float m_fACE_Overheating_PreviousBarrelTemperatureSetting; + protected float m_fACE_Overheating_PreviousAmmoTemperatureSetting; + + //------------------------------------------------------------------------------------------------ + override bool OnGameStart() + { + DiagMenu.RegisterMenu(SCR_DebugMenuID.ACE_OVERHEATING_DEBUGUI_MENU, "ACE Overheating", "ACE"); + DiagMenu.RegisterBool(SCR_DebugMenuID.ACE_OVERHEATING_DEBUGUI_MENU_TEMPERATURE_DIAG, "", "Show temperature diag", "ACE Overheating"); + DiagMenu.RegisterBool(SCR_DebugMenuID.ACE_OVERHEATING_DEBUGUI_MENU_JAM_SETTER, "", "Weapon jammed", "ACE Overheating"); + DiagMenu.RegisterRange(SCR_DebugMenuID.ACE_OVERHEATING_DEBUGUI_MENU_BARREL_TEMPERATURE_SETTER, "", "Barrel temperature [K]", "ACE Overheating", "298.15 1298.15 298.15 10"); + m_fACE_Overheating_PreviousBarrelTemperatureSetting = DiagMenu.GetRangeValue(SCR_DebugMenuID.ACE_OVERHEATING_DEBUGUI_MENU_BARREL_TEMPERATURE_SETTER); + DiagMenu.RegisterRange(SCR_DebugMenuID.ACE_OVERHEATING_DEBUGUI_MENU_AMMO_TEMPERATURE_SETTER, "", "Ammo temperature [K]", "ACE Overheating", "298.15 1298.15 298.15 10"); + m_fACE_Overheating_PreviousAmmoTemperatureSetting = DiagMenu.GetRangeValue(SCR_DebugMenuID.ACE_OVERHEATING_DEBUGUI_MENU_AMMO_TEMPERATURE_SETTER); + + return super.OnGameStart(); + } + + //------------------------------------------------------------------------------------------------ + override void OnUpdate(BaseWorld world, float timeslice) + { + super.OnUpdate(world, timeslice); + + ACE_Overheating_JammingSystem system = ACE_Overheating_JammingSystem.GetInstance(); + if (!system) + return; + + ACE_Overheating_BarrelComponent barrel = system.GetLocalActiveBarrel(); + if (barrel) + { + ACE_Overheating_HandleJamSetterDiag(barrel); + ACE_Overheating_HandleTemperatureSetterDiag(barrel); + } + + if (DiagMenu.GetBool(SCR_DebugMenuID.ACE_OVERHEATING_DEBUGUI_MENU_TEMPERATURE_DIAG)) + ACE_Overheating_ShowTemperatureDiag() + } + + //------------------------------------------------------------------------------------------------ + protected void ACE_Overheating_HandleJamSetterDiag(ACE_Overheating_BarrelComponent barrel) + { + bool currentJamState = barrel.IsJammed(); + bool currentJamSetting = DiagMenu.GetBool(SCR_DebugMenuID.ACE_OVERHEATING_DEBUGUI_MENU_JAM_SETTER); + if (currentJamState == currentJamSetting) + return; + + if (m_bACE_Overheating_PreviousJamState != currentJamState) + { + DiagMenu.SetValue(SCR_DebugMenuID.ACE_OVERHEATING_DEBUGUI_MENU_JAM_SETTER, currentJamState); + m_bACE_Overheating_PreviousJamState = currentJamState; + m_bACE_Overheating_PreviousJamSetting = currentJamState; + } + else if (m_bACE_Overheating_PreviousJamSetting != currentJamSetting) + { + SCR_PlayerController playerController = SCR_PlayerController.Cast(GetGame().GetPlayerController()); + if (playerController) + playerController.ACE_Overheating_RequestSetJamState(barrel, currentJamSetting); + + m_bACE_Overheating_PreviousJamState = currentJamSetting; + m_bACE_Overheating_PreviousJamSetting = currentJamSetting; + } + } + + //------------------------------------------------------------------------------------------------ + protected void ACE_Overheating_HandleTemperatureSetterDiag(ACE_Overheating_BarrelComponent barrel) + { + float newBarrelSetting = DiagMenu.GetRangeValue(SCR_DebugMenuID.ACE_OVERHEATING_DEBUGUI_MENU_BARREL_TEMPERATURE_SETTER); + + if (newBarrelSetting != m_fACE_Overheating_PreviousBarrelTemperatureSetting) + barrel.SetBarrelTemperature(newBarrelSetting); + else + DiagMenu.SetRangeValue(SCR_DebugMenuID.ACE_OVERHEATING_DEBUGUI_MENU_BARREL_TEMPERATURE_SETTER, barrel.GetBarrelTemperature()); + + m_fACE_Overheating_PreviousBarrelTemperatureSetting = DiagMenu.GetRangeValue(SCR_DebugMenuID.ACE_OVERHEATING_DEBUGUI_MENU_BARREL_TEMPERATURE_SETTER); + + float newAmmoSetting = DiagMenu.GetRangeValue(SCR_DebugMenuID.ACE_OVERHEATING_DEBUGUI_MENU_AMMO_TEMPERATURE_SETTER); + + if (newAmmoSetting != m_fACE_Overheating_PreviousAmmoTemperatureSetting) + barrel.SetAmmoTemperature(newAmmoSetting); + else + DiagMenu.SetRangeValue(SCR_DebugMenuID.ACE_OVERHEATING_DEBUGUI_MENU_AMMO_TEMPERATURE_SETTER, barrel.GetAmmoTemperature()); + + m_fACE_Overheating_PreviousAmmoTemperatureSetting = DiagMenu.GetRangeValue(SCR_DebugMenuID.ACE_OVERHEATING_DEBUGUI_MENU_AMMO_TEMPERATURE_SETTER); + } + + //------------------------------------------------------------------------------------------------ + protected void ACE_Overheating_ShowTemperatureDiag() + { + IEntity target; + string targetType; + ACE_DiagTools.GetDiagTargetCharacter(target, targetType); + + SCR_ChimeraCharacter targetChar = SCR_ChimeraCharacter.Cast(target); + if (!targetChar) + return; + + BaseWeaponManagerComponent weaponManager = targetChar.GetWeaponManager(); + if (!weaponManager) + return; + + BaseWeaponComponent weapon = weaponManager.GetCurrentWeapon(); + if (!weapon) + return; + + BaseMuzzleComponent muzzle = weapon.GetCurrentMuzzle(); + if (!muzzle) + return; + + ACE_Overheating_BarrelComponent barrel = ACE_Overheating_BarrelComponent.FromMuzzle(muzzle); + if (!barrel) + return; + + ACE_Overheating_Settings settings = ACE_SettingsHelperT.GetModSettings(); + if (!settings) + return; + + DbgUI.Begin(string.Format("ACE Overheating Diag (%1)", targetType), 0, 700); + DbgUI.Text(string.Format("Heating Rate: %1 K/Round", settings.m_fHeatingScale * barrel.GetData().GetHeatPerShot() / barrel.GetData().GetBarrelHeatCapacity())); + DbgUI.Text(string.Format("Heat Transfer Coefficient: %1 W/(m^2*K)", barrel.GetHeatTransferCoefficient())); + + ACE_Overheating_HelperAttachmentComponent helperAttachment = ACE_Overheating_HelperAttachmentComponent.Cast(muzzle.FindComponent(ACE_Overheating_HelperAttachmentComponent)); + if (helperAttachment) + DbgUI.Text(string.Format("Muzzle Dispersion Factor: %1", helperAttachment.GetMuzzleDispersionFactor())); + + DbgUI.Text(string.Format("Jam Chance: %1", barrel.GetJamChance())); + DbgUI.Text(string.Format("Is Jammed: %1", barrel.IsJammed().ToString())); + DbgUI.Text(string.Format("Barrel Temperature: %1 K", barrel.GetBarrelTemperature())); + DbgUI.PlotLiveClamped("BarrelTemperature", 500, 290, barrel.GetBarrelTemperature(), ACE_PhysicalConstants.ZERO_CELSIUS, ACE_PhysicalConstants.ZERO_CELSIUS + 1000, 100, 1000); + DbgUI.Text(string.Format("Ammo Temperature: %1 K", barrel.GetAmmoTemperature())); + DbgUI.PlotLiveClamped("AmmoTemperature", 500, 290, barrel.GetAmmoTemperature(), ACE_PhysicalConstants.ZERO_CELSIUS, ACE_PhysicalConstants.ZERO_CELSIUS + 1000, 100, 1000); + DbgUI.Text(string.Format("Cookoff Progress: %1 %%", 100 * barrel.GetCookOffProgress() / barrel.GetCookOffProgressScale())); + DbgUI.PlotLiveClamped("CookoffProgress", 500, 290, barrel.GetCookOffProgress() / barrel.GetCookOffProgressScale(), 0, 1, 100, 1000); + DbgUI.End(); + } +} +#endif diff --git a/addons/overheating/scripts/Game/ACE_Overheating/Diag/SCR_DebugMenuID.c b/addons/overheating/scripts/Game/ACE_Overheating/Diag/SCR_DebugMenuID.c new file mode 100644 index 000000000..9fe01501e --- /dev/null +++ b/addons/overheating/scripts/Game/ACE_Overheating/Diag/SCR_DebugMenuID.c @@ -0,0 +1,11 @@ +#ifdef ENABLE_DIAG +//------------------------------------------------------------------------------------------------ +modded enum SCR_DebugMenuID +{ + ACE_OVERHEATING_DEBUGUI_MENU, + ACE_OVERHEATING_DEBUGUI_MENU_TEMPERATURE_DIAG, + ACE_OVERHEATING_DEBUGUI_MENU_JAM_SETTER, + ACE_OVERHEATING_DEBUGUI_MENU_BARREL_TEMPERATURE_SETTER, + ACE_OVERHEATING_DEBUGUI_MENU_AMMO_TEMPERATURE_SETTER, +} +#endif \ No newline at end of file diff --git a/addons/overheating/scripts/Game/ACE_Overheating/FSM/WeaponAnim/ACE_Overheating_EWeaponAnimStateID.c b/addons/overheating/scripts/Game/ACE_Overheating/FSM/WeaponAnim/ACE_Overheating_EWeaponAnimStateID.c new file mode 100644 index 000000000..c212b0d1c --- /dev/null +++ b/addons/overheating/scripts/Game/ACE_Overheating/FSM/WeaponAnim/ACE_Overheating_EWeaponAnimStateID.c @@ -0,0 +1,6 @@ +//------------------------------------------------------------------------------------------------ +enum ACE_Overheating_EWeaponAnimStateID : ACE_FSM_EStateID +{ + REMOVE_MAGAZINE = 1 << 0, + RACK_BOLT = 1 << 1, +} diff --git a/addons/overheating/scripts/Game/ACE_Overheating/FSM/WeaponAnim/ACE_Overheating_RackBoltCompleted.c b/addons/overheating/scripts/Game/ACE_Overheating/FSM/WeaponAnim/ACE_Overheating_RackBoltCompleted.c new file mode 100644 index 000000000..6ec2b3108 --- /dev/null +++ b/addons/overheating/scripts/Game/ACE_Overheating/FSM/WeaponAnim/ACE_Overheating_RackBoltCompleted.c @@ -0,0 +1,9 @@ +//------------------------------------------------------------------------------------------------ +class ACE_Overheating_RackBoltCompleted : ACE_FSM_ITransition +{ + //------------------------------------------------------------------------------------------------ + override bool ShouldBePerformed(ACE_Overheating_WeaponAnimContext context, float timeSlice) + { + return !context.IsReloading(); + } +} diff --git a/addons/overheating/scripts/Game/ACE_Overheating/FSM/WeaponAnim/ACE_Overheating_RackBoltState.c b/addons/overheating/scripts/Game/ACE_Overheating/FSM/WeaponAnim/ACE_Overheating_RackBoltState.c new file mode 100644 index 000000000..788392c71 --- /dev/null +++ b/addons/overheating/scripts/Game/ACE_Overheating/FSM/WeaponAnim/ACE_Overheating_RackBoltState.c @@ -0,0 +1,96 @@ +//------------------------------------------------------------------------------------------------ +class ACE_Overheating_RackBoltState : ACE_FSM_IState +{ + // A reference to the context is needed for OnRackBoltAnimEvent + protected ref ACE_Overheating_WeaponAnimContext m_pContext; + + //------------------------------------------------------------------------------------------------ + override void OnEnter(ACE_Overheating_WeaponAnimContext context) + { + context.m_pCharAnim.CallCommand(context.m_iCharReloadCommandID, 1, 0); + context.m_pWeaponAnim.CallCommand(context.m_iWeaponReloadCommandID, 1, 0); + context.m_pCharController.GetOnAnimationEvent().Insert(OnRackBoltAnimEvent); + context.m_pCharController.OverrideMaxSpeed(0.25); + m_pContext = context; + } + + //------------------------------------------------------------------------------------------------ + override void OnUpdate(ACE_Overheating_WeaponAnimContext context, float timeSlice) + { + context.m_pCharController.SetWeaponADS(false); + } + + //------------------------------------------------------------------------------------------------ + override void OnExit(ACE_Overheating_WeaponAnimContext context) + { + context.m_pCharController.GetOnAnimationEvent().Remove(OnRackBoltAnimEvent); + context.m_pCharController.SetWeaponADS(context.m_bWasWeaponADS); + context.m_pCharController.OverrideMaxSpeed(1); + } + + //------------------------------------------------------------------------------------------------ + //! Evaluate and execute clearing if successful on rack bolt event + protected void OnRackBoltAnimEvent(AnimationEventID animEventType, AnimationEventID animUserString, int intParam, float timeFromStart, float timeToEnd) + { + if (animEventType != m_pContext.m_iRackBoltEvent) + return; + + m_pContext.m_pCharController.GetOnAnimationEvent().Remove(OnRackBoltAnimEvent); + + // Clearing can only happen when jammed or barrel is chambered. In case of jam, evaluate chance for clearing + if (m_pContext.m_pBarrel.IsJammed()) + { + if (Math.RandomFloat(0, 1) < m_pContext.m_pBarrel.GetClearJamFailureChance()) + return; + } + else + { + if (!m_pContext.m_pBarrel.GetMuzzle().IsCurrentBarrelChambered()) + return; + } + + ClearJam(m_pContext); + } + + //------------------------------------------------------------------------------------------------ + //! Clears jam and creates case ejection particle effect + protected void ClearJam(ACE_Overheating_WeaponAnimContext context) + { + SCR_PlayerController playerController = SCR_PlayerController.Cast(GetGame().GetPlayerController()); + if (playerController) + playerController.ACE_Overheating_RequestSetJamState(context.m_pBarrel, false); + + IEntity weapon = context.m_pWeapon.GetOwner(); + if (!weapon) + return; + + CaseEjectingEffectComponent caseEjection = CaseEjectingEffectComponent.Cast(weapon.FindComponent(CaseEjectingEffectComponent)); + if (!caseEjection) + return; + + IEntityComponentSource caseEjectionSource = caseEjection.GetComponentSource(weapon); + if (!caseEjectionSource) + return; + + ResourceName particlePrefabName; + caseEjectionSource.Get("ParticleEffect", particlePrefabName); + EntitySlotInfo slotInfo; + caseEjectionSource.Get("EffectPosition", slotInfo); + + if (!slotInfo) + return; + + ParticleEffectEntitySpawnParams spawnParams = new ParticleEffectEntitySpawnParams(); + spawnParams.Parent = context.m_pWeapon.GetOwner(); + spawnParams.PivotID = slotInfo.GetNodeId(); + slotInfo.GetLocalTransform(spawnParams.Transform); + + ParticleEffectEntity particleEmitter = ParticleEffectEntity.SpawnParticleEffect(particlePrefabName, spawnParams); + Particles particles = particleEmitter.GetParticles(); + particles.SetParam(0, EmitterParam.EMITTING_TIME, 1); + particles.MultParam(0, EmitterParam.VELOCITY, 0.5); + particles.MultParam(0, EmitterParam.VELOCITY_RND, 0.5); + particles.SetParam(1, EmitterParam.EMITTING_TIME, 0); + particles.SetParam(2, EmitterParam.EMITTING_TIME, 0); + } +} diff --git a/addons/overheating/scripts/Game/ACE_Overheating/FSM/WeaponAnim/ACE_Overheating_RemoveMagCompleted.c b/addons/overheating/scripts/Game/ACE_Overheating/FSM/WeaponAnim/ACE_Overheating_RemoveMagCompleted.c new file mode 100644 index 000000000..75b64e815 --- /dev/null +++ b/addons/overheating/scripts/Game/ACE_Overheating/FSM/WeaponAnim/ACE_Overheating_RemoveMagCompleted.c @@ -0,0 +1,12 @@ +//------------------------------------------------------------------------------------------------ +class ACE_Overheating_RemoveMagCompleted : ACE_FSM_ITransition +{ + //------------------------------------------------------------------------------------------------ + override bool ShouldBePerformed(ACE_Overheating_WeaponAnimContext context, float timeSlice) + { + if (context.m_bIsStartRemovingMag || context.IsReloading() || context.m_pWeapon.GetCurrentMagazine()) + return false; + + return true; + } +} diff --git a/addons/overheating/scripts/Game/ACE_Overheating/FSM/WeaponAnim/ACE_Overheating_RemoveMagFailed.c b/addons/overheating/scripts/Game/ACE_Overheating/FSM/WeaponAnim/ACE_Overheating_RemoveMagFailed.c new file mode 100644 index 000000000..0247b9db3 --- /dev/null +++ b/addons/overheating/scripts/Game/ACE_Overheating/FSM/WeaponAnim/ACE_Overheating_RemoveMagFailed.c @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------------------------ +class ACE_Overheating_RemoveMagFailed : ACE_FSM_ITransition +{ + //------------------------------------------------------------------------------------------------ + override bool ShouldBePerformed(ACE_Overheating_WeaponAnimContext context, float timeSlice) + { + // Can return false the first few frames, so we compensate with m_bIsStartRemovingMag + if (context.m_bIsStartRemovingMag || context.IsReloading()) + return false; + + return context.m_pWeapon.GetCurrentMagazine(); + } +} diff --git a/addons/overheating/scripts/Game/ACE_Overheating/FSM/WeaponAnim/ACE_Overheating_RemoveMagState.c b/addons/overheating/scripts/Game/ACE_Overheating/FSM/WeaponAnim/ACE_Overheating_RemoveMagState.c new file mode 100644 index 000000000..855883e15 --- /dev/null +++ b/addons/overheating/scripts/Game/ACE_Overheating/FSM/WeaponAnim/ACE_Overheating_RemoveMagState.c @@ -0,0 +1,46 @@ +//------------------------------------------------------------------------------------------------ +class ACE_Overheating_RemoveMagState : ACE_FSM_IState +{ + //------------------------------------------------------------------------------------------------ + override void OnEnter(ACE_Overheating_WeaponAnimContext context) + { + context.m_pCharController.OverrideMaxSpeed(0.25); + + BaseMagazineComponent currentMagComponent = context.m_pWeapon.GetCurrentMagazine(); + if (currentMagComponent) + { + IEntity currentMag = currentMagComponent.GetOwner(); + InventoryItemComponent magInventory = InventoryItemComponent.Cast(currentMag.FindComponent(InventoryItemComponent)); + BaseInventoryStorageComponent magStorage = magInventory.GetParentSlot().GetStorage(); + + bool result; + + // Trying to move magazine to storage is broken in MP + // See (1) in https://feedback.bistudio.com/T193647 + /* + BaseInventoryStorageComponent suitableStorage = context.m_pInventoryManager.FindStorageForItem(currentMag); + if (suitableStorage) + result = context.m_pInventoryManager.TryMoveItemToStorage(currentMag, suitableStorage); + else + */ + result = context.m_pInventoryManager.TryRemoveItemFromStorage(currentMag, magStorage); + + context.m_bIsStartRemovingMag = result; + } + } + + //------------------------------------------------------------------------------------------------ + override void OnExit(ACE_Overheating_WeaponAnimContext context) + { + context.m_pCharController.OverrideMaxSpeed(1); + } + + //------------------------------------------------------------------------------------------------ + override void OnUpdate(ACE_Overheating_WeaponAnimContext context, float timeSlice) + { + context.m_pCharController.SetWeaponADS(false); + + if (context.m_bIsStartRemovingMag && context.IsReloading()) + context.m_bIsStartRemovingMag = false; + } +} diff --git a/addons/overheating/scripts/Game/ACE_Overheating/FSM/WeaponAnim/ACE_Overheating_WeaponAnimContext.c b/addons/overheating/scripts/Game/ACE_Overheating/FSM/WeaponAnim/ACE_Overheating_WeaponAnimContext.c new file mode 100644 index 000000000..4b75179fe --- /dev/null +++ b/addons/overheating/scripts/Game/ACE_Overheating/FSM/WeaponAnim/ACE_Overheating_WeaponAnimContext.c @@ -0,0 +1,38 @@ +//------------------------------------------------------------------------------------------------ +class ACE_Overheating_WeaponAnimContext : Managed +{ + SCR_InventoryStorageManagerComponent m_pInventoryManager; + SCR_CharacterControllerComponent m_pCharController; + bool m_bWasWeaponADS; + CharacterAnimationComponent m_pCharAnim; + BaseWeaponComponent m_pWeapon; + ACE_Overheating_BarrelComponent m_pBarrel; + WeaponAnimationComponent m_pWeaponAnim; + TAnimGraphCommand m_iCharReloadCommandID; + TAnimGraphCommand m_iWeaponReloadCommandID; + TAnimGraphEvent m_iRackBoltEvent; + TAnimGraphTag m_iReloadTag; + bool m_bIsStartRemovingMag = false; + + //------------------------------------------------------------------------------------------------ + void ACE_Overheating_WeaponAnimContext(ChimeraCharacter char, BaseWeaponComponent weapon, ACE_Overheating_BarrelComponent barrel) + { + m_pInventoryManager = SCR_InventoryStorageManagerComponent.Cast(char.FindComponent(SCR_InventoryStorageManagerComponent)); + m_pCharController = SCR_CharacterControllerComponent.Cast(char.GetCharacterController()); + m_bWasWeaponADS = m_pCharController.GetInputContext().IsWeaponADS(); + m_pCharAnim = char.GetAnimationComponent(); + m_iCharReloadCommandID = m_pCharAnim.BindCommand("CMD_Weapon_Reload"); + m_iRackBoltEvent = m_pCharAnim.BindEvent("Weapon_Rack_Bolt"); + m_iReloadTag = m_pCharAnim.BindTag("TagWeaponReload"); + m_pWeapon = weapon; + m_pBarrel = barrel; + m_pWeaponAnim = WeaponAnimationComponent.Cast(weapon.GetOwner().FindComponent(WeaponAnimationComponent)); + m_iWeaponReloadCommandID = m_pWeaponAnim.BindCommand("CMD_Weapon_Reload"); + } + + //------------------------------------------------------------------------------------------------ + bool IsReloading() + { + return (m_pCharAnim.IsPrimaryTag(m_iReloadTag) || m_pCharAnim.IsSecondaryTag(m_iReloadTag)); + } +} diff --git a/addons/overheating/scripts/Game/ACE_Overheating/GameMode/SCR_BaseGameMode.c b/addons/overheating/scripts/Game/ACE_Overheating/GameMode/SCR_BaseGameMode.c new file mode 100644 index 000000000..ab7829043 --- /dev/null +++ b/addons/overheating/scripts/Game/ACE_Overheating/GameMode/SCR_BaseGameMode.c @@ -0,0 +1,22 @@ +//------------------------------------------------------------------------------------------------ +modded class SCR_BaseGameMode : BaseGameMode +{ + //------------------------------------------------------------------------------------------------ + //! Unregister dead players from systems + override protected void OnPlayerKilled(int playerId, IEntity playerEntity, IEntity killerEntity, notnull Instigator killer) + { + super.OnPlayerKilled(playerId, playerEntity, killerEntity, killer); + + SCR_ChimeraCharacter playerChar = SCR_ChimeraCharacter.Cast(playerEntity); + if (!playerChar) + return; + + EquipedWeaponStorageComponent weaponStorage = EquipedWeaponStorageComponent.Cast(playerChar.FindComponent(EquipedWeaponStorageComponent)); + if (weaponStorage) + weaponStorage.ACE_Overheating_ToggleRegisterWeapons(false); + + ACE_Overheating_AmmoTemperatureSystem ammoSystem = ACE_Overheating_AmmoTemperatureSystem.GetInstance(); + if (ammoSystem) + ammoSystem.Unregister(playerChar); + } +} diff --git a/addons/overheating/scripts/Game/ACE_Overheating/Jobs/ACE_Overheating_AmmoTemperatureJob.c b/addons/overheating/scripts/Game/ACE_Overheating/Jobs/ACE_Overheating_AmmoTemperatureJob.c new file mode 100644 index 000000000..6109ead03 --- /dev/null +++ b/addons/overheating/scripts/Game/ACE_Overheating/Jobs/ACE_Overheating_AmmoTemperatureJob.c @@ -0,0 +1,86 @@ +//------------------------------------------------------------------------------------------------ +//! The reference data shows that the functional form of cook-off times vs T_barrel is close to exponential (A. Hameed et al., Defence Technology 2014, 10, 86–91) +//! Pure Newton's law would predict logarithmic behavior when calculating the time to reach some threshold temperature +//! The solution is to have fast heat exchange coupled with an Arrhenius equation, where cookoff happens when a certain threshold reaction progress was exceeded. +//------------------------------------------------------------------------------------------------ +//! TO DO: Reset temperature when new bullet got chambered instead of using OnProjectileShot +class ACE_Overheating_AmmoTemperatureJob : ACE_IFrameJob +{ + protected static ACE_Overheating_Settings s_pSettings; + protected ref ACE_Overheating_CharacterContext m_pContext = null; + protected static const float MAX_COOKOFF_RATE_CONSTANT = 303717.68; // [1/s] + protected static const float COOKOFF_ACTIVATION_SCALE = 18.716667; + + //------------------------------------------------------------------------------------------------ + void ACE_Overheating_AmmoTemperatureJob() + { + if (!s_pSettings) + s_pSettings = ACE_SettingsHelperT.GetModSettings(); + } + + //------------------------------------------------------------------------------------------------ + override void OnUpdate(float timeSlice) + { + super.OnUpdate(timeSlice); + + if (!m_pContext.IsValid() || !m_pContext.m_pBarrel) + return; + + // Reset temperature when jammed or when chamber empty + if (m_pContext.m_pBarrel.IsJammed() || (m_pContext.m_bIsChamberingPossible && !m_pContext.m_pMuzzle.IsCurrentBarrelChambered())) + { + m_pContext.m_pBarrel.SetAmmoTemperature(ACE_WeatherHelper.GetAirTemperatureForEntity(m_pContext.m_pBarrel.GetOwner())); + m_pContext.m_pBarrel.SetCookOffProgress(0); + return; + } + + float nextTemperature = ComputeNextTemperature(timeSlice); + if (nextTemperature >= s_pSettings.m_fGunpowderAutoignitionTemperature) + { + float cookoffProgress = ComputeCookOffProgress(timeSlice, nextTemperature); + + // Do cook-off if progress has exceeded + if (cookoffProgress >= m_pContext.m_pBarrel.GetCookOffProgressScale()) + { + m_pContext.m_pCharCommandHandler.ACE_ForceWeaponFire(); + nextTemperature = ACE_WeatherHelper.GetAirTemperatureForEntity(m_pContext.m_pBarrel.GetOwner()); + cookoffProgress = 0; + m_pContext.m_pBarrel.InitCookOffCookOffProgressScale(); + } + + m_pContext.m_pBarrel.SetCookOffProgress(cookoffProgress); + } + + m_pContext.m_pBarrel.SetAmmoTemperature(nextTemperature); + } + + //------------------------------------------------------------------------------------------------ + //! Computes new bullet temperature by using Newton's law of cooling for heat transfer from barrel + protected float ComputeNextTemperature(float timeSlice) + { + // TO DO: Account for surface area + float progress = Math.Min(s_pSettings.m_fBarrel2BulletMassScaledTemperatureRateConstant / 1000 / m_pContext.m_pBarrel.GetData().GetBulletMass() * timeSlice, 1); // 1000 for kg to g + return Math.Lerp(m_pContext.m_pBarrel.GetAmmoTemperature(), m_pContext.m_pBarrel.GetBarrelTemperature(), progress); + } + + //------------------------------------------------------------------------------------------------ + //! Uses Arrhenius equation to compute the progress of some reaction that causes cookoff + protected float ComputeCookOffProgress(float timeSlice, float nextTemperature) + { + float progress = m_pContext.m_pBarrel.GetCookOffProgress(); + progress += timeSlice * MAX_COOKOFF_RATE_CONSTANT * ACE_Math.Exp(-COOKOFF_ACTIVATION_SCALE * s_pSettings.m_fGunpowderAutoignitionTemperature / nextTemperature); + return progress; + } + + //------------------------------------------------------------------------------------------------ + void SetContext(ACE_Overheating_CharacterContext context) + { + m_pContext = context; + } + + //------------------------------------------------------------------------------------------------ + ACE_Overheating_CharacterContext GetContext() + { + return m_pContext; + } +} diff --git a/addons/overheating/scripts/Game/ACE_Overheating/Jobs/ACE_Overheating_BarrelTemperatureJob.c b/addons/overheating/scripts/Game/ACE_Overheating/Jobs/ACE_Overheating_BarrelTemperatureJob.c new file mode 100644 index 000000000..14c2d574d --- /dev/null +++ b/addons/overheating/scripts/Game/ACE_Overheating/Jobs/ACE_Overheating_BarrelTemperatureJob.c @@ -0,0 +1,155 @@ +//------------------------------------------------------------------------------------------------ +class ACE_Overheating_BarrelTemperatureJob : ACE_IFrameJob +{ + protected static ACE_Overheating_Settings s_pSettings; + protected static BaseWeatherManagerEntity s_pWeatherManager; + protected ref ACE_Overheating_BarrelContext m_pContext = null; + + //------------------------------------------------------------------------------------------------ + void ACE_Overheating_BarrelTemperatureJob() + { + if (!s_pSettings) + s_pSettings = ACE_SettingsHelperT.GetModSettings(); + + if (!s_pWeatherManager) + { + ChimeraWorld world = GetGame().GetWorld(); + s_pWeatherManager = world.GetTimeAndWeatherManager(); + } + } + + //------------------------------------------------------------------------------------------------ + override void OnStart() + { + super.OnStart(); + + if (!m_pContext.IsValid()) + return; + + OnUpdate((GetGame().GetWorld().GetWorldTime() - m_pContext.m_pObject.GetLastTemperatureTimestamp()) / 1000); + } + + //------------------------------------------------------------------------------------------------ + override void OnStop() + { + super.OnStop(); + + if (!m_pContext.IsValid()) + return; + + m_pContext.m_pObject.SetLastTemperatureTimestamp(GetGame().GetWorld().GetWorldTime()); + } + + //------------------------------------------------------------------------------------------------ + override void OnUpdate(float timeSlice) + { + super.OnUpdate(timeSlice); + + if (!m_pContext.IsValid()) + return; + + float externalTemperature = ACE_WeatherHelper.GetAirTemperatureForEntity(m_pContext.m_pObject.GetOwner()); + float currentTemperature = m_pContext.m_pObject.GetBarrelTemperature(); + float nextTemperature = currentTemperature; + nextTemperature += (ComputeHeating(timeSlice) + ComputeCooling(timeSlice, currentTemperature, externalTemperature)) / m_pContext.m_pObject.GetData().GetBarrelHeatCapacity(); + nextTemperature = Math.Max(nextTemperature, externalTemperature); + m_pContext.m_pObject.SetBarrelTemperature(nextTemperature); + m_pContext.m_pObject.SetJamChance(ComputeJamChance(nextTemperature)); + + if (m_pContext.m_pHelperAttachment) + m_pContext.m_pHelperAttachment.UpdateStats(ComputeMuzzleDispersionFactor(nextTemperature)); + + if (m_pContext.m_pGlowEffect) + m_pContext.m_pGlowEffect.SetIntensity(Math.Clamp(Math.InverseLerp(s_pSettings.m_fMinGlowTemperature, 1300, nextTemperature), 0, 1)); + } + + //------------------------------------------------------------------------------------------------ + //! Returns the accumulated heat by fired projectiles + protected float ComputeHeating(float timeSlice) + { + return s_pSettings.m_fHeatingScale * m_pContext.m_pObject.PopAccumulatedHeat(); + } + + //------------------------------------------------------------------------------------------------ + //! Returns the heat loss of the barrel through convection and radiation + protected float ComputeCooling(float timeSlice, float currentTemperature, float externalTemperature) + { + // Conductive and convective heat flux (Newton's law of cooling) + float heatFlux = -ComputeHeatTransferCoefficient() * (currentTemperature - externalTemperature); + // Radidative heat flux (Stefan-Boltzmann law) + heatFlux -= m_pContext.m_pObject.GetData().GetBarrelEmissivity() * ACE_PhysicalConstants.STEFAN_BOLTZMANN * (Math.Pow(currentTemperature, 4) - Math.Pow(externalTemperature, 4)); + return heatFlux * m_pContext.m_pObject.GetData().GetBarrelSurfaceArea() * timeSlice; + } + + //------------------------------------------------------------------------------------------------ + //! Returns heat transfer coefficient in W / (m^2 * K) + //------------------------------------------------------------------------------------------------ + //! Equation (1): Nu = 0.26 * Re^0.6 * Pr^0.37 for Re in [1000, 20000] + //! Reference: A. Žukauskas, Adv. Heat Transfer 1972, 8, 131. + //------------------------------------------------------------------------------------------------ + //! AIR + //! --- + //! Relation: h = 4.5908 * v^0.6 / d^0.4 + //! + //! Derived from equation (1) with + //! - Pr(air) = 0.714672 + //! - k(air) = 0.02614 W/(m*K) + //! - η(air) = 1.846e-5 kg/(m*s) + //! - ρ(air) = 1.1839 kg/m^3 + //------------------------------------------------------------------------------------------------ + //! RAIN + //! ---- + //! Relation: h = RI * 9.3198 / d^0.4 + //! + //! Derived from equation (1), such that h = 50 for rain intensity (RI) = 1 and d = 0.015 m + //------------------------------------------------------------------------------------------------ + //! TO DO: Account for water and better relation for rain + protected float ComputeHeatTransferCoefficient() + { + vector airVelocity = s_pWeatherManager.GetWindSpeed() * vector.FromYaw(s_pWeatherManager.GetWindDirection()); + + if (!m_pContext.m_pOwnerChar.IsInVehicle()) + airVelocity += m_pContext.m_pOwnerChar.GetPhysics().GetVelocity(); + + float h = 4.5908 * Math.Pow(airVelocity.LengthSq(), 3.0 / 10.0) + 9.3198 * s_pWeatherManager.GetRainIntensity(); + h /= Math.Pow(m_pContext.m_pObject.GetData().GetBarrelDiameter(), 0.4); + h = Math.Max(12.5, h); + + if (m_pContext.m_bIsChamberingPossible) + h *= s_pSettings.m_fDefaultAirCoolingScale; + else + h *= s_pSettings.m_fOpenBoltAirCoolingScale; + + h += s_pSettings.m_fBaseHeatTransferCoefficient; + + #ifdef ENABLE_DIAG + m_pContext.m_pObject.SetHeatTransferCoefficient(h); + #endif + + return h; + } + + //------------------------------------------------------------------------------------------------ + protected float ComputeJamChance(float temperature) + { + return s_pSettings.m_fJamChanceScale * m_pContext.m_pObject.GetData().ComputeJamChance(temperature); + } + + //------------------------------------------------------------------------------------------------ + protected float ComputeMuzzleDispersionFactor(float temperature) + { + return 1 + s_pSettings.m_fMuzzleDispersionScale * m_pContext.m_pObject.GetData().ComputeAdditionalMuzzleDispersionFactor(temperature); + } + + //------------------------------------------------------------------------------------------------ + void SetContext(ACE_Overheating_BarrelContext context) + { + m_pContext = context; + } + + //------------------------------------------------------------------------------------------------ + ACE_Overheating_BarrelContext GetContext() + { + return m_pContext; + } +} diff --git a/addons/overheating/scripts/Game/ACE_Overheating/Jobs/Contexts/ACE_Overheating_BarrelContext.c b/addons/overheating/scripts/Game/ACE_Overheating/Jobs/Contexts/ACE_Overheating_BarrelContext.c new file mode 100644 index 000000000..589fb041f --- /dev/null +++ b/addons/overheating/scripts/Game/ACE_Overheating/Jobs/Contexts/ACE_Overheating_BarrelContext.c @@ -0,0 +1,24 @@ +//------------------------------------------------------------------------------------------------ +class ACE_Overheating_BarrelContext : ACE_FrameJobScheduler_IObjectContext +{ + SCR_ChimeraCharacter m_pOwnerChar; + ACE_Overheating_BarrelGlowEffectComponent m_pGlowEffect; + ACE_Overheating_HelperAttachmentComponent m_pHelperAttachment; + bool m_bIsChamberingPossible; + + //------------------------------------------------------------------------------------------------ + void ACE_Overheating_BarrelContext(ACE_Overheating_BarrelComponent object) + { + m_pOwnerChar = SCR_ChimeraCharacter.Cast(object.GetOwner().GetParent()); + MuzzleComponent muzzle = object.GetMuzzle(); + m_bIsChamberingPossible = muzzle.IsChamberingPossible(); + m_pHelperAttachment = ACE_Overheating_HelperAttachmentComponent.Cast(muzzle.FindComponent(ACE_Overheating_HelperAttachmentComponent)); + m_pGlowEffect = ACE_Overheating_BarrelGlowEffectComponent.FromMuzzle(muzzle); + } + + //------------------------------------------------------------------------------------------------ + override bool IsValid() + { + return m_pOwnerChar && m_pOwnerChar.GetPhysics() && super.IsValid(); + } +} diff --git a/addons/overheating/scripts/Game/ACE_Overheating/Jobs/Contexts/ACE_Overheating_CharacterContext.c b/addons/overheating/scripts/Game/ACE_Overheating/Jobs/Contexts/ACE_Overheating_CharacterContext.c new file mode 100644 index 000000000..0a07d448f --- /dev/null +++ b/addons/overheating/scripts/Game/ACE_Overheating/Jobs/Contexts/ACE_Overheating_CharacterContext.c @@ -0,0 +1,64 @@ +//------------------------------------------------------------------------------------------------ +class ACE_Overheating_CharacterContext : ACE_FrameJobScheduler_IObjectContext +{ + ACE_Overheating_BarrelComponent m_pBarrel; + BaseMuzzleComponent m_pMuzzle; + SCR_CharacterCommandHandlerComponent m_pCharCommandHandler; + bool m_bIsChamberingPossible; + + //------------------------------------------------------------------------------------------------ + void ACE_Overheating_CharacterContext(SCR_ChimeraCharacter object) + { + BaseWeaponManagerComponent weaponManager = object.GetWeaponManager(); + if (weaponManager) + OnWeaponChanged(weaponManager.GetCurrentWeapon(), null); + + EventHandlerManagerComponent eventHandlerManager = EventHandlerManagerComponent.Cast(object.FindComponent(EventHandlerManagerComponent)); + if (eventHandlerManager) + { + eventHandlerManager.RegisterScriptHandler("OnWeaponChanged", this, OnWeaponChanged); + eventHandlerManager.RegisterScriptHandler("OnMuzzleChanged", this, OnMuzzleChanged); + } + + m_pCharCommandHandler = SCR_CharacterCommandHandlerComponent.Cast(object.GetCommandHandler()); + } + + //------------------------------------------------------------------------------------------------ + //! Update fire handler when weapon changed + protected void OnWeaponChanged(BaseWeaponComponent newWeapon, BaseWeaponComponent prevWeapon) + { + m_pBarrel = ACE_Overheating_BarrelComponent.FromWeapon(newWeapon); + + m_pMuzzle = null; + if (m_pBarrel) + m_pMuzzle = m_pBarrel.GetMuzzle(); + + if (m_pMuzzle) + m_bIsChamberingPossible = m_pMuzzle.IsChamberingPossible(); + } + + //------------------------------------------------------------------------------------------------ + //! Update fire handler when muzzle changed + protected void OnMuzzleChanged(BaseWeaponComponent weapon, BaseMuzzleComponent newMuzzle, BaseMuzzleComponent prevMuzzle) + { + m_pBarrel = ACE_Overheating_BarrelComponent.FromMuzzle(newMuzzle); + + m_pMuzzle = newMuzzle; + if (m_pMuzzle) + m_bIsChamberingPossible = m_pMuzzle.IsChamberingPossible(); + } + + //------------------------------------------------------------------------------------------------ + void ~ACE_Overheating_CharacterContext() + { + if (!m_pObject) + return; + + EventHandlerManagerComponent eventHandlerManager = EventHandlerManagerComponent.Cast(m_pObject.FindComponent(EventHandlerManagerComponent)); + if (eventHandlerManager) + { + eventHandlerManager.RemoveScriptHandler("OnWeaponChanged", this, OnWeaponChanged); + eventHandlerManager.RemoveScriptHandler("OnMuzzleChanged", this, OnMuzzleChanged); + } + } +} diff --git a/addons/overheating/scripts/Game/ACE_Overheating/Mission/ACE_MissionHeaderSettings.c b/addons/overheating/scripts/Game/ACE_Overheating/Mission/ACE_MissionHeaderSettings.c new file mode 100644 index 000000000..ed20533de --- /dev/null +++ b/addons/overheating/scripts/Game/ACE_Overheating/Mission/ACE_MissionHeaderSettings.c @@ -0,0 +1,18 @@ +//------------------------------------------------------------------------------------------------ +//! Add mod settings to mission header +[BaseContainerProps()] +modded class ACE_MissionHeaderSettings +{ + [Attribute()] + protected ref ACE_Overheating_Settings m_ACE_Overheating; + + //------------------------------------------------------------------------------------------------ + //! Applies settings from mission header to config + override void ApplyToSettingsConfig(notnull ACE_SettingsConfig config) + { + super.ApplyToSettingsConfig(config); + + if (m_ACE_Overheating) + config.SetModSettings(m_ACE_Overheating); + } +} diff --git a/addons/overheating/scripts/Game/ACE_Overheating/Network/Notifications/ENotification.c b/addons/overheating/scripts/Game/ACE_Overheating/Network/Notifications/ENotification.c new file mode 100644 index 000000000..f19becab9 --- /dev/null +++ b/addons/overheating/scripts/Game/ACE_Overheating/Network/Notifications/ENotification.c @@ -0,0 +1,5 @@ +//------------------------------------------------------------------------------------------------ +modded enum ENotification +{ + ACE_OVERHEATING_BARREL_TEMPERATURE_RESULT, +} \ No newline at end of file diff --git a/addons/overheating/scripts/Game/ACE_Overheating/Player/SCR_PlayerController.c b/addons/overheating/scripts/Game/ACE_Overheating/Player/SCR_PlayerController.c new file mode 100644 index 000000000..d4467f654 --- /dev/null +++ b/addons/overheating/scripts/Game/ACE_Overheating/Player/SCR_PlayerController.c @@ -0,0 +1,150 @@ +//------------------------------------------------------------------------------------------------ +modded class SCR_PlayerController : PlayerController +{ + //------------------------------------------------------------------------------------------------ + override protected void OnControlledEntityChanged(IEntity from, IEntity to) + { + super.OnControlledEntityChanged(from, to); + + RplComponent rpl = RplComponent.Cast(FindComponent(RplComponent)); + if (!rpl) + return; + + SCR_ChimeraCharacter fromChar = SCR_ChimeraCharacter.Cast(from); + if (fromChar) + { + ACE_Overheating_JammingSystem jammingSystem = ACE_Overheating_JammingSystem.GetInstance(); + if (jammingSystem) + jammingSystem.Unregister(fromChar, rpl.IsOwner()); + + // Server side deregistrations + if (!rpl.IsProxy()) + { + EquipedWeaponStorageComponent weaponStorage = EquipedWeaponStorageComponent.Cast(fromChar.FindComponent(EquipedWeaponStorageComponent)); + if (weaponStorage) + weaponStorage.ACE_Overheating_ToggleRegisterWeapons(false); + + ACE_Overheating_AmmoTemperatureSystem ammoSystem = ACE_Overheating_AmmoTemperatureSystem.GetInstance(); + if (ammoSystem) + ammoSystem.Unregister(fromChar); + } + } + + SCR_ChimeraCharacter toChar = SCR_ChimeraCharacter.Cast(to); + if (toChar) + { + ACE_Overheating_JammingSystem jammingSystem = ACE_Overheating_JammingSystem.GetInstance(); + if (jammingSystem) + jammingSystem.Register(toChar, rpl.IsOwner()); + + // Server side registrations + if (!rpl.IsProxy()) + { + EquipedWeaponStorageComponent weaponStorage = EquipedWeaponStorageComponent.Cast(toChar.FindComponent(EquipedWeaponStorageComponent)); + if (weaponStorage) + weaponStorage.ACE_Overheating_ToggleRegisterWeapons(true); + + ACE_Overheating_AmmoTemperatureSystem ammoSystem = ACE_Overheating_AmmoTemperatureSystem.GetInstance(); + if (ammoSystem) + ammoSystem.Register(toChar); + } + } + } + + //------------------------------------------------------------------------------------------------ + void ACE_Overheating_RequestSetJamState(ACE_Overheating_BarrelComponent barrel, bool state) + { + Rpc(RplAsk_ACE_Overheating_RequestSetJamStateServer, Replication.FindItemId(barrel), state); + } + + //------------------------------------------------------------------------------------------------ + [RplRpc(RplChannel.Reliable, RplRcver.Server)] + protected void RplAsk_ACE_Overheating_RequestSetJamStateServer(RplId barrelID, bool state) + { + ACE_Overheating_BarrelComponent barrel = ACE_Overheating_BarrelComponent.Cast(Replication.FindItem(barrelID)); + if (barrel) + barrel.SetState(state); + } + + //------------------------------------------------------------------------------------------------ + void ACE_Overheating_RequestWeaponStateNotification(ENotification type, BaseWeaponComponent weapon) + { + Rpc(RpcAsk_ACE_Overheating_SendWeaponStateNotification, type, Replication.FindItemId(weapon)); + } + + //------------------------------------------------------------------------------------------------ + [RplRpc(RplChannel.Reliable, RplRcver.Server)] + protected void RpcAsk_ACE_Overheating_SendWeaponStateNotification(ENotification type, RplId weaponId) + { + BaseWeaponComponent weapon = BaseWeaponComponent.Cast(Replication.FindItem(weaponId)); + if (!weapon) + return; + + ACE_Overheating_BarrelComponent barrel = ACE_Overheating_BarrelComponent.FromWeapon(weapon); + if (!barrel) + return; + + int param1; + switch (type) + { + case ENotification.ACE_OVERHEATING_BARREL_TEMPERATURE_RESULT: + { + param1 = barrel.GetBarrelTemperature() - ACE_PhysicalConstants.ZERO_CELSIUS; + break; + } + } + + SCR_NotificationsComponent.SendToPlayer(GetPlayerId(), type, param1); + } + + //------------------------------------------------------------------------------------------------ + void ACE_Overheating_RequestSwapBarrel(BaseWeaponComponent weapon) + { + Rpc(RpcAsk_ACE_Overheating_SwapBarrel, Replication.FindItemId(weapon)); + } + + //------------------------------------------------------------------------------------------------ + [RplRpc(RplChannel.Reliable, RplRcver.Server)] + protected void RpcAsk_ACE_Overheating_SwapBarrel(RplId weaponId) + { + BaseWeaponComponent weapon = BaseWeaponComponent.Cast(Replication.FindItem(weaponId)); + if (!weapon) + return; + + ACE_Overheating_BarrelComponent barrel = ACE_Overheating_BarrelComponent.FromWeapon(weapon); + if (barrel) + barrel.SetBarrelTemperature(ACE_WeatherHelper.GetAirTemperatureForEntity(weapon.GetOwner())); + + ACE_Overheating_BarrelGlowEffectComponent glowEffect = ACE_Overheating_BarrelGlowEffectComponent.FromMuzzle(weapon.GetCurrentMuzzle()); + if (glowEffect) + glowEffect.ForceIntensity(0); + } + + //------------------------------------------------------------------------------------------------ + void ACE_Overheating_RequestCoolBarrel(BaseWeaponComponent weapon) + { + Rpc(RpcAsk_ACE_Overheating_CoolBarrel, Replication.FindItemId(weapon)); + } + + //------------------------------------------------------------------------------------------------ + [RplRpc(RplChannel.Reliable, RplRcver.Server)] + protected void RpcAsk_ACE_Overheating_CoolBarrel(RplId weaponId) + { + BaseWeaponComponent weapon = BaseWeaponComponent.Cast(Replication.FindItem(weaponId)); + if (!weapon) + return; + + ACE_Overheating_BarrelComponent barrel = ACE_Overheating_BarrelComponent.FromWeapon(weapon); + if (!barrel) + return; + + ACE_Overheating_Settings settings = ACE_SettingsHelperT.GetModSettings(); + if (!settings) + return; + + ACE_Overheating_BarrelTemperatureJob job = new ACE_Overheating_BarrelTemperatureJob(); + job.SetContext(new ACE_Overheating_BarrelContext(barrel)); + job.OnUpdate(settings.m_fWaterCoolingScale); + RpcAsk_ACE_Overheating_SendWeaponStateNotification(ENotification.ACE_OVERHEATING_BARREL_TEMPERATURE_RESULT, weaponId); + } +} diff --git a/addons/overheating/scripts/Game/ACE_Overheating/Settings/ACE_Overheating_Settings.c b/addons/overheating/scripts/Game/ACE_Overheating/Settings/ACE_Overheating_Settings.c new file mode 100644 index 000000000..1aa06edd9 --- /dev/null +++ b/addons/overheating/scripts/Game/ACE_Overheating/Settings/ACE_Overheating_Settings.c @@ -0,0 +1,42 @@ +//------------------------------------------------------------------------------------------------ +[BaseContainerProps()] +class ACE_Overheating_Settings : ACE_ModSettings +{ + [Attribute(defvalue: "1.0", desc: "Scales the heat transferred to the barrel by a shot. The larger, the faster the temperature of the barrel increases.", params: "0 inf")] + float m_fHeatingScale; + + [Attribute(defvalue: "1.0", desc: "Scale for how quickly a weapon gets cooled down by air. Cooling rate is multiplied by this scale.", params: "0 inf")] + float m_fDefaultAirCoolingScale; + + [Attribute(defvalue: "1.3", desc: "Scale for how quickly a weapon gets cooled down by air for open bolt weapons.", params: "0 inf")] + float m_fOpenBoltAirCoolingScale; + + [Attribute(defvalue: "18", desc: "Scale for how quickly a weapon cools down in water.", params: "0 inf")] + float m_fWaterCoolingScale; + + [Attribute(defvalue: "1.0", desc: "Scale for how likely a weapon jams.", params: "0 inf")] + float m_fJamChanceScale; + + [Attribute(defvalue: "0.1", desc: "Probability for clearing jam to fail.", params: "0 1")] + float m_fClearJamFailureChance; + + // The reference data (A. Hameed et al., Defence Technology 2014, 10, 86–91) with which our model was fitted used Bullseye propellant (433.15 K), but for ACE, we take the upper limit of Ball propellant (473.15 K) + [Attribute(defvalue: "473.15", desc: "Temperature at which ammo can cook off [K].", params: "0 1300")] + float m_fGunpowderAutoignitionTemperature; + + // Fit to M60 model, such that cook-off progress will exactly reach 1.0 and then stop progressing for the next bullet and T_barrel_final=35°C when firing 100 RPM for 2 minutes and then cease fire for 15 minutes. + [Attribute(defvalue: "125.63", desc: "Base heat transfer coefficient for cooling of barrel from other channels than radiation and convection from wind and rain.", params: "0 inf")] + float m_fBaseHeatTransferCoefficient; + + // MassScaledTemperatureRateConstant [g/s] = HeatTransferCoefficient [J/(s*m^2*K)] * SurfaceArea [m^2] / SpecificHeat [J/(g*K)] + // The fit of reference data (A. Hameed et al., Defence Technology 2014, 10, 86–91) would be 30.4587377 g/s, but we assume that heat transfer from barrel to bullet is far less efficient than in the experimental configuration of the paper + // "*1/15" is closer to the tail at high T of ACE3's cook-off time vs barrel temperature + [Attribute(defvalue: "2.031", desc: "Mass-scaled temperature rate constant for heat exchange between barrel and bullet [g/s]. The larger, the faster a chambered bullet will heat up to barrel temperature.", params: "0 inf")] + float m_fBarrel2BulletMassScaledTemperatureRateConstant; + + [Attribute(defvalue: "1.0", desc: "Scales the additional temperature-dependent dispersion of shots. Set to 0.0 to turn it off.", params: "0 inf")] + float m_fMuzzleDispersionScale; + + [Attribute(defvalue: "800", desc: "Temperature above which barrel starts glowing [K].", params: "0 1300")] + float m_fMinGlowTemperature; +} diff --git a/addons/overheating/scripts/Game/ACE_Overheating/Systems/ACE_Overheating_AmmoTemperatureSystem.c b/addons/overheating/scripts/Game/ACE_Overheating/Systems/ACE_Overheating_AmmoTemperatureSystem.c new file mode 100644 index 000000000..5f4fa1273 --- /dev/null +++ b/addons/overheating/scripts/Game/ACE_Overheating/Systems/ACE_Overheating_AmmoTemperatureSystem.c @@ -0,0 +1,56 @@ +//------------------------------------------------------------------------------------------------ +class ACE_Overheating_AmmoTemperatureSystem : GameSystem +{ + [Attribute()] + protected ref ACE_Overheating_AmmoTemperature_JobScheduler m_pScheduler; + + //------------------------------------------------------------------------------------------------ + static ACE_Overheating_AmmoTemperatureSystem GetInstance() + { + ChimeraWorld world = GetGame().GetWorld(); + return ACE_Overheating_AmmoTemperatureSystem.Cast(world.FindSystem(ACE_Overheating_AmmoTemperatureSystem)); + } + + //------------------------------------------------------------------------------------------------ + //! Should be paused when the world is not running + override bool ShouldBePaused() + { + return true; + } + + //------------------------------------------------------------------------------------------------ + override static void InitInfo(WorldSystemInfo outInfo) + { + outInfo.SetAbstract(false) + .SetUnique(true) + .SetLocation(ESystemLocation.Server); + } + + //------------------------------------------------------------------------------------------------ + override protected void OnInit() + { + m_pScheduler.OnInit(CreateTemplateJob()); + + ACE_FrameJobSystem jobManager = ACE_FrameJobSystem.GetInstance(); + if (jobManager) + jobManager.Register(m_pScheduler, ESystemPoint.Frame); + } + + //------------------------------------------------------------------------------------------------ + protected ACE_Overheating_AmmoTemperatureJob CreateTemplateJob() + { + return new ACE_Overheating_AmmoTemperatureJob(); + } + + //------------------------------------------------------------------------------------------------ + void Register(notnull SCR_ChimeraCharacter char) + { + m_pScheduler.Register(char); + } + + //------------------------------------------------------------------------------------------------ + void Unregister(SCR_ChimeraCharacter char) + { + m_pScheduler.Unregister(char); + } +} diff --git a/addons/overheating/scripts/Game/ACE_Overheating/Systems/ACE_Overheating_BarrelTemperatureSystem.c b/addons/overheating/scripts/Game/ACE_Overheating/Systems/ACE_Overheating_BarrelTemperatureSystem.c new file mode 100644 index 000000000..5672fdb40 --- /dev/null +++ b/addons/overheating/scripts/Game/ACE_Overheating/Systems/ACE_Overheating_BarrelTemperatureSystem.c @@ -0,0 +1,56 @@ +//------------------------------------------------------------------------------------------------ +class ACE_Overheating_BarrelTemperatureSystem : GameSystem +{ + [Attribute()] + protected ref ACE_Overheating_BarrelTemperature_JobScheduler m_pScheduler; + + //------------------------------------------------------------------------------------------------ + static ACE_Overheating_BarrelTemperatureSystem GetInstance() + { + ChimeraWorld world = GetGame().GetWorld(); + return ACE_Overheating_BarrelTemperatureSystem.Cast(world.FindSystem(ACE_Overheating_BarrelTemperatureSystem)); + } + + //------------------------------------------------------------------------------------------------ + //! Should be paused when the world is not running + override bool ShouldBePaused() + { + return true; + } + + //------------------------------------------------------------------------------------------------ + override static void InitInfo(WorldSystemInfo outInfo) + { + outInfo.SetAbstract(false) + .SetUnique(true) + .SetLocation(ESystemLocation.Server); + } + + //------------------------------------------------------------------------------------------------ + override protected void OnInit() + { + m_pScheduler.OnInit(CreateTemplateJob()); + + ACE_FrameJobSystem jobManager = ACE_FrameJobSystem.GetInstance(); + if (jobManager) + jobManager.Register(m_pScheduler, ESystemPoint.Frame); + } + + //------------------------------------------------------------------------------------------------ + protected ACE_Overheating_BarrelTemperatureJob CreateTemplateJob() + { + return new ACE_Overheating_BarrelTemperatureJob(); + } + + //------------------------------------------------------------------------------------------------ + void Register(notnull ACE_Overheating_BarrelComponent barrel) + { + m_pScheduler.Register(barrel); + } + + //------------------------------------------------------------------------------------------------ + void Unregister(ACE_Overheating_BarrelComponent barrel) + { + m_pScheduler.Unregister(barrel); + } +} diff --git a/addons/overheating/scripts/Game/ACE_Overheating/Systems/ACE_Overheating_JammingSystem.c b/addons/overheating/scripts/Game/ACE_Overheating/Systems/ACE_Overheating_JammingSystem.c new file mode 100644 index 000000000..dfb7fbc0b --- /dev/null +++ b/addons/overheating/scripts/Game/ACE_Overheating/Systems/ACE_Overheating_JammingSystem.c @@ -0,0 +1,151 @@ +//------------------------------------------------------------------------------------------------ +class ACE_Overheating_JammingSystem : GameSystem +{ + protected ACE_Overheating_BarrelComponent m_pLocalActiveBarrel = null; + + //------------------------------------------------------------------------------------------------ + static ACE_Overheating_JammingSystem GetInstance() + { + ChimeraWorld world = GetGame().GetWorld(); + return ACE_Overheating_JammingSystem.Cast(world.FindSystem(ACE_Overheating_JammingSystem)); + } + + //------------------------------------------------------------------------------------------------ + void Register(notnull ChimeraCharacter char, bool isOwner) + { + EventHandlerManagerComponent eventHandlerManager = EventHandlerManagerComponent.Cast(char.FindComponent(EventHandlerManagerComponent)); + if (!eventHandlerManager) + return; + + if (Replication.IsServer()) + eventHandlerManager.RegisterScriptHandler("OnProjectileShot", this, OnProjectileShot); + + if (isOwner) + { + BaseWeaponManagerComponent weaponManager = char.GetWeaponManager(); + if (weaponManager) + OnWeaponChangedLocal(weaponManager.GetCurrentWeapon(), null); + + eventHandlerManager.RegisterScriptHandler("OnWeaponChanged", this, OnWeaponChangedLocal); + eventHandlerManager.RegisterScriptHandler("OnMuzzleChanged", this, OnMuzzleChangedLocal); + } + } + + //------------------------------------------------------------------------------------------------ + void Unregister(notnull ChimeraCharacter char, bool isOwner) + { + EventHandlerManagerComponent eventHandlerManager = EventHandlerManagerComponent.Cast(char.FindComponent(EventHandlerManagerComponent)); + if (!eventHandlerManager) + return; + + if (Replication.IsServer()) + eventHandlerManager.RemoveScriptHandler("OnProjectileShot", this, OnProjectileShot); + + if (isOwner) + { + eventHandlerManager.RemoveScriptHandler("OnWeaponChanged", this, OnWeaponChangedLocal); + eventHandlerManager.RemoveScriptHandler("OnMuzzleChanged", this, OnMuzzleChangedLocal); + m_pLocalActiveBarrel = null; + UpdateFireHandlerLocal(char, true); + } + } + + //------------------------------------------------------------------------------------------------ + protected void OnProjectileShot(int playerID, BaseWeaponComponent weapon, IEntity entity) + { + ACE_Overheating_BarrelComponent barrel = ACE_Overheating_BarrelComponent.FromWeapon(weapon); + if (!barrel) + return; + + // TO DO: Move to temperature systems + barrel.IncremenHeatCounter(); + barrel.SetAmmoTemperature(ACE_WeatherHelper.GetAirTemperatureForEntity(weapon.GetOwner())); + barrel.SetCookOffProgress(0); + + if (Math.RandomFloat(0, 1) < barrel.GetJamChance()) + barrel.SetState(true); + } + + //------------------------------------------------------------------------------------------------ + void OnJamStateChanged(ACE_Overheating_BarrelComponent barrel, bool isJammed) + { + //! Only handle on local client + if (m_pLocalActiveBarrel != barrel) + return; + + ChimeraCharacter localPlayer = ChimeraCharacter.Cast(SCR_PlayerController.GetLocalControlledEntity()); + if (!localPlayer) + return; + + if (isJammed) + GetGame().GetCallqueue().CallLater(PlayWeaponSound, 500, false, barrel.GetOwner(), "SOUND_RELOAD_BOLT_PULL"); + + UpdateFireHandlerLocal(localPlayer, !isJammed); + } + + //------------------------------------------------------------------------------------------------ + //! Update fire handler when weapon changed + protected void OnWeaponChangedLocal(BaseWeaponComponent newWeapon, BaseWeaponComponent prevWeapon) + { + ChimeraCharacter localPlayer = ChimeraCharacter.Cast(SCR_PlayerController.GetLocalControlledEntity()); + if (!localPlayer) + return; + + m_pLocalActiveBarrel = ACE_Overheating_BarrelComponent.FromWeapon(newWeapon); + UpdateFireHandlerLocal(localPlayer, !m_pLocalActiveBarrel || !m_pLocalActiveBarrel.IsJammed()); + } + + //------------------------------------------------------------------------------------------------ + //! Update fire handler when muzzle changed + protected void OnMuzzleChangedLocal(BaseWeaponComponent weapon, BaseMuzzleComponent newMuzzle, BaseMuzzleComponent prevMuzzle) + { + ChimeraCharacter localPlayer = ChimeraCharacter.Cast(SCR_PlayerController.GetLocalControlledEntity()); + if (!localPlayer) + return; + + m_pLocalActiveBarrel = ACE_Overheating_BarrelComponent.FromMuzzle(newMuzzle); + UpdateFireHandlerLocal(localPlayer, !m_pLocalActiveBarrel || !m_pLocalActiveBarrel.IsJammed()); + } + + //------------------------------------------------------------------------------------------------ + //! Update fire handler + protected void UpdateFireHandlerLocal(ChimeraCharacter char, bool canHandleWeaponFire) + { + CharacterAnimationComponent animComponent = char.GetAnimationComponent(); + if (!animComponent) + return; + + SCR_CharacterCommandHandlerComponent cmdHandler = SCR_CharacterCommandHandlerComponent.Cast(animComponent.GetCommandHandler()); + if (!cmdHandler) + return; + + cmdHandler.ACE_SetCanHandleWeaponFire(canHandleWeaponFire); + + GetGame().GetInputManager().RemoveActionListener("CharacterFire", EActionTrigger.DOWN, OnFireFailedLocal); + + if (!canHandleWeaponFire) + GetGame().GetInputManager().AddActionListener("CharacterFire", EActionTrigger.DOWN, OnFireFailedLocal); + } + + //------------------------------------------------------------------------------------------------ + //! Play dry sound + protected void OnFireFailedLocal(float value = 0.0, EActionTrigger trigger = 0) + { + if (m_pLocalActiveBarrel) + PlayWeaponSound(m_pLocalActiveBarrel.GetOwner(), "SOUND_DRY"); + } + + //------------------------------------------------------------------------------------------------ + protected void PlayWeaponSound(IEntity weapon, string soundEvent) + { + WeaponSoundComponent soundComponent = WeaponSoundComponent.Cast(weapon.FindComponent(WeaponSoundComponent)); + if (soundComponent) + soundComponent.SoundEvent(soundEvent); + } + + //------------------------------------------------------------------------------------------------ + ACE_Overheating_BarrelComponent GetLocalActiveBarrel() + { + return m_pLocalActiveBarrel; + } +} diff --git a/addons/overheating/scripts/Game/ACE_Overheating/UI/HUD/AvailableActions/Conditions/ACE_Overheating_IsCharacterWeaponJammedCondition.c b/addons/overheating/scripts/Game/ACE_Overheating/UI/HUD/AvailableActions/Conditions/ACE_Overheating_IsCharacterWeaponJammedCondition.c new file mode 100644 index 000000000..81244c224 --- /dev/null +++ b/addons/overheating/scripts/Game/ACE_Overheating/UI/HUD/AvailableActions/Conditions/ACE_Overheating_IsCharacterWeaponJammedCondition.c @@ -0,0 +1,14 @@ +//------------------------------------------------------------------------------------------------ +[BaseContainerProps()] +class ACE_Overheating_IsCharacterWeaponJammedCondition : SCR_AvailableActionCondition +{ + //------------------------------------------------------------------------------------------------ + //! Returns true if the release action is available + override bool IsAvailable(SCR_AvailableActionsConditionData data) + { + if (!data) + return false; + + return GetReturnResult(data.ACE_Overheating_GetIsCharacterWeaponJammed()); + } +} diff --git a/addons/overheating/scripts/Game/ACE_Overheating/UI/HUD/AvailableActions/SCR_AvailableActionsConditionData.c b/addons/overheating/scripts/Game/ACE_Overheating/UI/HUD/AvailableActions/SCR_AvailableActionsConditionData.c new file mode 100644 index 000000000..533230a2b --- /dev/null +++ b/addons/overheating/scripts/Game/ACE_Overheating/UI/HUD/AvailableActions/SCR_AvailableActionsConditionData.c @@ -0,0 +1,41 @@ +//------------------------------------------------------------------------------------------------ +modded class SCR_AvailableActionsConditionData +{ + protected bool m_bACE_Overheating_IsCharacterWeaponJammed; + + //------------------------------------------------------------------------------------------------ + //! Clears all variables by setting them to their default state + //! Also invalidates this data + override protected void ACE_Clear() + { + super.ACE_Clear(); + m_bACE_Overheating_IsCharacterWeaponJammed = false; + } + + //------------------------------------------------------------------------------------------------ + //! Returns whether character is carrying + bool ACE_Overheating_GetIsCharacterWeaponJammed() + { + return m_bACE_Overheating_IsCharacterWeaponJammed; + } + + //------------------------------------------------------------------------------------------------ + // Fetch data + //------------------------------------------------------------------------------------------------ + + //------------------------------------------------------------------------------------------------ + //! Fetches data from the provided entity + //! Sets the validity of the data which can be received via IsValid() + override void FetchData(IEntity controlledEntity, float timeSlice) + { + super.FetchData(controlledEntity, timeSlice); + + ACE_Overheating_JammingSystem system = ACE_Overheating_JammingSystem.GetInstance(); + if (!system) + return; + + ACE_Overheating_BarrelComponent barrel = system.GetLocalActiveBarrel(); + if (barrel) + m_bACE_Overheating_IsCharacterWeaponJammed = barrel.IsJammed(); + } +} diff --git a/addons/overheating/scripts/Game/ACE_Overheating/UserActions/Inspection/ACE_Overheating_CheckWeaponUserAction.c b/addons/overheating/scripts/Game/ACE_Overheating/UserActions/Inspection/ACE_Overheating_CheckWeaponUserAction.c new file mode 100644 index 000000000..24bd399e2 --- /dev/null +++ b/addons/overheating/scripts/Game/ACE_Overheating/UserActions/Inspection/ACE_Overheating_CheckWeaponUserAction.c @@ -0,0 +1,14 @@ +//------------------------------------------------------------------------------------------------ +class ACE_Overheating_CheckWeaponUserAction : SCR_InspectionUserAction +{ + [Attribute(uiwidget: UIWidgets.SearchComboBox, desc: "Type of the notification", enums: ParamEnumArray.FromEnum(ENotification))] + protected ENotification m_eNotificationType; + + //------------------------------------------------------------------------------------------------ + override protected void PerformActionInternal(SCR_InventoryStorageManagerComponent manager, IEntity pOwnerEntity, IEntity pUserEntity) + { + SCR_PlayerController playerController = SCR_PlayerController.Cast(GetGame().GetPlayerController()); + if (playerController) + playerController.ACE_Overheating_RequestWeaponStateNotification(m_eNotificationType, m_WeaponComponent); + } +} diff --git a/addons/overheating/scripts/Game/ACE_Overheating/UserActions/Inspection/ACE_Overheating_CoolBarrelInWaterUserAction.c b/addons/overheating/scripts/Game/ACE_Overheating/UserActions/Inspection/ACE_Overheating_CoolBarrelInWaterUserAction.c new file mode 100644 index 000000000..ca6199b4f --- /dev/null +++ b/addons/overheating/scripts/Game/ACE_Overheating/UserActions/Inspection/ACE_Overheating_CoolBarrelInWaterUserAction.c @@ -0,0 +1,40 @@ +//------------------------------------------------------------------------------------------------ +class ACE_Overheating_CoolBarrelInWaterUserAction : SCR_InspectionUserAction +{ + protected float m_fTimer; + + //------------------------------------------------------------------------------------------------ + override bool CanBeShownScript(IEntity user) + { + if (!super.CanBeShownScript(user)) + return false; + + SCR_CharacterBuoyancyComponent buoyancy = SCR_CharacterBuoyancyComponent.Cast(user.FindComponent(SCR_CharacterBuoyancyComponent)); + if (!buoyancy) + return false; + + return buoyancy.IsInWater(); + } + + //------------------------------------------------------------------------------------------------ + override protected void OnActionStart(IEntity pUserEntity) + { + SCR_UISoundEntity.SoundEvent("ACE_OVERHEATING_SOUND_COOL_BARREL"); + } + + //------------------------------------------------------------------------------------------------ + override float GetActionProgressScript(float fProgress, float timeSlice) + { + fProgress = super.GetActionProgressScript(fProgress, timeSlice); + float overProgress = fProgress - GetActionDuration(); + + if (overProgress < 0) + return fProgress; + + SCR_PlayerController playerController = SCR_PlayerController.Cast(GetGame().GetPlayerController()); + if (playerController) + playerController.ACE_Overheating_RequestCoolBarrel(m_WeaponComponent); + + return overProgress; + } +} diff --git a/addons/overheating/scripts/Game/ACE_Overheating/UserActions/Inspection/ACE_Overheating_SwapBarrelUserAction.c b/addons/overheating/scripts/Game/ACE_Overheating/UserActions/Inspection/ACE_Overheating_SwapBarrelUserAction.c new file mode 100644 index 000000000..470069b18 --- /dev/null +++ b/addons/overheating/scripts/Game/ACE_Overheating/UserActions/Inspection/ACE_Overheating_SwapBarrelUserAction.c @@ -0,0 +1,34 @@ +//------------------------------------------------------------------------------------------------ +class ACE_Overheating_SwapBarrelUserAction : SCR_InspectionUserAction +{ + bool m_bSecondSoundPlayed; + + //------------------------------------------------------------------------------------------------ + override protected void PerformActionInternal(SCR_InventoryStorageManagerComponent manager, IEntity pOwnerEntity, IEntity pUserEntity) + { + SCR_PlayerController playerController = SCR_PlayerController.Cast(GetGame().GetPlayerController()); + if (playerController) + playerController.ACE_Overheating_RequestSwapBarrel(m_WeaponComponent); + } + + //------------------------------------------------------------------------------------------------ + override protected void OnActionStart(IEntity pUserEntity) + { + SCR_UISoundEntity.SoundEvent("ACE_OVERHEATING_SOUND_SWAP_BARREL"); + m_bSecondSoundPlayed = false; + } + + //------------------------------------------------------------------------------------------------ + override float GetActionProgressScript(float fProgress, float timeSlice) + { + float progress = super.GetActionProgressScript(fProgress, timeSlice); + + if (!m_bSecondSoundPlayed && GetActionDuration() - progress < 2) + { + SCR_UISoundEntity.SoundEvent("ACE_OVERHEATING_SOUND_SWAP_BARREL"); + m_bSecondSoundPlayed = true; + } + + return progress; + } +} diff --git a/addons/overheating/scripts/Game/ACE_Overheating/Weapon/Attachments/ACE_Overheating_HelperAttachmentComponent.c b/addons/overheating/scripts/Game/ACE_Overheating/Weapon/Attachments/ACE_Overheating_HelperAttachmentComponent.c new file mode 100644 index 000000000..c73d16c8d --- /dev/null +++ b/addons/overheating/scripts/Game/ACE_Overheating/Weapon/Attachments/ACE_Overheating_HelperAttachmentComponent.c @@ -0,0 +1,56 @@ +//------------------------------------------------------------------------------------------------ +class ACE_Overheating_HelperAttachmentComponentClass : AttachmentSlotComponentClass +{ +} + +//------------------------------------------------------------------------------------------------ +//! Helper attachment slot for modifying weapon stats from overheating +class ACE_Overheating_HelperAttachmentComponent : AttachmentSlotComponent +{ + protected bool m_bInitDone = false; + protected ACE_Overheating_BarrelComponent m_pBarrel; + protected IEntity m_pAttachedEntity; + protected SCR_WeaponStatsManagerComponent m_pStatsManager; + + //------------------------------------------------------------------------------------------------ + void Init() + { + m_pAttachedEntity = GetAttachedEntity(); + m_pStatsManager = SCR_WeaponStatsManagerComponent.Cast(m_pAttachedEntity.GetParent().FindComponent(SCR_WeaponStatsManagerComponent)); + m_bInitDone = true; + } + + //------------------------------------------------------------------------------------------------ + void UpdateStats(float muzzleDispersionFactor) + { + if (!m_bInitDone) + Init(); + + if (!m_pStatsManager || !m_pAttachedEntity) + return; + + m_pStatsManager.SetMuzzleDispersionFactor(m_pAttachedEntity, 0, muzzleDispersionFactor); + // Only known way to force sync in MP is through reattaching the entity + SetAttachment(null); + SetAttachment(m_pAttachedEntity); + + #ifdef ENABLE_DIAG + m_fMuzzleDispersionFactor = muzzleDispersionFactor; + #endif + } + +#ifdef ENABLE_DIAG + protected float m_fMuzzleDispersionFactor; + + //------------------------------------------------------------------------------------------------ + float GetMuzzleDispersionFactor() + { + float factor; + + if (m_pStatsManager) + m_pStatsManager.GetMuzzleDispersionFactor(0, factor); + + return factor; + } +#endif +} diff --git a/addons/overheating/scripts/Game/tmp/Jobs/ACE_Overheating_AmmoTemperature_JobScheduler.c b/addons/overheating/scripts/Game/tmp/Jobs/ACE_Overheating_AmmoTemperature_JobScheduler.c new file mode 100644 index 000000000..ab9eb1118 --- /dev/null +++ b/addons/overheating/scripts/Game/tmp/Jobs/ACE_Overheating_AmmoTemperature_JobScheduler.c @@ -0,0 +1,163 @@ +//------------------------------------------------------------------------------------------------ +//! Manual template initialized copy of +//! ACE_TemplateFrameJobScheduler +//! as workaround for: +//! - https://feedback.bistudio.com/T193122 +//! - https://feedback.bistudio.com/T193389 +[BaseContainerProps()] +class ACE_Overheating_AmmoTemperature_JobScheduler : ACE_IFrameJob +{ + [Attribute(defvalue: "1000", desc: "Approximate update timeout for a particular object [ms]")] + protected int m_fObjectUpdateTimeoutMS; + + [Attribute(defvalue: "10", desc: "Maximum number of entities to be updated per frame")] + protected int m_iMaxIterationsPerFrame; + + protected ref ACE_Overheating_AmmoTemperatureJob m_pTemplateJob; + protected ref array m_aJobs = {}; + protected ref array m_aInitialObjectsToRegister = {}; + protected ACE_FrameJobScheduler_EState m_eState = ACE_FrameJobScheduler_EState.UPDATE_QUEUE; + protected float m_fNextUpdateStartTime = 0; + protected int m_iCurrentJobIdx = 0; + protected int m_iNumMachines = 0; + + //------------------------------------------------------------------------------------------------ + //! Template is passed here rather than in ctor for usage of ACE_TemplateFrameJobScheduler in attributes + void OnInit(ACE_Overheating_AmmoTemperatureJob templateJob) + { + m_pTemplateJob = templateJob; + + foreach (SCR_ChimeraCharacter object : m_aInitialObjectsToRegister) + { + Register(object); + } + + m_aInitialObjectsToRegister.Clear(); + } + + //------------------------------------------------------------------------------------------------ + override void OnUpdate(float timeSlice) + { + super.OnUpdate(timeSlice); + float currentTime = GetGame().GetWorld().GetWorldTime(); + + switch (m_eState) + { + case ACE_FrameJobScheduler_EState.UPDATE_QUEUE: return UpdateQueueStep(currentTime); + case ACE_FrameJobScheduler_EState.UPDATE_OBJECTS: return UpdateObjectsStep(currentTime); + case ACE_FrameJobScheduler_EState.TIMEOUT: return TimeoutStep(currentTime); + } + } + + //------------------------------------------------------------------------------------------------ + protected void UpdateQueueStep(float currentTime) + { + m_iNumMachines = m_aJobs.Count(); + + for (int i = m_iNumMachines - 1; i >= 0; --i) + { + ACE_Overheating_AmmoTemperatureJob job = m_aJobs[i]; + if (job.ShouldBeStopped()) + UnregisterNow(i); + } + + m_iCurrentJobIdx = 0; + m_iNumMachines = m_aJobs.Count(); + + if (m_iNumMachines == 0) + return ToggleUpdate(false); + + m_fNextUpdateStartTime = currentTime + m_fObjectUpdateTimeoutMS; + ChangeState(ACE_FrameJobScheduler_EState.UPDATE_OBJECTS); + } + + //------------------------------------------------------------------------------------------------ + protected void UpdateObjectsStep(float currentTime) + { + for (int i = 0; i < m_iMaxIterationsPerFrame; ++i) + { + ACE_Overheating_AmmoTemperatureJob job = m_aJobs[m_iCurrentJobIdx]; + ACE_Overheating_CharacterContext context = job.GetContext(); + + if (context.IsValid()) + job.OnUpdate((currentTime - context.m_fLastUpdateTime) / 1000); + else + job.Stop(); + + context.m_fLastUpdateTime = currentTime; + ++m_iCurrentJobIdx; + + if (m_iCurrentJobIdx >= m_iNumMachines) + return ChangeState(ACE_FrameJobScheduler_EState.TIMEOUT); + } + } + + //------------------------------------------------------------------------------------------------ + protected void TimeoutStep(float currentTime) + { + if (currentTime >= m_fNextUpdateStartTime) + ChangeState(ACE_FrameJobScheduler_EState.UPDATE_QUEUE); + } + + //------------------------------------------------------------------------------------------------ + protected void ChangeState(ACE_FrameJobScheduler_EState newState) + { + m_eState = newState; + } + + //------------------------------------------------------------------------------------------------ + void Register(SCR_ChimeraCharacter object) + { + if (!m_pTemplateJob) + { + m_aInitialObjectsToRegister.Insert(object); + return; + } + + ACE_Overheating_CharacterContext context = new ACE_Overheating_CharacterContext(object); + if (!context.IsValid()) + return; + + ACE_Overheating_AmmoTemperatureJob job = CreateJob(); + job.SetContext(context); + job.OnStart(); + m_aJobs.Insert(job); + + if (!ShouldBeUpdated()) + ToggleUpdate(true); + } + + //------------------------------------------------------------------------------------------------ + void Unregister(SCR_ChimeraCharacter object) + { + foreach (int i, ACE_Overheating_AmmoTemperatureJob job : m_aJobs) + { + if (job.GetContext().m_pObject == object) + { + // Delay unregistration, unless the queue isn't touched (e.g. during timeout) + if (m_eState == ACE_FrameJobScheduler_EState.TIMEOUT) + UnregisterNow(i); + else + job.Stop(); + + return; + } + } + } + + //------------------------------------------------------------------------------------------------ + protected void UnregisterNow(int machineIdx) + { + ACE_Overheating_AmmoTemperatureJob job = m_aJobs[machineIdx]; + m_aJobs.Remove(machineIdx); + job.OnStop(); + } + + //------------------------------------------------------------------------------------------------ + protected ACE_Overheating_AmmoTemperatureJob CreateJob() + { + ACE_Overheating_AmmoTemperatureJob instance = new ACE_Overheating_AmmoTemperatureJob(); + instance.CopyFrom(m_pTemplateJob); + return instance; + } +} diff --git a/addons/overheating/scripts/Game/tmp/Jobs/ACE_Overheating_BarrelTemperature_JobScheduler.c b/addons/overheating/scripts/Game/tmp/Jobs/ACE_Overheating_BarrelTemperature_JobScheduler.c new file mode 100644 index 000000000..2c449b97a --- /dev/null +++ b/addons/overheating/scripts/Game/tmp/Jobs/ACE_Overheating_BarrelTemperature_JobScheduler.c @@ -0,0 +1,163 @@ +//------------------------------------------------------------------------------------------------ +//! Manual template initialized copy of +//! ACE_TemplateFrameJobScheduler +//! as workaround for: +//! - https://feedback.bistudio.com/T193122 +//! - https://feedback.bistudio.com/T193389 +[BaseContainerProps()] +class ACE_Overheating_BarrelTemperature_JobScheduler : ACE_IFrameJob +{ + [Attribute(defvalue: "1000", desc: "Approximate update timeout for a particular object [ms]")] + protected int m_fObjectUpdateTimeoutMS; + + [Attribute(defvalue: "10", desc: "Maximum number of entities to be updated per frame")] + protected int m_iMaxIterationsPerFrame; + + protected ref ACE_Overheating_BarrelTemperatureJob m_pTemplateJob; + protected ref array m_aJobs = {}; + protected ref array m_aInitialObjectsToRegister = {}; + protected ACE_FrameJobScheduler_EState m_eState = ACE_FrameJobScheduler_EState.UPDATE_QUEUE; + protected float m_fNextUpdateStartTime = 0; + protected int m_iCurrentJobIdx = 0; + protected int m_iNumMachines = 0; + + //------------------------------------------------------------------------------------------------ + //! Template is passed here rather than in ctor for usage of ACE_TemplateFrameJobScheduler in attributes + void OnInit(ACE_Overheating_BarrelTemperatureJob templateJob) + { + m_pTemplateJob = templateJob; + + foreach (ACE_Overheating_BarrelComponent object : m_aInitialObjectsToRegister) + { + Register(object); + } + + m_aInitialObjectsToRegister.Clear(); + } + + //------------------------------------------------------------------------------------------------ + override void OnUpdate(float timeSlice) + { + super.OnUpdate(timeSlice); + float currentTime = GetGame().GetWorld().GetWorldTime(); + + switch (m_eState) + { + case ACE_FrameJobScheduler_EState.UPDATE_QUEUE: return UpdateQueueStep(currentTime); + case ACE_FrameJobScheduler_EState.UPDATE_OBJECTS: return UpdateObjectsStep(currentTime); + case ACE_FrameJobScheduler_EState.TIMEOUT: return TimeoutStep(currentTime); + } + } + + //------------------------------------------------------------------------------------------------ + protected void UpdateQueueStep(float currentTime) + { + m_iNumMachines = m_aJobs.Count(); + + for (int i = m_iNumMachines - 1; i >= 0; --i) + { + ACE_Overheating_BarrelTemperatureJob job = m_aJobs[i]; + if (job.ShouldBeStopped()) + UnregisterNow(i); + } + + m_iCurrentJobIdx = 0; + m_iNumMachines = m_aJobs.Count(); + + if (m_iNumMachines == 0) + return ToggleUpdate(false); + + m_fNextUpdateStartTime = currentTime + m_fObjectUpdateTimeoutMS; + ChangeState(ACE_FrameJobScheduler_EState.UPDATE_OBJECTS); + } + + //------------------------------------------------------------------------------------------------ + protected void UpdateObjectsStep(float currentTime) + { + for (int i = 0; i < m_iMaxIterationsPerFrame; ++i) + { + ACE_Overheating_BarrelTemperatureJob job = m_aJobs[m_iCurrentJobIdx]; + ACE_Overheating_BarrelContext context = job.GetContext(); + + if (context.IsValid()) + job.OnUpdate((currentTime - context.m_fLastUpdateTime) / 1000); + else + job.Stop(); + + context.m_fLastUpdateTime = currentTime; + ++m_iCurrentJobIdx; + + if (m_iCurrentJobIdx >= m_iNumMachines) + return ChangeState(ACE_FrameJobScheduler_EState.TIMEOUT); + } + } + + //------------------------------------------------------------------------------------------------ + protected void TimeoutStep(float currentTime) + { + if (currentTime >= m_fNextUpdateStartTime) + ChangeState(ACE_FrameJobScheduler_EState.UPDATE_QUEUE); + } + + //------------------------------------------------------------------------------------------------ + protected void ChangeState(ACE_FrameJobScheduler_EState newState) + { + m_eState = newState; + } + + //------------------------------------------------------------------------------------------------ + void Register(ACE_Overheating_BarrelComponent object) + { + if (!m_pTemplateJob) + { + m_aInitialObjectsToRegister.Insert(object); + return; + } + + ACE_Overheating_BarrelContext context = new ACE_Overheating_BarrelContext(object); + if (!context.IsValid()) + return; + + ACE_Overheating_BarrelTemperatureJob job = CreateJob(); + job.SetContext(context); + job.OnStart(); + m_aJobs.Insert(job); + + if (!ShouldBeUpdated()) + ToggleUpdate(true); + } + + //------------------------------------------------------------------------------------------------ + void Unregister(ACE_Overheating_BarrelComponent object) + { + foreach (int i, ACE_Overheating_BarrelTemperatureJob job : m_aJobs) + { + if (job.GetContext().m_pObject == object) + { + // Delay unregistration, unless the queue isn't touched (e.g. during timeout) + if (m_eState == ACE_FrameJobScheduler_EState.TIMEOUT) + UnregisterNow(i); + else + job.Stop(); + + return; + } + } + } + + //------------------------------------------------------------------------------------------------ + protected void UnregisterNow(int machineIdx) + { + ACE_Overheating_BarrelTemperatureJob job = m_aJobs[machineIdx]; + m_aJobs.Remove(machineIdx); + job.OnStop(); + } + + //------------------------------------------------------------------------------------------------ + protected ACE_Overheating_BarrelTemperatureJob CreateJob() + { + ACE_Overheating_BarrelTemperatureJob instance = new ACE_Overheating_BarrelTemperatureJob(); + instance.CopyFrom(m_pTemplateJob); + return instance; + } +} diff --git a/addons/overheating/scripts/GameCode/ACE_Overheating/Components/InventorySystem/EquipedWeaponStorageComponent.c b/addons/overheating/scripts/GameCode/ACE_Overheating/Components/InventorySystem/EquipedWeaponStorageComponent.c new file mode 100644 index 000000000..26439c617 --- /dev/null +++ b/addons/overheating/scripts/GameCode/ACE_Overheating/Components/InventorySystem/EquipedWeaponStorageComponent.c @@ -0,0 +1,67 @@ +//------------------------------------------------------------------------------------------------ +modded class EquipedWeaponStorageComponent : BaseEquipedWeaponStorageComponent +{ + protected bool m_bACE_Overheating_ShouldRegisterWeapons = false; + + //------------------------------------------------------------------------------------------------ + //! Whether equipped weapons should be registered at temperature system + void ACE_Overheating_ToggleRegisterWeapons(bool enable) + { + ACE_Overheating_BarrelTemperatureSystem system = ACE_Overheating_BarrelTemperatureSystem.GetInstance(); + if (!system) + return; + + array weapons = {}; + GetAll(weapons); + + foreach (IEntity weapon : weapons) + { + ACE_Overheating_BarrelComponent barrel = ACE_Overheating_BarrelComponent.FromWeapon(weapon); + if (!barrel) + continue; + + if (enable) + system.Register(barrel); + else + system.Unregister(barrel); + } + + m_bACE_Overheating_ShouldRegisterWeapons = enable; + } + + //------------------------------------------------------------------------------------------------ + //! Register picked up weapon at temperature system + override protected void OnAddedToSlot(IEntity item, int slotID) + { + super.OnAddedToSlot(item, slotID); + + if (!m_bACE_Overheating_ShouldRegisterWeapons) + return; + + ACE_Overheating_BarrelComponent barrel = ACE_Overheating_BarrelComponent.FromWeapon(item); + if (!barrel) + return; + + ACE_Overheating_BarrelTemperatureSystem system = ACE_Overheating_BarrelTemperatureSystem.GetInstance(); + if (system) + system.Register(barrel); + } + + //------------------------------------------------------------------------------------------------ + //! Unregister dropped weapon from temperature system + override protected void OnRemovedFromSlot(IEntity item, int slotID) + { + super.OnRemovedFromSlot(item, slotID); + + if (!m_bACE_Overheating_ShouldRegisterWeapons) + return; + + ACE_Overheating_BarrelComponent barrel = ACE_Overheating_BarrelComponent.FromWeapon(item); + if (!barrel) + return; + + ACE_Overheating_BarrelTemperatureSystem system = ACE_Overheating_BarrelTemperatureSystem.GetInstance(); + if (system) + system.Unregister(barrel); + } +} diff --git a/addons/overheating/scripts/GameCode/ACE_Overheating/Effects/ACE_Overheating_BarrelGlowEffectComponent.c b/addons/overheating/scripts/GameCode/ACE_Overheating/Effects/ACE_Overheating_BarrelGlowEffectComponent.c new file mode 100644 index 000000000..ab8c11747 --- /dev/null +++ b/addons/overheating/scripts/GameCode/ACE_Overheating/Effects/ACE_Overheating_BarrelGlowEffectComponent.c @@ -0,0 +1,142 @@ +//------------------------------------------------------------------------------------------------ +//! How to configure a weapon for glowing: +//! -------------------------------------- +//! 1) Add ACE_Overheating_BarrelGlowEffectComponent as a child of MuzzleComponent to weapon prefab +//! 2) Add emissive map to weapon emat and bind `Emissive` to `m_vColor` +//! Example override for M249: +//! ``` +//! MatPBRBasic : "{758946B2EC5F1439}Assets/Weapons/MachineGuns/M249/Data/M249_Body_1.emat" { +//! Emissive 0 0 0 1 +//! EmissiveAbsoluteLV 0 +//! EmissiveMap "{3175FE13B1FC2769}Assets/Weapons/MachineGuns/M249/Data/M249_Body_1_EM.edds" +//! Refs { +//! "Emissive" "ACE_Overheating_BarrelGlowEffectComponent.m_vColor" +//! } +//! } +//! ``` +class ACE_Overheating_BarrelGlowEffectComponentClass : ScriptComponentClass +{ + [Attribute(defvalue: "0.188 0.025 0 1", desc: "Color for maximal glowing barrel.")] + protected ref Color m_cMaxColor; + + [Attribute(defvalue: "40", desc: "Resolution for target intensity.", params: "1 inf")] + protected int m_iMaxIntensityStep; + + [Attribute(defvalue: "0.03", desc: "Rate of change for approaching target intensity. [1/s]", params: "0 1")] + protected float m_fIntensityRate; + + //------------------------------------------------------------------------------------------------ + Color GetMaxColor() + { + return m_cMaxColor; + } + + //------------------------------------------------------------------------------------------------ + int GetMaxIntensityStep() + { + return m_iMaxIntensityStep; + } + + //------------------------------------------------------------------------------------------------ + float GetIntensityRate() + { + return m_fIntensityRate; + } +} + +//------------------------------------------------------------------------------------------------ +class ACE_Overheating_BarrelGlowEffectComponent : ScriptComponent +{ + [RplProp(onRplName: "OnIntensityStepChanged")] + protected int m_iIntensityStep; + + protected float m_fTargetIntensity; + protected float m_fIntensity; + protected vector m_vColor; + protected ACE_Overheating_BarrelGlowEffectComponentClass m_pData; + + //------------------------------------------------------------------------------------------------ + static ACE_Overheating_BarrelGlowEffectComponent FromMuzzle(BaseMuzzleComponent muzzle) + { + if (!muzzle) + return null; + + return ACE_Overheating_BarrelGlowEffectComponent.Cast(muzzle.FindComponent(ACE_Overheating_BarrelGlowEffectComponent)); + } + + //------------------------------------------------------------------------------------------------ + override protected void OnPostInit(IEntity owner) + { + super.OnPostInit(owner); + + if (!GetGame().InPlayMode()) + return; + + m_pData = ACE_Overheating_BarrelGlowEffectComponentClass.Cast(GetComponentData(owner)); + } + + //------------------------------------------------------------------------------------------------ + override protected void EOnFrame(IEntity owner, float timeSlice) + { + if (float.AlmostEqual(m_fTargetIntensity, m_fIntensity)) + { + ClearEventMask(owner, EntityEvent.FRAME); + return; + } + + float diff = m_fTargetIntensity - m_fIntensity; + m_fIntensity += diff.Sign() * m_pData.GetIntensityRate() * timeSlice; + UpdateColor(); + } + + //------------------------------------------------------------------------------------------------ + protected void UpdateColor() + { + Color color = m_pData.GetMaxColor(); + m_vColor = m_fIntensity * Vector(color.R(), color.G(), color.B()); + } + + //------------------------------------------------------------------------------------------------ + protected void OnIntensityStepChanged() + { + m_fTargetIntensity = (float)m_iIntensityStep / m_pData.GetMaxIntensityStep(); + SetEventMask(GetOwner(), EntityEvent.FRAME); + } + + //------------------------------------------------------------------------------------------------ + //! Sets intensity of glow, with 0 for no glow and 1 for max glow. Glow changes smoothly. + void SetIntensity(float intensity) + { + int step = Math.Round(intensity * m_pData.GetMaxIntensityStep()); + if (step == m_iIntensityStep) + return; + + m_iIntensityStep = step; + + if (!System.IsConsoleApp()) + OnIntensityStepChanged(); + + Replication.BumpMe(); + } + + //------------------------------------------------------------------------------------------------ + //! Same as SetIntensity, but change is done instantly + void ForceIntensity(float intensity) + { + m_iIntensityStep = Math.Round(intensity * m_pData.GetMaxIntensityStep()); + + if (!System.IsConsoleApp()) + RpcDo_ForceIntensityBroadcast(intensity); + + Rpc(RpcDo_ForceIntensityBroadcast, intensity); + } + + //------------------------------------------------------------------------------------------------ + [RplRpc(RplChannel.Reliable, RplRcver.Broadcast)] + protected void RpcDo_ForceIntensityBroadcast(float intensity) + { + m_fTargetIntensity = intensity; + m_fIntensity = intensity; + UpdateColor(); + } +} diff --git a/addons/overheating/thumbnail.png b/addons/overheating/thumbnail.png new file mode 100644 index 000000000..3d4283142 Binary files /dev/null and b/addons/overheating/thumbnail.png differ diff --git a/addons/weather/Configs/System/chimeraInputCommon.conf b/addons/weather/Configs/System/chimeraInputCommon.conf new file mode 100644 index 000000000..6a1e8822a --- /dev/null +++ b/addons/weather/Configs/System/chimeraInputCommon.conf @@ -0,0 +1,21 @@ +ActionManager { + Contexts { + ActionContext CharacterGeneralContext { + Actions { + Action ACE_Weather_WindInfoToggle { + InputSource InputSourceCombo "{667B2E0AB789E3BA}" { + FilterPreset "select" + Sources { + InputSourceValue "{667B2E0AA52AA52F}" { + Input "keyboard:KC_LSHIFT" + } + InputSourceValue "{667B2E0ADA28BBF7}" { + Input "keyboard:KC_K" + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/addons/weather/Configs/System/chimeraInputCommon.conf.meta b/addons/weather/Configs/System/chimeraInputCommon.conf.meta new file mode 100644 index 000000000..f1e7b1a2d --- /dev/null +++ b/addons/weather/Configs/System/chimeraInputCommon.conf.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{795184CF9AD764DB}Configs/System/chimeraInputCommon.conf" + Configurations { + CONFResourceClass PC { + } + CONFResourceClass XBOX_ONE : PC { + } + CONFResourceClass XBOX_SERIES : PC { + } + CONFResourceClass PS4 : PC { + } + CONFResourceClass PS5 : PC { + } + CONFResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/weather/Configs/System/keyBindingMenu.conf b/addons/weather/Configs/System/keyBindingMenu.conf new file mode 100644 index 000000000..e996b1f06 --- /dev/null +++ b/addons/weather/Configs/System/keyBindingMenu.conf @@ -0,0 +1,17 @@ +SCR_KeyBindingMenuConfig { + m_KeyBindingCategories { + SCR_KeyBindingCategory "{60C72E6BAD884638}" { + m_KeyBindingEntries { + SCR_KeyBindingEntry "{667B2E0B8A6F6691}" { + m_sActionName "separator" + m_sDisplayName "#ACE_Weather-AddonName" + } + SCR_KeyBindingEntry "{667B2E0B8BE33AC1}" { + m_sActionName "ACE_Weather_WindInfoToggle" + m_sDisplayName "#ACE_Weather-Keybind_WindInfoToggle" + m_sPreset "select" + } + } + } + } +} \ No newline at end of file diff --git a/addons/weather/Configs/System/keyBindingMenu.conf.meta b/addons/weather/Configs/System/keyBindingMenu.conf.meta new file mode 100644 index 000000000..f54af760a --- /dev/null +++ b/addons/weather/Configs/System/keyBindingMenu.conf.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{4EE7794C9A3F11EF}Configs/System/keyBindingMenu.conf" + Configurations { + CONFResourceClass PC { + } + CONFResourceClass XBOX_ONE : PC { + } + CONFResourceClass XBOX_SERIES : PC { + } + CONFResourceClass PS4 : PC { + } + CONFResourceClass PS5 : PC { + } + CONFResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/weather/Language/ACE_Weather_localization.cs_cz.conf b/addons/weather/Language/ACE_Weather_localization.cs_cz.conf new file mode 100644 index 000000000..3f2283ffe --- /dev/null +++ b/addons/weather/Language/ACE_Weather_localization.cs_cz.conf @@ -0,0 +1,10 @@ +StringTableRuntime { + Ids { + "ACE_Weather-AddonName" + "ACE_Weather-Keybind_WindInfoToggle" + } + Texts { + "ACE Weather" + "Zobrazit údaje o větru" + } +} \ No newline at end of file diff --git a/addons/weather/Language/ACE_Weather_localization.cs_cz.conf.meta b/addons/weather/Language/ACE_Weather_localization.cs_cz.conf.meta new file mode 100644 index 000000000..b60b3560e --- /dev/null +++ b/addons/weather/Language/ACE_Weather_localization.cs_cz.conf.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{736FE6EBA2DDF341}Language/ACE_Weather_localization.cs_cz.conf" + Configurations { + CONFResourceClass PC { + } + CONFResourceClass XBOX_ONE : PC { + } + CONFResourceClass XBOX_SERIES : PC { + } + CONFResourceClass PS4 : PC { + } + CONFResourceClass PS5 : PC { + } + CONFResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/weather/Language/ACE_Weather_localization.de_de.conf b/addons/weather/Language/ACE_Weather_localization.de_de.conf new file mode 100644 index 000000000..c699d9ad2 --- /dev/null +++ b/addons/weather/Language/ACE_Weather_localization.de_de.conf @@ -0,0 +1,10 @@ +StringTableRuntime { + Ids { + "ACE_Weather-AddonName" + "ACE_Weather-Keybind_WindInfoToggle" + } + Texts { + "ACE Weather" + "Zeige Windinformationen" + } +} \ No newline at end of file diff --git a/addons/weather/Language/ACE_Weather_localization.de_de.conf.meta b/addons/weather/Language/ACE_Weather_localization.de_de.conf.meta new file mode 100644 index 000000000..eef1a1479 --- /dev/null +++ b/addons/weather/Language/ACE_Weather_localization.de_de.conf.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{A611FCD8B17EE261}Language/ACE_Weather_localization.de_de.conf" + Configurations { + CONFResourceClass PC { + } + CONFResourceClass XBOX_ONE : PC { + } + CONFResourceClass XBOX_SERIES : PC { + } + CONFResourceClass PS4 : PC { + } + CONFResourceClass PS5 : PC { + } + CONFResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/weather/Language/ACE_Weather_localization.en_us.conf b/addons/weather/Language/ACE_Weather_localization.en_us.conf new file mode 100644 index 000000000..f037a9a5e --- /dev/null +++ b/addons/weather/Language/ACE_Weather_localization.en_us.conf @@ -0,0 +1,10 @@ +StringTableRuntime { + Ids { + "ACE_Weather-AddonName" + "ACE_Weather-Keybind_WindInfoToggle" + } + Texts { + "ACE Weather" + "Show wind info" + } +} \ No newline at end of file diff --git a/addons/weather/Language/ACE_Weather_localization.en_us.conf.meta b/addons/weather/Language/ACE_Weather_localization.en_us.conf.meta new file mode 100644 index 000000000..bfe00bc75 --- /dev/null +++ b/addons/weather/Language/ACE_Weather_localization.en_us.conf.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{F8E17693DB8DE760}Language/ACE_Weather_localization.en_us.conf" + Configurations { + CONFResourceClass PC { + } + CONFResourceClass XBOX_ONE : PC { + } + CONFResourceClass XBOX_SERIES : PC { + } + CONFResourceClass PS4 : PC { + } + CONFResourceClass PS5 : PC { + } + CONFResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/weather/Language/ACE_Weather_localization.es_es.conf b/addons/weather/Language/ACE_Weather_localization.es_es.conf new file mode 100644 index 000000000..b64891b8b --- /dev/null +++ b/addons/weather/Language/ACE_Weather_localization.es_es.conf @@ -0,0 +1,10 @@ +StringTableRuntime { + Ids { + "ACE_Weather-AddonName" + "ACE_Weather-Keybind_WindInfoToggle" + } + Texts { + "ACE Weather" + "Mostrar información del viento" + } +} \ No newline at end of file diff --git a/addons/weather/Language/ACE_Weather_localization.es_es.conf.meta b/addons/weather/Language/ACE_Weather_localization.es_es.conf.meta new file mode 100644 index 000000000..eb988bcfb --- /dev/null +++ b/addons/weather/Language/ACE_Weather_localization.es_es.conf.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{3DAD3B1A358F8C7F}Language/ACE_Weather_localization.es_es.conf" + Configurations { + CONFResourceClass PC { + } + CONFResourceClass XBOX_ONE : PC { + } + CONFResourceClass XBOX_SERIES : PC { + } + CONFResourceClass PS4 : PC { + } + CONFResourceClass PS5 : PC { + } + CONFResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/weather/Language/ACE_Weather_localization.fr_fr.conf b/addons/weather/Language/ACE_Weather_localization.fr_fr.conf new file mode 100644 index 000000000..05bf835b6 --- /dev/null +++ b/addons/weather/Language/ACE_Weather_localization.fr_fr.conf @@ -0,0 +1,10 @@ +StringTableRuntime { + Ids { + "ACE_Weather-AddonName" + "ACE_Weather-Keybind_WindInfoToggle" + } + Texts { + "ACE Weather" + "Afficher les informations sur le vent" + } +} \ No newline at end of file diff --git a/addons/weather/Language/ACE_Weather_localization.fr_fr.conf.meta b/addons/weather/Language/ACE_Weather_localization.fr_fr.conf.meta new file mode 100644 index 000000000..40c8f45a2 --- /dev/null +++ b/addons/weather/Language/ACE_Weather_localization.fr_fr.conf.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{8605CE2DD30C6F7D}Language/ACE_Weather_localization.fr_fr.conf" + Configurations { + CONFResourceClass PC { + } + CONFResourceClass XBOX_ONE : PC { + } + CONFResourceClass XBOX_SERIES : PC { + } + CONFResourceClass PS4 : PC { + } + CONFResourceClass PS5 : PC { + } + CONFResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/weather/Language/ACE_Weather_localization.it_it.conf b/addons/weather/Language/ACE_Weather_localization.it_it.conf new file mode 100644 index 000000000..02c1b8731 --- /dev/null +++ b/addons/weather/Language/ACE_Weather_localization.it_it.conf @@ -0,0 +1,10 @@ +StringTableRuntime { + Ids { + "ACE_Weather-AddonName" + "ACE_Weather-Keybind_WindInfoToggle" + } + Texts { + "ACE Weather" + "Mostra informazioni sul vento" + } +} \ No newline at end of file diff --git a/addons/weather/Language/ACE_Weather_localization.it_it.conf.meta b/addons/weather/Language/ACE_Weather_localization.it_it.conf.meta new file mode 100644 index 000000000..c3d1c58e4 --- /dev/null +++ b/addons/weather/Language/ACE_Weather_localization.it_it.conf.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{061941197E2EEC84}Language/ACE_Weather_localization.it_it.conf" + Configurations { + CONFResourceClass PC { + } + CONFResourceClass XBOX_ONE : PC { + } + CONFResourceClass XBOX_SERIES : PC { + } + CONFResourceClass PS4 : PC { + } + CONFResourceClass PS5 : PC { + } + CONFResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/weather/Language/ACE_Weather_localization.ja_jp.conf b/addons/weather/Language/ACE_Weather_localization.ja_jp.conf new file mode 100644 index 000000000..f4130efb5 --- /dev/null +++ b/addons/weather/Language/ACE_Weather_localization.ja_jp.conf @@ -0,0 +1,10 @@ +StringTableRuntime { + Ids { + "ACE_Weather-AddonName" + "ACE_Weather-Keybind_WindInfoToggle" + } + Texts { + "ACE Weather" + "風速を表示" + } +} \ No newline at end of file diff --git a/addons/weather/Language/ACE_Weather_localization.ja_jp.conf.meta b/addons/weather/Language/ACE_Weather_localization.ja_jp.conf.meta new file mode 100644 index 000000000..a0f247589 --- /dev/null +++ b/addons/weather/Language/ACE_Weather_localization.ja_jp.conf.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{1602FC8B405FDC2F}Language/ACE_Weather_localization.ja_jp.conf" + Configurations { + CONFResourceClass PC { + } + CONFResourceClass XBOX_ONE : PC { + } + CONFResourceClass XBOX_SERIES : PC { + } + CONFResourceClass PS4 : PC { + } + CONFResourceClass PS5 : PC { + } + CONFResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/weather/Language/ACE_Weather_localization.ko_kr.conf b/addons/weather/Language/ACE_Weather_localization.ko_kr.conf new file mode 100644 index 000000000..eab77b3c5 --- /dev/null +++ b/addons/weather/Language/ACE_Weather_localization.ko_kr.conf @@ -0,0 +1,10 @@ +StringTableRuntime { + Ids { + "ACE_Weather-AddonName" + "ACE_Weather-Keybind_WindInfoToggle" + } + Texts { + "ACE 날씨" + "바람 정보 표시" + } +} \ No newline at end of file diff --git a/addons/weather/Language/ACE_Weather_localization.ko_kr.conf.meta b/addons/weather/Language/ACE_Weather_localization.ko_kr.conf.meta new file mode 100644 index 000000000..6f7824cb9 --- /dev/null +++ b/addons/weather/Language/ACE_Weather_localization.ko_kr.conf.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{B6BCD427D372DF10}Language/ACE_Weather_localization.ko_kr.conf" + Configurations { + CONFResourceClass PC { + } + CONFResourceClass XBOX_ONE : PC { + } + CONFResourceClass XBOX_SERIES : PC { + } + CONFResourceClass PS4 : PC { + } + CONFResourceClass PS5 : PC { + } + CONFResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/weather/Language/ACE_Weather_localization.pl_pl.conf b/addons/weather/Language/ACE_Weather_localization.pl_pl.conf new file mode 100644 index 000000000..abc76bc7e --- /dev/null +++ b/addons/weather/Language/ACE_Weather_localization.pl_pl.conf @@ -0,0 +1,10 @@ +StringTableRuntime { + Ids { + "ACE_Weather-AddonName" + "ACE_Weather-Keybind_WindInfoToggle" + } + Texts { + "ACE Weather" + "Pokaż inf. o wietrze" + } +} \ No newline at end of file diff --git a/addons/weather/Language/ACE_Weather_localization.pl_pl.conf.meta b/addons/weather/Language/ACE_Weather_localization.pl_pl.conf.meta new file mode 100644 index 000000000..a4a63e245 --- /dev/null +++ b/addons/weather/Language/ACE_Weather_localization.pl_pl.conf.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{EACD72DD6D9D436C}Language/ACE_Weather_localization.pl_pl.conf" + Configurations { + CONFResourceClass PC { + } + CONFResourceClass XBOX_ONE : PC { + } + CONFResourceClass XBOX_SERIES : PC { + } + CONFResourceClass PS4 : PC { + } + CONFResourceClass PS5 : PC { + } + CONFResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/weather/Language/ACE_Weather_localization.pt_br.conf b/addons/weather/Language/ACE_Weather_localization.pt_br.conf new file mode 100644 index 000000000..280e00b87 --- /dev/null +++ b/addons/weather/Language/ACE_Weather_localization.pt_br.conf @@ -0,0 +1,10 @@ +StringTableRuntime { + Ids { + "ACE_Weather-AddonName" + "ACE_Weather-Keybind_WindInfoToggle" + } + Texts { + "ACE Weather" + "Mostrar informação do vento" + } +} \ No newline at end of file diff --git a/addons/weather/Language/ACE_Weather_localization.pt_br.conf.meta b/addons/weather/Language/ACE_Weather_localization.pt_br.conf.meta new file mode 100644 index 000000000..fab5c6868 --- /dev/null +++ b/addons/weather/Language/ACE_Weather_localization.pt_br.conf.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{3FBAE811566389D6}Language/ACE_Weather_localization.pt_br.conf" + Configurations { + CONFResourceClass PC { + } + CONFResourceClass XBOX_ONE : PC { + } + CONFResourceClass XBOX_SERIES : PC { + } + CONFResourceClass PS4 : PC { + } + CONFResourceClass PS5 : PC { + } + CONFResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/weather/Language/ACE_Weather_localization.ru_ru.conf b/addons/weather/Language/ACE_Weather_localization.ru_ru.conf new file mode 100644 index 000000000..bb52310c3 --- /dev/null +++ b/addons/weather/Language/ACE_Weather_localization.ru_ru.conf @@ -0,0 +1,10 @@ +StringTableRuntime { + Ids { + "ACE_Weather-AddonName" + "ACE_Weather-Keybind_WindInfoToggle" + } + Texts { + "ACE Weather" + "Показать информацию о ветре" + } +} \ No newline at end of file diff --git a/addons/weather/Language/ACE_Weather_localization.ru_ru.conf.meta b/addons/weather/Language/ACE_Weather_localization.ru_ru.conf.meta new file mode 100644 index 000000000..eab9ef011 --- /dev/null +++ b/addons/weather/Language/ACE_Weather_localization.ru_ru.conf.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{6AFBFCB9CB1AECA0}Language/ACE_Weather_localization.ru_ru.conf" + Configurations { + CONFResourceClass PC { + } + CONFResourceClass XBOX_ONE : PC { + } + CONFResourceClass XBOX_SERIES : PC { + } + CONFResourceClass PS4 : PC { + } + CONFResourceClass PS5 : PC { + } + CONFResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/weather/Language/ACE_Weather_localization.st b/addons/weather/Language/ACE_Weather_localization.st new file mode 100644 index 000000000..f8306332b --- /dev/null +++ b/addons/weather/Language/ACE_Weather_localization.st @@ -0,0 +1,32 @@ +StringTable { + ItemClassName "CustomStringTableItem" + Items { + CustomStringTableItem "{667B2E0B01C5BDEC}" { + Id "ACE_Weather-AddonName" + Target_en_us "ACE Weather" + Target_ko_kr "ACE 날씨" + Modified 1719367753 + Author "Kex" + LastChanged "Psycool" + } + CustomStringTableItem "{667B2E0B3C32F8F7}" { + Id "ACE_Weather-Keybind_WindInfoToggle" + Target_en_us "Show wind info" + Target_fr_fr "Afficher les informations sur le vent" + Target_it_it "Mostra informazioni sul vento" + Target_de_de "Zeige Windinformationen" + Target_es_es "Mostrar información del viento" + Target_cs_cz "Zobrazit údaje o větru" + Target_pl_pl "Pokaż inf. o wietrze" + Target_ru_ru "Показать информацию о ветре" + Target_ja_jp "風速を表示" + Target_ko_kr "바람 정보 표시" + Target_pt_br "Mostrar informação do vento" + Target_zh_cn "顯示風力資訊" + Target_uk_ua "Показати інформацію про вітер" + Modified 1719368269 + Author "Kex" + LastChanged "Kex" + } + } +} \ No newline at end of file diff --git a/addons/weather/Language/ACE_Weather_localization.st.meta b/addons/weather/Language/ACE_Weather_localization.st.meta new file mode 100644 index 000000000..16cf80454 --- /dev/null +++ b/addons/weather/Language/ACE_Weather_localization.st.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{95AF98816BFC4873}Language/ACE_Weather_localization.st" + Configurations { + StringTableResourceClass PC { + } + StringTableResourceClass XBOX_ONE : PC { + } + StringTableResourceClass XBOX_SERIES : PC { + } + StringTableResourceClass PS4 : PC { + } + StringTableResourceClass PS5 : PC { + } + StringTableResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/weather/Language/ACE_Weather_localization.uk_ua.conf b/addons/weather/Language/ACE_Weather_localization.uk_ua.conf new file mode 100644 index 000000000..665470d8d --- /dev/null +++ b/addons/weather/Language/ACE_Weather_localization.uk_ua.conf @@ -0,0 +1,10 @@ +StringTableRuntime { + Ids { + "ACE_Weather-AddonName" + "ACE_Weather-Keybind_WindInfoToggle" + } + Texts { + "ACE Weather" + "Показати інформацію про вітер" + } +} \ No newline at end of file diff --git a/addons/weather/Language/ACE_Weather_localization.uk_ua.conf.meta b/addons/weather/Language/ACE_Weather_localization.uk_ua.conf.meta new file mode 100644 index 000000000..4e8bf041c --- /dev/null +++ b/addons/weather/Language/ACE_Weather_localization.uk_ua.conf.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{E0A3A94FA73452F5}Language/ACE_Weather_localization.uk_ua.conf" + Configurations { + CONFResourceClass PC { + } + CONFResourceClass XBOX_ONE : PC { + } + CONFResourceClass XBOX_SERIES : PC { + } + CONFResourceClass PS4 : PC { + } + CONFResourceClass PS5 : PC { + } + CONFResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/weather/Language/ACE_Weather_localization.zh_cn.conf b/addons/weather/Language/ACE_Weather_localization.zh_cn.conf new file mode 100644 index 000000000..bff064fb7 --- /dev/null +++ b/addons/weather/Language/ACE_Weather_localization.zh_cn.conf @@ -0,0 +1,10 @@ +StringTableRuntime { + Ids { + "ACE_Weather-AddonName" + "ACE_Weather-Keybind_WindInfoToggle" + } + Texts { + "ACE Weather" + "顯示風力資訊" + } +} \ No newline at end of file diff --git a/addons/weather/Language/ACE_Weather_localization.zh_cn.conf.meta b/addons/weather/Language/ACE_Weather_localization.zh_cn.conf.meta new file mode 100644 index 000000000..5a23999c2 --- /dev/null +++ b/addons/weather/Language/ACE_Weather_localization.zh_cn.conf.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{3A13C7729E9482E8}Language/ACE_Weather_localization.zh_cn.conf" + Configurations { + CONFResourceClass PC { + } + CONFResourceClass XBOX_ONE : PC { + } + CONFResourceClass XBOX_SERIES : PC { + } + CONFResourceClass PS4 : PC { + } + CONFResourceClass PS5 : PC { + } + CONFResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/weather/Prefabs/Characters/Core/DefaultPlayerController.et b/addons/weather/Prefabs/Characters/Core/DefaultPlayerController.et new file mode 100644 index 000000000..70beb1703 --- /dev/null +++ b/addons/weather/Prefabs/Characters/Core/DefaultPlayerController.et @@ -0,0 +1,14 @@ +SCR_PlayerController { + ID "1A9BA6BEFA06E3B1" + components { + SCR_HUDManagerComponent "{2FDC275D9EBCDB8B}" { + InfoDisplays { + ACE_Weather_WindInfoDisplay "{667B23883AA0DCAC}" { + m_LayoutPath "{D09C66978322D6AD}UI/layouts/HUD/Weather/ACE_WindInfo.layout" + m_bShowWhenCreated 0 + m_eShow 7 + } + } + } + } +} \ No newline at end of file diff --git a/addons/weather/Prefabs/Characters/Core/DefaultPlayerController.et.meta b/addons/weather/Prefabs/Characters/Core/DefaultPlayerController.et.meta new file mode 100644 index 000000000..4cc4d98de --- /dev/null +++ b/addons/weather/Prefabs/Characters/Core/DefaultPlayerController.et.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{6E2BB64764E3BE9B}Prefabs/Characters/Core/DefaultPlayerController.et" + Configurations { + EntityTemplateResourceClass PC { + } + EntityTemplateResourceClass XBOX_ONE : PC { + } + EntityTemplateResourceClass XBOX_SERIES : PC { + } + EntityTemplateResourceClass PS4 : PC { + } + EntityTemplateResourceClass PS5 : PC { + } + EntityTemplateResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/weather/Prefabs/World/Game/Arland/TimeAndWeatherManager_Arland.et b/addons/weather/Prefabs/World/Game/Arland/TimeAndWeatherManager_Arland.et new file mode 100644 index 000000000..a7b7a1b0a --- /dev/null +++ b/addons/weather/Prefabs/World/Game/Arland/TimeAndWeatherManager_Arland.et @@ -0,0 +1,12 @@ +TimeAndWeatherManagerEntity : "{A3BAF78F6F03315B}Prefabs/World/Game/TimeAndWeatherManager.et" { + ID "5244F08C9618CADD" + m_aACE_MonthlyAverageTemperatureAirMaxHours { + 13.60 14.32 14.75 15.21 15.05 14.89 15.47 14.80 14.53 13.40 13.44 12.68 + } + m_aACE_MonthlyAverageDailyTemperatureAirMins { + 278.02 279.37 279.66 280.99 283.89 286.94 288.08 288.51 287.02 284.95 282.06 279.77 + } + m_aACE_MonthlyAverageDailyTemperatureAirMaxs { + 282.62 283.99 285.55 288.28 290.91 293.89 294.73 295.27 293.39 290.10 286.67 283.84 + } +} \ No newline at end of file diff --git a/addons/weather/Prefabs/World/Game/Arland/TimeAndWeatherManager_Arland.et.meta b/addons/weather/Prefabs/World/Game/Arland/TimeAndWeatherManager_Arland.et.meta new file mode 100644 index 000000000..c30598990 --- /dev/null +++ b/addons/weather/Prefabs/World/Game/Arland/TimeAndWeatherManager_Arland.et.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{5F7661408DB8C0A7}Prefabs/World/Game/Arland/TimeAndWeatherManager_Arland.et" + Configurations { + EntityTemplateResourceClass PC { + } + EntityTemplateResourceClass XBOX_ONE : PC { + } + EntityTemplateResourceClass XBOX_SERIES : PC { + } + EntityTemplateResourceClass PS4 : PC { + } + EntityTemplateResourceClass PS5 : PC { + } + EntityTemplateResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/weather/Prefabs/World/Game/Cain/TimeAndWeathedManager_Cain.et b/addons/weather/Prefabs/World/Game/Cain/TimeAndWeathedManager_Cain.et new file mode 100644 index 000000000..76280a1d5 --- /dev/null +++ b/addons/weather/Prefabs/World/Game/Cain/TimeAndWeathedManager_Cain.et @@ -0,0 +1,12 @@ +TimeAndWeatherManagerEntity : "{A3BAF78F6F03315B}Prefabs/World/Game/TimeAndWeatherManager.et" { + ID "5244F08C9618CADD" + m_aACE_MonthlyAverageTemperatureAirMaxHours { + 12.65 12.35 13.69 13.99 13.98 13.76 13.89 13.87 12.96 12.69 12.22 11.16 + } + m_aACE_MonthlyAverageDailyTemperatureAirMins { + 278.52 279.33 278.92 280.35 282.42 284.58 285.88 286.59 285.30 283.55 281.43 279.58 + } + m_aACE_MonthlyAverageDailyTemperatureAirMaxs { + 281.75 282.40 282.88 284.77 286.67 288.03 289.18 290.02 288.84 286.37 284.33 282.50 + } +} \ No newline at end of file diff --git a/addons/weather/Prefabs/World/Game/Cain/TimeAndWeathedManager_Cain.et.meta b/addons/weather/Prefabs/World/Game/Cain/TimeAndWeathedManager_Cain.et.meta new file mode 100644 index 000000000..4d775558d --- /dev/null +++ b/addons/weather/Prefabs/World/Game/Cain/TimeAndWeathedManager_Cain.et.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{C4DC66FF5350C358}Prefabs/World/Game/Cain/TimeAndWeathedManager_Cain.et" + Configurations { + EntityTemplateResourceClass PC { + } + EntityTemplateResourceClass XBOX_ONE : PC { + } + EntityTemplateResourceClass XBOX_SERIES : PC { + } + EntityTemplateResourceClass PS4 : PC { + } + EntityTemplateResourceClass PS5 : PC { + } + EntityTemplateResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/weather/Prefabs/World/Game/Eden/TimeAndWeatherManager_Eden.et b/addons/weather/Prefabs/World/Game/Eden/TimeAndWeatherManager_Eden.et new file mode 100644 index 000000000..a7b7a1b0a --- /dev/null +++ b/addons/weather/Prefabs/World/Game/Eden/TimeAndWeatherManager_Eden.et @@ -0,0 +1,12 @@ +TimeAndWeatherManagerEntity : "{A3BAF78F6F03315B}Prefabs/World/Game/TimeAndWeatherManager.et" { + ID "5244F08C9618CADD" + m_aACE_MonthlyAverageTemperatureAirMaxHours { + 13.60 14.32 14.75 15.21 15.05 14.89 15.47 14.80 14.53 13.40 13.44 12.68 + } + m_aACE_MonthlyAverageDailyTemperatureAirMins { + 278.02 279.37 279.66 280.99 283.89 286.94 288.08 288.51 287.02 284.95 282.06 279.77 + } + m_aACE_MonthlyAverageDailyTemperatureAirMaxs { + 282.62 283.99 285.55 288.28 290.91 293.89 294.73 295.27 293.39 290.10 286.67 283.84 + } +} \ No newline at end of file diff --git a/addons/weather/Prefabs/World/Game/Eden/TimeAndWeatherManager_Eden.et.meta b/addons/weather/Prefabs/World/Game/Eden/TimeAndWeatherManager_Eden.et.meta new file mode 100644 index 000000000..a7ef64273 --- /dev/null +++ b/addons/weather/Prefabs/World/Game/Eden/TimeAndWeatherManager_Eden.et.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{D3B9D1746BA699D5}Prefabs/World/Game/Eden/TimeAndWeatherManager_Eden.et" + Configurations { + EntityTemplateResourceClass PC { + } + EntityTemplateResourceClass XBOX_ONE : PC { + } + EntityTemplateResourceClass XBOX_SERIES : PC { + } + EntityTemplateResourceClass PS4 : PC { + } + EntityTemplateResourceClass PS5 : PC { + } + EntityTemplateResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/weather/Prefabs/World/Game/TimeAndWeatherManager.et b/addons/weather/Prefabs/World/Game/TimeAndWeatherManager.et new file mode 100644 index 000000000..32ccb3ed6 --- /dev/null +++ b/addons/weather/Prefabs/World/Game/TimeAndWeatherManager.et @@ -0,0 +1,12 @@ +TimeAndWeatherManagerEntity { + ID "5244F08C9618CADD" + m_aACE_MonthlyAverageTemperatureAirMaxHours { + 14.12 14.24 14.89 15.23 15.34 15.47 15.82 15.13 14.96 14.31 13.79 13.95 + } + m_aACE_MonthlyAverageDailyTemperatureAirMins { + 272.67 274.45 275.41 278.13 282.43 287.44 288.40 288.69 285.10 281.32 276.22 274.09 + } + m_aACE_MonthlyAverageDailyTemperatureAirMaxs { + 279.54 282.79 285.50 288.62 292.33 297.83 298.77 299.08 294.56 289.82 283.05 279.82 + } +} \ No newline at end of file diff --git a/addons/weather/Prefabs/World/Game/TimeAndWeatherManager.et.meta b/addons/weather/Prefabs/World/Game/TimeAndWeatherManager.et.meta new file mode 100644 index 000000000..8e8ade4fd --- /dev/null +++ b/addons/weather/Prefabs/World/Game/TimeAndWeatherManager.et.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{A3BAF78F6F03315B}Prefabs/World/Game/TimeAndWeatherManager.et" + Configurations { + EntityTemplateResourceClass PC { + } + EntityTemplateResourceClass XBOX_ONE : PC { + } + EntityTemplateResourceClass XBOX_SERIES : PC { + } + EntityTemplateResourceClass PS4 : PC { + } + EntityTemplateResourceClass PS5 : PC { + } + EntityTemplateResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/weather/UI/layouts/HUD/Weather/ACE_WindInfo.layout b/addons/weather/UI/layouts/HUD/Weather/ACE_WindInfo.layout new file mode 100644 index 000000000..b2595580e --- /dev/null +++ b/addons/weather/UI/layouts/HUD/Weather/ACE_WindInfo.layout @@ -0,0 +1,36 @@ +FrameWidgetClass { + Name "rootFrame" + Slot FrameWidgetSlot "{667B238989AA1DEF}" { + OffsetLeft 0 + OffsetTop 0 + SizeX 1920 + OffsetRight -1920 + SizeY 1080 + OffsetBottom -1080 + } + { + SizeLayoutWidgetClass "{667B2E26F81247E7}" { + Name "Layout" + Slot FrameWidgetSlot "{667B2E26F81247DD}" { + Anchor 1 1 1 1 + OffsetLeft 0 + OffsetTop 0 + SizeX 256 + OffsetRight -256 + SizeY 256 + OffsetBottom -256 + Alignment 1.75 1 + } + { + CanvasWidgetClass "{667B2E26A9C9585A}" { + Name "Canvas" + Slot AlignableSlot "{667B2E31A331DAAC}" { + HorizontalAlign 3 + VerticalAlign 3 + } + ZoomLevel 0.5 + } + } + } + } +} \ No newline at end of file diff --git a/addons/weather/UI/layouts/HUD/Weather/ACE_WindInfo.layout.meta b/addons/weather/UI/layouts/HUD/Weather/ACE_WindInfo.layout.meta new file mode 100644 index 000000000..3aefd40f9 --- /dev/null +++ b/addons/weather/UI/layouts/HUD/Weather/ACE_WindInfo.layout.meta @@ -0,0 +1,17 @@ +MetaFileClass { + Name "{D09C66978322D6AD}UI/layouts/HUD/Weather/ACE_WindInfo.layout" + Configurations { + LayoutResourceClass PC { + } + LayoutResourceClass XBOX_ONE : PC { + } + LayoutResourceClass XBOX_SERIES : PC { + } + LayoutResourceClass PS4 : PC { + } + LayoutResourceClass PS5 : PC { + } + LayoutResourceClass HEADLESS : PC { + } + } +} \ No newline at end of file diff --git a/addons/weather/addon.gproj b/addons/weather/addon.gproj new file mode 100644 index 000000000..66b5c0141 --- /dev/null +++ b/addons/weather/addon.gproj @@ -0,0 +1,83 @@ +GameProject { + ID "ACE_Weather" + GUID "667D049B9D9A0883" + TITLE "ACE Weather" + Dependencies { + "58D0FB3206B6F859" "60C4CE4888FF4621" + } + Configurations { + GameProjectConfig PC { + WidgetManagerSettings WidgetManagerSettings "{AC4BE58770485E02}" { + StringTables { + StringTableDefinition "{667B2E0AE586FBB4}" { + StringTableSource "{95AF98816BFC4873}Language/ACE_Weather_localization.st" + Languages { + LanguageDefinition "{667B2E0A1A7FA0EB}" { + Code "cs_cz" + StringTableRuntime "{736FE6EBA2DDF341}Language/ACE_Weather_localization.cs_cz.conf" + } + LanguageDefinition "{667B2E0A1A7FA008}" { + Code "de_de" + StringTableRuntime "{A611FCD8B17EE261}Language/ACE_Weather_localization.de_de.conf" + } + LanguageDefinition "{667B2E0A1A7FA065}" { + Code "en_us" + StringTableRuntime "{F8E17693DB8DE760}Language/ACE_Weather_localization.en_us.conf" + } + LanguageDefinition "{667B2E0A1A7FA05D}" { + Code "es_es" + StringTableRuntime "{3DAD3B1A358F8C7F}Language/ACE_Weather_localization.es_es.conf" + } + LanguageDefinition "{667B2E0A1A7FAFB0}" { + Code "fr_fr" + StringTableRuntime "{8605CE2DD30C6F7D}Language/ACE_Weather_localization.fr_fr.conf" + } + LanguageDefinition "{667B2E0A1A7FAFA9}" { + Code "it_it" + StringTableRuntime "{061941197E2EEC84}Language/ACE_Weather_localization.it_it.conf" + } + LanguageDefinition "{667B2E0A1A7FAF9F}" { + Code "ja_jp" + StringTableRuntime "{1602FC8B405FDC2F}Language/ACE_Weather_localization.ja_jp.conf" + } + LanguageDefinition "{667B2E0A1A7FAF8D}" { + Code "ko_kr" + StringTableRuntime "{B6BCD427D372DF10}Language/ACE_Weather_localization.ko_kr.conf" + } + LanguageDefinition "{667B2E0A1A7FAFE3}" { + Code "pl_pl" + StringTableRuntime "{EACD72DD6D9D436C}Language/ACE_Weather_localization.pl_pl.conf" + } + LanguageDefinition "{667B2E0A1A7FAFD5}" { + Code "pt_br" + StringTableRuntime "{3FBAE811566389D6}Language/ACE_Weather_localization.pt_br.conf" + } + LanguageDefinition "{667B2E0A1A7FAF3E}" { + Code "ru_ru" + StringTableRuntime "{6AFBFCB9CB1AECA0}Language/ACE_Weather_localization.ru_ru.conf" + } + LanguageDefinition "{667B2E0A1A7FAE88}" { + Code "uk_ua" + StringTableRuntime "{E0A3A94FA73452F5}Language/ACE_Weather_localization.uk_ua.conf" + } + LanguageDefinition "{667B2E0A1A7FAEFC}" { + Code "zh_cn" + StringTableRuntime "{3A13C7729E9482E8}Language/ACE_Weather_localization.zh_cn.conf" + } + } + } + } + } + } + GameProjectConfig XBOX_ONE { + } + GameProjectConfig XBOX_SERIES { + } + GameProjectConfig PS4 { + } + GameProjectConfig PS5 { + } + GameProjectConfig HEADLESS { + } + } +} \ No newline at end of file diff --git a/addons/weather/dev.gproj b/addons/weather/dev.gproj new file mode 100644 index 000000000..f9656d7cc --- /dev/null +++ b/addons/weather/dev.gproj @@ -0,0 +1,83 @@ +GameProject { + ID "ACE_Weather_Dev" + GUID "667B230F9505C8BA" + TITLE "ACE Weather Dev" + Dependencies { + "58D0FB3206B6F859" "65AD7D0D9941A380" + } + Configurations { + GameProjectConfig PC { + WidgetManagerSettings WidgetManagerSettings "{AC4BE58770485E02}" { + StringTables { + StringTableDefinition "{667B2E0AE586FBB4}" { + StringTableSource "{95AF98816BFC4873}Language/ACE_Weather_localization.st" + Languages { + LanguageDefinition "{667B2E0A1A7FA0EB}" { + Code "cs_cz" + StringTableRuntime "{736FE6EBA2DDF341}Language/ACE_Weather_localization.cs_cz.conf" + } + LanguageDefinition "{667B2E0A1A7FA008}" { + Code "de_de" + StringTableRuntime "{A611FCD8B17EE261}Language/ACE_Weather_localization.de_de.conf" + } + LanguageDefinition "{667B2E0A1A7FA065}" { + Code "en_us" + StringTableRuntime "{F8E17693DB8DE760}Language/ACE_Weather_localization.en_us.conf" + } + LanguageDefinition "{667B2E0A1A7FA05D}" { + Code "es_es" + StringTableRuntime "{3DAD3B1A358F8C7F}Language/ACE_Weather_localization.es_es.conf" + } + LanguageDefinition "{667B2E0A1A7FAFB0}" { + Code "fr_fr" + StringTableRuntime "{8605CE2DD30C6F7D}Language/ACE_Weather_localization.fr_fr.conf" + } + LanguageDefinition "{667B2E0A1A7FAFA9}" { + Code "it_it" + StringTableRuntime "{061941197E2EEC84}Language/ACE_Weather_localization.it_it.conf" + } + LanguageDefinition "{667B2E0A1A7FAF9F}" { + Code "ja_jp" + StringTableRuntime "{1602FC8B405FDC2F}Language/ACE_Weather_localization.ja_jp.conf" + } + LanguageDefinition "{667B2E0A1A7FAF8D}" { + Code "ko_kr" + StringTableRuntime "{B6BCD427D372DF10}Language/ACE_Weather_localization.ko_kr.conf" + } + LanguageDefinition "{667B2E0A1A7FAFE3}" { + Code "pl_pl" + StringTableRuntime "{EACD72DD6D9D436C}Language/ACE_Weather_localization.pl_pl.conf" + } + LanguageDefinition "{667B2E0A1A7FAFD5}" { + Code "pt_br" + StringTableRuntime "{3FBAE811566389D6}Language/ACE_Weather_localization.pt_br.conf" + } + LanguageDefinition "{667B2E0A1A7FAF3E}" { + Code "ru_ru" + StringTableRuntime "{6AFBFCB9CB1AECA0}Language/ACE_Weather_localization.ru_ru.conf" + } + LanguageDefinition "{667B2E0A1A7FAE88}" { + Code "uk_ua" + StringTableRuntime "{E0A3A94FA73452F5}Language/ACE_Weather_localization.uk_ua.conf" + } + LanguageDefinition "{667B2E0A1A7FAEFC}" { + Code "zh_cn" + StringTableRuntime "{3A13C7729E9482E8}Language/ACE_Weather_localization.zh_cn.conf" + } + } + } + } + } + } + GameProjectConfig XBOX_ONE { + } + GameProjectConfig XBOX_SERIES { + } + GameProjectConfig PS4 { + } + GameProjectConfig PS5 { + } + GameProjectConfig HEADLESS { + } + } +} \ No newline at end of file diff --git a/addons/weather/license.txt b/addons/weather/license.txt new file mode 100644 index 000000000..6ebf24cf1 --- /dev/null +++ b/addons/weather/license.txt @@ -0,0 +1,18 @@ +ACE Anvil - An experimental realism mod for Arma Reforger +Copyright (C) 2024 acemod + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +When publishing a derivative of this product you may not use a name that +might create the impression that your version is an official release. + +A full copy of this license can be found at the following address: +https://github.com/acemod/ACE-Anvil/blob/master/LICENSE. diff --git a/addons/weather/scripts/Game/ACE_Weather/Diag/ArmaReforgerScripted.c b/addons/weather/scripts/Game/ACE_Weather/Diag/ArmaReforgerScripted.c new file mode 100644 index 000000000..721bb729e --- /dev/null +++ b/addons/weather/scripts/Game/ACE_Weather/Diag/ArmaReforgerScripted.c @@ -0,0 +1,47 @@ +#ifdef ENABLE_DIAG +//------------------------------------------------------------------------------------------------ +modded class ArmaReforgerScripted : ChimeraGame +{ + protected bool m_bACE_Overheating_PreviousJamState = false; + protected bool m_bACE_Overheating_PreviousJamSetting = false; + protected float m_fACE_Overheating_PreviousBarrelTemperatureSetting; + protected float m_fACE_Overheating_PreviousAmmoTemperatureSetting; + + //------------------------------------------------------------------------------------------------ + override bool OnGameStart() + { + DiagMenu.RegisterMenu(SCR_DebugMenuID.ACE_WEATHER_DEBUGUI_MENU, "ACE Weather", "ACE"); + DiagMenu.RegisterBool(SCR_DebugMenuID.ACE_WEATHER_DEBUGUI_MENU_TEMPERATURE_DIAG, "", "Show temperature diag", "ACE Weather"); + + return super.OnGameStart(); + } + + //------------------------------------------------------------------------------------------------ + override void OnUpdate(BaseWorld world, float timeslice) + { + super.OnUpdate(world, timeslice); + + if (DiagMenu.GetBool(SCR_DebugMenuID.ACE_WEATHER_DEBUGUI_MENU_TEMPERATURE_DIAG)) + ACE_Weather_ShowTemperatureDiag() + } + + + + //------------------------------------------------------------------------------------------------ + protected void ACE_Weather_ShowTemperatureDiag() + { + ChimeraWorld world = GetGame().GetWorld(); + + TimeAndWeatherManagerEntity manager = world.GetTimeAndWeatherManager(); + if (!manager) + return; + + float airTemperature = manager.ACE_GetAirTemperature() - ACE_PhysicalConstants.ZERO_CELSIUS; + + DbgUI.Begin("ACE Weather Diag", 0, 700); + DbgUI.Text(string.Format("Air Temperature: %1 deg C", ACE_Math.Round(airTemperature, 1))); + DbgUI.PlotLiveClamped("AirTemperature", 500, 500, airTemperature, -10, 40, 100, 10000); + DbgUI.End(); + } +} +#endif \ No newline at end of file diff --git a/addons/weather/scripts/Game/ACE_Weather/Diag/SCR_DebugMenuID.c b/addons/weather/scripts/Game/ACE_Weather/Diag/SCR_DebugMenuID.c new file mode 100644 index 000000000..7055f4ff3 --- /dev/null +++ b/addons/weather/scripts/Game/ACE_Weather/Diag/SCR_DebugMenuID.c @@ -0,0 +1,8 @@ +#ifdef ENABLE_DIAG +//------------------------------------------------------------------------------------------------ +modded enum SCR_DebugMenuID +{ + ACE_WEATHER_DEBUGUI_MENU, + ACE_WEATHER_DEBUGUI_MENU_TEMPERATURE_DIAG, +} +#endif \ No newline at end of file diff --git a/addons/weather/scripts/Game/ACE_Weather/UI/HUD/ACE_Weather_WindInfoDisplay.c b/addons/weather/scripts/Game/ACE_Weather/UI/HUD/ACE_Weather_WindInfoDisplay.c new file mode 100644 index 000000000..7b5aa0da0 --- /dev/null +++ b/addons/weather/scripts/Game/ACE_Weather/UI/HUD/ACE_Weather_WindInfoDisplay.c @@ -0,0 +1,214 @@ +//------------------------------------------------------------------------------------------------ +class ACE_Weather_WindInfoDisplay : SCR_InfoDisplayExtended +{ + protected ChimeraCharacter m_CharacterEntity; + protected TNodeId m_CharHeadBone; + protected TimeAndWeatherManagerEntity m_WeatherManager; + protected Widget m_wLayout; + protected CanvasWidget m_wCanvas; + protected vector m_vCanvasCenter; + protected ref LineDrawCommand m_MainLine = new LineDrawCommand(); + protected ref LineDrawCommand m_InnerCircle = new LineDrawCommand(); + protected ref array m_aDrawCommands = {m_InnerCircle, m_MainLine}; + protected ref array m_aOuterCircleVertices; + + // Lengths with respect to a native widget size of 256x256 + protected const float MAIN_LINE_LENGTH = 2 * 48; + protected const float LINE_WIDTH = 2 * 3; + protected const float TEN_KNOTS_BARB_LENGTH = 2 * 20; + protected const float FIVE_KNOTS_BARB_LENGTH = 2 * 10; + protected const float INTER_FEATHER_DIST = 2 * 7; + protected const float FEATHER_ANGLE_RAD = 0.3; + protected const float INNER_CIRCLE_RADIUS = 2 * 5; + protected const float OUTER_CIRCLE_RADIUS = 2 * 15; + protected const int CRICLE_VERTEX_COUNT = 16; + + protected float m_fDPIScale; + protected float m_fMainLineLengthScaled; + protected float m_fLineWidthScaled; + protected float m_fTenKnotsBarbLengthScaled; + protected float m_fFiveKnotsBarbLengthScaled; + protected float m_fInterFeatherDistScaled; + protected float m_fInnerCircleRadiusScaled; + protected float m_fOuterCircleRadiusScaled; + + //------------------------------------------------------------------------------------------------ + override void DisplayStartDraw(IEntity owner) + { + ChimeraWorld world = GetGame().GetWorld(); + m_WeatherManager = world.GetTimeAndWeatherManager(); + m_wLayout = m_wRoot.FindWidget("Layout"); + m_wCanvas = CanvasWidget.Cast(m_wLayout.FindWidget("Canvas")); + m_InnerCircle.m_iColor = Color.WHITE; + m_MainLine.m_iColor = Color.WHITE; + GetGame().GetInputManager().AddActionListener("ACE_Weather_WindInfoToggle", EActionTrigger.DOWN, ToggleDisplay); + } + + //------------------------------------------------------------------------------------------------ + protected void UpdateDPIScale(float scale) + { + m_fDPIScale = scale; + m_vCanvasCenter = m_fDPIScale * 0.5 * FrameSlot.GetSize(m_wLayout); + m_fMainLineLengthScaled = m_fDPIScale * MAIN_LINE_LENGTH; + m_fLineWidthScaled = m_fDPIScale * LINE_WIDTH; + m_fTenKnotsBarbLengthScaled = m_fDPIScale * TEN_KNOTS_BARB_LENGTH; + m_fFiveKnotsBarbLengthScaled = m_fDPIScale * FIVE_KNOTS_BARB_LENGTH; + m_fInterFeatherDistScaled = m_fDPIScale * INTER_FEATHER_DIST; + m_fInnerCircleRadiusScaled = m_fDPIScale * INNER_CIRCLE_RADIUS; + m_fOuterCircleRadiusScaled = m_fDPIScale * OUTER_CIRCLE_RADIUS; + m_InnerCircle.m_fWidth = m_fLineWidthScaled; + m_MainLine.m_fWidth = m_fLineWidthScaled; + } + + //------------------------------------------------------------------------------------------------ + override void DisplayStopDraw(IEntity owner) + { + GetGame().GetInputManager().RemoveActionListener("ACE_Weather_WindInfoToggle", EActionTrigger.DOWN, ToggleDisplay); + } + + //------------------------------------------------------------------------------------------------ + override void DisplayControlledEntityChanged(IEntity from, IEntity to) + { + Show(false); + + m_CharacterEntity = ChimeraCharacter.Cast(to); + if (!m_CharacterEntity) + return; + + m_CharHeadBone = m_CharacterEntity.GetAnimation().GetBoneIndex("Head"); + } + + //------------------------------------------------------------------------------------------------ + override protected void DisplayUpdate(IEntity owner, float timeSlice) + { + if (!IsShown() || !m_CharacterEntity) + return; + + float dpiScale = GetGame().GetWorkspace().DPIScale(1); + if (m_fDPIScale != dpiScale) + { + UpdateDPIScale(dpiScale); + UpdateCirclesVertices(); + } + + UpdateWindBarbs(); + } + + //------------------------------------------------------------------------------------------------ + protected void UpdateWindBarbs() + { + m_aDrawCommands = {m_InnerCircle, m_MainLine}; + + int fiveKnotsCount = Math.Round(ACE_PhysicalConstants.MPS2KNOTS * m_WeatherManager.GetWindSpeed() / 5.0); + if (fiveKnotsCount == 0) + { + // Draw an outer circle if wind is too faint + m_MainLine.m_Vertices = m_aOuterCircleVertices; + m_wCanvas.SetDrawCommands(m_aDrawCommands); + return; + } + + // Get wind direction relative to head + vector localHeadTransform[4]; + m_CharacterEntity.GetAnimation().GetBoneMatrix(m_CharHeadBone, localHeadTransform); + float headDir = m_CharacterEntity.VectorToParent(localHeadTransform[0]).ToYaw(); + float windDir = m_WeatherManager.GetWindDirection(); + float windAngleRad = Math.DEG2RAD * (windDir - headDir); + vector screenWindVec = Vector(-Math.Cos(windAngleRad), -Math.Sin(windAngleRad), 0); + vector screenPerpVec = Vector(screenWindVec[1], -screenWindVec[0], 0); + + vector mainStart = m_vCanvasCenter - m_fInnerCircleRadiusScaled * screenWindVec; + vector mainEnd = m_vCanvasCenter - m_fMainLineLengthScaled * screenWindVec; + m_MainLine.m_Vertices = {mainStart[0], mainStart[1], mainEnd[0], mainEnd[1]}; + vector featherPos = mainEnd; + + m_aDrawCommands.Reserve(m_aDrawCommands.Count() + Math.Ceil(0.5 * fiveKnotsCount)); + + // Single 5 knots barb is offset for clarification + if (fiveKnotsCount == 1) + featherPos += m_fInterFeatherDistScaled * screenWindVec; + + while (fiveKnotsCount > 0) + { + float featherLen = m_fTenKnotsBarbLengthScaled; + + if (fiveKnotsCount >= 10) + { + m_aDrawCommands.Insert(GetPennantDrawCommand(featherPos, featherLen, screenWindVec, screenPerpVec)); + fiveKnotsCount -= 10; + } + else + { + if (fiveKnotsCount == 1) + featherLen = m_fFiveKnotsBarbLengthScaled; + + m_aDrawCommands.Insert(GetBarbDrawCommand(featherPos, featherLen, screenWindVec, screenPerpVec)); + fiveKnotsCount -= 2; + } + + featherPos += m_fInterFeatherDistScaled * screenWindVec; + } + + m_wCanvas.SetDrawCommands(m_aDrawCommands); + } + + //------------------------------------------------------------------------------------------------ + protected CanvasWidgetCommand GetPennantDrawCommand(inout vector featherPos, float featherLen, vector screenWindVec, vector screenPerpVec) + { + PolygonDrawCommand pennant = new PolygonDrawCommand(); + pennant.m_iColor = Color.WHITE; + featherPos += m_fLineWidthScaled * screenWindVec; + vector start = featherPos + 0.5 * m_fLineWidthScaled * (screenWindVec - screenPerpVec); + vector apex1 = featherPos + featherLen * (screenPerpVec * Math.Cos(FEATHER_ANGLE_RAD) - screenWindVec * Math.Sin(FEATHER_ANGLE_RAD)); + vector apex2 = apex1 - m_fLineWidthScaled * screenWindVec; + vector end = start - featherLen * screenWindVec * Math.Sin(FEATHER_ANGLE_RAD) - m_fLineWidthScaled * screenWindVec; + pennant.m_Vertices = {start[0], start[1], apex1[0], apex1[1], apex2[0], apex2[1], end[0], end[1]}; + return pennant; + } + + //------------------------------------------------------------------------------------------------ + protected CanvasWidgetCommand GetBarbDrawCommand(inout vector featherPos, float featherLen, vector screenWindVec, vector screenPerpVec) + { + LineDrawCommand barb = new LineDrawCommand(); + barb.m_iColor = Color.WHITE; + barb.m_fWidth = m_fLineWidthScaled; + vector barbEnd = featherPos + featherLen * (screenPerpVec * Math.Cos(FEATHER_ANGLE_RAD) - screenWindVec * Math.Sin(FEATHER_ANGLE_RAD)); + barb.m_Vertices = {featherPos[0], featherPos[1], barbEnd[0], barbEnd[1]}; + return barb; + } + + //------------------------------------------------------------------------------------------------ + protected void UpdateCirclesVertices() + { + m_aOuterCircleVertices = {}; + m_aOuterCircleVertices.Reserve(2 * CRICLE_VERTEX_COUNT + 2); + m_InnerCircle.m_Vertices = {}; + m_InnerCircle.m_Vertices.Reserve(2 * CRICLE_VERTEX_COUNT + 2); + + for (int i = 0; i <= CRICLE_VERTEX_COUNT; ++i) + { + float angle = i * Math.PI2 / CRICLE_VERTEX_COUNT; + m_aOuterCircleVertices.Insert(m_vCanvasCenter[0] + m_fOuterCircleRadiusScaled * Math.Cos(angle)); + m_aOuterCircleVertices.Insert(m_vCanvasCenter[1] + m_fOuterCircleRadiusScaled * Math.Sin(angle)); + m_InnerCircle.m_Vertices.Insert(m_vCanvasCenter[0] + m_fInnerCircleRadiusScaled * Math.Cos(angle)); + m_InnerCircle.m_Vertices.Insert(m_vCanvasCenter[1] + m_fInnerCircleRadiusScaled * Math.Sin(angle)); + } + } + + //------------------------------------------------------------------------------------------------ + protected void ToggleDisplay() + { + Show(!IsShown()); + } + + //------------------------------------------------------------------------------------------------ + //! Terminate screen when chracter transitions from uncon to death + override protected void DisplayConsciousnessChanged(bool conscious, bool init = false) + { + if (init || !conscious) + return; + + if (m_CharacterController.GetLifeState() == ECharacterLifeState.DEAD) + Show(false); + } +} diff --git a/addons/weather/scripts/GameCode/ACE_Weather/World/TimeAndWeatherManagerEntity.c b/addons/weather/scripts/GameCode/ACE_Weather/World/TimeAndWeatherManagerEntity.c new file mode 100644 index 000000000..05e703f73 --- /dev/null +++ b/addons/weather/scripts/GameCode/ACE_Weather/World/TimeAndWeatherManagerEntity.c @@ -0,0 +1,195 @@ +//------------------------------------------------------------------------------------------------ +//! Calculate air temperature based on corrected SinExp model +//! Ref.: Int. J. Climatol. 2006, 26, 75. (Equations 3a, 3b and 4) +modded class TimeAndWeatherManagerEntity : BaseTimeAndWeatherManagerEntity +{ + [Attribute(desc: "Average hour of the day at which peak air temperature occurs per month in 24 h format.", params: "0 24", category: "Temperature")] + protected ref array m_aACE_MonthlyAverageTemperatureAirMaxHours; + + [Attribute(desc: "Average daily minimum air temperature for each month in Kelvin", params: "0 1000", category: "Temperature")] + protected ref array m_aACE_MonthlyAverageDailyTemperatureAirMins; + + [Attribute(desc: "Average daily maximum air temperature for each month in Kelvin", params: "0 1000", category: "Temperature")] + protected ref array m_aACE_MonthlyAverageDailyTemperatureAirMaxs; + + [Attribute(defvalue: "1.45", desc: "Overcast-induced temperature shift is overcast times this factor in Kelvin. Symmetrically shifts Tmax down and Tmin up to lower DTR.", category: "Temperature")] + protected float m_fACE_OvercastTemperatureFactor; + + [Attribute(defvalue: "2.2", desc: "Exponential temperature decay rate at night. γ in SinExp model.", params: "0 100", category: "Temperature")] + protected float m_fACE_SinExp_Gamma; + + [Attribute(defvalue: "0.888", desc: "Autoregressive coefficient of mean temperature noise.", params: "0 1", category: "Temperature")] + protected float m_fACE_MeanTemperatureAirAutoRegCoeff; + + [Attribute(defvalue: "3.218", desc: "Standard deviation of mean temperature noise in Kelvin.", params: "0 1000", category: "Temperature")] + protected float m_fACE_MeanTemperatureAirStdDev; + + [Attribute(defvalue: "0.566", desc: "Autoregressive coefficient of diurnal temperature range noise.", params: "0 1", category: "Temperature")] + protected float m_fACE_DiurnalTemperatureRangeAutoRegCoeff; + + [Attribute(defvalue: "1.204", desc: "Standard deviation of diurnal temperature range noise in Kelvin.", params: "0 1000", category: "Temperature")] + protected float m_fACE_DiurnalTemperatureRangeStdDev; + + [Attribute(defvalue: "1.0", desc: "Minimum diurnal temperature range in Kelvin.", params: "0 1000", category: "Temperature")] + protected float m_fACE_MinDiurnalTemperatureRange; + + protected bool m_bACE_IsCurrentlyDay; + + protected float m_fACE_SinExp_Tmin; + protected float m_fACE_SinExp_Tmax; + protected float m_fACE_SinExp_Ts; + protected float m_fACE_SinExp_Alpha; + protected float m_fACE_SinExp_Tau; + protected float m_fACE_SinExp_L; + protected float m_fACE_SinExp_Hr; + protected float m_fACE_SinExp_Hs; + protected float m_fACE_SinExp_Hmax; + + protected ref ACE_AutoRegModel m_fACE_DiurnalTemperatureRangeNoiseGenerator; + protected ref ACE_AutoRegModel m_fACE_MeanTemperatureAirNoiseGenerator; + + //------------------------------------------------------------------------------------------------ + //! TODO: Better approach for accuratly initializing SinExp from any starting point + override protected void EOnInit(IEntity owner) + { + super.EOnInit(owner); + + if (!GetGame().InPlayMode()) + return; + + RplComponent rpl = SCR_EntityHelper.GetEntityRplComponent(owner); + if (rpl && rpl.IsProxy()) + return; + + m_fACE_DiurnalTemperatureRangeNoiseGenerator = ACE_AutoRegModel(m_fACE_DiurnalTemperatureRangeAutoRegCoeff, m_fACE_DiurnalTemperatureRangeStdDev); + m_fACE_MeanTemperatureAirNoiseGenerator = ACE_AutoRegModel(m_fACE_MeanTemperatureAirAutoRegCoeff, m_fACE_MeanTemperatureAirStdDev); + + // Day init always has to be done + m_fACE_SinExp_Tmin = ACE_InterpolateForDayFromMonthlyAverage(GetMonth(), GetDay(), m_aACE_MonthlyAverageDailyTemperatureAirMins); + m_fACE_SinExp_Tmin += m_fACE_OvercastTemperatureFactor * ACE_ComputeAverageOvercastForecast(12); + m_fACE_SinExp_Tmin += m_fACE_DiurnalTemperatureRangeNoiseGenerator.SamplePoint(); + m_fACE_SinExp_Tmin += m_fACE_MeanTemperatureAirNoiseGenerator.SamplePoint(); + ACE_UpdateSunrisePortion(GetYear(), GetMonth(), GetDay()); + Print(m_fACE_SinExp_Hr); + Print(m_fACE_SinExp_Hs); + m_bACE_IsCurrentlyDay = IsDayHour(GetTimeOfTheDay()); + if (!m_bACE_IsCurrentlyDay) + { + m_fACE_CurrentAirTemperature = ACE_CalculateAirTemperature(m_fACE_SinExp_Hs - 0.001); // Get sunset temp slightly before sunset, will be loaded into sunset temp by updatesunsetportion + ACE_UpdateSunsetPortion(GetYear(), GetMonth(), GetDay()); + } + + Replication.BumpMe(); + } + + //------------------------------------------------------------------------------------------------ + override void ACE_UpdateWeather(float timeSlice) + { + super.ACE_UpdateWeather(timeSlice); + + if (IsDayHour(GetTimeOfTheDay()) != m_bACE_IsCurrentlyDay) // If out of date, update the params + { + m_bACE_IsCurrentlyDay = !m_bACE_IsCurrentlyDay; + if (m_bACE_IsCurrentlyDay) + ACE_UpdateSunrisePortion(GetYear(), GetMonth(), GetDay()); + else + ACE_UpdateSunsetPortion(GetYear(), GetMonth(), GetDay()); + } + + m_fACE_CurrentAirTemperature = ACE_CalculateAirTemperature(GetTimeOfTheDay()); + Replication.BumpMe(); + } + + //------------------------------------------------------------------------------------------------ + protected float ACE_CalculateAirTemperature(float currentTime) + { + if (currentTime < m_fACE_SinExp_Hr) // Post midnight, pre sunrise + { + return m_fACE_SinExp_Tau + (m_fACE_SinExp_Ts - m_fACE_SinExp_Tau) * ACE_Math.Exp(-m_fACE_SinExp_Gamma * (currentTime + 24 - m_fACE_SinExp_Hs) / (24 - m_fACE_SinExp_L)); + } + else if (currentTime < m_fACE_SinExp_Hs) // sun is out, post sunrise pre sunset + { + float phase = Math.PI * (currentTime - m_fACE_SinExp_Hr) / (m_fACE_SinExp_L + 2 * m_fACE_SinExp_Alpha); + return m_fACE_SinExp_Tmin + (m_fACE_SinExp_Tmax - m_fACE_SinExp_Tmin) * Math.Sin(phase); + } + else // sun is set, pre midnight + { + return m_fACE_SinExp_Tau + (m_fACE_SinExp_Ts - m_fACE_SinExp_Tau) * ACE_Math.Exp(-m_fACE_SinExp_Gamma * (currentTime - m_fACE_SinExp_Hs) / (24 - m_fACE_SinExp_L)); + } + } + + //------------------------------------------------------------------------------------------------ + protected void ACE_UpdateSunrisePortion(int year, int month, int day) + { + m_fACE_SinExp_Hmax = ACE_InterpolateForDayFromMonthlyAverage(month, day, m_aACE_MonthlyAverageTemperatureAirMaxHours); + m_fACE_SinExp_Tmax = ACE_InterpolateForDayFromMonthlyAverage(month, day, m_aACE_MonthlyAverageDailyTemperatureAirMaxs); + m_fACE_SinExp_Tmax -= m_fACE_OvercastTemperatureFactor * ACE_ComputeAverageOvercastForecast(12); + m_fACE_SinExp_Tmax -= m_fACE_DiurnalTemperatureRangeNoiseGenerator.SamplePoint(); + m_fACE_SinExp_Tmax += m_fACE_MeanTemperatureAirNoiseGenerator.SamplePoint(); + + if (m_fACE_SinExp_Tmax - m_fACE_SinExp_Tmin < m_fACE_MinDiurnalTemperatureRange) + m_fACE_SinExp_Tmax = m_fACE_SinExp_Tmin + m_fACE_MinDiurnalTemperatureRange; + + if (!GetSunriseHour(m_fACE_SinExp_Hr)) + m_fACE_SinExp_Hr = 0; // Workaround for polar circles + + if (!GetSunsetHour(m_fACE_SinExp_Hs)) + m_fACE_SinExp_Hs = 24; // Workaround for polar circles + + m_fACE_SinExp_L = m_fACE_SinExp_Hs - m_fACE_SinExp_Hr; + m_fACE_SinExp_Alpha = m_fACE_SinExp_Hmax - (m_fACE_SinExp_Hr + m_fACE_SinExp_Hs) / 2; + } + + //------------------------------------------------------------------------------------------------ + protected void ACE_UpdateSunsetPortion(int year, int month, int day) + { + m_fACE_SinExp_Ts = m_fACE_CurrentAirTemperature; + + ACE_AddDaysToDate(year, month, day, 1); // Get tommorow's date + + float dstOffset = 0; + if (IsDSTEnabled()) + dstOffset = GetDSTOffset(); + + float hrPrime; + if (!GetSunriseHourForDate(year, month, day, GetCurrentLatitude(), GetCurrentLongitude(), GetTimeZoneOffset(), dstOffset, hrPrime)) + hrPrime = 0; // Workaround for polar circles + + m_fACE_SinExp_Tmin = ACE_InterpolateForDayFromMonthlyAverage(month, day, m_aACE_MonthlyAverageDailyTemperatureAirMins); + m_fACE_SinExp_Tmin += m_fACE_OvercastTemperatureFactor * ACE_ComputeAverageOvercastForecast(12); + m_fACE_SinExp_Tmin += m_fACE_DiurnalTemperatureRangeNoiseGenerator.SamplePoint(); + m_fACE_SinExp_Tmin += m_fACE_MeanTemperatureAirNoiseGenerator.SamplePoint(); + + if (m_fACE_SinExp_Tmax - m_fACE_SinExp_Tmin < m_fACE_MinDiurnalTemperatureRange) + m_fACE_SinExp_Tmin = m_fACE_SinExp_Tmax - m_fACE_MinDiurnalTemperatureRange; + + float expResult = ACE_Math.Exp(-m_fACE_SinExp_Gamma * (24 + hrPrime - m_fACE_SinExp_Hs) / (24 - m_fACE_SinExp_L)); + m_fACE_SinExp_Tau = (m_fACE_SinExp_Tmin - m_fACE_SinExp_Ts * expResult) / (1 - expResult); + } + + //------------------------------------------------------------------------------------------------ + protected float ACE_InterpolateForDayFromMonthlyAverage(int month, int day, array monthlyAverages) + { + float lambda = (day - 0.5 * ACE_AVERAGE_DAYS_PER_MONTH) / ACE_AVERAGE_DAYS_PER_MONTH; + + if (lambda >= 0) + return Math.Lerp(monthlyAverages[month - 1], monthlyAverages[month % 12], lambda); + else + return Math.Lerp(monthlyAverages[month - 1], monthlyAverages[(month + 10) % 12], -lambda); + } + + //------------------------------------------------------------------------------------------------ + //! Compute average overcast for given duration in hours + protected float ACE_ComputeAverageOvercastForecast(float forecastDuration) + { + float weight = 1.0; + + float changeDuration = GetTransitionManager().GetTimeLeftUntilNextState(); + if (changeDuration < forecastDuration) + weight = GetTransitionManager().GetTimeLeftUntilNextState() / forecastDuration; + + float average = weight * ACE_GetOvercastForState(GetTransitionManager().GetCurrentState()); + average += (1.0 - weight) * ACE_GetOvercastForState(GetTransitionManager().GetNextState()); + return average; + } +} diff --git a/addons/weather/thumbnail.png b/addons/weather/thumbnail.png new file mode 100644 index 000000000..3d4283142 Binary files /dev/null and b/addons/weather/thumbnail.png differ diff --git a/docs/src/content/docs/components/core.mdx b/docs/src/content/docs/components/core.mdx index d84d63445..92696ec7e 100644 --- a/docs/src/content/docs/components/core.mdx +++ b/docs/src/content/docs/components/core.mdx @@ -3,3 +3,18 @@ title: Core --- Common functions and systems used by other mods. + +Additional features: + +- Turret radial menu +- More gestures (_e.g._ sit on the floor) + +### Usage + +#### Turret Inspection Radial Menu + +- Use the `Inspect` keybind in `Equipment` category (Default: Hold R) + +#### Play Gestures + +- Use the `Open gestures menu` keybind in `Character` category (Default: F1) diff --git a/docs/src/content/docs/components/overheating.mdx b/docs/src/content/docs/components/overheating.mdx new file mode 100644 index 000000000..a866b591b --- /dev/null +++ b/docs/src/content/docs/components/overheating.mdx @@ -0,0 +1,98 @@ +--- +title: Overheating +--- + +Simulates heating of weapons when firing with the following effects: +- The hotter a weapon gets, the more likely a jam occurs. +- Ammo can cook-off when exceeding `m_fGunpowderAutoignitionTemperature` (see [Settings](#settings)). +- Temperature-dependent muzzle dispersion (_i.e._ weapon accuracy drops with temperature) +- Barrel of MGs start glowing when exceeding `m_fMinGlowTemperature` (see [Settings](#settings)). + +## Usage + +### Try Clearing Jam + +- Try clearing jam with LShift+R (ACE default) + +### Check Temperature of Barrel + +- An interaction for checking the temperature is visible on the barrel in weapon inspection mode. + +### Swap Barrel + +- An interaction for swapping the barrel is visible on the barrel in weapon inspection mode. +- Swapping barrels is only available for machine guns. +- Barrel is not an inventory item yet, so you currently don't need to carry anything to execute the action. + +### Cool Barrel in Water + +- An interaction for cooling the barrel is available in weapon inspection mode when standing in water. + +## Settings + +Certain aspects of this mod can be configured in the mission header section of a server config file. An overview of available fields is given below in the table: + +| Field | Value | Description | +| ------------------------------------- | -------------------- | -------------------------------------------------- | +| `m_fHeatingScale` | Type: `float`**
Range: 0 to ∞
Default: `1.0` | Scales the heat transferred to the barrel by a shot. The larger, the faster the temperature of the barrel increases. | +| `m_fDefaultAirCoolingScale` | Type: `float`**
Range: 0 to ∞
Default: `1.0` | Scale for how quickly a weapon gets cooled down by air. Cooling rate is multiplied by this scale. | +| `m_fOpenBoltAirCoolingScale` | Type: `float`**
Range: 0 to ∞
Default: `1.3` | Scale for how quickly a weapon gets cooled down by air for open bolt weapons. | +| `m_fWaterCoolingScale` | Type: `float`**
Range: 0 to ∞
Default: `18.0` | Scale for how quickly a weapon cools down in water. | +| `m_fJamChanceScale` | Type: `float`**
Range: 0 to ∞
Default: `1.0` | Scale for how likely a weapon jams. | +| `m_fClearJamFailureChance` | Type: `float`**
Range: 0 to 1
Default: `0.1` | Probability for clearing jam to fail. | +| `m_fGunpowderAutoignitionTemperature` | Type: `float`**
Range: 0 to 1300
Default: `473.15` | Temperature at which ammo can cook off [K]. | +| `m_fBaseHeatTransferCoefficient` | Type: `float`**
Range: 0 to ∞
Default: `125.63` | Base heat transfer coefficient for cooling of barrel from other channels than radiation and convection from wind and rain. | +| `m_fBarrel2BulletMassScaledTemperatureRateConstant` | Type: `float`**
Range: 0 to ∞
Default: `2.031` | Mass-scaled temperature rate constant for heat exchange between barrel and bullet [g/s]. The larger, the faster a chambered bullet will heat up to barrel temperature. | +| `m_fMuzzleDispersionScale` | Type: `float`**
Range: 0 to ∞
Default: `1.0` | Scales the additional temperature-dependent dispersion of shots. Set to 0.0 to turn it off. | +| `m_fMinGlowTemperature` | Type: `float`**
Range: 0 to 1300
Default: `800.0` | Temperature above which barrel starts glowing [K]. | + +\*\* Note that floats need a decimal point to get properly read. + +Example for the `missionHeader` in a server config: +``` +"missionHeader": { + "m_ACE_Settings": { + "m_ACE_Overheating_Settings": { + "m_fHeatingScale": 1.0, + "m_fDefaultAirCoolingScale": 1.0, + "m_fOpenBoltAirCoolingScale": 1.3, + "m_fWaterCoolingScale": 18.0, + "m_fJamChanceScale": 1.0, + "m_fClearJamFailureChance": 0.1, + "m_fGunpowderAutoignitionTemperature": 473.15, + "m_fBaseHeatTransferCoefficient": 125.63, + "m_fBarrel2BulletMassScaledTemperatureRateConstant": 2.031, + "m_fMuzzleDispersionScale": 1.0, + "m_fMinGlowTemperature": 800.0 + } + } +} +``` + +## Modded Weapons Support + +### Base Requirements + +- `ACE_Overheating_BarrelComponent` as a child component of `MuzzleComponent` on the weapon prefab (already present if prefab inherits from `Rifle_Base.et`, `Handgun_Base.et` or `MachineGun_Base.et`). + +### Additional Requirements for Muzzle Dispersion + +- `ACE_Overheating_HelperAttachmentComponent` slotted with `ACE_Overheating_HelperAttachment.et` as a child component of `MuzzleComponent` on the weapon prefab (already present if prefab inherits from `Rifle_Base.et`, `Handgun_Base.et` or `MachineGun_Base.et`). +- `SCR_WeaponStatsManagerComponent` on the weapon prefab (already present if prefab inherits from `Handgun_Base.et`, `MachineGun_Base.et` or `LongRangeRifle_Base.et`). + +### Additional Requirements for Glowing + +- `ACE_Overheating_BarrelGlowEffectComponent` as a child component of `MuzzleComponent` on the weapon prefab (already present if prefab inherits from `MachineGun_Base.et`). +- Emissive map on the weapon's emat with `Emissive` attribute bound to `ACE_Overheating_BarrelGlowEffectComponent.m_vColor` via `Refs` (see [BIKI](https://community.bistudio.com/wiki/Arma_Reforger:Weapon_Collimator_Creation#Manual_Material_Corrections) for docs on `Refs` ) + + Example override of `M60_Body2.emat`: + ``` + MatPBRBasic : "{51F0B466B57B2722}Assets/Weapons/MachineGuns/M60/Data/M60_Body2.emat" { + Emissive 0 0 0 1 + EmissiveAbsoluteLV 0 + EmissiveMap "{E65ED29824A4834C}Assets/Weapons/MachineGuns/M60/Data/M60_Body2_EM.edds" + Refs { + "Emissive" "ACE_Overheating_BarrelGlowEffectComponent.m_vColor" + } + } + ``` diff --git a/docs/src/content/docs/components/weather.mdx b/docs/src/content/docs/components/weather.mdx new file mode 100644 index 000000000..f698c6c17 --- /dev/null +++ b/docs/src/content/docs/components/weather.mdx @@ -0,0 +1,12 @@ +--- +title: Weather +--- + +Adds a toggleable display for showing information about wind direction and strength. + +## Usage + +### Show Wind Info + +- Toggle wind info display with `Show wind info` keybind in `ACE` category (Default: Shift+K). +- The wind direction and strength are indicated by a [wind barb](https://www.weather.gov/hfo/windbarbinfo) in the top left corner.