NFG WhatHiMean 0 Posted October 24, 2023 I'm attempting to make a script for dynamic civ vehicle spawns in a city, right now I have my idea down on how I want to do it but I can't implement it properly. I'm still new to scripting and can't figure out exactly what I'm doing wrong here. Thanks for the help in advance! Spoiler // Define markers for the city of Voskovo _VoskovoMarkers = [ "voskovoMarker", "voskovoMarker_1", "voskovoMarker_2", "voskovoMarker_3", "voskovoMarker_4", "voskovoMarker_5", "voskovoMarker_6", "voskovoMarker_7", "voskovoMarker_8", "voskovoMarker_9", "voskovoMarker_10", "voskovoMarker_11" ]; // Define vehicles with their corresponding spawn weights (in percentages) _vehiclesWithWeights = [ ["C_Hatchback_01_F", 20], ["C_Hatchback_01_sport_F", 6], ["C_Offroad_02_unarmed_F", 14], ["C_Offroad_01_F", 20], ["C_SUV_01_F", 20], ["C_Van_01_transport_F", 5], ["RHS_Ural_Civ_01", 5], ["RHS_Ural_Civ_02", 5], ["RHS_Ural_Civ_03", 5] ]; // Function to pick a random vehicle based on weights pickRandomVehicle = { params ["_vehicles"]; _totalWeight = 0; // Calculate total weight and display a debug message { _totalWeight = _totalWeight + _x select 1; systemChat format["Adding %1 weight. Total weight: %2", _x select 1, _totalWeight]; } forEach _vehicles; _randomNum = random _totalWeight; // Display a debug message for random number generated systemChat format["Random Number: %1", _randomNum]; // Iterate through vehicles to find the one to spawn { if (_randomNum <= _x select 1) then { _result = _x select 0; systemChat format["Selected Vehicle: %1", _result]; return; }; _randomNum = _randomNum - (_x select 1); } forEach _vehicles; // Display a debug message if no vehicle is selected systemChat "No vehicle selected!"; }; // Iterate through each Voskovo marker and spawn a vehicle with debug messages _spawnedVehicles = []; { // Pick a random marker and get its position and rotation [_markerPos, _markerDir] = pickRandomMarker(_x); // Pick a random vehicle based on weights _vehicleClass = pickRandomVehicle(_vehiclesWithWeights); // Spawn the selected vehicle at the marker position with the specified rotation _vehicle = _vehicleClass createVehicle [_markerPos, [], 0, "NONE"]; _vehicle setDir _markerDir; // Store spawned vehicle information for future reference if needed _spawnedVehicles pushBack _vehicle; // Display a debug message for the spawned vehicle systemChat format["Spawned Vehicle: %1 at Marker: %2", _vehicleClass, _x]; } forEach _VoskovoMarkers; // Iterate through Voskovo markers I'm kinda lost atm, maybe I've been working on this too long lol Share this post Link to post Share on other sites
mrcurry 496 Posted October 24, 2023 1 hour ago, NFG WhatHiMean said: I'm attempting to make a script for dynamic civ vehicle spawns in a city, right now I have my idea down on how I want to do it but I can't implement it properly. I'm still new to scripting and can't figure out exactly what I'm doing wrong here. Thanks for the help in advance! Reveal hidden contents // Define markers for the city of Voskovo _VoskovoMarkers = [ "voskovoMarker", "voskovoMarker_1", "voskovoMarker_2", "voskovoMarker_3", "voskovoMarker_4", "voskovoMarker_5", "voskovoMarker_6", "voskovoMarker_7", "voskovoMarker_8", "voskovoMarker_9", "voskovoMarker_10", "voskovoMarker_11" ]; // Define vehicles with their corresponding spawn weights (in percentages) _vehiclesWithWeights = [ ["C_Hatchback_01_F", 20], ["C_Hatchback_01_sport_F", 6], ["C_Offroad_02_unarmed_F", 14], ["C_Offroad_01_F", 20], ["C_SUV_01_F", 20], ["C_Van_01_transport_F", 5], ["RHS_Ural_Civ_01", 5], ["RHS_Ural_Civ_02", 5], ["RHS_Ural_Civ_03", 5] ]; // Function to pick a random vehicle based on weights pickRandomVehicle = { params ["_vehicles"]; _totalWeight = 0; // Calculate total weight and display a debug message { _totalWeight = _totalWeight + _x select 1; systemChat format["Adding %1 weight. Total weight: %2", _x select 1, _totalWeight]; } forEach _vehicles; _randomNum = random _totalWeight; // Display a debug message for random number generated systemChat format["Random Number: %1", _randomNum]; // Iterate through vehicles to find the one to spawn { if (_randomNum <= _x select 1) then { _result = _x select 0; systemChat format["Selected Vehicle: %1", _result]; return; }; _randomNum = _randomNum - (_x select 1); } forEach _vehicles; // Display a debug message if no vehicle is selected systemChat "No vehicle selected!"; }; // Iterate through each Voskovo marker and spawn a vehicle with debug messages _spawnedVehicles = []; { // Pick a random marker and get its position and rotation [_markerPos, _markerDir] = pickRandomMarker(_x); // Pick a random vehicle based on weights _vehicleClass = pickRandomVehicle(_vehiclesWithWeights); // Spawn the selected vehicle at the marker position with the specified rotation _vehicle = _vehicleClass createVehicle [_markerPos, [], 0, "NONE"]; _vehicle setDir _markerDir; // Store spawned vehicle information for future reference if needed _spawnedVehicles pushBack _vehicle; // Display a debug message for the spawned vehicle systemChat format["Spawned Vehicle: %1 at Marker: %2", _vehicleClass, _x]; } forEach _VoskovoMarkers; // Iterate through Voskovo markers I'm kinda lost atm, maybe I've been working on this too long lol I recommend checking out the syntax pages on the biki again 😉 SQF does not have all the neat features many modern languages do. Spoiler // Define markers for the city of Voskovo private _VoskovoMarkers = [ //-- This is fine, I would put a private keyword ahead as good practice to avoid overriding variables in the caller's scope "voskovoMarker", "voskovoMarker_1", "voskovoMarker_2", "voskovoMarker_3", "voskovoMarker_4", "voskovoMarker_5", "voskovoMarker_6", "voskovoMarker_7", "voskovoMarker_8", "voskovoMarker_9", "voskovoMarker_10", "voskovoMarker_11" ]; // Define vehicles with their corresponding spawn weights (in percentages) private _vehiclesWithWeights = [ //-- Same as above ["C_Hatchback_01_F", 20], ["C_Hatchback_01_sport_F", 6], ["C_Offroad_02_unarmed_F", 14], ["C_Offroad_01_F", 20], ["C_SUV_01_F", 20], ["C_Van_01_transport_F", 5], ["RHS_Ural_Civ_01", 5], ["RHS_Ural_Civ_02", 5], ["RHS_Ural_Civ_03", 5] ]; // Function to pick a random vehicle based on weights, private _pickRandomVehicle = { //-- Note that any variable that doesn't start with '_' will be declared as a 'global' variable in missionNamespace and be accessible in all scripts for the duration of the session, to be avoided unless required. //-- Again good practice to use 'private' keyword params ["_vehicles"]; private _totalWeight = 0; // Calculate total weight and display a debug message { _totalWeight = _totalWeight + (_x select 1); //-- Brackets added since + takes precedence over select, could have also changed select to a # systemChat format["Adding %1 weight. Total weight: %2", _x select 1, _totalWeight]; } forEach _vehicles; private _randomNum = random _totalWeight; // Display a debug message for random number generated systemChat format["Random Number: %1", _randomNum]; // -- Define _result for return private _result = ""; // Iterate through vehicles to find the one to spawn { if (_randomNum <= _x select 1) then { _result = _x select 0; systemChat format["Selected Vehicle: %1", _result]; //-- return is not a valid keyword in SQF, instead the result of the last executed statement in the code is always returned, therefore we put _result; to be "executed" at the end. //-- We still have to break the loop though, for that we can use break; //return; break; }; _randomNum = _randomNum - (_x select 1); } forEach _vehicles; // -- Since we can't easily just return in SQF we have to check our data at the end of the loop if( _result == "" ) exitWith { // Display a debug message if no vehicle is selected systemChat "No vehicle selected!"; }; // Return _result; }; // Iterate through each Voskovo marker and spawn a vehicle with debug messages private _spawnedVehicles = []; { // Pick a random marker and get its position and rotation //-- Nope no need, '_x' already contains the current element of the array, magic variables ftw... //[_markerPos, _markerDir] = pickRandomMarker(_x); private _marker = _x; private _markerPos = markerPos _marker; private _markerDir = markerDir _marker; // Pick a random vehicle based on weights // -- Note that functions in SQF are just a variable pointing to data of CODE-type hence we can't directly execute them // -- We need to use call (synchronous, can return) or spawn (asynchronous, cannot return) private _vehicleClass = [_vehiclesWithWeights] call _pickRandomVehicle; // -- We could also use command 'selectRandomWeighted' but that requires a special format on the array and would be less educational ;) // Spawn the selected vehicle at the marker position with the specified rotation // -- createVehicle requires all parameters on the right hand side when using the extended syntax private _vehicle = createVehicle [_vehicleClass, _markerPos, [], 0, "NONE"]; _vehicle setDir _markerDir; // Store spawned vehicle information for future reference if needed _spawnedVehicles pushBack _vehicle; // Display a debug message for the spawned vehicle systemChat format["Spawned Vehicle: %1 at Marker: %2", _vehicleClass, _x]; } forEach _VoskovoMarkers; // Iterate through Voskovo markers // For testing TST_vehicles = _spawnedVehicles; 1 Share this post Link to post Share on other sites
NFG WhatHiMean 0 Posted October 24, 2023 33 minutes ago, mrcurry said: I recommend checking out the syntax pages on the biki again 😉 SQF does not have all the neat features many modern languages do. Hide contents // Define markers for the city of Voskovo private _VoskovoMarkers = [ //-- This is fine, I would put a private keyword ahead as good practice to avoid overriding variables in the caller's scope "voskovoMarker", "voskovoMarker_1", "voskovoMarker_2", "voskovoMarker_3", "voskovoMarker_4", "voskovoMarker_5", "voskovoMarker_6", "voskovoMarker_7", "voskovoMarker_8", "voskovoMarker_9", "voskovoMarker_10", "voskovoMarker_11" ]; // Define vehicles with their corresponding spawn weights (in percentages) private _vehiclesWithWeights = [ //-- Same as above ["C_Hatchback_01_F", 20], ["C_Hatchback_01_sport_F", 6], ["C_Offroad_02_unarmed_F", 14], ["C_Offroad_01_F", 20], ["C_SUV_01_F", 20], ["C_Van_01_transport_F", 5], ["RHS_Ural_Civ_01", 5], ["RHS_Ural_Civ_02", 5], ["RHS_Ural_Civ_03", 5] ]; // Function to pick a random vehicle based on weights, private _pickRandomVehicle = { //-- Note that any variable that doesn't start with '_' will be declared as a 'global' variable in missionNamespace and be accessible in all scripts for the duration of the session, to be avoided unless required. //-- Again good practice to use 'private' keyword params ["_vehicles"]; private _totalWeight = 0; // Calculate total weight and display a debug message { _totalWeight = _totalWeight + (_x select 1); //-- Brackets added since + takes precedence over select, could have also changed select to a # systemChat format["Adding %1 weight. Total weight: %2", _x select 1, _totalWeight]; } forEach _vehicles; private _randomNum = random _totalWeight; // Display a debug message for random number generated systemChat format["Random Number: %1", _randomNum]; // -- Define _result for return private _result = ""; // Iterate through vehicles to find the one to spawn { if (_randomNum <= _x select 1) then { _result = _x select 0; systemChat format["Selected Vehicle: %1", _result]; //-- return is not a valid keyword in SQF, instead the result of the last executed statement in the code is always returned, therefore we put _result; to be "executed" at the end. //-- We still have to break the loop though, for that we can use break; //return; break; }; _randomNum = _randomNum - (_x select 1); } forEach _vehicles; // -- Since we can't easily just return in SQF we have to check our data at the end of the loop if( _result == "" ) exitWith { // Display a debug message if no vehicle is selected systemChat "No vehicle selected!"; }; // Return _result; }; // Iterate through each Voskovo marker and spawn a vehicle with debug messages private _spawnedVehicles = []; { // Pick a random marker and get its position and rotation //-- Nope no need, '_x' already contains the current element of the array, magic variables ftw... //[_markerPos, _markerDir] = pickRandomMarker(_x); private _marker = _x; private _markerPos = markerPos _marker; private _markerDir = markerDir _marker; // Pick a random vehicle based on weights // -- Note that functions in SQF are just a variable pointing to data of CODE-type hence we can't directly execute them // -- We need to use call (synchronous, can return) or spawn (asynchronous, cannot return) private _vehicleClass = [_vehiclesWithWeights] call _pickRandomVehicle; // -- We could also use command 'selectRandomWeighted' but that requires a special format on the array and would be less educational ;) // Spawn the selected vehicle at the marker position with the specified rotation // -- createVehicle requires all parameters on the right hand side when using the extended syntax private _vehicle = createVehicle [_vehicleClass, _markerPos, [], 0, "NONE"]; _vehicle setDir _markerDir; // Store spawned vehicle information for future reference if needed _spawnedVehicles pushBack _vehicle; // Display a debug message for the spawned vehicle systemChat format["Spawned Vehicle: %1 at Marker: %2", _vehicleClass, _x]; } forEach _VoskovoMarkers; // Iterate through Voskovo markers // For testing TST_vehicles = _spawnedVehicles; This is super helpful! Love the comments! 🙂 I realize now that I didn't implement it the way I wanted it. I plan to run this script for multiple cities and I want only one or two vehicles to spawn instead of every marker spawning. Quick other question is there a way to change the loading screen from whatever map to a custom image? I've looked around for a answer and I couldn't find anything other then the tiny loading image which I got working fine. Spoiler // Define markers for the city of Voskovo private _VoskovoMarkers = [ //-- This is fine, I would put a private keyword ahead as good practice to avoid overriding variables in the caller's scope "voskovoMarker", "voskovoMarker_1", "voskovoMarker_2", "voskovoMarker_3", "voskovoMarker_4", "voskovoMarker_5", "voskovoMarker_6", "voskovoMarker_7", "voskovoMarker_8", "voskovoMarker_9", "voskovoMarker_10", "voskovoMarker_11" ]; private _VelikayaMarkers = [ "velikayaMaker", "velikayaMaker_1", "velikayaMaker_2", "velikayaMaker_3", "velikayaMaker_4", "velikayaMaker_5", "velikayaMaker_6", "velikayaMaker_7", "velikayaMaker_8", "velikayaMaker_9", "velikayaMaker_10", "velikayaMaker_11", "velikayaMaker_12", "velikayaMaker_13", "velikayaMaker_14", "velikayaMaker_15" ]; // Define vehicles with their corresponding spawn weights (in percentages) private _vehiclesWithWeights = [ //-- Same as above ["C_Hatchback_01_F", 20], ["C_Hatchback_01_sport_F", 6], ["C_Offroad_02_unarmed_F", 14], ["C_Offroad_01_F", 20], ["C_SUV_01_F", 20], ["C_Van_01_transport_F", 5], ["RHS_Ural_Civ_01", 5], ["RHS_Ural_Civ_02", 5], ["RHS_Ural_Civ_03", 5] ]; // Function to pick a random vehicle based on weights, private _pickRandomVehicle = { //-- Note that any variable that doesn't start with '_' will be declared as a 'global' variable in missionNamespace and be accessible in all scripts for the duration of the session, to be avoided unless required. //-- Again good practice to use 'private' keyword params ["_vehicles"]; private _totalWeight = 0; // Calculate total weight and display a debug message { _totalWeight = _totalWeight + (_x select 1); //-- Brackets added since + takes precedence over select, could have also changed select to a # systemChat format["Adding %1 weight. Total weight: %2", _x select 1, _totalWeight]; } forEach _vehicles; private _randomNum = random _totalWeight; // Display a debug message for random number generated systemChat format["Random Number: %1", _randomNum]; // -- Define _result for return private _result = ""; // Iterate through vehicles to find the one to spawn { if (_randomNum <= _x select 1) then { _result = _x select 0; systemChat format["Selected Vehicle: %1", _result]; //-- return is not a valid keyword in SQF, instead the result of the last executed statement in the code is always returned, therefore we put _result; to be "executed" at the end. //-- We still have to break the loop though, for that we can use break; //return; break; }; _randomNum = _randomNum - (_x select 1); } forEach _vehicles; // -- Since we can't easily just return in SQF we have to check our data at the end of the loop if( _result == "" ) exitWith { // Display a debug message if no vehicle is selected systemChat "No vehicle selected!"; }; // Return _result; }; // Iterate through each Voskovo marker and spawn a vehicle with debug messages private _voskSpawnedVehicles = []; { private _marker = _x; private _markerPos = markerPos _marker; private _markerDir = markerDir _marker; // Pick a random vehicle based on weights // -- Note that functions in SQF are just a variable pointing to data of CODE-type hence we can't directly execute them // -- We need to use call (synchronous, can return) or spawn (asynchronous, cannot return) private _vehicleClass = [_vehiclesWithWeights] call _pickRandomVehicle; // -- We could also use command 'selectRandomWeighted' but that requires a special format on the array and would be less educational 😉 // Spawn the selected vehicle at the marker position with the specified rotation // -- createVehicle requires all parameters on the right hand side when using the extended syntax private _vehicle = createVehicle [_vehicleClass, _markerPos, [], 0, "NONE"]; _vehicle setDir _markerDir; _voskSpawnedVehicles pushBack _vehicle; // Display a debug message for the spawned vehicle systemChat format["Spawned Vehicle: %1 at Marker: %2", _vehicleClass, _x]; } forEach _VoskovoMarkers; private _veliSpawnedVehicles = []; { private _marker = _x; private _markerPos = markerPos _marker; private _markerDir = markerDir _marker; private _vehicleClass = [_vehiclesWithWeights] call _pickRandomVehicle; private _vehicle = createVehicle [_vehicleClass, _markerPos, [], 0, "NONE"]; _vehicle setDir _markerDir; _veliSpawnedVehicles pushBack _vehicle; systemChat format["Spawned Vehicle: %1 at Marker: %2", _vehicleClass, _x]; } forEach _VelikayaMarkers; I'm not that great at coding (chatgpt is genuinely useful for this lmao, that's part of why the syntax was wrong) Share this post Link to post Share on other sites
mrcurry 496 Posted October 25, 2023 9 hours ago, NFG WhatHiMean said: Quick other question is there a way to change the loading screen from whatever map to a custom image? https://community.bistudio.com/wiki/Arma_3:_Loading_Screens Share this post Link to post Share on other sites
NFG WhatHiMean 0 Posted October 25, 2023 8 hours ago, mrcurry said: https://community.bistudio.com/wiki/Arma_3:_Loading_Screens Thanks, guess I'm not very good at searching lol Share this post Link to post Share on other sites