object erh_compass : player_tools { // greebo: Gets called upon addition to the inventory void inventory_item_init(entity userEntity, float overlayHandle, string overlayName); // Gets called when the player switches to another inventory item void inventory_item_unselect(entity userEntity, float overlayHandle); // Gets called when this item is selected in the inventory void inventory_item_select(entity userEntity, float overlayHandle); // Gets called to update the HUD (not each frame!) void inventory_item_update(entity userEntity, float overlayHandle); // Updates the HUD variables void updateCompass(entity userEntity); // greebo: Call this function in a new thread. It will update the compass HUD each frame. void updateLoop(entity userEntity); // Member variables vector _playerAngles; float _compcwise; float _compccwise; // The GUI overlay handle (containing the compass model) float _overlayHandle; // The thread number of the update loop float _updateThreadNum; }; void erh_compass::updateCompass(entity userEntity) { vector pa; vector temp=userEntity.getViewAngles(); vector visdir; pa = (getEntityKey("ent")).getOrigin()-userEntity.getEyePos(); visdir_x=sys.cos(temp_x)*sys.cos(temp_y); visdir_y=sys.cos(temp_x)*sys.sin(temp_y); visdir_z=-sys.sin(temp_x); visdir=sys.vecNormalize(visdir); pa=sys.vecNormalize(pa); _playerAngles=sys.VecToAngles(visdir)-sys.VecToAngles(pa); if (_playerAngles_x>180) { _playerAngles_x=_playerAngles_x-360; } else if (_playerAngles_x < -180) { _playerAngles_x=_playerAngles_x+360; } float yaw = _playerAngles_y+90; // Clamp the pitch to [COMPASS_MIN_PITCH .. COMPASS_MAX_PITCH] float playerPitchClamped = _playerAngles_x; if (playerPitchClamped > 0) { playerPitchClamped = COMPASS_MAX_PITCH * playerPitchClamped/90; } else { playerPitchClamped = COMPASS_MIN_PITCH * -playerPitchClamped/90; } float modelPitch = -playerPitchClamped * sys.cos(yaw); float modelRoll = playerPitchClamped * sys.sin(yaw); userEntity.setGuiFloat(_overlayHandle, "modelYaw", -yaw); userEntity.setGuiFloat(_overlayHandle, "modelPitch", modelPitch); userEntity.setGuiFloat(_overlayHandle, "modelRoll", modelRoll); } void erh_compass::updateLoop(entity userEntity) { // Update the compass GUI each frame eachFrame { updateCompass(userEntity); } } void erh_compass::inventory_item_init(entity userEntity, float overlayHandle, string overlayName) { _overlayHandle = overlayHandle; updateCompass(userEntity); } void erh_compass::inventory_item_select(entity userEntity, float overlayHandle) { _overlayHandle = overlayHandle; // Disable the default inventory userEntity.setGuiFloat(userEntity.getInventoryOverlay(), "Inventory_ItemVisible", 0); // Make the compass GUI visible userEntity.setGuiFloat(_overlayHandle, "CompassVisible", 1); // Start a new thread _updateThreadNum = thread updateLoop(userEntity); } void erh_compass::inventory_item_unselect(entity userEntity, float overlayHandle) { _overlayHandle = overlayHandle; // Kill the update loop sys.terminate(_updateThreadNum); // Disable the compass userEntity.setGuiFloat(_overlayHandle, "CompassVisible", 0); // Enable the default inventory again userEntity.setGuiFloat(userEntity.getInventoryOverlay(), "Inventory_ItemVisible", 1); } void erh_compass::inventory_item_update(entity userEntity, float overlayHandle) { updateCompass(userEntity); }