-
Content Count
204 -
Joined
-
Last visited
-
Medals
Everything posted by Luft08
-
Taking control of AI units without interrupting what they are doing.
Luft08 posted a topic in ARMA 3 - MISSION EDITING & SCRIPTING
I am making a multiplayer mission in which a player takes control of a convoy in order to give it waypoints. The convoy starts parked along a road. The problem I'm having is that when the player takes control some of the vehicles start moving. I have already set their formation to single file. I'm not sure why this is happening or how to stop it. My code should allow a player to take control of the convoy without interrupting the convoy's actions. I add a custom menu to whichever player has a particular object (Radio) and remove it when they relinquish it. Here is some of the code: // Important!! Run these on both client and server. // LFT_ConvoyControlFunctions.sqf /* * Function: LFT_AddConvoyMenu * Parameters: * _player - Object: The player to add the convoy control menu actions to. * Returns: * None * Description: * Adds custom menu actions to the player for transferring and removing convoy control. */ LFT_AddConvoyMenu = { params ["_player"]; // Check if convoy actions already exist private _existingActions = _player getVariable ["convoyActions", []]; if (count _existingActions > 0) exitWith {}; // Add convoy control actions private _transferActionId = _player addAction ["Transfer convoy control", { params ["_player"]; // Transfer control of the convoy to the player [_player] call LFT_TransferAIGroupToPlayer; }]; private _removeActionId = _player addAction ["Remove convoy control", { params ["_player"]; // Remove control of the convoy from the player [_player] call LFT_TransferControlBackToAI; }]; // Store the action IDs _player setVariable ["convoyActions", [_transferActionId, _removeActionId], true]; }; /* * Function: LFT_RemoveConvoyMenu * Parameters: * _player - Object: The player to remove the convoy control menu actions from. * Returns: * None * Description: * Removes all convoy-related custom menu actions from the player. */ LFT_RemoveConvoyMenu = { params ["_player"]; private _actionIds = _player getVariable ["convoyActions", []]; { _player removeAction _x; } forEach _actionIds; _player setVariable ["convoyActions", nil, true]; [_player] call LFT_TransferControlBackToAI; }; /* * Function: LFT_TransferAIGroupToPlayer * Parameters: * _player - Object: The player to transfer control to. * Returns: * None * Description: * Transfers control of the AI group to the player and makes the player the leader. */ LFT_TransferAIGroupToPlayer = { params ["_player"]; originalPlayerGroup = group _player; if (originalPlayerGroup == group convoyCommander) exitWith {}; // Transfer all units from the original group to the player's group (units originalCommanderGroup) joinSilent originalPlayerGroup; // Select the player as the leader of the new group originalPlayerGroup selectLeader _player; [originalPlayerGroup, _player] remoteExec ["selectLeader", groupOwner originalPlayerGroup]; }; /* * Function: LFT_TransferControlBackToAI * Parameters: * _player - Object: The player to transfer control from. * Returns: * None * Description: * Transfers control of the AI group back to the original AI leader and makes the original AI unit the leader. */ LFT_TransferControlBackToAI = { params ["_player"]; // Check if originalCommanderGroup is null and create a new group if necessary if (isNull originalCommanderGroup) then { originalCommanderGroup = createGroup west; }; { [_x] joinSilent originalCommanderGroup; } forEach units group _player; originalCommanderGroup selectLeader convoyCommander; [originalCommanderGroup, convoyCommander] remoteExec ["selectLeader", groupOwner originalCommanderGroup]; [_player] joinSilent originalPlayerGroup; [originalPlayerGroup, _player] remoteExec ["selectLeader", groupOwner originalPlayerGroup]; }; -
Querying a map's Default Traffic Signs for info
Luft08 posted a topic in ARMA 3 - MISSION EDITING & SCRIPTING
I have noticed that I cannot get the facing information for default traffic signs on a map. Are traffic signs that are placed on a map by default special? Do I need to use some other method (Not getDir Object) to get their facing direction? The command getDir for a default sign always returns 0. -
Querying a map's Default Traffic Signs for info
Luft08 replied to Luft08's topic in ARMA 3 - MISSION EDITING & SCRIPTING
I have an idea that I need to play around with. What if I create a bounding box around the traffic sign. Can I: 1. Create a bounding box around static terrain objects. 2. Get the static terrain object facing using a bounding box. I'll play around with it for a while. -
Spawning units that show up in the lobby
Luft08 posted a topic in ARMA 3 - MISSION EDITING & SCRIPTING
I want to spawn a convoy and then allow players to select any unit in that convoy they wish to play. I have a script that spawns a convoy that gets run in the initServer script. The LFT_CreateConvoy function uses BIS_fnc_spawnVehicle for each vehicle type which produce an array [vehicle, crewArray, group] which I pushBack into a global array LFT_Convoy: if(!isServer) exitWith {}; private _vehicleTypes = ["B_APC_Wheeled_01_cannon_F", "B_Truck_01_ammo_F", "B_Truck_01_medical_F", "B_Truck_01_fuel_F", "B_Truck_01_Repair_F", "B_Truck_01_transport_F", "B_MRAP_01_hmg_F"]; private _side = west; private _startPos = [11328.6,3241.32,0]; private _spacing = 25; private _direction = 304.631; LFT_Convoy = [_vehicleTypes, _startPos, _side, _spacing, _direction] call LFT_CreateConvoy; { // Extract the crew array from the current element of Lft_Convoy private _crewArray = _x select 1; // Iterate over each element in the crew array { // Set the variable "playable" to true for each crew member _x setVariable ["playable", true]; } forEach _crewArray; } forEach Lft_Convoy; This code gets run in the initServer script. I believe that is before the lobby but when the lobby is displayed there are no slots available. Can spawned units be made to appear in the lobby? -
Making Ambient Traffic Obey Stop Signs
Luft08 posted a topic in ARMA 3 - MISSION EDITING & SCRIPTING
I'm trying to write a function to alert me when a vehicle is approaching a stop sign. I'm having difficulty finding a way to determine if the sign is facing the vehicle. What I have so far: LFT_ShouldReactToSign = { params ["_vehicle", "_signClassName", "_detectionRange"]; // Get the model path from the class name private _signModelPath = getText (configFile >> "CfgVehicles" >> _signClassName >> "model"); // Get the position and direction of the vehicle private _vehiclePos = getPos _vehicle; private _vehicleDir = getDir _vehicle; // Log vehicle direction for debugging diag_log format ["Vehicle Direction: %1", _vehicleDir]; // Find the nearest objects within the specified detection range private _nearbyObjects = nearestObjects [_vehiclePos, [], _detectionRange]; // Check each object to see if it matches the sign model path { private _objectModelInfo = getModelInfo _x; private _objectModelPath = _objectModelInfo select 1; if (_objectModelPath == _signModelPath) then { private _signPos = getPos _x; private _signDir = getDir _x; // Get the facing direction of the sign // Log sign direction for debugging diag_log format ["Sign Direction: %1", _signDir]; private _distanceToSign = _vehicle distance _signPos; private _directionToSign = _vehiclePos getDir _signPos; // Check if the sign is in front of the vehicle and within a certain distance if (_distanceToSign < _detectionRange && abs(_vehicleDir - _directionToSign) < 45) then { // Check if the sign is facing the vehicle if (abs((_signDir - 180) - _vehicleDir) < 45) then { // Additional checks can be added here to ensure the sign is for the vehicle's lane true }; }; }; } forEach _nearbyObjects; // If no sign is detected, return false false }; -
What do we use as a light source inside buildings?
Luft08 posted a topic in ARMA 3 - MISSION EDITING & SCRIPTING
I have a mission using the Global Mobilization DLC. Sometimes the missions are at night and the inside of buildings are dark. There use to be a light entity but I guess the BIS libraries changed or something. The old way I use to light up the inside of buildings no longer works and I was wondering how it is done now? Thanks. -
Can you pass a local variable to BIS_fnc_loop ?
Luft08 posted a topic in ARMA 3 - MISSION EDITING & SCRIPTING
I have the following method: LFT_startCarLoops = { params ["_cityAreaArray", "_percent", "_carTypeArray", "_deletionRange", "_spawnRange"]; // Initialize global array to keep track of spawned cars if (isNil "ambientParkedCars") then { ambientParkedCars = []; }; ["itemAdd", ["checkPlayerProximityForCarsLoop", { [_cityAreaArray, _percent, _carTypeArray, _spawnRange] call LFT_CheckPlayerProximityAndSpawnCars; }, 1]] call BIS_fnc_loop; ["itemAdd", ["checkCarsProximityLoop", { [_deletionRange] call LFT_CheckCarsProximity; }, 1]] call BIS_fnc_loop; }; I need it to run some other code every few seconds. However, although this method gets data through the parameters (I have checked), when it gets to the BIS_fnc_loop the value of _cityAreaArray doesn't get passed and becomes "any". I need it to LFT_CheckPlayerProximityAndSpawnCars. LFT_CheckPlayerProximityAndSpawnCars = { params ["_cityAreaArray", "_percent", "_carTypeArray", "_spawnRange"]; <Some code> }; -
Problem with old mission i.e. VirtualAISquad
Luft08 posted a topic in ARMA 3 - MISSION EDITING & SCRIPTING
I created a mission some time ago that uses the Global Mobilization DLC and the CBA_A3 mod. I have not run the mission for a long time and now when I start it I get error messages: Bad Vehicle Type Virtual AI Squad and mpmissions\__CUR_MP.gm_weferlingen_summer\mission.sqm/Mission/Entities/Item65.type:Vehicle class VirtualAISquad no longer exists I searched mission.sqm and found two references to VirtualAISquad. They refer to light emitters. I don't see the emitters in the Eden editor and when I comment out the offending classes and try to start the mission Arma 3 crashes. I don't know how to proceed. -
Displaying Messages With Pictures in Game
Luft08 posted a topic in ARMA 3 - MISSION EDITING & SCRIPTING
I wish to display card-like messages while in-game. A header, picture and text below then buttons. Is this possible? I'm trying to create a scenario that is more board game like. The players will get random cards that can add items or abilities if the card is used. I would like it to have a header on top then a nice picture with text below that and finally buttons that will allow them to use or save the card. Thanks. -
I want to execute a function after units reach their given waypoint but the function takes an argument. I wanted to use setWaypointStatements but the argument is in a private variable and it is not possible to place the argument into a global variable because the function gets executed by many AI units that require the argument have different values. Is there any way to do this?
-
I can't seem to get a handle on locality. I understand it, I just can't seem to not get smacked in the face by it. The other day Harzach helped me identify my locality problem and I though I was being so careful but I once again have code that runs fine in single player but not on my dedicated server. When a player destroys an enemy vehicle I want to award that player points based on the vehicle type and send a hint message to only that player. When I create the vehicle I attach an event handler to it (from code that only runs on the server). LFT_MilitaryTraffic: if(!isServer) exitWith {}; // Delete dead vehicles for "_c" from 0 to ((count militaryVehicleArray) - 1) do { private _veh = militaryVehicleArray # _c; if(!alive _veh) then { militaryVehicleArray deleteAt _c; }; }; while {(count militaryVehicleArray) < MAX_VEHICLES } do { // Get Vehicle Type private _vehicleType = selectRandom vehicleTypeArray; // Get Random road positions for start private _posStart = [0,0]; private _startSeg = [] call LFT_GetRandomRoadSeg; _posStart = getPos _startSeg; // Spawn Vehicle. private _roadDir = [_startSeg] call LFT_GetRoadDirection; private _vehArray = [_posStart, _roadDir, _vehicleType, east] call BIS_fnc_spawnVehicle; private _vehObject = _vehArray # 0; private _group = _vehArray # 2; _group deleteGroupWhenEmpty true; _vehObject addEventHandler["Killed", { params ["_unit", "_killer", "_instigator", "_useEffects"]; [_unit, _killer] remoteExecCall ["LFT_AwardKillPoints"]; }]; if(_vehicleType == "O_Truck_02_Ammo_F") then { _vehObject addEventHandler["Killed", { params ["_unit", "_killer", "_instigator", "_useEffects"]; for "_c" from 1 to 10 do { private _bomb = "Bo_GBU12_LGB" createVehicle (getPos _unit); _bomb setDamage 1; }; }]; }; militaryVehicleArray pushBack _vehObject; // Send Vehicle // _group = _vehArray # 2; [_group] call LFT_SetWaypoint; }; I assume that the event handler will run on the server so I remoteExecCall a function (LFT_AwardKillPoints) that has been compiled and placed into a variable. The variable has been declared a public variable: initServer: if(!isServer) exitWith {}; private _year = 2035; private _month = 7; private _day = 19; private _hour = 12; private _min = floor random 60; setDate [_year, _month, _day, _hour, _min]; private _handle = [] execVM "scripts\initVariables.sqf"; waitUntil {scriptDone _handle}; LFT_RaptorMaintenance = compileFinal preprocessfilelinenumbers "scripts\LFT_RaptorMaintenance.sqf"; LFT_VehicleMaintenance = compileFinal preprocessfilelinenumbers "scripts\LFT_VehicleMaintenance.sqf"; LFT_MilitaryTraffic = compileFinal preprocessfilelinenumbers "scripts\LFT_MilitaryTraffic.sqf"; LFT_GetRandomRoadSeg = compileFinal preprocessfilelinenumbers "scripts\LFT_GetRandomRoadSeg.sqf"; LFT_SetWaypoint = compileFinal preprocessfilelinenumbers "scripts\LFT_SetWaypoint.sqf"; LFT_GetRoadDirection = compileFinal preprocessfilelinenumbers "scripts\LFT_GetRoadDirection.sqf"; LFT_AwardKillPoints = compileFinal preprocessfilelinenumbers "scripts\LFT_AwardKillPoints.sqf"; LFT_InitBuildingManagement = compileFinal preprocessfilelinenumbers "scripts\LFT_InitBuildingManagement.sqf"; publicVariable "LFT_RaptorMaintenance"; publicVariable "LFT_VehicleMaintenance"; publicVariable "LFT_MilitaryTraffic"; publicVariable "LFT_GetRandomRoadSeg"; publicVariable "LFT_SetWaypoint"; publicVariable "LFT_GetRoadDirection"; publicVariable "LFT_awardKillPoints"; addMissionEventHandler ["entityRespawned",{ params ["_unit"]; call { if (side _unit isEqualTo WEST) exitWith {_unit setpos getpos respawn_west_1}; }; }]; [] spawn LFT_MilitaryTraffic; serverReady = true; publicVariable "serverReady"; LFT_AwardKillPoints: params ["_unit", "_killer"]; if(player isEqualTo _killer) then { { private _unitType = _x # 0; private _unitTypeText = _x # 1; private _unitTypeScore = _x # 2; if(_unitType isEqualTo (TypeOf _unit)) exitWith { hint format ["You have destroyed a %1. +%2 Points!", _unitTypeText, _unitTypeScore]; // TODO - add _unitTypeScore to players total score. }; } forEach scoreTable; }; The function uses an array called scoreTable that has also been made public: initVariables.sqf: if(!isServer) exitWith {}; MAX_VEHICLES = 150; player_1_Score = 0; player_2_Score = 0; player_3_Score = 0; player_4_Score = 0; vehicleTypeArray = [ "O_APC_Wheeled_02_rcws_v2_F", "O_MRAP_02_F", "O_MRAP_02_hmg_F", "O_LSV_02_AT_F", "O_LSV_02_armed_F", "O_LSV_02_unarmed_F", "O_Truck_03_device_F", "O_Truck_03_ammo_F", "O_Truck_03_fuel_F", "O_Truck_03_medical_F", "O_Truck_03_repair_F", "O_Truck_03_transport_F", "O_Truck_03_covered_F", "O_Truck_02_Ammo_F", "O_Truck_02_fuel_F", "O_Truck_02_medical_F", "O_Truck_02_box_F", "O_Truck_02_transport_F", "O_Truck_02_covered_F" ]; scoreTable = [ ["O_APC_Wheeled_02_rcws_v2_F","Unarmed Ifrit",10], ["O_MRAP_02_F","Ifrit GMG",30], ["O_MRAP_02_hmg_F","Ifrit HMG",30], ["O_LSV_02_AT_F","Qilin (AT)",20], ["O_LSV_02_armed_F","Qilin (Mini-Gun)",20], ["O_LSV_02_unarmed_F", "Qilin (Unarmed)", 5], ["O_Truck_03_device_F","Tempest (Device)",10], ["O_Truck_03_ammo_F","Tempest (Ammo)",25], ["O_Truck_03_fuel_F","Tempest (Fuel)",25], ["O_Truck_03_medical_F","Tempest (Medical)",10], ["O_Truck_03_repair_F","Tempest (Repair)",25], ["O_Truck_03_transport_F","Tempest (Transport)",30], ["O_Truck_03_covered_F","Tempest (Covered Transport)",30], ["O_Truck_02_Ammo_F","Zamak Ammo",25], ["O_Truck_02_fuel_F","Zamak Fuel",25], ["O_Truck_02_medical_F","Zamak Medical",10], ["O_Truck_02_box_F","Zamak Repair",25], ["O_Truck_02_transport_F","Zamak Transport",30], ["O_Truck_02_covered_F","Zamak Transport (Covered)",30] ]; publicVariable "scoreTable"; mainIsland = [[9803.08,9978.81], 5000]; cityArray = [ ["GeorgeTown",[6093.99,10023.6],1000], ["BluePerl",[13436.6,11933.5],800], ["Kotomo",[10786.3,6455.53],400], ["Tanouka",[9029.22,10021.6],500] ]; militaryVehicleArray = []; Again, It works when I run it from my PC but not on a dedicated server. Any ideas? Thanks.
-
Locality... The Bain of my existence
Luft08 replied to Luft08's topic in ARMA 3 - MISSION EDITING & SCRIPTING
Never mind... I just tested it out on the server after my long post and it is working. 🤪 -
Rearm code works in single player but not on dedicated server
Luft08 posted a topic in ARMA 3 - MISSION EDITING & SCRIPTING
I made a super simple mission that has four helicopters named raptor_1, raptor_2, raptor_3 and raptor_4. I populated the main Tanoa island with opfor vehicles and have them running around. The players each take a helicopter and try to destroy as many vehicles as they can then come back and land on a pad to get rearmed, refueled and repaired. Everything works in single player mode but when I put the mission on a dedicated server the rearming, refueling and repair process does not work. The helopads each have a trigger: Type:None, Activation: Blufor, Activation Type: present. The condition field has: (raptor_1 in thisList || raptor_2 in thisList || raptor_3 in thisList || raptor_4 in thisList); The on Activation field has: [thisTrigger] remoteExecCall ["LFT_RaptorMaintenance"]; // Note I tried [thisTrigger] call LFT_RaptorMaintenance; but it didn't work either. The LFT_RaptorMaintenance function: params ["_trigger"]; if(raptor_1 inArea _trigger) then {[raptor_1] call LFT_VehicleMaintenance;}; if(raptor_2 inArea _trigger) then { [raptor_2] call LFT_VehicleMaintenance;}; if(raptor_3 inArea _trigger) then { [raptor_3] call LFT_VehicleMaintenance;}; if(raptor_4 inArea _trigger) then { [raptor_4] call LFT_VehicleMaintenance;}; The LFT_VehicleMaintenance function: params ["_vehicle"]; _vehicle setVehicleAmmo 1; _vehicle setFuel 1; _vehicle setDamage 0; How do I make this work on a dedicated server. As I said, it does work in single player. Thanks -
Rearm code works in single player but not on dedicated server
Luft08 replied to Luft08's topic in ARMA 3 - MISSION EDITING & SCRIPTING
Doh! Thanks! 😁 -
Rearm code works in single player but not on dedicated server
Luft08 replied to Luft08's topic in ARMA 3 - MISSION EDITING & SCRIPTING
Each function is in it's own sqf file and I compile the files from the initServer.sqf file: if(!isServer) exitWith {}; private _year = 2035; private _month = 7; private _day = 19; private _hour = 6 + floor random 10; private _min = floor random 60; setDate [_year, _month, _day, _hour, _min]; private _handle = [] execVM "scripts\initVariables.sqf"; waitUntil {scriptDone _handle}; LFT_RaptorMaintenance = compileFinal preprocessfilelinenumbers "scripts\LFT_RaptorMaintenance.sqf"; LFT_VehicleMaintenance = compileFinal preprocessfilelinenumbers "scripts\LFT_VehicleMaintenance.sqf"; LFT_MilitaryTraffic = compileFinal preprocessfilelinenumbers "scripts\LFT_MilitaryTraffic.sqf"; LFT_GetRandomRoadSeg = compileFinal preprocessfilelinenumbers "scripts\LFT_GetRandomRoadSeg.sqf"; LFT_SetWaypoint = compileFinal preprocessfilelinenumbers "scripts\LFT_SetWaypoint.sqf"; LFT_GetRoadDirection = compileFinal preprocessfilelinenumbers "scripts\LFT_GetRoadDirection.sqf"; [] call LFT_MilitaryTraffic; serverReady = true; publicVariable "serverReady"; -
Rearm code works in single player but not on dedicated server
Luft08 replied to Luft08's topic in ARMA 3 - MISSION EDITING & SCRIPTING
Nope, but maybe I need to put in a few more logging statements to see what's happening on the client side. -
Rearm code works in single player but not on dedicated server
Luft08 replied to Luft08's topic in ARMA 3 - MISSION EDITING & SCRIPTING
I placed diag_Log messages at the beginning of each function. Everything is being called so I assume that the code in the LFT_VehicleMaintenance function is failing when run on a dedicated server. params ["_vehicle"] _vehicle setVehicleAmmo 1; _vehicle setFuel 1; _vehicle setDamage 0; -
Rearm code works in single player but not on dedicated server
Luft08 replied to Luft08's topic in ARMA 3 - MISSION EDITING & SCRIPTING
Thanks rowdied, I'll look over the code but what I really want is to understand why my code fails on the server. -
Rearm code works in single player but not on dedicated server
Luft08 replied to Luft08's topic in ARMA 3 - MISSION EDITING & SCRIPTING
Good idea. Because it is running on the server I'll have to put in some logging messages to determine that. -
I wish to light the inside of a building during a night mission. (on a dedicated server) I found a post that seems like a solution but the light only works when the script runs locally so I put a call to the script in the initPlayerLocal.sqf file but that didn't help. In my initPlayerLocal method I have: [BaseLight_1, 0.5, 5.4] call LFT_LightSource; [BaseLight_2, 0.5, 1.8] call LFT_LightSource; BaseLight_1 and BaseLight_2 are logic objects. LFT_LightSource: /* NOTE: Runs locally. */ params["_light", "_intensity", "_height"]; _light setPosATL[(getPosATL _light select 0), (getPosATL _light select 1), _height]; BIS_lightEmitor01 = "#lightpoint" createVehicleLocal getPosATL _light; BIS_lightEmitor01 setLightColor [1, 1, 1]; BIS_lightEmitor01 setLightBrightness _intensity; BIS_lightEmitor01 setLightAmbient [1,1,1]; BIS_lightEmitor01 lightAttachObject [_light, [0, 0, 0.1]]; The code works perfectly when I run the mission from my PC.
-
In the initServer.sqf file I call a method that compiles several functions including the LFT_LightSource function. In the initServer.sqf file: _handle = [] execVM "scripts\common\compileMethods.sqf"; waitUntil {scriptDone _handle}; In the scripts\common\compileMethods.sqf file: if(!isServer) exitWith {}; inView = compileFinal preprocessfilelinenumbers "LFT_Common\inView.sqf"; isPrimaryAmmoLow = compileFinal preprocessfilelinenumbers "LFT_Common\isPrimaryAmmoLow.sqf"; LFT_Attack_Ground_Troops = compileFinal preprocessfilelinenumbers "LFT_Common\LFT_Attack_Ground_Troops.sqf"; LFT_LightSource = compileFinal preprocessfilelinenumbers "LFT_Common\LFT_LightSource.sqf";
-
I guess I don't understand what you mean when you say I don't need to broadcast the creation of a lightPoint. My code doesn't do that. The call to the LFT_LightSource function is placed in the initPlayerLocal.sqf file that gets run locally on every player's PC at the start of the mission so it should work but it doesn't. Very frustrating. I'll see if I can get your remoteExec way of doing it to work. Thanks for the help.
-
Yep, lightpoints and all commands are local. No joy.
-
Yes, I realize that createVehicleLocal is local. But I believe that creating a lightpoint must be done at the local level which is why I put the call into the initPlayerLocal.sqf file which is run locally. I'll try createVehicle but I don't have confidence that it will work. Thanks for you reply.
-
How can I tell if AI are running low on ammo?
Luft08 posted a topic in ARMA 3 - MISSION EDITING & SCRIPTING
I have a mission where opfor has taken control of a town. I have various weapon caches scattered throughout the town. When an AI unit gets low on ammo I want to set a waypoint to the nearest cache and when he arrives fill up his ammo. The problem is that I don't know how to test to see if he is low on ammo. (Not completely out, just low). Is there a function or event handler that can help me do this? Thanks.