diff --git a/.editorconfig b/.editorconfig index f8ae8b4..025b86f 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,5 +1,12 @@ +root = true + [*] -indent_size = 2 +end_of_line = lf +insert_final_newline = true +charset = utf-8 indent_style = space +indent_size = 2 trim_trailing_whitespace = true -insert_final_newline = true + +[*.md] +trim_trailing_whitespace = false diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..3c59efe --- /dev/null +++ b/.gitattributes @@ -0,0 +1,4 @@ +* text=auto +*.png binary +*.jpg binary +*.paa binary diff --git a/.github/my-config.yml b/.github/release-drafter.yml similarity index 100% rename from .github/my-config.yml rename to .github/release-drafter.yml diff --git a/.github/workflows/Workflows_Documentation.md b/.github/workflows/Workflows_Documentation.md deleted file mode 100644 index 05de500..0000000 --- a/.github/workflows/Workflows_Documentation.md +++ /dev/null @@ -1,10 +0,0 @@ -# Documenting the workflow - -build does what ? - -job is to validate - - -development does what - - does what Release_candidate.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8cec807..21fdfe5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,4 +1,4 @@ -name: CI/Validate +name: Build on: push: @@ -11,29 +11,44 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout the source code - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Validate SQF run: python3 tools/sqf_validator.py - name: Validate Config run: python3 tools/config_style_checker.py - - name: Validate Stringtables - run: python3 tools/stringtable_validator.py - - name: Validate Return Types - run: python3 tools/return_checker.py - name: Check for BOM uses: arma-actions/bom-check@master + build: runs-on: ubuntu-latest steps: - - name: Checkout the source code - uses: actions/checkout@v2 - with: - fetch-depth: 1 - - name: Build with HEMTT - uses: arma-actions/hemtt@master - with: - command: build --release --ci - - uses: actions/upload-artifact@v2 + - name: Checkout the source code + uses: actions/checkout@v3 + - name: Setup HEMTT + uses: arma-actions/hemtt@v1 + - name: Run HEMTT release + run: hemtt release --no-archive + - name: Rename release folder + run: mv .hemttout/release .hemttout/@hatchet_framework + - uses: actions/upload-artifact@v3 + with: + name: hatchet_framework-${{ github.sha }}-nobin + path: .hemttout/@* + + publish: + needs: [build] + if: github.repository == 'Project-Hatchet/Interaction-Framework' && ! contains(github.event.head_commit.message, '[ci skip]') && github.ref == 'refs/heads/main' + runs-on: ubuntu-latest + steps: + # Upload to Steam Workshop + - name: Download Artifacts + uses: actions/download-artifact@v3 + - uses: arma-actions/workshop-upload@v1 with: - name: hatchet - path: releases/hatchet.zip + appId: '107410' + itemId: '2403978406' # Hatchet Framework - Test Version + contentPath: '.hemttout/@*' + changelog: 'See changelog on GitHub: https://github.com/Project-Hatchet/Interaction-Framework/commits' + env: + STEAM_USERNAME: ${{ secrets.STEAM_USERNAME }} + STEAM_PASSWORD: ${{ secrets.STEAM_PASSWORD }} diff --git a/.github/workflows/development.yml b/.github/workflows/development.yml deleted file mode 100644 index 7fae349..0000000 --- a/.github/workflows/development.yml +++ /dev/null @@ -1,30 +0,0 @@ -name: Steam_Upload/Dev - -on: - push: - branches: - - main - -jobs: - build_addon: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set VERSION env - run: echo VERSION=${GITHUB_REF:11} >> $GITHUB_ENV - - name: Build addon with HEMTT - uses: arma-actions/hemtt@master - with: - command: 'build --release' - # Upload to Steam Workshop - - name: Extract mod.zip - run: cd releases && sudo unzip hatchet.zip - - uses: arma-actions/workshop-upload@v1 - with: - appId: '107410' # default - itemId: '2403978406' # Id of item to update - contentPath: 'releases/@hatchet' - changelog: 'Content of change notes' - env: - STEAM_USERNAME: ${{ secrets.STEAM_USERNAME }} - STEAM_PASSWORD: ${{ secrets.STEAM_PASSWORD }} diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml index 57b7206..39c12bd 100644 --- a/.github/workflows/release-drafter.yml +++ b/.github/workflows/release-drafter.yml @@ -6,13 +6,11 @@ on: - main jobs: - update_release_draft: + draft: runs-on: ubuntu-latest + if: github.repository == 'Project-Hatchet/Interaction-Framework' steps: - # Drafts your next Release notes as Pull Requests are merged into "master" - - uses: release-drafter/release-drafter@v5 - # (Optional) specify config name to use, relative to .github/. Default: release-drafter.yml - with: - config-name: my-config.yml - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Release Drafter + uses: release-drafter/release-drafter@v5 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..18b9bed --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,36 @@ +name: Release + +on: + push: + tags: + - 'v*.*.*' + +jobs: + build_addon: + runs-on: ubuntu-latest + steps: + - name: Checkout the source code + uses: actions/checkout@v3 + - name: Setup HEMTT + uses: arma-actions/hemtt@v1 + - name: Run HEMTT release + run: hemtt release + - name: Rename release folder + run: mv .hemttout/release .hemttout/@hatchet_framework + - name: Upload to GitHub + uses: actions/action-gh-release@v1 + with: + draft: true + files: releases/hatchet_framework_*.zip + name: 'Hatchet Framework ${{ github.ref_name }}' + tag_name: ${{ github.ref_name }} + target_commitish: ${{ github.sha }} + #- uses: arma-actions/workshop-upload@v1 + # with: + # appId: '107410' + # itemId: '' # Hatchet Framework - Stable Version + # contentPath: '.hemttout/@*' + # changelog: 'See changelog on GitHub: https://github.com/Project-Hatchet/Interaction-Framework/releases' + # env: + # STEAM_USERNAME: ${{ secrets.STEAM_USERNAME }} + # STEAM_PASSWORD: ${{ secrets.STEAM_PASSWORD }} diff --git a/.github/workflows/release_main.yml b/.github/workflows/release_main.yml deleted file mode 100644 index 2574531..0000000 --- a/.github/workflows/release_main.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: Steam_Upload/Main_Release - -on: - push: - tags: - - 'v*.*.*' - -jobs: - build_addon: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set VERSION env - run: echo VERSION=${GITHUB_REF:11} >> $GITHUB_ENV - - name: Build addon with HEMTT - uses: arma-actions/hemtt@master - with: - command: 'build --release' - # Upload to Steam Workshop - - uses: arma-actions/workshop-upload@v1 - with: - appId: '107410' # default - itemId: '2403978406' # Id of item to update - contentPath: 'releases/${{ env.VERSION }}/@Hatchet Framework - Test Version' - changelog: 'Content of change notes' - env: - STEAM_USERNAME: ${{ secrets.STEAM_USERNAME }} - STEAM_PASSWORD: ${{ secrets.STEAM_PASSWORD }} diff --git a/.github/workflows/release_rc.yml b/.github/workflows/release_rc.yml deleted file mode 100644 index 2a60c03..0000000 --- a/.github/workflows/release_rc.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: Steam_Upload/Release_Candidate - -on: - push: - tags: - - 'rc-v*.*.*' - -jobs: - build_addon: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Set VERSION env - run: echo VERSION=${GITHUB_REF:11} >> $GITHUB_ENV - - name: Build addon with HEMTT - uses: arma-actions/hemtt@master - with: - command: 'build --release' - # Upload to Steam Workshop - - uses: arma-actions/workshop-upload@v1 - with: - appId: '107410' # default - itemId: '2403978406' # Id of item to update - contentPath: 'releases/${{ env.VERSION }}/@Hatchet Framework - Test Version' - changelog: 'Content of change notes' - env: - STEAM_USERNAME: ${{ secrets.STEAM_USERNAME }} - STEAM_PASSWORD: ${{ secrets.STEAM_PASSWORD }} diff --git a/.gitignore b/.gitignore index f2be826..f0a5a74 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,22 @@ +*.zip +*.bak +*.cache +keys/* +*.pbo +texHeaders.bin +*.swp +*.swo +*.biprivatekey +Thumbs.db -## Added by HEMTT +## HEMTT releases/* -*.biprivatekey -keys/* -.hemtt/local.toml -addons/*.pbo +hemtt +hemtt.exe +.hemttout +#### + +## SCONS +release +.sconsign.dblite #### diff --git a/.hemtt/base.toml b/.hemtt/base.toml deleted file mode 100644 index 1737f32..0000000 --- a/.hemtt/base.toml +++ /dev/null @@ -1,9 +0,0 @@ -name = "Project Hatchet" -prefix = "hatchet" -author = "Project Hatchet" -mainprefix = "z" - -include = ["./include"] -folder_optionals = true - -releasebuild = ["@zip {{modname}}", "@zip {{key_name}}"] diff --git a/.hemtt/hooks/post_release/01_rename_zip.rhai b/.hemtt/hooks/post_release/01_rename_zip.rhai new file mode 100644 index 0000000..6e9e24a --- /dev/null +++ b/.hemtt/hooks/post_release/01_rename_zip.rhai @@ -0,0 +1,11 @@ +let releases = HEMTT_RFS.join("releases"); +let name_nospaces = HEMTT.project().name(); +name_nospaces.replace(" ", "_"); + +let src = releases.join(HEMTT.project().prefix() + "-" + HEMTT.project().version().to_string() + ".zip"); +let dst = releases.join(name_nospaces.to_lower() + "_" + HEMTT.project().version().to_string_short() + ".zip"); + +print("Moving zip to " + dst); +if !src.move(dst) { + warn("Failed to move " + src + " to " + dst + " (maybe --no-archive?)"); +} diff --git a/.hemtt/project.toml b/.hemtt/project.toml new file mode 100644 index 0000000..6e1d74f --- /dev/null +++ b/.hemtt/project.toml @@ -0,0 +1,35 @@ +name = "Hatchet Framework" +prefix = "hatchet_vxf" +author = "Project Hatchet" +mainprefix = "z" + +[files] +include = [ + "mod.cpp", + "README.md", + "LICENSE", + "logo_vxf_ca.paa", + "meta.cpp", +] + +[version] +git_hash = 0 + +[asc] +enabled = true +exclude = [ + "/initsettings.sqf", + "/initkeybinds.sqf", + "/xeh_prep.sqf", +] + +[hemtt.config] +preset = "Hemtt" + +[hemtt.release] +folder = "vxf_framework" + +[hemtt.launch] +workshop = [ + "450814997", # CBA_A3's Workshop ID +] diff --git a/.sconsign.dblite b/.sconsign.dblite deleted file mode 100644 index 2785199..0000000 Binary files a/.sconsign.dblite and /dev/null differ diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index f8e78a2..0000000 --- a/.travis.yml +++ /dev/null @@ -1,6 +0,0 @@ -language: python -python: -- '3.4' -script: -- python3 tools/sqf_validator.py -- python3 tools/config_style_checker.py diff --git a/AUTHORS.txt b/AUTHORS.txt deleted file mode 100644 index 7989a35..0000000 --- a/AUTHORS.txt +++ /dev/null @@ -1,6 +0,0 @@ -# CONTRIBUTOR LIST - -# CORE TEAM - - -# CONTRIBUTORS diff --git a/SConstruct b/SConstruct index 2c8e6c6..282c607 100644 --- a/SConstruct +++ b/SConstruct @@ -17,7 +17,7 @@ def allFilesIn(path): return [s.replace("$", "$$") for s in glob.glob(path + '/**/*', recursive=True) if os.path.isfile(s)] def getSettings(): - with open("build.json") as file: + with open("tools/build.json") as file: return json.load(file) def targetDefinition(target, description): @@ -82,8 +82,8 @@ def commandsToCreateSymlink(pbo): return commands def buildPbo(settings,env, pbo): - env.Command(pbo.outputPath, allFilesIn(pbo.folder), - f'"{addonBuilderPath()}" "{os.path.abspath(pbo.folder)}" "{os.path.abspath(settings["addonsFolder"])}" -clear -include=buildExtIncludes.txt') + env.Command(pbo.outputPath, allFilesIn(pbo.folder), + f'"{addonBuilderPath()}" "{os.path.abspath(pbo.folder)}" "{os.path.abspath(settings["addonsFolder"])}" -clear -include=tools\\buildExtIncludes.txt') targetDefinition(pbo.name, f"Build the {pbo.name} pbo.") return env.Alias(pbo.name, pbo.outputPath) @@ -100,14 +100,14 @@ pbos = getPboInfo(settings) pboAliases = [buildPbo(settings,env, pbo) for pbo in pbos] env.Command("buildTools", [], Mkdir("buildTools")) - + env.Command(r"buildTools\Natural Docs", [], [downloadNaturaldocs, Delete(r"buildTools\NaturalDocs.zip")]) allPbos = env.Alias("all", pboAliases) targetDefinition("all", "Build all pbos.") buildDocs = env.Command(r"docs\index.html", - [s for s in allFilesIn(settings["addonsFolder"]) if s.endswith(".sqf")] + [r"buildTools\Natural Docs"], + [s for s in allFilesIn(settings["addonsFolder"]) if s.endswith(".sqf")] + [r"buildTools\Natural Docs"], [Mkdir("docs"), r'"buildTools\Natural Docs\NaturalDocs.exe" naturaldocs']) env.AlwaysBuild(buildDocs) @@ -130,4 +130,4 @@ except Exception as e: print(e) print("Error: Couldn't find arma 3, cannot make or remove symlinks") -env.Default("all") \ No newline at end of file +env.Default("all") diff --git a/addons/hatchet_vxf_core/$PBOPREFIX$ b/addons/hatchet_vxf_core/$PBOPREFIX$ deleted file mode 100644 index 162039c..0000000 --- a/addons/hatchet_vxf_core/$PBOPREFIX$ +++ /dev/null @@ -1 +0,0 @@ -z/htf/hatchet_vxf_core \ No newline at end of file diff --git a/addons/hatchet_vxf_core/config.cpp b/addons/hatchet_vxf_core/config.cpp deleted file mode 100644 index 955558a..0000000 --- a/addons/hatchet_vxf_core/config.cpp +++ /dev/null @@ -1,12 +0,0 @@ -class CfgPatches { - class vxf_core { - name = "Vortex Vehicle Framework"; - author = "Vortex Vehicles"; - units[] = {}; - weapons[] = {}; - requiredVersion = 1.0; - requiredAddons[] = {}; - }; -}; - -#include "config\cfgFunctions.hpp" diff --git a/addons/hatchet_vxf_core/config/cfgFunctions.hpp b/addons/hatchet_vxf_core/config/cfgFunctions.hpp deleted file mode 100644 index 4fcc698..0000000 --- a/addons/hatchet_vxf_core/config/cfgFunctions.hpp +++ /dev/null @@ -1,47 +0,0 @@ -// #include "\vxf_core\includes\configMacros.hpp" - -class cfgFunctions { - class vxf_core { - class functions { - //startup - class init { - postInit = 1; - file = "hatchet_vxf_core\functions\init.sqf"; - }; - class getVehicleConfig { - file = "hatchet_vxf_core\functions\getVehicleConfig.sqf"; - }; - class startLoops { - file = "hatchet_vxf_core\functions\startLoops.sqf"; - }; - - //events - class vehicleChanged { - file = "hatchet_vxf_core\functions\events\vehicleChanged.sqf"; - }; - class perFrame { - file = "hatchet_vxf_core\functions\events\perFrame.sqf"; - }; - class perSecond { - file = "hatchet_vxf_core\functions\events\perSecond.sqf"; - }; - - //module handling - class load { - file = "hatchet_vxf_core\functions\modules\load.sqf"; - }; - class loadAll { - file = "hatchet_vxf_core\functions\modules\loadAll.sqf"; - }; - class start { - file = "hatchet_vxf_core\functions\modules\start.sqf"; - }; - class hasModule { - file = "hatchet_vxf_core\functions\modules\hasModule.sqf"; - }; - class shutDownAll { - file = "hatchet_vxf_core\functions\modules\shutDownAll.sqf"; - }; - }; - }; -}; diff --git a/addons/hatchet_vxf_core/functions/events/perFrame.sqf b/addons/hatchet_vxf_core/functions/events/perFrame.sqf deleted file mode 100644 index fe36504..0000000 --- a/addons/hatchet_vxf_core/functions/events/perFrame.sqf +++ /dev/null @@ -1,48 +0,0 @@ -/* - * vxf_core_fnc_perFrame - * - * Function will run relevante modules' per frame functions - * - * Params: array[array[(object) vehicle, (scalar) last frame time], (scalar)pfhId] - * Returns: nothing - * - * Author: Yax - */ -params ["_args", "_pfhId"]; -_args params ["_vehicle", "_lastFrameTime"]; - -//shutdown conditions -if ( - (vehicle player != _vehicle) || - (!alive player) || - (!alive _vehicle) -) exitWith { - [vxf_vehicle] call vxf_core_fnc_shutDownAll; - [_pfhId] call CBA_fnc_removePerFrameHandler; - vxf_perFrameHandler = nil; - if (!isNil {vxf_drawHandler}) then { - removeMissionEventHandler ["Draw3d",vxf_drawHandler]; - vxf_drawHandler = nil; - }; -}; - -if (cba_missionTime == _lastFrameTime) exitWith {vxf_paused = true;}; -_args set [1, cba_missionTime]; -if (vxf_paused) then { - // unpause - ["vxf_unPause", []] call CBA_fnc_localEvent; -}; -vxf_paused = false; - -//frame time will be passed on to modules -private _frameTime = (cba_missionTime - _lastFrameTime); -//skip a frame when unpausing so time between frames stays normal -if (_frameTime > 1) exitWith {}; - -private ["_func"]; -{ //forEach vehicle vxf_modules - if (_x # 1) then { - _func = missionNameSpace getVariable (_x # 3); - if (!isNil {_func}) then {[_vehicle, _frameTime] call _func;}; - }; -} forEach (_vehicle getVariable ["vxf_modules", []]); diff --git a/addons/hatchet_vxf_core/functions/events/perSecond.sqf b/addons/hatchet_vxf_core/functions/events/perSecond.sqf deleted file mode 100644 index 6b932c6..0000000 --- a/addons/hatchet_vxf_core/functions/events/perSecond.sqf +++ /dev/null @@ -1,38 +0,0 @@ -/* - * vxf_core_fnc_perSecond - * - * Function will run relevante modules' per second functions - * - * Params: array[array[(object) vehicle], (scalar)pfhId] - * Returns: nothing - * - * Author: Yax - */ -params ["_args", "_pfhId"]; -_args params ["_vehicle"]; - -//shutdown conditions -if ( - (vehicle player != _vehicle) || - (!alive player) || - (!alive _vehicle) -) exitWith { - [_pfhId] call CBA_fnc_removePerFrameHandler; - vxf_perSecondHandler = nil; -}; - -if (vxf_paused) exitWith {}; - -private _modules = (_vehicle getVariable ["vxf_modules", []]); -[_vehicle, _modules] spawn { - params ["_vehicle", "_modules"]; - private _moduleDelay = 1 / ((count _modules) + 1); - private ["_func"]; - { //forEach vehicle vxf_modules - sleep _moduleDelay; - if (_x # 1) then { - _func = missionNameSpace getVariable (_x # 4); - if (!isNil {_func}) then {[_vehicle] call _func;}; - }; - } forEach _modules; -}; diff --git a/addons/hatchet_vxf_core/functions/events/vehicleChanged.sqf b/addons/hatchet_vxf_core/functions/events/vehicleChanged.sqf deleted file mode 100644 index f13964e..0000000 --- a/addons/hatchet_vxf_core/functions/events/vehicleChanged.sqf +++ /dev/null @@ -1,33 +0,0 @@ -/* - * vxf_core_fnc_vehicleChanged - * - * Function is triggered by cba vehicleChanged eventhandler - * when called, it will check if the vehicle has any vxf config, - * and if relevant, set up the functions for it - * - * Params: Array[(object) caller, (object) newVehicle] - * Returns: nil - * - * Author: Yax - */ - -params ["_caller", "_newVehicle"]; - -if (isNil "_caller" || isNil "_newVehicle") exitWith {}; -if (_caller !=player) exitWith {}; -if (!(isNil "vxf_vehicle")) then {[vxf_vehicle] call vxf_core_fnc_shutDownAll;}; - -private _isVxfSetup = [_newVehicle] call vxf_core_fnc_getVehicleConfig; - -//end the function if the vehicle isn't compatible -if (!_isVxfSetup) exitWith { - _newVehicle setVariable ["vxf_modules", nil]; -}; - -[_newVehicle] call vxf_core_fnc_loadAll; -[_newVehicle] call vxf_core_fnc_startLoops; -vxf_vehicle = _newVehicle; - -vxf_interaction_vehicleSwitchedEH = _newVehicle addEventHandler ["SeatSwitched", { - if (_this # 1 == player) then {[player, vehicle player] call vxf_core_fnc_vehicleChanged;}; -}]; diff --git a/addons/hatchet_vxf_core/functions/getVehicleConfig.sqf b/addons/hatchet_vxf_core/functions/getVehicleConfig.sqf deleted file mode 100644 index ae9d056..0000000 --- a/addons/hatchet_vxf_core/functions/getVehicleConfig.sqf +++ /dev/null @@ -1,58 +0,0 @@ -/* - * vxf_core_fnc_getVehicleConfig - * - * Function will look through the cfgVehicles for the vehicle - * and look for relevant vxf config subclasses, when it finds them - * the most relevant one will be assigned to the vehicle's vxf_config variable - * - * Params: (object) vehicle - * Returns: (bool) success - * - * Author: Yax - */ - -params ["_vehicle"]; - -private _configFound = false; -private _configSources = []; - -_vehicle setVariable ["vxf_config", nil]; -private _turretIndex = [player] call ace_common_fnc_getTurretIndex; - -if(player == driver _vehicle) then { - _configSources pushBack "vxf_driver"; -}; - -private _copilotTurretIndex = [_vehicle] call ace_common_fnc_getTurretCopilot; -if((count _copilotTurretIndex) > 0 && (count _turretIndex) > 0 && {(_turretIndex # 0) == (_copilotTurretIndex # 0)}) then { - _configSources pushBack "vxf_copilot"; -}; - -if(count _turretIndex > 0) then { - _configSources pushBack format["vxf_turret_%1",(_turretIndex # 0)]; -}; - -if(player == gunner _vehicle) then { - _configSources pushBack "vxf_gunner"; -}; - -if(_vehicle getCargoIndex player > -1) then { - _configSources pushBack "vxf_cargo"; -}; - -_configSources pushBack "vxf"; - -{ - private _config = (configFile >> "cfgVehicles" >> (typeOf _vehicle) >> _x); - if(isClass _config) exitWith { - _configFound = true; - //if there was already a config present, a seat change happened, so do a shutdown of old systems - //if (!isNil {_vehicle getVariable "vxf_config"}) then { - // [_vehicle] call vxf_core_fnc_shutDown; - //}; - _vehicle setVariable ["vxf_config", _config]; - _vehicle setVariable ["vxf_projectPrefix", getText (_config >> "projectPrefix")]; - }; -}forEach _configSources; - -_configFound diff --git a/addons/hatchet_vxf_core/functions/init.sqf b/addons/hatchet_vxf_core/functions/init.sqf deleted file mode 100644 index 8ed7bb7..0000000 --- a/addons/hatchet_vxf_core/functions/init.sqf +++ /dev/null @@ -1,2 +0,0 @@ -["vehicle", vxf_core_fnc_vehicleChanged, true] call CBA_fnc_addPlayerEventHandler; -vxf_paused = false; diff --git a/addons/hatchet_vxf_core/functions/modules/hasModule.sqf b/addons/hatchet_vxf_core/functions/modules/hasModule.sqf deleted file mode 100644 index b132ad2..0000000 --- a/addons/hatchet_vxf_core/functions/modules/hasModule.sqf +++ /dev/null @@ -1,24 +0,0 @@ -/* - * vxf_core_fnc_hasModule - * - * Checks if a module exists - * - * Params: array[array[(object) vehicle, (string) module name, (optional, string) classname] - * Returns: (boolean) has module - * - * Author: Yax - */ - -params ["_vehicle", "_moduleName",["_className", nil]]; - -private _vehicleModuleArray = _vehicle getVariable ["vxf_modules", []]; -private _isClass = if(!isNil "_className") then [{_vehicle isKindOf _className}, {true}]; -private _hasModule = false; -{ // forEach _vehicleModuleArray - _name = _x # 0; - if (_moduleName == _name) exitWith { - _hasModule = true; - }; -} forEach _vehicleModuleArray; - -(_hasModule && _isClass) diff --git a/addons/hatchet_vxf_core/functions/modules/load.sqf b/addons/hatchet_vxf_core/functions/modules/load.sqf deleted file mode 100644 index 3c61c61..0000000 --- a/addons/hatchet_vxf_core/functions/modules/load.sqf +++ /dev/null @@ -1,43 +0,0 @@ -/* - * vxf_core_fnc_load - * - * Loads a single module with default paths - * - * Params: array[array[(object) vehicle, (string) module name] - * Returns: nothing - * - * Author: Yax - */ -params ["_vehicle", "_moduleName"]; - -private _vehicleModuleArray = _vehicle getVariable ["vxf_modules", []]; - -#define HANDLEDEFAULT(VAR,MODULENAME,PATH) private VAR = format[PATH, MODULENAME]; - -private _startUp = true; - -HANDLEDEFAULT(_setup,_moduleName,"vxf_%1_fnc_setup") -HANDLEDEFAULT(_perFrame,_moduleName,"vxf_%1_fnc_perFrame") -HANDLEDEFAULT(_perSecond,_moduleName,"vxf_%1_fnc_perSecond") -HANDLEDEFAULT(_shutDown,_moduleName,"vxf_%1_fnc_shutDown") - -if (_startUp && _setup != "") then { - private _func = (missionNameSpace getVariable _setup); - if (!isNil "_func" && typeName _func == "CODE") then { - _result = ([_vehicle] call _func); - if (typeName _result == "BOOL" && {!_result}) then { - _startUp = false; - }; - }; -}; - -_vehicleModuleArray pushBack [ - _moduleName, - _startUp, - _setup, - _perFrame, - _perSecond, - _shutDown -]; - -_vehicle setVariable ["vxf_modules", _vehicleModuleArray]; diff --git a/addons/hatchet_vxf_core/functions/modules/loadAll.sqf b/addons/hatchet_vxf_core/functions/modules/loadAll.sqf deleted file mode 100644 index ed4b8fc..0000000 --- a/addons/hatchet_vxf_core/functions/modules/loadAll.sqf +++ /dev/null @@ -1,55 +0,0 @@ -/* - * vxf_core_fnc_loadAll - * - * Reads out relevant vehicle modules from config and stores them in vehicle variables - * - * Params: array[array[(object) vehicle] - * Returns: nothing - * - * Author: Yax - */ -params ["_vehicle"]; - -private _vehicleModuleArray = []; - -private _vehicleConfig = _vehicle getVariable "vxf_config"; -private _modules = "true" configClasses (_vehicleConfig >> "modules"); - -private _projectPrefix = _vehicle getVariable ["vxf_projectPrefix", ""]; -#define HANDLEDEFAULT(VAR,MODULENAME,PATH) if(VAR == "" && {!isNil{missionNameSpace getVariable format[PATH, MODULENAME]}}) then {VAR = format[PATH, MODULENAME];}; - -{ //forEach _modules - private _moduleConfig = _x; - private _moduleName = configName _x; - private _startUp = (getNumber (_moduleConfig >> "startOnEnter") == 1); - - private _setup = getText (_moduleConfig >> "setup"); - HANDLEDEFAULT(_setup,_moduleName,(_projectPrefix+"_%1_fnc_setup")) - private _shutDown = getText (_moduleConfig >> "shutDown"); - HANDLEDEFAULT(_shutDown,_moduleName,(_projectPrefix+"_%1_fnc_shutDown")) - private _perFrame = getText (_moduleConfig >> "perFrame"); - HANDLEDEFAULT(_perFrame,_moduleName,(_projectPrefix+"_%1_fnc_perFrame")) - private _perSecond = getText (_moduleConfig >> "perSecond"); - HANDLEDEFAULT(_perSecond,_moduleName,(_projectPrefix+"_%1_fnc_perSecond")) - - if (_startUp && _setup != "") then { - private _func = (missionNameSpace getVariable _setup); - if (!isNil "_func" && typeName _func == "CODE") then { - private _result = ([_vehicle] call _func); - if (typeName _result == "BOOL" && {!_result}) then { - _startUp = false; - }; - }; - }; - - _vehicleModuleArray pushBack [ - _moduleName, - _startUp, - _setup, - _perFrame, - _perSecond, - _shutDown - ]; -} forEach _modules; - -_vehicle setVariable ["vxf_modules", _vehicleModuleArray]; diff --git a/addons/hatchet_vxf_core/functions/modules/shutDownAll.sqf b/addons/hatchet_vxf_core/functions/modules/shutDownAll.sqf deleted file mode 100644 index 6d5d853..0000000 --- a/addons/hatchet_vxf_core/functions/modules/shutDownAll.sqf +++ /dev/null @@ -1,34 +0,0 @@ -/* - * vxf_core_fnc_setup - * - * Reads out relevant vehicle modules from config and stores them in vehicle variables - * - * Params: array[array[(object) vehicle] - * Returns: nothing - * - * Author: Yax - */ -params ["_vehicle"]; - -if (isNil "_vehicle") then {_vehicle = vxf_vehicle}; - -vxf_perFrameHandler call CBA_fnc_removePerFrameHandler; -vxf_perSecondHandler call CBA_fnc_removePerFrameHandler; -if (!isNil "vxf_drawHandler") then { - removeMissionEventHandler ["Draw3d",vxf_drawHandler]; -}; -vxf_perFrameHandler = nil; -vxf_perSecondHandler = nil; -vxf_drawHandler = nil; - -private ["_func"]; -{ //forEach vehicle vxf_modules - if (_x # 1) then { - _func = missionNameSpace getVariable (_x # 5); - if (!isNil {_func}) then {[_vehicle] call _func;}; - }; - _x set [1, false]; -} forEach (_vehicle getVariable ["vxf_modules", []]); - -_vehicle removeEventHandler ["SeatSwitched", vxf_interaction_vehicleSwitchedEH]; -vxf_vehicle = nil; diff --git a/addons/hatchet_vxf_core/functions/modules/start.sqf b/addons/hatchet_vxf_core/functions/modules/start.sqf deleted file mode 100644 index f12f885..0000000 --- a/addons/hatchet_vxf_core/functions/modules/start.sqf +++ /dev/null @@ -1,32 +0,0 @@ -/* - * vxf_core_fnc_start - * - * Starts a loaded module - * - * Params: array[array[(object) vehicle, (string) module name] - * Returns: nothing - * - * Author: Yax - */ - -params ["_vehicle", "_moduleName", ["_parameters", nil]]; - -private _vehicleModuleArray = _vehicle getVariable ["vxf_modules", []]; - -private ["_moduleName", "_running", "_setup"]; -{ // forEach _vehicleModuleArray - _module = _x; - _name = _module # 0; - if (_moduleName == _name) exitWith { - _running = _module # 1; - _setup = _module # 2; - if (!_running) then { - private _func = (missionNameSpace getVariable _setup); - if (!isNil "_func" && typeName _func == "CODE") then { - _running = ([_vehicle, _parameters] call _func); - }; - }; - _module set [1, _running]; - _vehicleModuleArray set [_foreachIndex, _module]; - }; -} forEach _vehicleModuleArray; diff --git a/addons/hatchet_vxf_core/functions/startLoops.sqf b/addons/hatchet_vxf_core/functions/startLoops.sqf deleted file mode 100644 index e772487..0000000 --- a/addons/hatchet_vxf_core/functions/startLoops.sqf +++ /dev/null @@ -1,29 +0,0 @@ -/* - * vxf_core_fnc_startLoops - * - * starts the per per frameHandlers and the draw3D eventHandler - * - * Params: ARRAY[(object) vehicle] - * Returns: nil - * - * Author: Yax - */ - -params ["_vehicle"]; - -private _vehicleConfig = _vehicle getVariable "vxf_config"; - -//set up draw3D handler -if (isClass (_vehicleConfig >> "interaction")) then { - [_vehicle, "interaction"] call vxf_core_fnc_load; -}; - -//set up perFrameHandler -if (isNil "vxf_perFrameHandler") then { - vxf_perFrameHandler = [vxf_core_fnc_perFrame, 0, [_vehicle, cba_missionTime]] call CBA_fnc_addPerFrameHandler; -}; - -//set up perSecondHandler for once per second -if (isNil "vxf_perSecondHandler") then { - vxf_perSecondHandler = [vxf_core_fnc_perSecond, 1, [_vehicle]] call CBA_fnc_addPerFrameHandler; -}; diff --git a/addons/hatchet_vxf_core/includes/configMacros.hpp b/addons/hatchet_vxf_core/includes/configMacros.hpp deleted file mode 100644 index dfcdafe..0000000 --- a/addons/hatchet_vxf_core/includes/configMacros.hpp +++ /dev/null @@ -1,4 +0,0 @@ -/* - * A set of script macros for basic config setup - */ -#define TOSTRING(s) #s; diff --git a/addons/hatchet_vxf_interaction/$PBOPREFIX$ b/addons/hatchet_vxf_interaction/$PBOPREFIX$ deleted file mode 100644 index ceaa5c2..0000000 --- a/addons/hatchet_vxf_interaction/$PBOPREFIX$ +++ /dev/null @@ -1 +0,0 @@ -z/htf/hatchet_vxf_interaction \ No newline at end of file diff --git a/addons/hatchet_vxf_interaction/config.cpp b/addons/hatchet_vxf_interaction/config.cpp deleted file mode 100644 index 5cf884f..0000000 --- a/addons/hatchet_vxf_interaction/config.cpp +++ /dev/null @@ -1,14 +0,0 @@ -class CfgPatches { - class vxf_interaction { - name = "Vortex Vehicle Framework"; - author = "Vortex Vehicles"; - units[] = {}; - weapons[] = {}; - requiredVersion = 1.0; - requiredAddons[] = {"cba_common", "cba_events"}; - }; -}; - -#include "config\cfgFunctions.hpp" -#include "config\cfgSounds.hpp" -#include "config\mouseBlocker.hpp" diff --git a/addons/hatchet_vxf_interaction/config/cfgFunctions.hpp b/addons/hatchet_vxf_interaction/config/cfgFunctions.hpp deleted file mode 100644 index 002b40e..0000000 --- a/addons/hatchet_vxf_interaction/config/cfgFunctions.hpp +++ /dev/null @@ -1,89 +0,0 @@ -// #include "\vxf_core\includes\configMacros.hpp" - -class cfgFunctions { - class vxf_interaction { - class functions { - class init { - postInit = 1; - file = "hatchet_vxf_interaction\functions\init.sqf"; - }; - class preInit { - preInit = 1; - file = "hatchet_vxf_interaction\functions\preInit.sqf"; - }; - - class setup { - file = "hatchet_vxf_interaction\functions\setup.sqf"; - }; - class loadAll { - file = "hatchet_vxf_interaction\functions\loadAll.sqf"; - }; - class loadItem { - file = "hatchet_vxf_interaction\functions\loadItem.sqf"; - }; - class draw3D { - file = "hatchet_vxf_interaction\functions\draw3D.sqf"; - }; - class drawLabel { - file = "hatchet_vxf_interaction\functions\drawLabel.sqf"; - }; - class perFrame { - file = "hatchet_vxf_interaction\functions\perFrame.sqf"; - }; - class checkInteraction { - file = "hatchet_vxf_interaction\functions\checkInteraction.sqf"; - }; - class shutDown { - file = "hatchet_vxf_interaction\functions\shutDown.sqf"; - }; - class handleMouseBlocker { - file = "hatchet_vxf_interaction\functions\handleMouseBlocker.sqf"; - }; - class attemptCloseActionMenu { - file = "hatchet_vxf_interaction\functions\attemptCloseActionMenu.sqf"; - }; - - class buttonDown { - file = "hatchet_vxf_interaction\functions\keys\buttonDown.sqf"; - }; - class buttonUp { - file = "hatchet_vxf_interaction\functions\keys\buttonUp.sqf"; - }; - class leverAnimate { - file = "hatchet_vxf_interaction\functions\keys\leverAnimate.sqf"; - }; - class knobAnimate { - file = "hatchet_vxf_interaction\functions\keys\knobAnimate.sqf"; - }; - class dragStart { - file = "hatchet_vxf_interaction\functions\keys\dragStart.sqf"; - }; - class drag { - file = "hatchet_vxf_interaction\functions\keys\drag.sqf"; - }; - class dragStop { - file = "hatchet_vxf_interaction\functions\keys\dragStop.sqf"; - }; - - class pointCalculate { - file = "hatchet_vxf_interaction\functions\pointing\pointCalculate.sqf"; - }; - class pointDraw { - file = "hatchet_vxf_interaction\functions\pointing\pointDraw.sqf"; - }; - class pointNetSend { - file = "hatchet_vxf_interaction\functions\pointing\pointNetSend.sqf"; - }; - class pointNetReceive { - file = "hatchet_vxf_interaction\functions\pointing\pointNetReceive.sqf"; - }; - class pointStart { - file = "hatchet_vxf_interaction\functions\pointing\pointStart.sqf"; - }; - - class scriptedInteract { - file = "hatchet_vxf_interaction\functions\scriptedInteract.sqf"; - }; - }; - }; -}; diff --git a/addons/hatchet_vxf_interaction/config/cfgSounds.hpp b/addons/hatchet_vxf_interaction/config/cfgSounds.hpp deleted file mode 100644 index 8b8f574..0000000 --- a/addons/hatchet_vxf_interaction/config/cfgSounds.hpp +++ /dev/null @@ -1,51 +0,0 @@ -class CfgSounds -{ - class vxf_Switch_Sound - { - name = "vxf_Switch_Sound"; - sound[] = {"\vxf_interaction\sounds\switch.wss",1,1,1}; - titles[]={}; - }; - class vxf_Switch_Sound_1 - { - name = "vxf_Switch_Sound_1"; - sound[] = {"\vxf_interaction\sounds\switch1.wss",1,1,1}; - titles[]={}; - }; - class vxf_Switch_Sound_2 - { - name = "vxf_Switch_Sound_2"; - sound[] = {"\vxf_interaction\sounds\switch2.wss",1,1,1}; - titles[]={}; - }; - class vxf_Switch_Sound_3 - { - name = "vxf_Switch_Sound_3"; - sound[] = {"\vxf_interaction\sounds\switch3.wss",1,1,1}; - titles[]={}; - }; - class vxf_Switch_Sound_4 - { - name = "vxf_Switch_Sound_4"; - sound[] = {"\vxf_interaction\sounds\switch4.wss",1,1,1}; - titles[]={}; - }; - class vxf_Switch_Sound_5 - { - name = "vxf_Switch_Sound_5"; - sound[] = {"\vxf_interaction\sounds\switch5.wss",1,1,1}; - titles[]={}; - }; - class vxf_HeavySwitch_Sound - { - name = "vxf_HeavySwitch_Sound"; - sound[] = {"\vxf_interaction\sounds\heavySwitch.wss",1,1,1}; - titles[]={}; - }; - class vxf_dial_sound - { - name = "vxf_dial_sound"; - sound[] = {"\vxf_interaction\sounds\dial.wss",1,1,1}; - titles[]={}; - }; -}; diff --git a/addons/hatchet_vxf_interaction/config/mouseBlocker.hpp b/addons/hatchet_vxf_interaction/config/mouseBlocker.hpp deleted file mode 100644 index 0643ac5..0000000 --- a/addons/hatchet_vxf_interaction/config/mouseBlocker.hpp +++ /dev/null @@ -1,12 +0,0 @@ -class vxf_interaction_mouseBlocker { - idd = 86005; - movingEnable = 0; - //duration = 9999999; - enableSimulation = 1; - //fadein = 0; - //fadeout = 0; - //hideCursor = 1; - onLoad = "uiNamespace setVariable [""vxf_interaction_mouseBlocker"",true];"; - onUnload = "uiNamespace setVariable [""vxf_interaction_mouseBlocker"",false]; vxf_interaction_cursorPos = [0.5,0.5];"; - //class controls { }; -}; diff --git a/addons/hatchet_vxf_interaction/functions/attemptCloseActionMenu.sqf b/addons/hatchet_vxf_interaction/functions/attemptCloseActionMenu.sqf deleted file mode 100644 index 9c1778b..0000000 --- a/addons/hatchet_vxf_interaction/functions/attemptCloseActionMenu.sqf +++ /dev/null @@ -1,6 +0,0 @@ -[] spawn { - if (missionNamespace getVariable ["vxf_uh60_interaction_autoclose_actionmenu", false]) then { - showCommandingMenu "RscMainMenu"; - showCommandingMenu ""; - }; - }; \ No newline at end of file diff --git a/addons/hatchet_vxf_interaction/functions/checkInteraction.sqf b/addons/hatchet_vxf_interaction/functions/checkInteraction.sqf deleted file mode 100644 index d638518..0000000 --- a/addons/hatchet_vxf_interaction/functions/checkInteraction.sqf +++ /dev/null @@ -1,55 +0,0 @@ -/* - * vxf_interaction_fnc_checkInteraction - * - * checks if a sub-item is valid for interaction - * - * params: (array)[ - * (string) name - * (string) condition - * (array) sub-items - * OPTIONAL: (string) position type - * OPTIONAL: (string) position - * OPTIONAL: (string) label - * OPTIONAL: (scalar) radius - * OPTIONAL: (string) buttonDown code - * OPTIONAL: (string) buttonUp code - * OPTIONAL: (string) buttonHold - * OPTIONAL: (string) buttonMove - * ] - * - * returns: on success array, on failure nil - */ - -#include "interactDefines.hpp" -PARAMS; - -scopeName "main"; - -// cut it off if the condition is false -if (_condition != "" && {!(_vehicle call (compile _condition))}) exitWith {nil}; - -if (!isNil "_positionType") then { - // get the selection position coordinates - if (_positionType == "anim") then { - _position = _vehicle selectionPosition _position; - }; - private _positionWorld = _vehicle modelToWorldVisual _position; - private _screenPos = worldToScreen _positionWorld; - // make sure the position is on the screen - if (count _screenPos == 2) then { - private _btnSel = (_screenPos distance vxf_interaction_cursorPos) < (_radius * vxf_interaction_buttonRadius); - if (_btnSel) then { - _this breakOut "main"; - }; - }; -}; - -private ["_result"]; -{ // forEach _subItems - _result = _x call vxf_interaction_fnc_checkInteraction; - if (!isNil "_result") then { - _result breakOut "main"; - }; -} forEach _subItems; - -nil diff --git a/addons/hatchet_vxf_interaction/functions/draw3D.sqf b/addons/hatchet_vxf_interaction/functions/draw3D.sqf deleted file mode 100644 index 3f2c2b9..0000000 --- a/addons/hatchet_vxf_interaction/functions/draw3D.sqf +++ /dev/null @@ -1,61 +0,0 @@ -/* - * vxf_interaction_fnc_draw3D - * - * runs the draw3D eventhandler code to check for interaction - * - */ - -#include "interactDefines.hpp" - -private _vehicle = vehicle player; - -if (cameraView != "INTERNAL") exitWith {}; -if (!isNull curatorCamera) exitWith {}; -if (!isNil {uinamespace getVariable "BIS_fnc_camera_display"}) exitWith {}; - -if (uiNamespace getVariable ["vxf_interaction_mouseBlocker", false]) then { - _this call vxf_interaction_fnc_handleMouseBlocker; -}; - - - -if (vxf_interaction_updateIndex >= vxf_interaction_updateEvery && !vxf_interaction_dragging && !vxf_interaction_buttonHolding) then { - vxf_interaction_updateIndex = 0; - private _result = nil; - { // forEach (_vehicle getVariable ["vxf_interaction", []]) - _result = _x call vxf_interaction_fnc_checkInteraction; - if (!isNil "_result") exitWith {}; - } forEach (_vehicle getVariable ["vxf_interaction", []]); - - vxf_interaction_currentButton = _result; -}; -vxf_interaction_updateIndex = vxf_interaction_updateIndex + 1; - -_this call vxf_interaction_fnc_drawLabel; - -if (vxf_interaction_crosshair) then { - ["+",-1,0.485,1,0,0, 794] spawn BIS_fnc_dynamicText; -}; - -if (vxf_interaction_pointStart) then { - [_vehicle] call vxf_interaction_fnc_pointCalculate; -}; -[_vehicle] call vxf_interaction_fnc_pointDraw; - -if (!isNil "vxf_interaction_knobHolding" && !vxf_interaction_dragging) then { - vxf_interaction_knobHolding PARAMS; - _knobConfig params KNOBPARAMS; - private _animationPhase = _vehicle animationPhase _animation; - private _animationEnd =_vehicle getVariable ["knob_" + _animation, _animationPhase]; - if ( - (_animationPhase > _animationEnd - 0.02) && - (_animationPhase < _animationEnd + 0.02) - ) then { - vxf_interaction_knobHolding = nil; - [_vehicle, _animationPhase] call _dragStop; - _vehicle setVariable [("knob_" + _animation), nil]; - vxf_animating_keys deleteAt (vxf_animating_keys find _animation); - } else { - [_vehicle, _animationPhase] call _dragging; - }; -}; diff --git a/addons/hatchet_vxf_interaction/functions/drawLabel.sqf b/addons/hatchet_vxf_interaction/functions/drawLabel.sqf deleted file mode 100644 index b6f875f..0000000 --- a/addons/hatchet_vxf_interaction/functions/drawLabel.sqf +++ /dev/null @@ -1,115 +0,0 @@ -/* - * vxf_interaction_fnc_drawLabel - * - * interaction button release functionality - */ - - private _vehicle = vehicle player; - -#include "interactDefines.hpp" - -if (isNil "vxf_interaction_currentButton") exitWith { - ["",0,0.4,0,0,0, 1301] spawn BIS_fnc_dynamicText; - ["",0,0.4,0,0,0, 1301] spawn BIS_fnc_dynamicText; -}; - -vxf_interaction_currentButton PARAMS; -if (_positionType == "anim") then { - _position = _vehicle selectionPosition _position; -}; - -private _color = if (vxf_interaction_buttonHolding) then {[1,0,0,1]} else {[1,1,1,1]}; -private _size = if (vxf_interaction_buttonHolding) then {0.045} else {0.05}; -_label = if (vxf_interaction_showLabels > 0.5) then { - if (count _buttonConfig > 0 && count _knobConfig == 0) then { - private _fmt = if (vxf_interaction_showLabels > 1) then { - "[%1] %2" - } else { - "%2" - }; - format [_fmt,((["Hatchet Vehicle Framework","vxf_interaction"] call CBA_fnc_getKeybind)# 5) call CBA_fnc_localizeKey, _label] - } else { - _label - } -} else { - "" -}; - -drawIcon3D [ - "\a3\ui_f\data\IGUI\Cfg\Cursors\selected_ca.paa", - _color, - _vehicle modelToWorldVisual _position, - 1, - 1, - 0, - _label, - 2, - _size -]; - -if (count _knobConfig > 0) then { - _knobConfig params KNOBPARAMS; - if ((inputAction "prevAction" > 0 || vxf_alternative_scroll_up) && !vxf_interaction_scrolledHolding) then { - [_vehicle, 1, _knobConfig] call vxf_interaction_fnc_knobAnimate; - }; - if ((inputAction "nextAction" > 0 || vxf_alternative_scroll_down) && !vxf_interaction_scrolledHolding) then { - [_vehicle, -1, _knobConfig] call vxf_interaction_fnc_knobAnimate; - }; - if (vxf_interaction_showLabels > 1) then { - ["Scroll or drag to spin",0,0.6,0,0,0, 1303] spawn BIS_fnc_dynamicText; - } else { - ["",0,0.6,0,0,0, 1303] spawn BIS_fnc_dynamicText; - }; -} else { - ["",0,0.6,0,0,0, 1303] spawn BIS_fnc_dynamicText; -}; - -if (count _animConfig > 0 && count _knobConfig == 0) then { - _animConfig params ANIMPARAMS; - private _closestState = 0; - private _closestDiff = 9999; - private ["_diff"]; - private _animationPhase = (_vehicle animationPhase _animation); - { // forEach _animationSteps - _diff = abs(_animationPhase - _x); - if (_diff < _closestDiff) then { - _closestDiff = _diff; - _closestState = _forEachIndex; - }; - } forEach _animationSteps; - private _currentState = _closestState; - if (_currentState == -1) exitWith { - ["",0,0.4,0,0,0, 1301] spawn BIS_fnc_dynamicText; - ["",0,0.4,0,0,0, 1301] spawn BIS_fnc_dynamicText; - }; - private _loopFirst = if (_animLooping) then {0} else {-1}; - private _loopLast = if (_animLooping) then {(count _animationSteps) - 1} else {-1}; - private _prevStep = if (_currentState == 0) then {_loopLast} else {_currentState - 1}; - private _nextStep = if (_currentState == (count _animationSteps) - 1) then {_loopFirst} else {_currentState + 1}; - if (vxf_interaction_showLabels > 1) then { - if (_prevStep > -1) then { - [format ["Set to %2 with %1", actionKeysNames "prevAction", _animationLabels # _prevStep],(-safeZoneX)+(vxf_interaction_cursorPos # 0) - (safeZoneW / 2),((vxf_interaction_cursorPos # 1) - 0.1),0,0,0, 1301] spawn BIS_fnc_dynamicText; - } else { - ["",0,0.4,0,0,0, 1301] spawn BIS_fnc_dynamicText; - }; - if (_nextStep > -1) then { - [format ["Set to %2 with %1", actionKeysNames "nextAction", _animationLabels # _nextStep],(-safeZoneX)+(vxf_interaction_cursorPos # 0) - (safeZoneW / 2),((vxf_interaction_cursorPos # 1) + 0.1),0,0,0, 1302] spawn BIS_fnc_dynamicText; - } else { - ["",0,0.4,0,0,0, 1302] spawn BIS_fnc_dynamicText; - }; - } else { - ["",0,0.4,0,0,0, 1301] spawn BIS_fnc_dynamicText; - ["",0,0.6,0,0,0, 1302] spawn BIS_fnc_dynamicText; - }; - if ((inputAction "prevAction" > 0 || vxf_alternative_scroll_up) && _prevStep > -1) then { - [_vehicle, _animation, _animationSteps # _prevStep, _animationLabels # _prevStep, _animationSpeed, _animStart, _animEnd, vxf_interaction_currentButton] call vxf_interaction_fnc_leverAnimate; - }; - if ((inputAction "nextAction" > 0 || vxf_alternative_scroll_down) && _nextStep > -1) then { - [_vehicle, _animation, _animationSteps # _nextStep, _animationLabels # _nextStep, _animationSpeed, _animStart, _animEnd, vxf_interaction_currentButton] call vxf_interaction_fnc_leverAnimate; - }; -} else { - ["",0,0.4,0,0,0, 1301] spawn BIS_fnc_dynamicText; - ["",0,0.6,0,0,0, 1302] spawn BIS_fnc_dynamicText; -}; - -if (inputAction "prevAction" == 0 && inputAction "nextAction" == 0 && !vxf_alternative_scroll_down && !vxf_alternative_scroll_up) then {vxf_interaction_scrolledHolding = false;}; diff --git a/addons/hatchet_vxf_interaction/functions/handleMouseBlocker.sqf b/addons/hatchet_vxf_interaction/functions/handleMouseBlocker.sqf deleted file mode 100644 index 846e9c1..0000000 --- a/addons/hatchet_vxf_interaction/functions/handleMouseBlocker.sqf +++ /dev/null @@ -1,16 +0,0 @@ -vxf_interaction_cursorPos = getMousePosition; -if (inputAction "defaultAction" > 0 && !vxf_interaction_cursor_mouseDown) then { - if (!isNil "vxf_interaction_currentButton") then { - // systemChat "CLICKING"; - [vehicle player, vxf_interaction_currentButton] call vxf_interaction_fnc_buttonDown; - vxf_interaction_cursor_mouseDown = true; - }; -}; - -if (inputAction "defaultAction" == 0 && vxf_interaction_cursor_mouseDown) then { - if (!isNil "vxf_interaction_currentButton") then { - // systemChat "UNCLICKING"; - [vehicle player, vxf_interaction_currentButton] call vxf_interaction_fnc_buttonUp; - vxf_interaction_cursor_mouseDown = false; - }; -}; \ No newline at end of file diff --git a/addons/hatchet_vxf_interaction/functions/init.sqf b/addons/hatchet_vxf_interaction/functions/init.sqf deleted file mode 100644 index 79635f6..0000000 --- a/addons/hatchet_vxf_interaction/functions/init.sqf +++ /dev/null @@ -1,18 +0,0 @@ -/* - * vxf_interaction_fnc_init - * - * initialises some base variables for the interaction system - */ - -//how many frames to wait between updates -vxf_interaction_updateEvery = 5; -vxf_interaction_updateIndex = 0; -vxf_interaction_currentButton = nil; -vxf_interaction_buttonHoldCode = nil; -vxf_interaction_buttonRadius = 1; -vxf_interaction_buttonHolding = false; -vxf_interaction_knobHolding = nil; -vxf_interaction_dragging = false; - -vxf_point_icons = []; -vxf_point_lifetime = 2; diff --git a/addons/hatchet_vxf_interaction/functions/interactDefines.hpp b/addons/hatchet_vxf_interaction/functions/interactDefines.hpp deleted file mode 100644 index 9b515c4..0000000 --- a/addons/hatchet_vxf_interaction/functions/interactDefines.hpp +++ /dev/null @@ -1,7 +0,0 @@ -#define TOSTRING(s) #s -#define PARAMS params ["_name","_condition","_subItems",["_positionType", nil],["_position", nil],["_label", nil],["_radius", nil],["_clickSound",""],["_interactCondition",{true}],["_buttonConfig", nil], ["_animConfig", nil], ["_knobConfig", nil]] -#define BTNPARAMS params ["_buttonDown", "_buttonUp", "_buttonHold", ["_knobClick", nil]] -#define ANIMPARAMS ["_animation", "_animationSpeed", "_animLooping", "_animationSteps", "_animationLabels", "_animStart", "_animEnd"] -#define KNOBPARAMS ["_animation", "_scrollIncrement", "_dragRange", "_animLooping", "_animLimits", "_animSpeed", "_dragStart", "_dragging", "_dragStop"] -#define FNC_STRING(NAME) (if(!isNil{missionNameSpace getVariable NAME}) then {missionNameSpace getVariable NAME} else {{nil}}) -#define ISFULLARRAY(ARR) (!isNil TOSTRING(ARR) && {typeName ARR == "ARRAY"} && {count ARR > 0}) diff --git a/addons/hatchet_vxf_interaction/functions/keys/buttonDown.sqf b/addons/hatchet_vxf_interaction/functions/keys/buttonDown.sqf deleted file mode 100644 index fc3e5e8..0000000 --- a/addons/hatchet_vxf_interaction/functions/keys/buttonDown.sqf +++ /dev/null @@ -1,31 +0,0 @@ -/* - * vxf_interaction_fnc_buttonDown - * - * interaction button press down functionality - */ - -#include "../interactDefines.hpp" - -params ["_vehicle", "_button", ["_forced", false]]; -if (isNil{_vehicle getVariable "vxf_interaction"}) exitWith {false}; -if (isNil "vxf_interaction_currentButton" && !_forced) exitWith {}; - -_button PARAMS; -diag_log format ["%2: button down %1", _name, time]; - -if(!(_vehicle call compile _interactCondition)) exitWith {}; - -_buttonConfig BTNPARAMS; - -if (_clickSound != "") then {playSound _clickSound}; - -[_vehicle] call _buttonDown; -[_vehicle, _position, 1, name player] call vxf_interaction_fnc_pointNetSend; - -if (!isNil "_buttonHold") then { - vxf_interaction_buttonHoldCode = _buttonHold; -}; -vxf_interaction_buttonHolding = true; -vxf_interaction_dragging_buttonDownTime = time; - -true diff --git a/addons/hatchet_vxf_interaction/functions/keys/buttonUp.sqf b/addons/hatchet_vxf_interaction/functions/keys/buttonUp.sqf deleted file mode 100644 index a44fc25..0000000 --- a/addons/hatchet_vxf_interaction/functions/keys/buttonUp.sqf +++ /dev/null @@ -1,29 +0,0 @@ -/* - * vxf_interaction_fnc_buttonUp - * - * interaction button release functionality - */ - -#include "../interactDefines.hpp" - -vxf_interaction_buttonHolding = false; -params ["_vehicle", "_button"]; -if (isNil{_vehicle getVariable "vxf_interaction"}) exitWith {false}; - -_button PARAMS; -diag_log format ["%2: button up %1", _name, time]; - -if(!(_vehicle call compile _interactCondition)) exitWith {}; - -_buttonConfig BTNPARAMS; - -[_vehicle] call _buttonUp; -vxf_interaction_buttonHoldCode = nil; -if (!isNil "_knobClick") then { - private _clickTime = time - vxf_interaction_dragging_buttonDownTime; - if (_clickTime < 0.25) then { - systemChat format["CLICK TIME %1", _clickTime]; - [_vehicle] call _knobClick; - }; -}; -true diff --git a/addons/hatchet_vxf_interaction/functions/keys/drag.sqf b/addons/hatchet_vxf_interaction/functions/keys/drag.sqf deleted file mode 100644 index d830ee0..0000000 --- a/addons/hatchet_vxf_interaction/functions/keys/drag.sqf +++ /dev/null @@ -1,34 +0,0 @@ -/* - * vxf_interaction_fnc_drag - * - * interaction button knob drag - */ - -#include "../interactDefines.hpp" - -params ["_vehicle"]; - -vxf_interaction_currentButton PARAMS; -_knobConfig params KNOBPARAMS; -diag_log format ["%2: dragging %1", _name, time]; - -if (_positionType == "anim") then { - _position = _vehicle selectionPosition _position; -}; -private _positionWorld = _vehicle modelToWorldVisual _position; -private _screenPos = worldToScreen _positionWorld; -// make sure the position is on the screen -if (count _screenPos == 2) then { - private _verticalDistance = 0.5 - (_screenPos # 1); - //systemchat str (_verticalDistance / _dragRange) * _animRange; - //systemChat str [abs _verticalDistance, abs vxf_interaction_dragging_lastDragDistance, abs (abs vxf_interaction_dragging_lastDragDistance - abs _verticalDistance)]; - if(abs (abs vxf_interaction_dragging_lastDragDistance - abs _verticalDistance) > 0.02) then { - systemChat str _verticalDistance; - private _animRange = (_animLimits # 0) - (_animLimits # 1); - vxf_interaction_dragging_lastDragDistance = _verticalDistance; - private _dragEndPoint = vxf_interaction_dragging_startAnimPhase + ((_verticalDistance / _dragRange) * _animRange); - _dragEndPoint = _dragEndPoint min (_animLimits # 1) max (_animLimits # 0); - _vehicle animateSource [_animation, _dragEndPoint, 10]; - [_vehicle, _animation] call _dragging; - }; -}; diff --git a/addons/hatchet_vxf_interaction/functions/keys/dragStart.sqf b/addons/hatchet_vxf_interaction/functions/keys/dragStart.sqf deleted file mode 100644 index 5b10d91..0000000 --- a/addons/hatchet_vxf_interaction/functions/keys/dragStart.sqf +++ /dev/null @@ -1,22 +0,0 @@ -/* - * vxf_interaction_fnc_dragStart - * - * interaction button knob drag - */ - -#include "../interactDefines.hpp" - -params ["_vehicle"]; - -vxf_interaction_currentButton PARAMS; -_knobConfig params KNOBPARAMS; -diag_log format ["%2: drag start %1", _name, time]; - -if (isNil{_vehicle getVariable "vxf_interaction"}) exitWith {false}; -if (!isNil "vxf_interaction_knobHolding" && vxf_interaction_knobHolding # 0 != _animation) exitWith {false}; - -vxf_interaction_knobHolding = vxf_interaction_currentButton; -vxf_interaction_dragging = true; -vxf_interaction_dragging_startAnimPhase = _vehicle animationPhase _animation; -vxf_interaction_dragging_lastDragDistance = 0; -[_vehicle, vxf_interaction_dragging_startAnimPhase] call _dragStart; diff --git a/addons/hatchet_vxf_interaction/functions/keys/dragStop.sqf b/addons/hatchet_vxf_interaction/functions/keys/dragStop.sqf deleted file mode 100644 index b2f95f9..0000000 --- a/addons/hatchet_vxf_interaction/functions/keys/dragStop.sqf +++ /dev/null @@ -1,15 +0,0 @@ -/* - * vxf_interaction_fnc_dragStop - */ - -#include "../interactDefines.hpp" - -params ["_vehicle"]; - -vxf_interaction_currentButton PARAMS; -_knobConfig params KNOBPARAMS; -diag_log format ["%2: drag stop %1", _name, time]; - -vxf_interaction_dragging = false; -vxf_interaction_knobHolding = nil; -[_vehicle, _vehicle animationPhase _animation] call _dragStop; diff --git a/addons/hatchet_vxf_interaction/functions/keys/knobAnimate.sqf b/addons/hatchet_vxf_interaction/functions/keys/knobAnimate.sqf deleted file mode 100644 index 69c9589..0000000 --- a/addons/hatchet_vxf_interaction/functions/keys/knobAnimate.sqf +++ /dev/null @@ -1,33 +0,0 @@ -/* - * vxf_interaction_fnc_knobAnimate - * - * interaction button animate knob scrollwheel functionality - */ - -#include "../interactDefines.hpp" - -params ["_vehicle", "_animDirection", "_knobConfig"]; -_knobConfig params KNOBPARAMS; -diag_log format ["%2: knob animate %1", _name, time]; - -if (isNil{_vehicle getVariable "vxf_interaction"}) exitWith {false}; -if (!isNil "vxf_interaction_knobHolding" && vxf_interaction_knobHolding # 0 != _animation) exitWith {false}; - -private _animationPhase = (_vehicle animationPhase _animation); -private _base = _vehicle getVariable [("knob_" + _animation), _animationPhase]; -private _endPoint = _base + (_scrollIncrement * _animDirection); -_endPoint = _endPoint min (_animLimits # 1) max (_animLimits # 0); -_vehicle setVariable [("knob_" + _animation), _endPoint]; -_vehicle animateSource [_animation, _endPoint, _animSpeed]; -vxf_interaction_knobHolding = vxf_interaction_currentButton; - -vxf_interaction_currentButton PARAMS; - -[] call vxf_interaction_fnc_attemptCloseActionMenu; - -if(!(_vehicle call compile _interactCondition)) exitWith {}; -if (_animation in vxf_animating_keys) exitWith {false}; - -[_vehicle] call _dragStart; -[_vehicle, _position, 1, name player] call vxf_interaction_fnc_pointNetSend; -vxf_animating_keys pushBack _animation; diff --git a/addons/hatchet_vxf_interaction/functions/keys/leverAnimate.sqf b/addons/hatchet_vxf_interaction/functions/keys/leverAnimate.sqf deleted file mode 100644 index f5c199a..0000000 --- a/addons/hatchet_vxf_interaction/functions/keys/leverAnimate.sqf +++ /dev/null @@ -1,37 +0,0 @@ -/* - * vxf_interaction_fnc_leverAnimate - * - * interaction button animate lever/switch functionality - */ - -#include "../interactDefines.hpp" - -params ["_vehicle", "_animation", "_animationTarget", "_animationTargetLabel", "_animationSpeed", "_animStart", "_animEnd", "_button"]; - -if (isNil{_vehicle getVariable "vxf_interaction"}) exitWith {false}; -if (_animation in vxf_animating_keys) exitWith {false}; - -_button PARAMS; -diag_log format ["%2: lever animate %1", _name, time]; - -if(!(_this call compile _interactCondition)) exitWith { - [] call vxf_interaction_fnc_attemptCloseActionMenu; -}; - -if (_clickSound != "") then {playSound _clickSound}; - -[_vehicle, _animation, _animationTargetLabel, _animationTarget] call _animStart; -[_vehicle, _position, 1, name player] call vxf_interaction_fnc_pointNetSend; -vxf_animating_keys pushBack _animation; - -_vehicle animateSource [_animation, _animationTarget, _animationSpeed]; -[_vehicle, _animation, _animationTarget, _animationTargetLabel, _animEnd] spawn { - params ["_vehicle", "_animation", "_animationTarget", "_animationTargetLabel", "_animEnd"]; - private _startTime = cba_missionTime; - [] call vxf_interaction_fnc_attemptCloseActionMenu; - waitUntil { - cba_missionTime > _startTime + 3 || - ((_vehicle animationPhase _animation > _animationTarget - 0.02) && (_vehicle animationPhase _animation < _animationTarget + 0.02))}; - [_vehicle, _animation, _animationTargetLabel, _animationTarget] call _animEnd; - vxf_animating_keys deleteAt (vxf_animating_keys find _animation); -}; diff --git a/addons/hatchet_vxf_interaction/functions/loadAll.sqf b/addons/hatchet_vxf_interaction/functions/loadAll.sqf deleted file mode 100644 index a1f896a..0000000 --- a/addons/hatchet_vxf_interaction/functions/loadAll.sqf +++ /dev/null @@ -1,20 +0,0 @@ -/* - * vxf_interaction_fnc_loadAll - * - * loads interaction from config - * - * params: (array)[(object) vehicle] - */ - -params ["_vehicle"]; - -private _vehicleInteraction = []; - -private _vehicleConfig = _vehicle getVariable "vxf_config"; -private _interaction = "true" configClasses (_vehicleConfig >> "interaction"); - -{ // forEach _interaction - _vehicleInteraction pushBack ([_vehicle, _x] call vxf_interaction_fnc_loadItem); -} forEach _interaction; - -_vehicle setVariable ["vxf_interaction", _vehicleInteraction]; diff --git a/addons/hatchet_vxf_interaction/functions/loadItem.sqf b/addons/hatchet_vxf_interaction/functions/loadItem.sqf deleted file mode 100644 index 89534ac..0000000 --- a/addons/hatchet_vxf_interaction/functions/loadItem.sqf +++ /dev/null @@ -1,130 +0,0 @@ -/* - * vxf_interaction_fnc_loadItem - * - * loads part of interaction from config - * - * params: (array)[(object) vehicle, (configClass) config] - * - * returns: (array)[ - * (string) name - * (string) condition - * (array) sub-items - * OPTIONAL: (string) position type - * OPTIONAL: (string) position - * OPTIONAL: (string) label - * OPTIONAL: (scalar) radius - * OPTIONAL: (array) button config - * OPTIONAL: (array) lever config - * ] - */ -#include "interactDefines.hpp" - -params ["_vehicle", "_config"]; - -private _result = [ - configName _config, - getText (_config >> "condition") -]; - -private _subItems = []; -private _subItemConfigs = "true" configClasses _config; -{ //forEach _subItems - _subItems pushBack ([_vehicle, _x] call vxf_interaction_fnc_loadItem); -} forEach _subItemConfigs; - -_result pushBack _subItems; - -private _positionType = getText (_config >> "positionType"); -private _position = getText (_config >> "position"); -if (_positionType == "static") then { - _position = _vehicle selectionPosition _position; -}; -if (_positionType == "coordinates") then { - _positionType = "static"; - _position = getArray (_config >> "position"); -}; -private _label = getText (_config >> "label"); -private _radius = getNumber (_config >> "radius"); -private _interactCondition = getText (_config >> "interactionCondition"); -private _buttonDown = getText (_config >> "buttonDown"); -private _buttonUp = getText (_config >> "buttonUp"); -private _buttonHold = getText (_config >> "buttonHold"); -private _clickSound = getText (_config >> "clickSound"); - -private _buttonConfig = []; -if(_buttonDown != "" || _buttonUp != "" || _buttonHold != "") then { - _buttonConfig = [ - compile _buttonDown, - compile _buttonUp, - (if (_buttonHold != "") then {compile _buttonHold} else {nil}) - ]; -}; - -private _animation = getText (_config >> "animation"); -private _animStates = (_config >> "animStates") call BIS_fnc_getCfgData; -private _animLabels = (_config >> "animLabels") call BIS_fnc_getCfgData; -private _animSpeed = getNumber (_config >> "animSpeed"); -private _animLooping = getNumber (_config >> "looping"); -private _animStart = getText (_config >> "animStart"); -private _animEnd = getText (_config >> "animEnd"); -private _animConfig = []; -if (_animation != "" && ISFULLARRAY(_animStates) && ISFULLARRAY(_animLabels)) then { - _animConfig = [ - _animation, - (if (_animSpeed == 0) then {true} else {_animSpeed}), - (_animLooping == 1), - _animStates, - _animLabels, - compile _animStart, - compile _animEnd - ]; -}; - -private _scrollIncrement = getNumber (_config >> "scrollIncrement"); -private _dragRange = getNumber (_config >> "dragRange"); -private _animLimits = (_config >> "animLimits") call BIS_fnc_getCfgData; -private _dragStart = getText (_config >> "dragStart"); -private _dragging = getText (_config >> "dragging"); -private _dragStop = getText (_config >> "dragStop"); -private _knobConfig = []; -if (_animation != "" && _dragRange > 0 && ISFULLARRAY(_animLimits)) then { - _knobConfig = [ - _animation, - _scrollIncrement, - _dragRange, - _animLooping, - _animLimits, - (if (_animSpeed == 0) then {true} else {_animSpeed}), - compile _dragStart, - (if (_dragging != "") then {compile _dragging} else {nil}), - compile _dragStop - ]; - _buttonConfig = [ - {_this call vxf_interaction_fnc_dragStart}, - {_this call vxf_interaction_fnc_dragStop}, - {_this call vxf_interaction_fnc_drag}, - compile _buttonUp - ]; -}; - -//check if there is sufficient data for an interaction -if ( - _positionType != "" && - (typeName _position == "STRING" && {_position != ""}) || (typeName _position == "ARRAY") && - // _label != "" && - _radius > -1 -) then { - _result = _result + [ - _positionType, - _position, - _label, - _radius, - _clickSound, - _interactCondition, - _buttonConfig, - _animConfig, - _knobConfig - ]; -}; - -_result diff --git a/addons/hatchet_vxf_interaction/functions/perFrame.sqf b/addons/hatchet_vxf_interaction/functions/perFrame.sqf deleted file mode 100644 index 01aa831..0000000 --- a/addons/hatchet_vxf_interaction/functions/perFrame.sqf +++ /dev/null @@ -1,17 +0,0 @@ -/* - * vxf_interaction_fnc_perFrame - * - * Runs per frame for interaction, handles button holding code - * - * Params: array[(object) vehicle, (scalar) frame time] - */ - -#include "interactDefines.hpp" - -params ["_vehicle", "_frameTime"]; - -if (!isNil "vxf_interaction_buttonHoldCode") then { - _this call vxf_interaction_buttonHoldCode; -}; - -vxf_interaction_buttonRadius = (call cba_fnc_getFov # 1); diff --git a/addons/hatchet_vxf_interaction/functions/pointing/pointCalculate.sqf b/addons/hatchet_vxf_interaction/functions/pointing/pointCalculate.sqf deleted file mode 100644 index 46fa96f..0000000 --- a/addons/hatchet_vxf_interaction/functions/pointing/pointCalculate.sqf +++ /dev/null @@ -1,30 +0,0 @@ -/* - * vxf_interaction_fnc_pointCalculate - * - * calculates pointing position and sends it to other crew - * - * params (array)[(object) vehicle] - */ - -params ["_vehicle"]; - -vxf_interaction_pointStart = false; - -private _eye = eyePos player; -private _visualDiff = getPosVisual player vectorDiff getPos player; -_eye = _eye vectorAdd _visualDiff; -private _beginVec = (vectorNormalized (getCameraViewDirection player)) vectorMultiply 0.5; -private _begin = _eye vectorAdd _beginVec; -private _endVec = (vectorNormalized (getCameraViewDirection player)) vectorMultiply 5; -private _end = _eye vectorAdd _endVec; -private _intersections = lineIntersectsSurfaces [_begin, _end, player, objNull, true, 1, "FIRE", "VIEW"]; -private _keyDownPos = if(count _intersections > 0) then { - _intersections # 0 # 0 -} else { - (eyePos player vectorAdd _endVec) -}; - -if(!isNil {_keyDownPos}) then { - private _pointPos = _vehicle worldToModelVisual ASLtoAGL _keyDownPos; - [_vehicle, _pointPos, 0, name player] call vxf_interaction_fnc_pointNetSend; -}; diff --git a/addons/hatchet_vxf_interaction/functions/pointing/pointDraw.sqf b/addons/hatchet_vxf_interaction/functions/pointing/pointDraw.sqf deleted file mode 100644 index eccd739..0000000 --- a/addons/hatchet_vxf_interaction/functions/pointing/pointDraw.sqf +++ /dev/null @@ -1,18 +0,0 @@ -/* - * vxf_interaction_fnc_pointDraw - * - * draws pointing positions - * - * params (array)[(object) vehicle] - */ - -params ["_vehicle"]; - -{ - if (cba_missionTime > (_x # 1) + vxf_point_lifetime) then { - vxf_point_icons deleteAt _forEachIndex; - } else { - private _drawPos = if(typeName (_x # 0) == "STRING") then {_vehicle selectionPosition (_x # 0)} else {(_x # 0)}; - drawIcon3D [_x # 2, [1,0,0,1], _vehicle modelToWorldVisual _drawPos, 2, 2, 0, (_x # 3)]; - }; -} forEach vxf_point_icons; diff --git a/addons/hatchet_vxf_interaction/functions/pointing/pointNetReceive.sqf b/addons/hatchet_vxf_interaction/functions/pointing/pointNetReceive.sqf deleted file mode 100644 index 42d29fc..0000000 --- a/addons/hatchet_vxf_interaction/functions/pointing/pointNetReceive.sqf +++ /dev/null @@ -1,16 +0,0 @@ -/* - * vxf_interaction_fnc_pointNetReceive - * - * receives pointing positions and adds timestamps and textures - * - * params (array)[(positionModel) pointPos, (SCALAR) type, (string) player name] - */ - -params ["_pointPos", "_pointType", "_name"]; - -private _pointTextures = [ - "\a3\ui_f\data\IGUI\Cfg\CrewAimIndicator\commander_ca.paa", - "\a3\ui_f\data\IGUI\Cfg\Cursors\freelook_ca.paa" -]; - -vxf_point_icons pushBack [_pointPos, cba_missionTime, _pointTextures # _pointType, _name]; diff --git a/addons/hatchet_vxf_interaction/functions/pointing/pointNetSend.sqf b/addons/hatchet_vxf_interaction/functions/pointing/pointNetSend.sqf deleted file mode 100644 index 71f52ca..0000000 --- a/addons/hatchet_vxf_interaction/functions/pointing/pointNetSend.sqf +++ /dev/null @@ -1,13 +0,0 @@ -/* - * vxf_interaction_fnc_pointNetSend - * - * sends pointing positions - * - * params (array)[(object) vehicle, (positionModel) pointPos, (SCALAR) icon index, (string) label] - */ - -params ["_vehicle", "_pointPos", "_iconIndex", "_label"]; - -if(vxf_uh60_interaction_pointing) then { - [_pointPos, _iconIndex, _label] remoteExecCall ["vxf_interaction_fnc_pointNetReceive", crew _vehicle]; -}; diff --git a/addons/hatchet_vxf_interaction/functions/pointing/pointStart.sqf b/addons/hatchet_vxf_interaction/functions/pointing/pointStart.sqf deleted file mode 100644 index c51c38c..0000000 --- a/addons/hatchet_vxf_interaction/functions/pointing/pointStart.sqf +++ /dev/null @@ -1,13 +0,0 @@ -/* - * vxf_interaction_fnc_pointStart - * - * used to point at something inside a vehicle, will draw a marker for other crew - * this function only starts pointing, actual pointing code is handled inside draw3D - * - */ - -private _vehicle = vehicle player; -if (isNil{_vehicle getVariable "vxf_interaction"}) exitWith {false}; - -vxf_interaction_pointStart = true; -true diff --git a/addons/hatchet_vxf_interaction/functions/preInit.sqf b/addons/hatchet_vxf_interaction/functions/preInit.sqf deleted file mode 100644 index 9b4795f..0000000 --- a/addons/hatchet_vxf_interaction/functions/preInit.sqf +++ /dev/null @@ -1,115 +0,0 @@ -[ - "Hatchet Vehicle Framework", - "vxf_interaction_scrollUpAlt", - "Scroll Up Alternative", - {vxf_alternative_scroll_up = true;}, - {vxf_alternative_scroll_up = false;}, - [16, [false, true, false]], - false -] call CBA_fnc_addKeybind; -[ - "Hatchet Vehicle Framework", - "vxf_interaction_scrollDownAlt", - "Scroll Down Alternative", - {vxf_alternative_scroll_down = true;}, - {vxf_alternative_scroll_down = false;}, - [18, [false, true, false]], - false -] call CBA_fnc_addKeybind; - -[ - "Hatchet Vehicle Framework", - "vxf_interaction", - "Vehicle Interaction", - {[vehicle player, vxf_interaction_currentButton] call vxf_interaction_fnc_buttonDown}, - {[vehicle player, vxf_interaction_currentButton] call vxf_interaction_fnc_buttonUp}, - [33, [false, false, false]], - false -] call CBA_fnc_addKeybind; - -[ - "Hatchet Vehicle Framework", - "vxf_interaction_alternative", - "Vehicle Interaction Alternative (adds alt+F by default)", - {[vehicle player, vxf_interaction_currentButton] call vxf_interaction_fnc_buttonDown}, - {[vehicle player, vxf_interaction_currentButton] call vxf_interaction_fnc_buttonUp}, - [33, [false, false, true]], - false -] call CBA_fnc_addKeybind; - -[ - "vxf_interaction_updateEvery", - "SLIDER", - "Label update rates(frames between)", - "Hatchet Vehicle Framework", - [0,10,5,0], - nil, - {} -] call CBA_Settings_fnc_init; - -[ - "vxf_uh60_interaction_pointing", - "checkbox", - "Enable pointing system(uses remoteCall)", - "Hatchet Vehicle Framework", - [true], - nil, - {} -] call CBA_Settings_fnc_init; - -[ - "Hatchet Vehicle Framework", - "vxf_cursor_hold", - "Show Interaction Cursor", - { - if (isNil "vxf_vehicle") exitWith {}; - vxf_interaction_cursor_mouseDown = false; - (findDisplay 46) createDisplay "vxf_interaction_mouseBlocker"; - (finddisplay 86005) displayAddEventHandler ["KeyUp", {[_this,'keyup'] call CBA_events_fnc_keyHandler}]; - setMousePosition [0.5, 0.5]; - }, - { - if (isNil "vxf_vehicle") exitWith {}; - if (uiNamespace getVariable ["vxf_interaction_mouseBlocker", false]) then { - (findDisplay 86005) closeDisplay 0; - }; - }, - [220, [false, false, false]], - false -] call CBA_fnc_addKeybind; - -[ - "vxf_uh60_interaction_autoclose_actionmenu", - "checkbox", - "Automatically close action menu (experimental)", - "Hatchet Vehicle Framework", - [false], - nil, - {} -] call CBA_Settings_fnc_init; - -[ - "vxf_interaction_showLabels", - "LIST", - [ - "Label Settings", - "Select what format of interaction labels to show." - ], - "Hatchet Vehicle Framework", - [ - [0, 1, 2], - ["No Labels","Hide Keybinds", "Full Label"], - 2 - ] -] call CBA_fnc_addSetting; - -vtx_uh60m_enabled_jvmf = true; -vtx_uh60m_enabled_fms = true; -vtx_uh60m_enabled_mfd = true; -vtx_uh60m_enabled_fd = true; -vtx_uh60m_enabled_cas = true; -vtx_uh60m_enabled_aar = true; -vtx_uh60m_enabled_flir = true; -vtx_uh60m_enabled_engine = true; -vxf_alternative_scroll_up = false; -vxf_alternative_scroll_down = false; \ No newline at end of file diff --git a/addons/hatchet_vxf_interaction/functions/scriptedInteract.sqf b/addons/hatchet_vxf_interaction/functions/scriptedInteract.sqf deleted file mode 100644 index 1fbf990..0000000 --- a/addons/hatchet_vxf_interaction/functions/scriptedInteract.sqf +++ /dev/null @@ -1,28 +0,0 @@ -/* -* vxf_interaction_fnc_scriptedInteract -* -* call a button or lever from a script -*/ - -params ["_vehicle", "_config", ["_animationTargetLabel", nil]]; - -private _vehicleConfig = _vehicle getVariable "vxf_config"; - -if (isNil "_vehicleConfig") exitWith {}; - -private _configPath = _vehicleConfig >> "interaction"; -{_configPath = _configPath >> _x} forEach _config; -private _interactionConfig = [_vehicle, _configPath] call vxf_interaction_fnc_loadItem; - -if (isNil "_animationTargetLabel") exitWith { - [_vehicle, _interactionConfig, true] call vxf_interaction_fnc_buttonDown; - [_vehicle, _interactionConfig, true] call vxf_interaction_fnc_buttonUp; -}; - -_interactionConfig params ["_name","_condition","_subItems",["_positionType", nil],["_position", nil],["_label", nil],["_radius", nil],["_clickSound",""],["_interactCondition",{true}],["_buttonConfig", nil], ["_animConfig", nil], ["_knobConfig", nil]]; -_animConfig params ["_animation", "_animationSpeed", "_animLooping", "_animationSteps", "_animationLabels", "_animStart", "_animEnd"]; - -private _stepIndex = _animationLabels find _animationTargetLabel; -if (_stepIndex == -1) exitWith {}; -private _targetAnimStep = _animationSteps # _stepIndex; -[_vehicle, _animation, _targetAnimStep, _animationTargetLabel, _animationSpeed, _animStart, _animEnd, _interactionConfig] call vxf_interaction_fnc_leverAnimate; diff --git a/addons/hatchet_vxf_interaction/functions/setup.sqf b/addons/hatchet_vxf_interaction/functions/setup.sqf deleted file mode 100644 index 074dbb7..0000000 --- a/addons/hatchet_vxf_interaction/functions/setup.sqf +++ /dev/null @@ -1,23 +0,0 @@ -/* - * vxf_interaction_fnc_setup - * - * starts the interaction system - * - * params (array)[(object) vehicle] - */ - -params ["_vehicle"]; - -_this call vxf_interaction_fnc_loadAll; - -if (isNil{vxf_drawHandler}) then { - vxf_drawHandler = addmissioneventhandler ["Draw3d",vxf_interaction_fnc_draw3D]; -}; - -private _vehicleConfig = _vehicle getVariable "vxf_config"; -vxf_interaction_crosshair = (getNumber (_vehicleConfig >> "interaction" >> "crossHair") == 1); - -vxf_animating_keys = []; -vxf_interaction_cursorPos = [0.5,0.5]; - -true diff --git a/addons/hatchet_vxf_interaction/functions/shutDown.sqf b/addons/hatchet_vxf_interaction/functions/shutDown.sqf deleted file mode 100644 index e69de29..0000000 diff --git a/addons/hatchet_vxf_interaction/sounds/dial.wss b/addons/hatchet_vxf_interaction/sounds/dial.wss deleted file mode 100644 index 8ef0330..0000000 Binary files a/addons/hatchet_vxf_interaction/sounds/dial.wss and /dev/null differ diff --git a/addons/hatchet_vxf_interaction/sounds/heavySwitch.wss b/addons/hatchet_vxf_interaction/sounds/heavySwitch.wss deleted file mode 100644 index ef082fe..0000000 Binary files a/addons/hatchet_vxf_interaction/sounds/heavySwitch.wss and /dev/null differ diff --git a/addons/hatchet_vxf_interaction/sounds/switch.wss b/addons/hatchet_vxf_interaction/sounds/switch.wss deleted file mode 100644 index b77b93e..0000000 Binary files a/addons/hatchet_vxf_interaction/sounds/switch.wss and /dev/null differ diff --git a/addons/hatchet_vxf_interaction/sounds/switch1.wss b/addons/hatchet_vxf_interaction/sounds/switch1.wss deleted file mode 100644 index fbadb93..0000000 Binary files a/addons/hatchet_vxf_interaction/sounds/switch1.wss and /dev/null differ diff --git a/addons/hatchet_vxf_interaction/sounds/switch2.wss b/addons/hatchet_vxf_interaction/sounds/switch2.wss deleted file mode 100644 index 375a063..0000000 Binary files a/addons/hatchet_vxf_interaction/sounds/switch2.wss and /dev/null differ diff --git a/addons/hatchet_vxf_interaction/sounds/switch3.wss b/addons/hatchet_vxf_interaction/sounds/switch3.wss deleted file mode 100644 index 785709d..0000000 Binary files a/addons/hatchet_vxf_interaction/sounds/switch3.wss and /dev/null differ diff --git a/addons/hatchet_vxf_interaction/sounds/switch4.wss b/addons/hatchet_vxf_interaction/sounds/switch4.wss deleted file mode 100644 index 533fb5c..0000000 Binary files a/addons/hatchet_vxf_interaction/sounds/switch4.wss and /dev/null differ diff --git a/addons/hatchet_vxf_interaction/sounds/switch5.wss b/addons/hatchet_vxf_interaction/sounds/switch5.wss deleted file mode 100644 index 485e181..0000000 Binary files a/addons/hatchet_vxf_interaction/sounds/switch5.wss and /dev/null differ diff --git a/addons/hatchet_vxf_util/$PBOPREFIX$ b/addons/hatchet_vxf_util/$PBOPREFIX$ deleted file mode 100644 index f480971..0000000 --- a/addons/hatchet_vxf_util/$PBOPREFIX$ +++ /dev/null @@ -1 +0,0 @@ -z/htf/hatchet_vxf_util \ No newline at end of file diff --git a/addons/hatchet_vxf_util/config.cpp b/addons/hatchet_vxf_util/config.cpp deleted file mode 100644 index da90220..0000000 --- a/addons/hatchet_vxf_util/config.cpp +++ /dev/null @@ -1,12 +0,0 @@ -class CfgPatches { - class vxf_util { - name = "Vortex Vehicle Framework"; - author = "Vortex Vehicles"; - units[] = {}; - weapons[] = {}; - requiredVersion = 1.0; - requiredAddons[] = {"cba_common", "cba_events"}; - }; -}; - -#include "config\cfgFunctions.hpp" diff --git a/addons/hatchet_vxf_util/config/cfgFunctions.hpp b/addons/hatchet_vxf_util/config/cfgFunctions.hpp deleted file mode 100644 index 2d712a7..0000000 --- a/addons/hatchet_vxf_util/config/cfgFunctions.hpp +++ /dev/null @@ -1,16 +0,0 @@ -class cfgFunctions { - class vxf_util { - class functions { - // PID Controllers - class pidCreate { - file = "hatchet_vxf_util\functions\pid\create.sqf"; - }; - class pidRun { - file = "hatchet_vxf_util\functions\pid\run.sqf"; - }; - class pidReset { - file = "hatchet_vxf_util\functions\pid\reset.sqf"; - }; - }; - }; -}; diff --git a/addons/hatchet_vxf_util/functions/pid/create.sqf b/addons/hatchet_vxf_util/functions/pid/create.sqf deleted file mode 100644 index 134c349..0000000 --- a/addons/hatchet_vxf_util/functions/pid/create.sqf +++ /dev/null @@ -1,17 +0,0 @@ -/* - * vxf_util_fnc_pidCreate - * - * Creates a new PiD controller - * - * params: (array)[(SCALAR) proportional, (SCALAR) integral, (SCALAR) derivative] - * - * returns: (bool) success - */ - -params ["_vehicle", "_name", "_kp", "_ki", "_kd"]; - -if (isNil "_vehicle" || _name == "") exitWith {false}; - -_vehicle setVariable [format ["vxf_pid_%1", _name], [_kp, _ki, _kd, 0, 0]]; - -true diff --git a/addons/hatchet_vxf_util/functions/pid/reset.sqf b/addons/hatchet_vxf_util/functions/pid/reset.sqf deleted file mode 100644 index 3bd8ab4..0000000 --- a/addons/hatchet_vxf_util/functions/pid/reset.sqf +++ /dev/null @@ -1,20 +0,0 @@ -/* - * vxf_util_fnc_pidReset - * - * Resets a PiD controller - * - * params: (array)[(SCALAR) proportional, (SCALAR) integral, (SCALAR) derivative] - * - * returns: (bool) success - */ - -params ["_vehicle", "_name"]; - -if (isNil "_vehicle" || _name == "") exitWith {}; - -private _pid = _vehicle getVariable [format ["vxf_pid_%1", _name], nil]; -if (isNil "_pid") exitWith {}; - -_pid set [3, 0]; -_pid set [4, 0]; -_vehicle setVariable [format ["vxf_pid_%1", _name], _pid]; diff --git a/addons/hatchet_vxf_util/functions/pid/run.sqf b/addons/hatchet_vxf_util/functions/pid/run.sqf deleted file mode 100644 index 7bc8c6b..0000000 --- a/addons/hatchet_vxf_util/functions/pid/run.sqf +++ /dev/null @@ -1,25 +0,0 @@ -/* - * vxf_util_fnc_pidRun - * - * Runs a pid controller update - * - * params: (array)[(object) vehicle, (string) name, (SCALAR) frameTime, (SCALAR) desired value, (SCALAR) actual value] - * - */ - -params ["_vehicle", "_name", "_frameTime", "_desiredValue", "_actualValue"]; - -private _pid = _vehicle getVariable [format ["vxf_pid_%1", _name], nil]; -if (isNil "_pid") exitWith {0}; - -_pid params ["_kp", "_ki", "_kd", "_priorError", "_integral"]; - -private _error = _desiredValue - _actualValue; -_integral = _integral + (_error * _frameTime); -private _derivative = (_error - _priorError) / _frameTime; -private _output = _kp * _error + _ki * _integral + _kd * _derivative; -_priorError = _error; - -_vehicle setVariable [format ["vxf_pid_%1", _name], [_kp, _ki, _kd, _priorError, _integral]]; - -_output diff --git a/addons/interaction/CfgSounds.hpp b/addons/interaction/CfgSounds.hpp index 8a998e6..ccf4edc 100644 --- a/addons/interaction/CfgSounds.hpp +++ b/addons/interaction/CfgSounds.hpp @@ -1,4 +1,4 @@ -#define SOUND(NAME,PATH) class PREFIX_NAME { name = QUOTE(NAME); sound[] = {QUOTE(\z\PREFIX\addons\COMPONENT\sounds\PATH.wss), 1, 1, 1}; titles[] = {}} +#define SOUND(NAME,PATH) class PREFIX_NAME { name = QUOTE(NAME); sound[] = {QUOTE(\z\PREFIX\addons\COMPONENT\sounds\PATH.wss), 1, 1, 1}; titles[] = {}; } class CfgSounds { SOUND(Switch_Sound,switch); diff --git a/buil.txt b/buil.txt deleted file mode 100644 index 8b13789..0000000 --- a/buil.txt +++ /dev/null @@ -1 +0,0 @@ - diff --git a/build.bat b/build.bat new file mode 100644 index 0000000..3392b5b --- /dev/null +++ b/build.bat @@ -0,0 +1,3 @@ +@echo off +hemtt.exe build +pause diff --git a/hemtt.exe b/hemtt.exe deleted file mode 100644 index 98836fa..0000000 Binary files a/hemtt.exe and /dev/null differ diff --git a/release/@vxf_framework/addons/hatchet_vxf_core.pbo b/release/@vxf_framework/addons/hatchet_vxf_core.pbo deleted file mode 100644 index 2787483..0000000 Binary files a/release/@vxf_framework/addons/hatchet_vxf_core.pbo and /dev/null differ diff --git a/release/@vxf_framework/addons/hatchet_vxf_interaction.pbo b/release/@vxf_framework/addons/hatchet_vxf_interaction.pbo deleted file mode 100644 index 58090fa..0000000 Binary files a/release/@vxf_framework/addons/hatchet_vxf_interaction.pbo and /dev/null differ diff --git a/release/@vxf_framework/addons/hatchet_vxf_util.pbo b/release/@vxf_framework/addons/hatchet_vxf_util.pbo deleted file mode 100644 index 4e6b5ed..0000000 Binary files a/release/@vxf_framework/addons/hatchet_vxf_util.pbo and /dev/null differ diff --git a/build.json b/tools/build.json similarity index 100% rename from build.json rename to tools/build.json diff --git a/tools/build.py b/tools/build.py deleted file mode 100644 index 154d962..0000000 --- a/tools/build.py +++ /dev/null @@ -1,91 +0,0 @@ -#!/usr/bin/env python3 - -import os -import sys -import subprocess - -######## GLOBALS ######### -MAINPREFIX = "z" -PREFIX = "htf_" -########################## - -def mod_time(path): - if not os.path.isdir(path): - return os.path.getmtime(path) - maxi = os.path.getmtime(path) - for p in os.listdir(path): - maxi = max(mod_time(os.path.join(path, p)), maxi) - return maxi - - -def check_for_changes(addonspath, module): - if not os.path.exists(os.path.join(addonspath, "{}{}.pbo".format(PREFIX,module))): - return True - return mod_time(os.path.join(addonspath, module)) > mod_time(os.path.join(addonspath, "{}{}.pbo".format(PREFIX,module))) - -def check_for_obsolete_pbos(addonspath, file): - module = file[len(PREFIX):-4] - if not os.path.exists(os.path.join(addonspath, module)): - return True - return False - -def main(): - print(""" - #################### - # PROJ_TEMPL3 Debug Build # - #################### -""") - - scriptpath = os.path.realpath(__file__) - projectpath = os.path.dirname(os.path.dirname(scriptpath)) - addonspath = os.path.join(projectpath, "addons") - - os.chdir(addonspath) - - made = 0 - failed = 0 - skipped = 0 - removed = 0 - - for file in os.listdir(addonspath): - if os.path.isfile(file): - if check_for_obsolete_pbos(addonspath, file): - removed += 1 - print(" Removing obsolete file => " + file) - os.remove(file) - print("") - - for p in os.listdir(addonspath): - path = os.path.join(addonspath, p) - if not os.path.isdir(path): - continue - if p[0] == ".": - continue - if not check_for_changes(addonspath, p): - skipped += 1 - print(" Skipping {}.".format(p)) - continue - - print("# Making {} ...".format(p)) - - try: - subprocess.check_output([ - "makepbo", - "-NUP", - "-@={}\\{}\\addons\\{}".format(MAINPREFIX,PREFIX.rstrip("_"),p), - p, - "{}{}.pbo".format(PREFIX,p) - ], stderr=subprocess.STDOUT) - except: - failed += 1 - print(" Failed to make {}.".format(p)) - else: - made += 1 - print(" Successfully made {}.".format(p)) - - print("\n# Done.") - print(" Made {}, skipped {}, removed {}, failed to make {}.".format(made, skipped, removed, failed)) - - -if __name__ == "__main__": - sys.exit(main()) diff --git a/buildExtIncludes.txt b/tools/buildExtIncludes.txt similarity index 100% rename from buildExtIncludes.txt rename to tools/buildExtIncludes.txt diff --git a/tools/config_style_checker.py b/tools/config_style_checker.py index 9de62ba..afa78a2 100644 --- a/tools/config_style_checker.py +++ b/tools/config_style_checker.py @@ -1,4 +1,5 @@ #!/usr/bin/env python3 + import fnmatch import os import re @@ -15,6 +16,14 @@ def pushClosing(t): def popClosing(): closing << closingStack.pop() + reIsClass = re.compile(r'^\s*class(.*)') + reIsClassInherit = re.compile(r'^\s*class(.*):') + reIsClassBody = re.compile(r'^\s*class(.*){') + reBadColon = re.compile(r'\s*class (.*) :') + reSpaceAfterColon = re.compile(r'\s*class (.*): ') + reSpaceBeforeCurly = re.compile(r'\s*class (.*) {') + reClassSingleLine = re.compile(r'\s*class (.*)[{;]') + with open(filepath, 'r', encoding='utf-8', errors='ignore') as file: content = file.read() @@ -39,7 +48,7 @@ def popClosing(): checkForSemiColumn = False # Extra information so we know what line we find errors at - lineNumber = 0 + lineNumber = 1 indexOfCharacter = 0 # Parse all characters in the content of this file to search for potential errors @@ -117,32 +126,52 @@ def popClosing(): if brackets_list.count('{') != brackets_list.count('}'): print("ERROR: A possible missing curly brace {{ or }} in file {0} {{ = {1} }} = {2}".format(filepath,brackets_list.count('{'),brackets_list.count('}'))) bad_count_file += 1 + + file.seek(0) + for lineNumber, line in enumerate(file.readlines()): + if reIsClass.match(line): + if reBadColon.match(line): + print(f"WARNING: bad class colon {filepath} Line number: {lineNumber+1}") + # bad_count_file += 1 + if reIsClassInherit.match(line): + if not reSpaceAfterColon.match(line): + print(f"WARNING: bad class missing space after colon {filepath} Line number: {lineNumber+1}") + if reIsClassBody.match(line): + if not reSpaceBeforeCurly.match(line): + print(f"WARNING: bad class inherit missing space before curly braces {filepath} Line number: {lineNumber+1}") + if not reClassSingleLine.match(line): + print(f"WARNING: bad class braces placement {filepath} Line number: {lineNumber+1}") + # bad_count_file += 1 + return bad_count_file def main(): + print("Validating Config Style") + sqf_list = [] bad_count = 0 + parser = argparse.ArgumentParser() parser.add_argument('-m','--module', help='only search specified module addon folder', required=False, default="") args = parser.parse_args() - # Allow running from root directory as well as from inside the tools directory - rootDir = "../addons" - if (os.path.exists("addons")): - rootDir = "addons" + for folder in ['addons', 'optionals']: + # Allow running from root directory as well as from inside the tools directory + rootDir = "../" + folder + if (os.path.exists(folder)): + rootDir = folder - for root, dirnames, filenames in os.walk(f"{rootDir}/{args.module}"): - for filename in fnmatch.filter(filenames, '*.cpp'): - sqf_list.append(os.path.join(root, filename)) - for filename in fnmatch.filter(filenames, '*.hpp'): - sqf_list.append(os.path.join(root, filename)) + for root, dirnames, filenames in os.walk(rootDir + '/' + args.module): + for filename in fnmatch.filter(filenames, '*.cpp'): + sqf_list.append(os.path.join(root, filename)) + for filename in fnmatch.filter(filenames, '*.hpp'): + sqf_list.append(os.path.join(root, filename)) for filename in sqf_list: bad_count = bad_count + check_config_style(filename) - print(f"\n Checked {len(sqf_list)} files\nErrors detected: {bad_count}") - + print("------\nChecked {0} files\nErrors detected: {1}".format(len(sqf_list), bad_count)) if (bad_count == 0): print("Config validation PASSED") else: diff --git a/tools/make.cfg b/tools/make.cfg deleted file mode 100644 index 027b9b5..0000000 --- a/tools/make.cfg +++ /dev/null @@ -1,92 +0,0 @@ -# EXAMPLE MAKE.CFG FILE -# Please see the comments for each option. Most options can be left -# off for sane defaults. - -################################################################# -# Default make target -################################################################# -[DEFAULT] - -# Project name (with @ symbol) -# This is used for naming the release files. -# Default: Current folder name -project = @hatchet_framework - -# Path to project secret key for signing -# Make sure this isn't in your public repository! -# Default: \private_keys\hatchet_framework_3.0.0.biprivatekey -# key = P:\private_keys\hatchet_framework_3.0.0.biprivatekey - -# Path to where private keys are automatically created if the command-line parameter "key" is used -# Make sure this isn't in your public repository! -# Default: \private_keys -# private_key_path = P:\private_keys - -# If set to True, the make system will attempt to autodetect addons in the -# current folder by looking for directories with 'config.cpp' in them. -# Default: True -# module_autodetect = True - -# List of directories to ignore when autodetecting addons. -# Default: release -# ignore = release, my_unfinished_module - -# If autodetect is set to False, only folders whose names are in this list -# will be built as modules. -# Default: None -# modules = my_module, my_supporting_module - -# This is the folder hierarchy that will be used as prefix inside the PBO. -# Default: None -prefix = z\hatchet_framework\addons - -# Set the location where the addon source folders (i.e. P:\z\ace\addons) -# Default: \\addons -module_root = P:\z\hatchet_framework\addons - -# Set the location where the optional addon source folders (i.e. P:\z\ace\optionals) -# Default: \\optionals -optionals_root = P:\z\hatchet_framework\optionals - - -# If the command-line variable test, the addons built will be copied to the following folder. -# Default: %USERPROFILE%\documents\Arma 3\ -# test_dir = %USERPROFILE%\documents\Arma 3\ - - -# Directory where the built addon will be saved. -# Default: release -release_dir = P:\z\hatchet_framework\release - - -# This string will be prefixed to all build PBO file names. -# Default: None -pbo_name_prefix = htc_ - -# This string will be prefixed to release archive. -# Default: None -zipPrefix = hatchet_framework - -# Which build tool will be used? Options: pboproject, addonbuilder -# Default: addonbuilder -build_tool = pboproject - -################################################################## -# Alternate build target using a different key -################################################################### -# [DifferentKey] -# key = C:\Keys\different.biprivatekey - -################################################################## -# Alternate build target ignoring some modules when detecting -################################################################### -# [IgnoreSome] -# key = C:\Keys\different.biprivatekey -# ignore = release, my_server_module, my_private_module - -################################################################## -# Alternate build target with fixed build list -################################################################### -# [Fixed] -# module_autodetect = False -# modules = my_module, my_other_module diff --git a/tools/make.py b/tools/make.py deleted file mode 100644 index 4d4366d..0000000 --- a/tools/make.py +++ /dev/null @@ -1,1510 +0,0 @@ -#!/usr/bin/env python3 -# vim: set fileencoding=utf-8 : - -# make.py -# An Arma 3 addon build system - -############################################################################### - -# The MIT License (MIT) - -# Copyright (c) 2013-2014 Ryan Schultz - -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: - -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. - -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -############################################################################### - -__version__ = "0.9" - -import sys - -if sys.version_info[0] == 2: - print("Python 3 is required.") - sys.exit(1) - -import os -import os.path -import shutil -import platform -import glob -import subprocess -import hashlib -import configparser -import json -import traceback -import time -import timeit -import re -import fileinput - -if sys.platform == "win32": - import winreg - -######## GLOBALS ######### -project = "@htf" -project_version = "0.3.0" -arma3tools_path = "" -work_drive = "" -module_root = "" -make_root = "" -release_dir = "" -module_root_parent = "" -optionals_root = "" -key_name = "htf" -key = "" -dssignfile = "" -prefix = "htf" -pbo_name_prefix = "htf_" -signature_blacklist = [] -importantFiles = ["mod.cpp", "meta.cpp", "README.md", "AUTHORS.txt", "LICENSE"] -versionFiles = ["README.md", "mod.cpp"] - -ciBuild = True # Used for CI builds - -############################################################################### -# http://akiscode.com/articles/sha-1directoryhash.shtml -# Copyright (c) 2009 Stephen Akiki -# MIT License (Means you can do whatever you want with this) -# See http://www.opensource.org/licenses/mit-license.php -# Error Codes: -# -1 -> Directory does not exist -# -2 -> General error (see stack traceback) -def get_directory_hash(directory): - directory_hash = hashlib.sha1() - if not os.path.exists (directory): - return -1 - - try: - for root, dirs, files in os.walk(directory): - for names in files: - path = os.path.join(root, names) - try: - f = open(path, 'rb') - except: - # You can't open the file for some reason - f.close() - continue - - while 1: - # Read file in as little chunks - buf = f.read(4096) - if not buf: break - new = hashlib.sha1(buf) - directory_hash.update(new.digest()) - f.close() - - except: - # Print the stack traceback - traceback.print_exc() - return -2 - - retVal = directory_hash.hexdigest() - #print_yellow("Hash Value for {} is {}".format(directory,retVal)) - return directory_hash.hexdigest() - -def Fract_Sec(s): - temp = float() - temp = float(s) / (60*60*24) - d = int(temp) - temp = (temp - d) * 24 - h = int(temp) - temp = (temp - h) * 60 - m = int(temp) - temp = (temp - m) * 60 - sec = temp - return d,h,m,sec - #endef Fract_Sec - -# Copyright (c) André Burgaud -# http://www.burgaud.com/bring-colors-to-the-windows-console-with-python/ -if sys.platform == "win32": - from ctypes import windll, Structure, c_short, c_ushort, byref - - SHORT = c_short - WORD = c_ushort - - class COORD(Structure): - """struct in wincon.h.""" - _fields_ = [ - ("X", SHORT), - ("Y", SHORT)] - - class SMALL_RECT(Structure): - """struct in wincon.h.""" - _fields_ = [ - ("Left", SHORT), - ("Top", SHORT), - ("Right", SHORT), - ("Bottom", SHORT)] - - class CONSOLE_SCREEN_BUFFER_INFO(Structure): - """struct in wincon.h.""" - _fields_ = [ - ("dwSize", COORD), - ("dwCursorPosition", COORD), - ("wAttributes", WORD), - ("srWindow", SMALL_RECT), - ("dwMaximumWindowSize", COORD)] - - # winbase.h - STD_INPUT_HANDLE = -10 - STD_OUTPUT_HANDLE = -11 - STD_ERROR_HANDLE = -12 - - # wincon.h - FOREGROUND_BLACK = 0x0000 - FOREGROUND_BLUE = 0x0001 - FOREGROUND_GREEN = 0x0002 - FOREGROUND_CYAN = 0x0003 - FOREGROUND_RED = 0x0004 - FOREGROUND_MAGENTA = 0x0005 - FOREGROUND_YELLOW = 0x0006 - FOREGROUND_GREY = 0x0007 - FOREGROUND_INTENSITY = 0x0008 # foreground color is intensified. - - BACKGROUND_BLACK = 0x0000 - BACKGROUND_BLUE = 0x0010 - BACKGROUND_GREEN = 0x0020 - BACKGROUND_CYAN = 0x0030 - BACKGROUND_RED = 0x0040 - BACKGROUND_MAGENTA = 0x0050 - BACKGROUND_YELLOW = 0x0060 - BACKGROUND_GREY = 0x0070 - BACKGROUND_INTENSITY = 0x0080 # background color is intensified. - - stdout_handle = windll.kernel32.GetStdHandle(STD_OUTPUT_HANDLE) - SetConsoleTextAttribute = windll.kernel32.SetConsoleTextAttribute - GetConsoleScreenBufferInfo = windll.kernel32.GetConsoleScreenBufferInfo - - def get_text_attr(): - """Returns the character attributes (colors) of the console screen - buffer.""" - csbi = CONSOLE_SCREEN_BUFFER_INFO() - GetConsoleScreenBufferInfo(stdout_handle, byref(csbi)) - return csbi.wAttributes - - def set_text_attr(color): - """Sets the character attributes (colors) of the console screen - buffer. Color is a combination of foreground and background color, - foreground and background intensity.""" - SetConsoleTextAttribute(stdout_handle, color) -############################################################################### - -def find_bi_tools(work_drive): - """Find BI tools.""" - - reg = winreg.ConnectRegistry(None, winreg.HKEY_CURRENT_USER) - try: - k = winreg.OpenKey(reg, r"Software\bohemia interactive\arma 3 tools") - arma3tools_path = winreg.QueryValueEx(k, "path")[0] - winreg.CloseKey(k) - except: - raise Exception("BadTools","Arma 3 Tools are not installed correctly or the P: drive needs to be created.") - - addonbuilder_path = os.path.join(arma3tools_path, "AddonBuilder", "AddonBuilder.exe") - dssignfile_path = os.path.join(arma3tools_path, "DSSignFile", "DSSignFile.exe") - dscreatekey_path = os.path.join(arma3tools_path, "DSSignFile", "DSCreateKey.exe") - cfgconvert_path = os.path.join(arma3tools_path, "CfgConvert", "CfgConvert.exe") - - if os.path.isfile(addonbuilder_path) and os.path.isfile(dssignfile_path) and os.path.isfile(dscreatekey_path) and os.path.isfile(cfgconvert_path): - return [addonbuilder_path, dssignfile_path, dscreatekey_path, cfgconvert_path] - else: - raise Exception("BadTools","Arma 3 Tools are not installed correctly or the P: drive needs to be created.") - - -def find_depbo_tools(): - """Use registry entries to find DePBO-based tools.""" - requiredToolPaths = {"pboProject": None, "rapify": None, "MakePbo": None} - failed = False - - for tool in requiredToolPaths: - try: - try: - k = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r"Software\Mikero\{}".format(tool)) - path = winreg.QueryValueEx(k, "exe")[0] - except FileNotFoundError: - try: - k = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r"Software\Mikero\{}".format(tool)) - path = winreg.QueryValueEx(k, "exe")[0] - except FileNotFoundError: - try: - k = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r"Software\Wow6432Node\Mikero\{}".format(tool)) - path = winreg.QueryValueEx(k, "exe")[0] - except FileNotFoundError: - k = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r"Software\Wow6432Node\Mikero\{}".format(tool)) - path = winreg.QueryValueEx(k, "exe")[0] - except FileNotFoundError: - print_error("Could not find {}".format(tool)) - failed = True - else: - #Strip any quotations from the path due to a MikeRo tool bug which leaves a trailing space in some of its registry paths. - requiredToolPaths[tool] = path.strip('"') - print_green("Found {}.".format(tool)) - finally: - winreg.CloseKey(k) - - if failed: - raise Exception("BadDePBO", "DePBO tools not installed correctly") - - return requiredToolPaths - - -def color(color): - """Set the color. Works on Win32 and normal terminals.""" - if sys.platform == "win32": - if color == "green": - set_text_attr(FOREGROUND_GREEN | get_text_attr() & 0x0070 | FOREGROUND_INTENSITY) - elif color == "yellow": - set_text_attr(FOREGROUND_YELLOW | get_text_attr() & 0x0070 | FOREGROUND_INTENSITY) - elif color == "red": - set_text_attr(FOREGROUND_RED | get_text_attr() & 0x0070 | FOREGROUND_INTENSITY) - elif color == "blue": - set_text_attr(FOREGROUND_BLUE | get_text_attr() & 0x0070 | FOREGROUND_INTENSITY) - elif color == "reset": - set_text_attr(FOREGROUND_GREY | get_text_attr() & 0x0070) - elif color == "grey": - set_text_attr(FOREGROUND_GREY | get_text_attr() & 0x0070) - else : - if color == "green": - sys.stdout.write('\033[92m') - elif color == "red": - sys.stdout.write('\033[91m') - elif color == "blue": - sys.stdout.write('\033[94m') - elif color == "reset": - sys.stdout.write('\033[0m') - -def print_error(msg): - color("red") - print("ERROR: {}".format(msg)) - color("reset") - global printedErrors - printedErrors += 1 - -def print_green(msg): - color("green") - print(msg) - color("reset") - -def print_blue(msg): - color("blue") - print(msg) - color("reset") - -def print_yellow(msg): - color("yellow") - print(msg) - color("reset") - - -def copy_important_files(source_dir,destination_dir): - originalDir = os.getcwd() - - # Copy importantFiles - try: - print_blue("\nSearching for important files in {}".format(source_dir)) - print("Source_dir: {}".format(source_dir)) - print("Destination_dir: {}".format(destination_dir)) - - for file in importantFiles: - filePath = os.path.join(module_root_parent, file) - if os.path.exists(filePath): - print_green("Copying file => {}".format(filePath)) - shutil.copy(os.path.join(source_dir,filePath), destination_dir) - else: - missingFiles.append("{}".format(filePath)) - print_error("Failed copying file => {}".format(filePath)) - except: - print_error("COPYING IMPORTANT FILES.") - raise - - # Copy all extension DLL's - try: - os.chdir(os.path.join(source_dir)) - print_blue("\nSearching for DLLs in {}".format(os.getcwd())) - filenames = glob.glob("*.dll") - - if not filenames: - print ("Empty SET") - - for dll in filenames: - print_green("Copying dll => {}".format(os.path.join(source_dir,dll))) - if os.path.isfile(dll): - shutil.copyfile(os.path.join(source_dir,dll),os.path.join(destination_dir,dll)) - except: - print_error("COPYING DLL FILES.") - raise - finally: - os.chdir(originalDir) - - - -def copy_optionals_for_building(mod,pbos): - src_directories = os.listdir(optionals_root) - current_dir = os.getcwd() - - print_blue("\nChecking optionals folder...") - try: - #special server.pbo processing - files = glob.glob(os.path.join(release_dir, project, "optionals", "*.pbo")) - for file in files: - file_name = os.path.basename(file) - #print ("Adding the following file: {}".format(file_name)) - pbos.append(file_name) - pbo_path = os.path.join(release_dir, project, "optionals", file_name) - sigFile_name = file_name +"."+ key_name + ".bisign" - sig_path = os.path.join(release_dir, project, "optionals", sigFile_name) - if (os.path.isfile(pbo_path)): - print("Moving {} for processing.".format(pbo_path)) - shutil.move(pbo_path, os.path.join(release_dir, project, "addons", file_name)) - - if (os.path.isfile(sig_path)): - #print("Moving {} for processing.".format(sig_path)) - shutil.move(sig_path, os.path.join(release_dir, project, "addons", sigFile_name)) - - except: - print_error("Error in moving") - raise - finally: - os.chdir(current_dir) - - try: - for dir_name in src_directories: - mod.append(dir_name) - #userconfig requires special handling since it is not a PBO source folder. - #CfgConvert fails to build server.pbo if userconfig is not found in P:\ - if (dir_name == "userconfig"): - if (os.path.exists(os.path.join(release_dir, project, "optionals", dir_name))): - shutil.rmtree(os.path.join(release_dir, project, "optionals", dir_name), True) - shutil.copytree(os.path.join(optionals_root,dir_name), os.path.join(release_dir, project, "optionals", dir_name)) - destination = os.path.join(work_drive,dir_name) - else: - destination = os.path.join(module_root,dir_name) - - print("Temporarily copying {} => {} for building.".format(os.path.join(optionals_root,dir_name),destination)) - if (os.path.exists(destination)): - shutil.rmtree(destination, True) - shutil.copytree(os.path.join(optionals_root,dir_name), destination) - except: - print_error("Copy Optionals Failed") - raise - finally: - os.chdir(current_dir) - - -def cleanup_optionals(mod): - print("") - try: - for dir_name in mod: - #userconfig requires special handling since it is not a PBO source folder. - if (dir_name == "userconfig"): - destination = os.path.join(work_drive,dir_name) - else: - destination = os.path.join(module_root,dir_name) - - print("Cleaning {}".format(destination)) - - try: - file_name = "{}{}.pbo".format(pbo_name_prefix,dir_name) - folder= "@{}{}".format(pbo_name_prefix,dir_name) - src_file_path = os.path.join(release_dir, project, "addons", file_name) - dst_file_path = os.path.join(release_dir, project, "optionals",folder,"addons",file_name) - - sigFile_name = "{}.{}.bisign".format(file_name,key_name) - src_sig_path = os.path.join(release_dir, project, "addons", sigFile_name) - dst_sig_path = os.path.join(release_dir, project, "optionals",folder,"addons", sigFile_name) - - - if (os.path.isfile(src_file_path)): - if (os.path.isfile(dst_file_path)): - # print("Cleanuping up old file {}".format(dst_file_path)) - os.remove(dst_file_path); - #print("Preserving {}".format(file_name)) - os.renames(src_file_path,dst_file_path) - if (os.path.isfile(src_sig_path)): - if (os.path.isfile(dst_sig_path)): - # print("Cleanuping up old file {}".format(dst_sig_path)) - os.remove(dst_sig_path); - #print("Preserving {}".format(sigFile_name)) - os.renames(src_sig_path,dst_sig_path) - except FileExistsError: - print_error("{} already exists".format(file_name)) - continue - shutil.rmtree(destination) - - except FileNotFoundError: - print_yellow("{} file not found".format(file_name)) - - except: - print_error("Cleaning Optionals Failed") - raise - - -def purge(dir, pattern, friendlyPattern="files"): - print_green("Deleting {} files from directory: {}".format(friendlyPattern,dir)) - if os.path.exists(dir): - for f in os.listdir(dir): - if re.search(pattern, f): - os.remove(os.path.join(dir, f)) - - -def build_signature_file(file_name): - global key - global dssignfile - global signature_blacklist - ret = 0 - baseFile = os.path.basename(file_name) - #print_yellow("Sig_fileName: {}".format(baseFile)) - if not (baseFile in signature_blacklist): - print("Signing with {}.".format(key)) - ret = subprocess.call([dssignfile, key, file_name]) - if ret == 0: - return True - else: - return False - - -def check_for_obsolete_pbos(addonspath, file): - module = file[len(pbo_name_prefix):-4] - if not os.path.exists(os.path.join(addonspath, module)): - return True - return False - - -def backup_config(module): - #backup original $PBOPREFIX$ - global work_drive - global prefix - - try: - configpath = os.path.join(work_drive, prefix, module, "$PBOPREFIX$") - if os.path.isfile(configpath): - shutil.copyfile(configpath, os.path.join(work_drive, prefix, module, "$PBOPREFIX$.backup")) - else: - print_error("$PBOPREFIX$ Does not exist for module: {}.".format(module)) - - except: - print_error("Error creating backup of $PBOPREFIX$ for module {}.".format(module)) - - return True - -def addon_restore(modulePath): - #restore original $PBOPREFIX$ - try: - if os.path.isfile(os.path.join(modulePath, "$PBOPREFIX$.backup")): - if os.path.isfile(os.path.join(modulePath, "$PBOPREFIX$")): - os.remove(os.path.join(modulePath, "$PBOPREFIX$")) - os.rename(os.path.join(modulePath, "$PBOPREFIX$.backup"), os.path.join(modulePath, "$PBOPREFIX$")) - except: - print_yellow("Some error occurred. Check your addon folder {} for integrity".format(modulePath)) - - return True - - -def get_project_version(version_increments=[]): - global project_version - versionStamp = project_version - #do the magic based on https://github.com/acemod/ACE3/issues/806#issuecomment-95639048 - - try: - scriptModPath = os.path.join(module_root, "main\script_version.hpp") - - if os.path.isfile(scriptModPath): - f = open(scriptModPath, "r") - hpptext = f.read() - f.close() - - if hpptext: - majorText = re.search(r"#define MAJOR (.*\b)", hpptext).group(1) - minorText = re.search(r"#define MINOR (.*\b)", hpptext).group(1) - patchText = re.search(r"#define PATCHLVL (.*\b)", hpptext).group(1) - buildText = re.search(r"#define BUILD (.*\b)", hpptext).group(1) - - # Increment version (reset all below except build) - if version_increments != []: - if "major" in version_increments: - majorText = int(majorText) + 1 - minorText = 0 - patchText = 0 - elif "minor" in version_increments: - minorText = int(minorText) + 1 - patchText = 0 - elif "patch" in version_increments: - patchText = int(patchText) + 1 - - # Always increment build - if "build" in version_increments: - buildText = int(buildText) + 1 - - print_green("Incrementing version to {}.{}.{}.{}".format(majorText,minorText,patchText,buildText)) - with open(scriptModPath, "w", newline="\n") as file: - file.writelines([ - "#define MAJOR {}\n".format(majorText), - "#define MINOR {}\n".format(minorText), - "#define PATCHLVL {}\n".format(patchText), - "#define BUILD {}\n".format(buildText) - ]) - - if majorText: - versionStamp = "{}.{}.{}.{}".format(majorText,minorText,patchText,buildText) - - else: - print_error("A Critical file seems to be missing or inaccessible: {}".format(scriptModPath)) - raise FileNotFoundError("File Not Found: {}".format(scriptModPath)) - - except Exception as e: - print_error("Get_project_version error: {}".format(e)) - print_error("Check the integrity of the file: {}".format(scriptModPath)) - versionStamp = project_version - print_error("Resetting to the default version stamp: {}".format(versionStamp)) - input("Press Enter to continue...") - print("Resuming build...") - - print_yellow("{} VERSION set to {}".format(project.lstrip("@").upper(),versionStamp)) - project_version = versionStamp - return project_version - - -def replace_file(filePath, oldSubstring, newSubstring): - for line in fileinput.input(filePath, inplace=True): - # Use stdout directly, print() adds newlines automatically - sys.stdout.write(line.replace(oldSubstring,newSubstring)) - - -def set_version_in_files(): - newVersion = project_version # MAJOR.MINOR.PATCH.BUILD - newVersionArr = newVersion.split(".") - newVersionShort = ".".join((newVersionArr[0],newVersionArr[1],newVersionArr[2])) # MAJOR.MINOR.PATCH - - # Regex patterns - pattern = re.compile(r"([\d]+\.[\d]+\.[\d]+\.[\d]+)") # MAJOR.MINOR.PATCH.BUILD - patternShort = re.compile(r"([\d]+\.[\d]+\.[\d]+)") # MAJOR.MINOR.PATCH - - # Change versions in files containing version - for i in versionFiles: - filePath = os.path.join(module_root_parent, i) - - try: - # Save the file contents to a variable if the file exists - if os.path.isfile(filePath): - f = open(filePath, "r+") - fileText = f.read() - f.close() - - if fileText: - # Version string files - # Search and save version stamp - versionsFound = re.findall(pattern, fileText) + re.findall(patternShort, fileText) - # Filter out sub-versions of other versions - versionsFound = [j for i, j in enumerate(versionsFound) if all(j not in k for k in versionsFound[i + 1:])] - - # Replace version stamp if any of the new version parts is higher than the one found - for versionFound in versionsFound: - if versionFound: - # Use the same version length as the one found - newVersionUsed = "" # In case undefined - if versionFound.count(".") == newVersion.count("."): - newVersionUsed = newVersion - if versionFound.count(".") == newVersionShort.count("."): - newVersionUsed = newVersionShort - - # Print change and modify the file if changed - if newVersionUsed and versionFound != newVersionUsed: - print_green("Changing version {} => {} in {}".format(versionFound, newVersionUsed, filePath)) - replace_file(filePath, versionFound, newVersionUsed) - except WindowsError as e: - # Temporary file is still "in use" by Python, pass this exception - pass - except Exception as e: - print_error("set_version_in_files error: {}".format(e)) - raise - - return True - - -def stash_version_files_for_building(): - try: - for file in versionFiles: - filePath = os.path.join(module_root_parent, file) - if os.path.exists(filePath): - # Take only file name for stash location if in subfolder (otherwise it gets removed when removing folders from release dir) - if "\\" in file: - count = file.count("\\") - file = file.split("\\", count)[-1] - stashPath = os.path.join(release_dir, file) - print("Temporarily stashing {} => {}.bak for version update".format(filePath, stashPath)) - shutil.copy(filePath, "{}.bak".format(stashPath)) - else: - print_error("Failed temporarily stashing {} for version update".format(filePath)) - missingFiles.append("{}".format(filePath)) - except: - print_error("Stashing version files failed") - raise - - # Set version - set_version_in_files() - return True - - -def restore_version_files(): - try: - print_blue("\nRestoring version files...") - - for file in versionFiles: - filePath = os.path.join(module_root_parent, file) - # Take only file name for stash path if in subfolder (otherwise it gets removed when removing folders from release dir) - if "\\" in file: - count = file.count("\\") - file = file.split("\\", count)[-1] - stashPath = os.path.join(release_dir, file) - if os.path.exists(filePath): - print("Restoring {}".format(filePath)) - shutil.move("{}.bak".format(stashPath), filePath) - except: - print_error("Restoring version files failed") - raise - return True - - -def get_private_keyname(commitID,module="main"): - global pbo_name_prefix - global project_version - - keyName = str("{prefix}{version}-{commit_id}".format(prefix=pbo_name_prefix,version=project_version,commit_id=commitID)) - return keyName - - -def get_commit_ID(): - # Get latest commit ID - global make_root - curDir = os.getcwd() - commit_id = "" - - try: - # Verify if Git repository - gitpath = os.path.join(os.path.dirname(make_root), ".git") - assert os.path.exists(gitpath) - - # Try to get commit ID through Git client - os.chdir(make_root) - commit_id = subprocess.check_output(["git", "rev-parse", "HEAD"]) - commit_id = str(commit_id, "utf-8")[:8] - except FileNotFoundError: - # Try to get commit ID from git files (subprocess failed - eg. no Git client) - head_path = os.path.join(gitpath, "HEAD") - if os.path.exists(head_path): - with open(head_path, "r") as head_file: - branch_path = head_file.readline().split(": ") - - # Commit ID is written in HEAD file directly when in detached state - if len(branch_path) == 1: - commit_id = branch_path[0] - else: - branch_path = branch_path[-1].strip() - ref_path = os.path.join(gitpath, branch_path) - if os.path.exists(ref_path): - with open(ref_path, "r") as ref_file: - commit_id = ref_file.readline() - - if commit_id != "": - commit_id = commit_id.strip()[:8] - else: - raise - except: - # All other exceptions (eg. AssertionException) - if commit_id == "": - raise - finally: - pass - if commit_id == "": - print_error("Failed to determine commit ID - folder is not a Git repository.") - commit_id = "NOGIT" - os.chdir(curDir) - - print_yellow("COMMIT ID set to {}".format(commit_id)) - return commit_id - - -def version_stamp_pboprefix(module,commitID): - ### Update pboPrefix with the correct version stamp. Use commit_id as the build number. - #This function will not handle any $PBOPREFIX$ backup or cleanup. - global work_drive - global prefix - - configpath = os.path.join(work_drive, prefix, module, "$PBOPREFIX$") - - try: - f = open(configpath, "r") - configtext = f.read() - f.close() - - if configtext: - if re.search(r"version=(.*?)$", configtext, re.DOTALL): - if configtext: - configtext = re.sub(r"version=(.*?)$", "version={}\n".format(commitID), configtext, flags=re.DOTALL) - f = open(configpath, "w") - f.write(configtext) - f.close() - else: - os.remove(os.path.join(work_drive, prefix, module, "$PBOPREFIX$")) - os.rename(os.path.join(work_drive, prefix, module, "$PBOPREFIX$.backup"), os.path.join(work_drive, prefix, module, "$PBOPREFIX$")) - else: - if configtext: - #append version info - f = open(configpath, "a") - f.write("\nversion = {}".format(commitID)) - f.close() - else: - os.remove(os.path.join(work_drive, prefix, module, "$PBOPREFIX$")) - os.rename(os.path.join(work_drive, prefix, module, "$PBOPREFIX$.backup"), os.path.join(work_drive, prefix, module, "$PBOPREFIX$")) - except Exception as e: - print_error("Failed to include build number: {}".format(e)) - return False - - return True - - -############################################################################### - - -def main(argv): - """Build an Arma addon suite in a directory from rules in a make.cfg file.""" - print_blue("\nmake.py for Arma, modified for Advanced Combat Environment v{}".format(__version__)) - - global project_version - global arma3tools_path - global work_drive - global module_root - global make_root - global release_dir - global module_root_parent - global optionals_root - global key_name - global key - global dssignfile - global prefix - global pbo_name_prefix - global ciBuild - global missingFiles - global failedBuilds - global printedErrors - - printedErrors = 0 - - if sys.platform != "win32": - print_error("Non-Windows platform (Cygwin?). Please re-run from cmd.") - sys.exit(1) - - reg = winreg.ConnectRegistry(None, winreg.HKEY_CURRENT_USER) - try: - k = winreg.OpenKey(reg, r"Software\bohemia interactive\arma 3 tools") - arma3tools_path = winreg.QueryValueEx(k, "path")[0] - winreg.CloseKey(k) - except: - raise Exception("BadTools","Arma 3 Tools are not installed correctly or the P: drive needs to be created.") - - # Default behaviors - test = False # Copy to Arma 3 directory? - arg_modules = False # Only build modules on command line? - use_pboproject = True # Default to pboProject build tool - make_target = "DEFAULT" # Which section in make.cfg to use for the build - new_key = True # Make a new key and use it to sign? - quiet = False # Suppress output from build tool? - - # Parse arguments - if "help" in argv or "-h" in argv or "--help" in argv: - print (""" -make.py [help] [test] [force] [key ] [target ] [release ] - [module name] [module name] [...] - -test -- Copy result to Arma 3. -release -- Make archive with . -force -- Ignore cache and build all. -checkexternal -- Check External Files -target -- Use rules in make.cfg under heading [] rather than - default [Make] -key -- Use key in working directory with to sign. If it does not - exist, create key. -quiet -- Suppress command line output from build tool. - -If module names are specified, only those modules will be built. - -Examples: - make.py force test - Build all modules (ignoring cache) and copy the mod folder to the Arma 3 - directory. - make.py mymodule_gun - Only build the module named 'mymodule_gun'. - make.py force key MyNewKey release 1.0 - Build all modules (ignoring cache), sign them with NewKey, and pack them - into a zip file for release with version 1.0. - - -If a file called $NOBIN$ is found in the module directory, that module will not be binarized. - -See the make.cfg file for additional build options. -""") - sys.exit(0) - - if "force" in argv: - argv.remove("force") - force_build = True - else: - force_build = False - - if "test" in argv: - test = True - argv.remove("test") - - if "release" in argv: - make_release_zip = True - argv.remove("release") - else: - make_release_zip = False - - if "target" in argv: - make_target = argv[argv.index("target") + 1] - argv.remove("target") - argv.remove(make_target) - force_build = True - - if "key" in argv: - new_key = True - key_name = argv[argv.index("key") + 1] - argv.remove("key") - argv.remove(key_name) - - if "quiet" in argv: - quiet = True - argv.remove("quiet") - - if "checkexternal" in argv: - argv.remove("checkexternal") - check_external = True - else: - check_external = False - - if "version" in argv: - argv.remove("version") - version_update = True - else: - version_update = False - - version_increments = [] - if "increment_build" in argv: - argv.remove("increment_build") - version_increments.append("build") - if "increment_patch" in argv: - argv.remove("increment_patch") - version_increments.append("patch") - if "increment_minor" in argv: - argv.remove("increment_minor") - version_increments.append("minor") - if "increment_major" in argv: - argv.remove("increment_major") - version_increments.append("major") - - if "ci" in argv: - argv.remove("ci") - ciBuild = True - - print_yellow("\nCheck external references is set to {}".format(str(check_external))) - - # Get the directory the make script is in. - make_root = os.path.dirname(os.path.realpath(__file__)) - make_root_parent = os.path.abspath(os.path.join(os.getcwd(), os.pardir)) - os.chdir(make_root) - - - - cfg = configparser.ConfigParser(); - try: - cfg.read(os.path.join(make_root, "make.cfg")) - - # Project name (with @ symbol) - project = cfg.get(make_target, "project", fallback="@"+os.path.basename(os.getcwd())) - - # BI Tools work drive on Windows - work_drive = cfg.get(make_target, "work_drive", fallback="P:\\") - - # Private key path - key = cfg.get(make_target, "key", fallback=None) - - # Private key creation directory - private_key_path = cfg.get(make_target, "private_key_path", fallback=os.path.join(work_drive, "private_keys")) - - # Project prefix (folder path) - prefix = cfg.get(make_target, "prefix", fallback="") - - # Release archive prefix - zipPrefix = cfg.get(make_target, "zipPrefix", fallback=project.lstrip("@").lower()) - - # Should we autodetect modules on a complete build? - module_autodetect = cfg.getboolean(make_target, "module_autodetect", fallback=True) - - # Manual list of modules to build for a complete build - modules = cfg.get(make_target, "modules", fallback=None) - # Parse it out - if modules: - modules = [x.strip() for x in modules.split(',')] - else: - modules = [] - - # List of directories to ignore when detecting - ignore = [x.strip() for x in cfg.get(make_target, "ignore", fallback="release").split(',')] - - # Which build tool should we use? - build_tool = cfg.get(make_target, "build_tool", fallback="addonbuilder").lower() - - # Release/build directory, relative to script dir - release_dir = cfg.get(make_target, "release_dir", fallback="release") - - #Directory to copy the final built PBO's for a test run. - test_dir = cfg.get(make_target, "test_dir", fallback=os.path.join(os.environ["USERPROFILE"],r"documents\Arma 3")) - - # Project PBO file prefix (files are renamed to prefix_name.pbo) - pbo_name_prefix = cfg.get(make_target, "pbo_name_prefix", fallback=None) - - # Project module Root - module_root_parent = os.path.abspath(os.path.join(os.path.join(work_drive, prefix), os.pardir)) - module_root = cfg.get(make_target, "module_root", fallback=os.path.join(make_root_parent, "addons")) - optionals_root = os.path.join(module_root_parent, "optionals") - extensions_root = os.path.join(module_root_parent, "extensions") - - if (os.path.isdir(module_root)): - os.chdir(module_root) - else: - print_error ("Directory {} does not exist.".format(module_root)) - sys.exit(1) - - commit_id = get_commit_ID() - get_project_version(version_increments) - key_name = versionStamp = get_private_keyname(commit_id) - print_green ("module_root: {}".format(module_root)) - - if (os.path.isdir(optionals_root)): - print_green ("optionals_root: {}".format(optionals_root)) - else: - print("optionals_root does not exist: {}".format(optionals_root)) - - print_green ("release_dir: {}".format(release_dir)) - - except: - raise - print_error("Could not parse make.cfg.") - sys.exit(1) - - # See if we have been given specific modules to build from command line. - if len(argv) > 1 and not make_release_zip: - arg_modules = True - modules = [a for a in argv[1:] if a[0] != "-"] - - # Find the tools we need. - try: - tools = find_bi_tools(work_drive) - addonbuilder = tools[0] - dssignfile = tools[1] - dscreatekey = tools[2] - cfgconvert = tools[3] - - except: - print_error("Arma 3 Tools are not installed correctly or the P: drive has not been created.") - sys.exit(1) - - if build_tool == "pboproject": - try: - depbo_tools = find_depbo_tools() - - pboproject = depbo_tools["pboProject"] - rapifyTool = depbo_tools["rapify"] - makepboTool = depbo_tools["MakePbo"] - except: - raise - print_error("Could not find dePBO tools. Download the needed tools from: https://dev.withsix.com/projects/mikero-pbodll/files") - sys.exit(1) - - # Try to open and deserialize build cache file. - try: - cache = {} - with open(os.path.join(make_root, "make.cache"), 'r') as f: - cache_raw = f.read() - - cache = json.loads(cache_raw) - - except: - print ("No cache found.") - cache = {} - - # Check the build version (from main) with cached version - forces a full rebuild when version changes - cacheVersion = "None"; - if 'cacheVersion' in cache: - cacheVersion = cache['cacheVersion'] - - if (project_version != cacheVersion): - cache = {} - print("Reseting Cache {0} to New Version {1}".format(cacheVersion, project_version)) - cache['cacheVersion'] = project_version - - if not os.path.isdir(os.path.join(release_dir, project, "addons")): - try: - os.makedirs(os.path.join(release_dir, project, "addons")) - except: - print_error("Cannot create release directory") - raise - - if not os.path.isdir(os.path.join(release_dir, project, "keys")): - try: - os.makedirs(os.path.join(release_dir, project, "keys")) - except: - print_error("Cannot create release directory") - raise - - failedBuilds = [] - missingFiles = [] - - # Update version stamp in all files that contain it - # Update version only for release if full update not requested (backup and restore files) - print_blue("\nChecking for obsolete version numbers...") - if not version_update: - stash_version_files_for_building() - else: - # Set version - set_version_in_files(); - print("Version in files has been changed, make sure you commit and push the updates!") - - try: - # Temporarily copy optionals_root for building. They will be removed later. - if (os.path.isdir(optionals_root)): - optionals_modules = [] - optional_files = [] - copy_optionals_for_building(optionals_modules,optional_files) - - # Get list of subdirs in make root. - dirs = next(os.walk(module_root))[1] - - # Autodetect what directories to build. - if module_autodetect and not arg_modules: - modules = [] - for path in dirs: - # Any dir that has a config.cpp in its root is an addon to build. - config_path = os.path.join(path, 'config.cpp') - if os.path.isfile(config_path) and not path in ignore: - modules.append(path) - - # Make the key specified from command line if necessary. - if new_key: - if not os.path.isfile(os.path.join(private_key_path, key_name + ".biprivatekey")): - print_yellow("\nRequested key does not exist.") - try: - os.makedirs(private_key_path) - except: - pass - curDir = os.getcwd() - os.chdir(private_key_path) - ret = subprocess.call([dscreatekey, key_name]) # Created in make_root - os.chdir(curDir) - if ret == 0: - print_green("Created: {}".format(os.path.join(private_key_path, key_name + ".biprivatekey"))) - print("Removing any old signature keys...") - purge(os.path.join(module_root, release_dir, project, "addons"), "^.*\.bisign$","*.bisign") - purge(os.path.join(module_root, release_dir, project, "optionals"), "^.*\.bisign$","*.bisign") - purge(os.path.join(module_root, release_dir, project, "keys"), "^.*\.bikey$","*.bikey") - else: - print_error("Failed to create key!") - - - - else: - print_green("\nNOTE: Using key {}".format(os.path.join(private_key_path, key_name + ".biprivatekey"))) - - try: - print("Copying public key to release directory.") - - try: - os.makedirs(os.path.join(module_root, release_dir, project, "keys")) - except: - pass - - # Use biKeyNameAbrev to attempt to minimize problems from this BI Bug REFERENCE: http://feedback.arma3.com/view.php?id=22133 - biKeyNameAbrev = key_name.split("-")[0] - shutil.copyfile(os.path.join(private_key_path, key_name + ".bikey"), os.path.join(module_root, release_dir, project, "keys", "{}.bikey".format(biKeyNameAbrev))) - - except: - print_error("Could not copy key to release directory.") - raise - - key = os.path.join(private_key_path, "{}.biprivatekey".format(key_name)) - - # Remove any obsolete files. - print_blue("\nChecking for obsolete files...") - obsolete_check_path = os.path.join(module_root, release_dir, project,"addons") - for file in os.listdir(obsolete_check_path): - if (file.endswith(".pbo") and os.path.isfile(os.path.join(obsolete_check_path,file))): - if check_for_obsolete_pbos(module_root, file): - fileName = os.path.splitext(file)[0] - print_yellow("Removing obsolete pbo => {}".format(file)) - purge(obsolete_check_path, "{}\..".format(fileName), "{}.*".format(fileName)) - - obsolete_check_path = os.path.join(module_root, release_dir, project) - for file in os.listdir(obsolete_check_path): - if (file.endswith(".dll") and os.path.isfile(os.path.join(obsolete_check_path,file))): - if not os.path.exists(os.path.join(module_root_parent, file)): - print_yellow("Removing obsolete dll => {}".format(file)) - try: - os.remove(os.path.join(obsolete_check_path,file)) - except: - print_error("\nFailed to delete {}".format(os.path.join(obsolete_check_path,file))) - pass - - # For each module, prep files and then build. - print_blue("\nBuilding...") - for module in modules: - print_green("\nMaking {}".format(module + "-"*max(1, (60-len(module))))) - missing = False - sigMissing = False - - # Cache check - if module in cache: - old_sha = cache[module] - else: - old_sha = "" - - # Hash the module - new_sha = get_directory_hash(os.path.join(module_root, module)) - - # Is the pbo or sig file missing? - missing = not os.path.isfile(os.path.join(release_dir, project, "addons", "{}{}.pbo".format(pbo_name_prefix,module))) - sigFile = "{}{}.pbo.{}.bisign".format(pbo_name_prefix,module,key_name) - sigMissing = not os.path.isfile(os.path.join(release_dir, project, "addons", sigFile)) - - if missing: - print_yellow("Missing PBO file {}{}.pbo. Building...".format(pbo_name_prefix,module)) - - # Check if it needs rebuilt - # print ("Hash:", new_sha) - if old_sha == new_sha and not missing: - if not force_build: - print("Module has not changed.") - if sigMissing: - if key: - print("Missing Signature key {}".format(sigFile)) - build_signature_file(os.path.join(module_root, release_dir, project, "addons", "{}{}.pbo".format(pbo_name_prefix,module))) - # Skip everything else - continue - - # Only do this if the project isn't stored directly on the work drive. - # Split the path at the drive name and see if they are on the same drive (usually P:) - if os.path.splitdrive(module_root)[0] != os.path.splitdrive(work_drive)[0]: - try: - # Remove old work drive version (ignore errors) - shutil.rmtree(os.path.join(work_drive, prefix, module), True) - - # Copy module to the work drive - shutil.copytree(module, os.path.join(work_drive, prefix, module)) - - except: - raise - print_error("Could not copy module to work drive. Does the module exist?") - input("Press Enter to continue...") - print("Resuming build...") - continue - #else: - #print("WARNING: Module is stored on work drive ({}).".format(work_drive)) - - try: - # Remove the old pbo, key, and log - old = os.path.join(module_root, release_dir, project, "addons", "{}{}".format(pbo_name_prefix,module)) + "*" - files = glob.glob(old) - for f in files: - os.remove(f) - - if pbo_name_prefix: - old = os.path.join(module_root, release_dir, project, "addons", "{}{}".format(pbo_name_prefix,module)) + "*" - files = glob.glob(old) - for f in files: - os.remove(f) - except: - raise - print_error("Could not copy module to work drive. Does the module exist?") - input("Press Enter to continue...") - print("Resuming build...") - continue - - # Build the module into a pbo - print_blue("Building: {}".format(os.path.join(work_drive, prefix, module))) - print_blue("Destination: {}".format(os.path.join(module_root, release_dir, project, "addons"))) - - # Make destination folder (if needed) - try: - os.makedirs(os.path.join(module_root, release_dir, project, "addons")) - except: - pass - - - # Run build tool - build_successful = False - if build_tool == "pboproject": - try: - nobinFilePath = os.path.join(work_drive, prefix, module, "$NOBIN$") - backup_config(module) - - version_stamp_pboprefix(module,commit_id) - - if os.path.isfile(nobinFilePath): - print_green("$NOBIN$ Found. Proceeding with non-binarizing!") - cmd = [makepboTool, "-P","-A","-G","-N","-X=*.backup", os.path.join(work_drive, prefix, module),os.path.join(module_root, release_dir, project,"addons")] - - else: - if check_external: - cmd = [pboproject, "-P", os.path.join(work_drive, prefix, module), "+Engine=Arma3", "-S","+Noisy", "+X", "+Clean", "+Mod="+os.path.join(module_root, release_dir, project), "-Key"] - else: - cmd = [pboproject, "-P", os.path.join(work_drive, prefix, module), "+Engine=Arma3", "-S","+Noisy", "-X", "+Clean", "+Mod="+os.path.join(module_root, release_dir, project), "-Key"] - - color("grey") - if quiet: - devnull = open(os.devnull, 'w') - ret = subprocess.call(cmd, stdout=devnull) - devnull.close() - else: - ret = subprocess.call(cmd) - color("reset") - - if ret == 0: - print_green("pboProject return code == {}".format(str(ret))) - # Prettyprefix rename the PBO if requested. - if pbo_name_prefix: - try: - os.rename(os.path.join(module_root, release_dir, project, "addons", "{}.pbo".format(module)), os.path.join(module_root, release_dir, project, "addons", "{}{}.pbo".format(pbo_name_prefix,module))) - except: - raise - print_error("Could not rename built PBO with prefix.") - # Sign result - if (key and not "{}{}.pbo".format(pbo_name_prefix,module) in signature_blacklist): - print("Signing with {}.".format(key)) - if pbo_name_prefix: - ret = subprocess.call([dssignfile, key, os.path.join(module_root, release_dir, project, "addons", "{}{}.pbo".format(pbo_name_prefix,module))]) - else: - ret = subprocess.call([dssignfile, key, os.path.join(module_root, release_dir, project, "addons", "{}.pbo".format(module))]) - - if ret == 0: - build_successful = True - else: - build_successful = True - - if not build_successful: - print_error("pboProject return code == {}".format(str(ret))) - print_error("Module not successfully built/signed. Check your {}temp\{}_packing.log for more info.".format(work_drive,module)) - print ("Resuming build...") - failedBuilds.append("{}".format(module)) - continue - - # Back to the root - os.chdir(module_root) - - except: - raise - print_error("Could not run Addon Builder.") - input("Press Enter to continue...") - print ("Resuming build...") - continue - finally: - addon_restore(os.path.join(work_drive, prefix, module)) - - elif build_tool== "addonbuilder": - # Detect $NOBIN$ and do not binarize if found. - if os.path.isfile(os.path.join(work_drive, prefix, module, "$NOBIN$")): - do_binarize = False - print("$NOBIN$ file found in module, packing only.") - else: - do_binarize = True - try: - # Call AddonBuilder - os.chdir("P:\\") - - cmd = [addonbuilder, os.path.join(work_drive, prefix, module), os.path.join(make_root, release_dir, project, "addons"), "-clear", "-project="+work_drive] - if not do_binarize: - cmd.append("-packonly") - - if quiet: - previousDirectory = os.getcwd() - os.chdir(arma3tools_path) - devnull = open(os.devnull, 'w') - ret = subprocess.call(cmd, stdout=devnull) - devnull.close() - os.chdir(previousDirectory) - else: - previousDirectory = os.getcwd() - os.chdir(arma3tools_path) - print_error("Current directory - {}".format(os.getcwd())) - ret = subprocess.call(cmd) - os.chdir(previousDirectory) - print_error("Current directory - {}".format(os.getcwd())) - color("reset") - print_green("completed") - # Prettyprefix rename the PBO if requested. - if pbo_name_prefix: - try: - os.rename(os.path.join(make_root, release_dir, project, "addons", "{}.pbo".format(module)), os.path.join(make_root, release_dir, project, "addons", "{}{}.pbo".format(pbo_name_prefix,module))) - except: - raise - print_error("Could not rename built PBO with prefix.") - - if ret == 0: - # Sign result - - #print_yellow("Sig_fileName: ace_{}.pbo".format(module)) - if (key and not "{}{}.pbo".format(pbo_name_prefix,module) in signature_blacklist) : - print("Signing with {}.".format(key)) - if pbo_name_prefix: - ret = subprocess.call([dssignfile, key, os.path.join(make_root, release_dir, project, "addons","{}{}.pbo".format(pbo_name_prefix,module))]) - else: - ret = subprocess.call([dssignfile, key, os.path.join(make_root, release_dir, project, "addons", "{}.pbo".format(module))]) - - if ret == 0: - build_successful = True - else: - build_successful = True - - if not build_successful: - print_error("Module not successfully built. Check your {}temp\{}_packing.log for more info.".format(work_drive,module)) - - # Back to the root - os.chdir(make_root) - - except: - raise - print_error("Could not run Addon Builder.") - input("Press Enter to continue...") - print ("Resuming build...") - continue - - else: - print_error("Unknown build_tool {}!".format(build_tool)) - - # Update the hash for a successfully built module - if build_successful: - cache[module] = new_sha - - except Exception as e: - print_yellow("Cancel or some error detected: {}".format(e)) - - - finally: - copy_important_files(module_root_parent,os.path.join(release_dir, project)) - if (os.path.isdir(optionals_root)): - cleanup_optionals(optionals_modules) - if not version_update: - restore_version_files() - - # Done building all modules! - - # Write out the cache state - cache_out = json.dumps(cache) - with open(os.path.join(make_root, "make.cache"), 'w') as f: - f.write(cache_out) - - # Delete the pboproject temp files if building a release. - if make_release_zip and build_tool == "pboproject": - try: - shutil.rmtree(os.path.join(release_dir, project, "temp"), True) - except: - print_error("ERROR: Could not delete pboProject temp files.") - - # Make release - if make_release_zip: - release_name = "{}_{}".format(zipPrefix, project_version.rsplit(".", 1)[0]) - - try: - # Delete all log files - for root, dirs, files in os.walk(os.path.join(release_dir, project, "addons")): - for currentFile in files: - if currentFile.lower().endswith("log"): - os.remove(os.path.join(root, currentFile)) - - # Remove all zip files from release folder to prevent zipping the zip - for file in os.listdir(release_dir): - if file.endswith(".zip"): - os.remove(os.path.join(release_dir, file)) - - # Create a zip with the contents of release folder in it - print_blue("\nMaking release: {}.zip ...".format(release_name)) - print("Packing...") - release_zip = shutil.make_archive("{}".format(release_name), "zip", release_dir) - - # Move release zip to release folder - shutil.copy(release_zip, release_dir) - os.remove(release_zip) - except: - raise - print_error("Could not make release.") - - # Copy to Arma 3 folder for testing - if test: - print_blue("\nCopying to Arma 3.") - - if sys.platform == "win32": - reg = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE) - try: - k = winreg.OpenKey(reg, r"SOFTWARE\Wow6432Node\Bohemia Interactive\Arma 3") - a3_path = winreg.EnumValue(k, 1)[1] - winreg.CloseKey(k) - except: - print_error("Could not find Arma 3's directory in the registry.") - else: - a3_path = cygwin_a3path - - print_yellow("Path from the registry => {}".format(a3_path)) - a3_path = test_dir - - print_yellow("Copying build files to {}".format(a3_path)) - - if os.path.exists(a3_path): - try: - shutil.rmtree(os.path.join(a3_path, project), True) - shutil.copytree(os.path.join(module_root, release_dir, project), os.path.join(a3_path, project)) - except: - print_error("Could not copy files. Is Arma 3 running?") - - tracedErrors = len(failedBuilds) + len(missingFiles) - if printedErrors > 0: # printedErrors includes tracedErrors - printedOnlyErrors = printedErrors - tracedErrors - print() - print_error("Failed with {} errors.".format(printedErrors)) - if len(failedBuilds) > 0: - for failedBuild in failedBuilds: - print("- {} build failed!".format(failedBuild)) - if len(missingFiles) > 0: - for missingFile in missingFiles: - print("- {} not found!".format(missingFile)) - if printedOnlyErrors > 0: - print_yellow("- {} untraced error(s)!".format(printedOnlyErrors)) - else: - print_green("\nCompleted with 0 errors.") - - -if __name__ == "__main__": - start_time = timeit.default_timer() - main(sys.argv) - d,h,m,s = Fract_Sec(timeit.default_timer() - start_time) - print("\nTotal Program time elapsed: {0:2}h {1:2}m {2:4.5f}s".format(h,m,s)) - - if ciBuild: - sys.exit(0) - - input("Press Enter to continue...") diff --git a/tools/setup.bat b/tools/setup.bat new file mode 100644 index 0000000..8d7245a --- /dev/null +++ b/tools/setup.bat @@ -0,0 +1,16 @@ +;@Findstr -bv ;@F "%~f0" | powershell -Command - & pause & goto:eof + +Write-Output "=> Downloading ..." +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 + +$url = "https://github.com/BrettMayson/HEMTT/releases/latest/download/windows-x64.zip" +(New-Object Net.WebClient).DownloadFile($url, "hemtt.zip"); Write-Output "$url => hemtt.zip" + +Write-Output "`n=> Extracting ..." +Expand-Archive -Path "hemtt.zip" -DestinationPath "..\." -Force; Write-Output "hemtt.zip" +Remove-Item "hemtt.zip" + +Write-Output "`n=> Verifying ..." +Start-Process -FilePath ..\hemtt.exe -ArgumentList --version -NoNewWindow -Wait + +Write-Output "`nTools successfully installed to project!" diff --git a/tools/setup.py b/tools/setup.py deleted file mode 100644 index 6134943..0000000 --- a/tools/setup.py +++ /dev/null @@ -1,105 +0,0 @@ -#!/usr/bin/env python3 - -####################### -# hatchet_framework Setup Script # -####################### - -import os -import sys -import shutil -import platform -import subprocess -import winreg - -######## GLOBALS ######### -MAINDIR = "x" -PROJECTDIR = "hatchet_framework" -CBA = "P:\\x\\cba" -########################## - -def main(): - FULLDIR = "{}\\{}".format(MAINDIR,PROJECTDIR) - print(""" - ###################################### - # hatchet_framework Development Environment Setup # - ###################################### - - This script will create your hatchet_framework dev environment for you. - - Before you run this, you should already have: - - A properly setup ACE3 Development Environment - - If you have not done those things yet, please abort this script in the next step and do so first. - - This script will create two hard links on your system, both pointing to your hatchet_framework project folder: - [Arma 3 installation directory]\\{} => hatchet_framework project folder - P:\\{} => hatchet_framework project folder - """.format(FULLDIR,FULLDIR)) - print("\n") - - try: - reg = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE) - key = winreg.OpenKey(reg, - r"SOFTWARE\Wow6432Node\bohemia interactive\arma 3") - armapath = winreg.EnumValue(key,1)[1] - except: - print("Failed to determine Arma 3 Path.") - return 1 - - if not os.path.exists("P:\\z\\ace"): - print("No ACE3 Development Environment detected.") - return 2 - - scriptpath = os.path.realpath(__file__) - projectpath = os.path.dirname(os.path.dirname(scriptpath)) - - print("# Detected Paths:") - print(" Arma Path: {}".format(armapath)) - print(" Project Path: {}".format(projectpath)) - - repl = input("\nAre these correct? (y/n): ") - if repl.lower() != "y": - return 3 - - print("\n# Creating links ...") - - if os.path.exists("P:\\{}\\{}".format(MAINDIR,PROJECTDIR)): - print("Link on P: already exists. Please finish the setup manually.") - return 4 - - if os.path.exists(os.path.join(armapath, MAINDIR, PROJECTDIR)): - print("Link in Arma directory already exists. Please finish the setup manually.") - return 5 - - try: - if not os.path.exists("P:\\{}".format(MAINDIR)): - os.mkdir("P:\\{}".format(MAINDIR)) - if not os.path.exists(os.path.join(armapath, MAINDIR)): - os.mkdir(os.path.join(armapath, MAINDIR)) - - if platform.win32_ver()[0] == "7": - subprocess.call(["cmd", "/c", "mklink", "/D", "P:\\{}\\{}".format(MAINDIR,PROJECTDIR), projectpath]) - subprocess.call(["cmd", "/c", "mklink", "/D", os.path.join(armapath, MAINDIR, PROJECTDIR), projectpath]) - else: - subprocess.call(["cmd", "/c", "mklink", "/D", "/J", "P:\\{}\\{}".format(MAINDIR,PROJECTDIR), projectpath]) - subprocess.call(["cmd", "/c", "mklink", "/D", "/J", os.path.join(armapath, MAINDIR, PROJECTDIR), projectpath]) - except: - raise - print("Something went wrong during the link creation. Please finish the setup manually.") - return 6 - - print("# Links created successfully.") - - return 0 - - -if __name__ == "__main__": - exitcode = main() - - if exitcode > 0: - print("\nSomething went wrong during the setup. Make sure you run this script as administrator. If these issues persist, please follow the instructions on the ACE3 wiki to perform the setup manually.") - else: - print("\nSetup successfully completed.") - - input("\nPress enter to exit ...") - sys.exit(exitcode) diff --git a/tools/sqf_validator.py b/tools/sqf_validator.py index 0520007..c338b2d 100644 --- a/tools/sqf_validator.py +++ b/tools/sqf_validator.py @@ -3,217 +3,189 @@ import fnmatch import os import re +import ntpath import sys - - -def valid_keyword_after_code(content, index): - for word in ["for", - "do", - "count", - "each", - "forEach", - "else", - "and", - "not", - "isEqualTo", - "in", - "call", - "spawn", - "execVM", - "catch", - "param", - "select", - "apply", - "findIf", - "remoteExec"]: - if content.find(word, index, index + len(word)) != -1: - return True - +import argparse + +def validKeyWordAfterCode(content, index): + keyWords = ["for", "do", "count", "each", "forEach", "else", "and", "not", "isEqualTo", "in", "call", "spawn", "execVM", "catch", "param", "select", "apply", "findIf", "remoteExec"]; + for word in keyWords: + try: + subWord = content.index(word, index, index+len(word)) + return True; + except: + pass return False +def check_sqf_syntax(filepath): + bad_count_file = 0 + def pushClosing(t): + closingStack.append(closing.expr) + closing << Literal( closingFor[t[0]] ) -def check_sqf(filepath): - errors = [] + def popClosing(): + closing << closingStack.pop() - with open(filepath, "r", encoding="utf-8", errors="ignore") as file: + with open(filepath, 'r', encoding='utf-8', errors='ignore') as file: content = file.read() # Store all brackets we find in this file, so we can validate everything on the end - brackets = [] - - # Used in case we are in a line comment (//) - ignore_till_eol = False + brackets_list = [] # To check if we are in a comment block - in_comment_block = False - check_if_comment = False - - # Used in case we are in a comment block (/* */) - # This is true if we detect a * inside a comment block - # If the next character is a /, it means we end our comment block - check_if_closing = False + isInCommentBlock = False + checkIfInComment = False + # Used in case we are in a line comment (//) + ignoreTillEndOfLine = False + # Used in case we are in a comment block (/* */). This is true if we detect a * inside a comment block. + # If the next character is a /, it means we end our comment block. + checkIfNextIsClosingBlock = False # We ignore everything inside a string - in_string = False - + isInString = False # Used to store the starting type of a string, so we can match that to the end of a string - string_type = "" + inStringType = ''; - # Used to check for semicolon after code blocks - last_is_curly_brace = False - check_for_semicolon = False + lastIsCurlyBrace = False + checkForSemicolon = False + onlyWhitespace = True # Extra information so we know what line we find errors at - line_number = 1 - - char_index = 0 + lineNumber = 1 + indexOfCharacter = 0 + # Parse all characters in the content of this file to search for potential errors for c in content: - if last_is_curly_brace: - last_is_curly_brace = False - + if (lastIsCurlyBrace): + lastIsCurlyBrace = False # Test generates false positives with binary commands that take CODE as 2nd arg (e.g. findIf) - check_for_semicolon = not re.search( - "findIf", content, re.IGNORECASE) - - # Keep track of current line number - if c == "\n": - line_number += 1 - - # While we are in a string, we can ignore everything else, except the end of the string - if in_string: - if c == string_type: - in_string = False - - # Look for the end of this comment block - elif in_comment_block: - if c == "*": - check_if_closing = True - elif check_if_closing: - if c == "/": - in_comment_block = False - elif c != "*": - check_if_closing = False - - # If we are not in a comment block, we will check if we are at the start of one or count the () {} and [] - else: - # This means we have encountered a /, so we are now checking if this is an inline comment or a comment block - if check_if_comment: - check_if_comment = False - - # If the next character after / is a *, we are at the start of a comment block - if c == "*": - in_comment_block = True - - # Otherwise, check if we are in an line comment, / followed by another / (//) - elif c == "/": - ignore_till_eol = True - - if not in_comment_block: - if ignore_till_eol: - # We are in a line comment, just continue going through the characters until we find an end of line - if c == "\n": - ignore_till_eol = False - else: - if c == '"' or c == "'": - in_string = True - string_type = c - elif c == "/": - check_if_comment = True - elif c == "\t": - errors.append( - f" ERROR: Found a tab on line {line_number}.") - elif c in ["(", "[", "{"]: - brackets.append(c) - elif c == ")": - if not brackets or brackets[-1] in ["[", "{"]: - errors.append( - f" ERROR: Missing parenthesis '(' on line {line_number}.") - brackets.append(c) - elif c == "]": - if not brackets or brackets[-1] in ["(", "{"]: - errors.append( - " ERROR: Missing square bracket '[' on line {line_number}.") - brackets.append(c) - elif c == "}": - last_is_curly_brace = True - - if not brackets or brackets[-1] in ["(", "["]: - errors.append(f" ERROR: Missing curly brace {{ on line {line_number}.") - brackets.append(c) - - if check_for_semicolon: - # Keep reading until no white space or comments - if c not in [" ", "\t", "\n", "/"]: - check_for_semicolon = False - if c not in ["]", ")", "}", ";", ",", "&", "!", "|", "="] and not valid_keyword_after_code(content, char_index): - errors.append(f" ERROR: Possible missing semicolon ';' on line {line_number}.") - char_index += 1 - - # Compare opening and closing bracket counts - if brackets.count("(") != brackets.count(")"): - errors.append(" ERROR: Unequal number of parentheses, '(' = {}, ')' = {}.".format( - brackets.count("("), brackets.count(")"))) - - if brackets.count("[") != brackets.count("]"): - errors.append(" ERROR: Unequal number of square brackets, '[' = {}, ']' = {}.".format( - brackets.count("["), brackets.count("]"))) - - if brackets.count("{") != brackets.count("}"): - errors.append(" ERROR: Unequal number of curly braces, '{{' = {}, '}}' = {}.".format( - brackets.count("{"), brackets.count("}"))) - - # Ensure includes are before block comments - if re.compile('\s*(/\*[\s\S]+?\*/)\s*#include').match(content): - errors.append(" ERROR: Found an #include after a block comment.") - - return errors - - -def main(): - print(f""" -Validating SQF expect errors ------------------- - """) + checkForSemicolon = not re.search('findIf', content, re.IGNORECASE) - # Allow running from root directory and tools directory - root_dir = ".." - if os.path.exists("addons"): - root_dir = "." + if c == '\n': # Keeping track of our line numbers + onlyWhitespace = True # reset so we can see if # is for a preprocessor command + lineNumber += 1 # so we can print accurate line number information when we detect a possible error + if (isInString): # while we are in a string, we can ignore everything else, except the end of the string + if (c == inStringType): + isInString = False + # if we are not in a comment block, we will check if we are at the start of one or count the () {} and [] + elif (isInCommentBlock == False): - # Check all SQF files in the project directory - sqf_files = [] + # This means we have encountered a /, so we are now checking if this is an inline comment or a comment block + if (checkIfInComment): + checkIfInComment = False + if c == '*': # if the next character after / is a *, we are at the start of a comment block + isInCommentBlock = True + elif (c == '/'): # Otherwise, will check if we are in an line comment + ignoreTillEndOfLine = True # and an line comment is a / followed by another / (//) We won't care about anything that comes after it + + if (isInCommentBlock == False): + if (ignoreTillEndOfLine): # we are in a line comment, just continue going through the characters until we find an end of line + if (c == '\n'): + ignoreTillEndOfLine = False + else: # validate brackets + if (c == '"' or c == "'"): + isInString = True + inStringType = c + elif (c == '#' and onlyWhitespace): + ignoreTillEndOfLine = True + elif (c == '/'): + checkIfInComment = True + elif (c == '('): + brackets_list.append('(') + elif (c == ')'): + if (brackets_list[-1] in ['{', '[']): + print("ERROR: Possible missing round bracket ')' detected at {0} Line number: {1}".format(filepath,lineNumber)) + bad_count_file += 1 + brackets_list.append(')') + elif (c == '['): + brackets_list.append('[') + elif (c == ']'): + if (brackets_list[-1] in ['{', '(']): + print("ERROR: Possible missing square bracket ']' detected at {0} Line number: {1}".format(filepath,lineNumber)) + bad_count_file += 1 + brackets_list.append(']') + elif (c == '{'): + brackets_list.append('{') + elif (c == '}'): + lastIsCurlyBrace = True + if (brackets_list[-1] in ['(', '[']): + print("ERROR: Possible missing curly brace '}}' detected at {0} Line number: {1}".format(filepath,lineNumber)) + bad_count_file += 1 + brackets_list.append('}') + elif (c== '\t'): + print("ERROR: Tab detected at {0} Line number: {1}".format(filepath,lineNumber)) + bad_count_file += 1 + + if (c not in [' ', '\t', '\n']): + onlyWhitespace = False + + if (checkForSemicolon): + if (c not in [' ', '\t', '\n', '/']): # keep reading until no white space or comments + checkForSemicolon = False + if (c not in [']', ')', '}', ';', ',', '&', '!', '|', '='] and not validKeyWordAfterCode(content, indexOfCharacter)): # , 'f', 'd', 'c', 'e', 'a', 'n', 'i']): + print("ERROR: Possible missing semicolon ';' detected at {0} Line number: {1}".format(filepath,lineNumber)) + bad_count_file += 1 + + else: # Look for the end of our comment block + if (c == '*'): + checkIfNextIsClosingBlock = True; + elif (checkIfNextIsClosingBlock): + if (c == '/'): + isInCommentBlock = False + elif (c != '*'): + checkIfNextIsClosingBlock = False + indexOfCharacter += 1 + + if brackets_list.count('[') != brackets_list.count(']'): + print("ERROR: A possible missing square bracket [ or ] in file {0} [ = {1} ] = {2}".format(filepath,brackets_list.count('['),brackets_list.count(']'))) + bad_count_file += 1 + if brackets_list.count('(') != brackets_list.count(')'): + print("ERROR: A possible missing round bracket ( or ) in file {0} ( = {1} ) = {2}".format(filepath,brackets_list.count('('),brackets_list.count(')'))) + bad_count_file += 1 + if brackets_list.count('{') != brackets_list.count('}'): + print("ERROR: A possible missing curly brace {{ or }} in file {0} {{ = {1} }} = {2}".format(filepath,brackets_list.count('{'),brackets_list.count('}'))) + bad_count_file += 1 + pattern = re.compile('\s*(/\*[\s\S]+?\*/)\s*#include') + if pattern.match(content): + print("ERROR: A found #include after block comment in file {0}".format(filepath)) + bad_count_file += 1 + + + + return bad_count_file - for root, _, files in os.walk(root_dir): - for file in fnmatch.filter(files, "*.sqf"): - sqf_files.append(os.path.join(root, file)) +def main(): - sqf_files.sort() + print("Validating SQF") + sqf_list = [] bad_count = 0 - for filepath in sqf_files: - errors = check_sqf(filepath) + parser = argparse.ArgumentParser() + parser.add_argument('-m','--module', help='only search specified module addon folder', required=False, default="") + args = parser.parse_args() - if errors: - print( - f"Found {len(errors)} error(s) in {os.path.relpath(filepath, root_dir)}: ") + for folder in ['addons', 'optionals']: + # Allow running from root directory as well as from inside the tools directory + rootDir = "../" + folder + if (os.path.exists(folder)): + rootDir = folder - for error in errors: - print(error) + for root, dirnames, filenames in os.walk(rootDir + '/' + args.module): + for filename in fnmatch.filter(filenames, '*.sqf'): + sqf_list.append(os.path.join(root, filename)) - bad_count += 1 + for filename in sqf_list: + bad_count = bad_count + check_sqf_syntax(filename) - print("\nChecked {} files, found errors in {}.".format( - len(sqf_files), bad_count)) - if bad_count == 0: - print("SQF Validation PASSED") + print("------\nChecked {0} files\nErrors detected: {1}".format(len(sqf_list), bad_count)) + if (bad_count == 0): + print("SQF validation PASSED") else: - print("SQF Validation FAILED") + print("SQF validation FAILED") return bad_count - if __name__ == "__main__": sys.exit(main())