diff --git a/ReallifeGamemode.Client/Business/cardealer.ts b/ReallifeGamemode.Client/Business/cardealer.ts index 3559de57..2862585e 100644 --- a/ReallifeGamemode.Client/Business/cardealer.ts +++ b/ReallifeGamemode.Client/Business/cardealer.ts @@ -12,7 +12,7 @@ const ListItem = NativeUI.ListItem; import moneyFormat from '../moneyformat'; -export default function carDealer(globalData: GlobalData) { +export default function carDealer(globalData: IGlobalData) { var shopMenu: NativeUI.Menu; diff --git a/ReallifeGamemode.Client/Business/main.ts b/ReallifeGamemode.Client/Business/main.ts index 005d05c6..7b76bdfc 100644 --- a/ReallifeGamemode.Client/Business/main.ts +++ b/ReallifeGamemode.Client/Business/main.ts @@ -12,7 +12,7 @@ const ListItem = NativeUI.ListItem; import InputHelper from '../inputhelper'; -export default function business(globalData: GlobalData) { +export default function business(globalData: IGlobalData) { var keyBound = false; diff --git a/ReallifeGamemode.Client/CharCreator/main.ts b/ReallifeGamemode.Client/CharCreator/main.ts index 66344688..88efebc3 100644 --- a/ReallifeGamemode.Client/CharCreator/main.ts +++ b/ReallifeGamemode.Client/CharCreator/main.ts @@ -24,7 +24,7 @@ const localPlayer = mp.players.local; -export default function charCreator(globalData: GlobalData) { +export default function charCreator(globalData: IGlobalData) { var creatorHairMenu; diff --git a/ReallifeGamemode.Client/Gui/Inventory/inventory.ts b/ReallifeGamemode.Client/Gui/Inventory/inventory.ts index f1fe3bcc..b1e8191c 100644 --- a/ReallifeGamemode.Client/Gui/Inventory/inventory.ts +++ b/ReallifeGamemode.Client/Gui/Inventory/inventory.ts @@ -1,6 +1,6 @@ import InputHelper from '../../inputhelper'; -export default function inventory(globalData: GlobalData) { +export default function inventory(globalData: IGlobalData) { var q; var qw = 0; diff --git a/ReallifeGamemode.Client/Gui/cityhall.ts b/ReallifeGamemode.Client/Gui/cityhall.ts index 5fb60d30..937c9ee3 100644 --- a/ReallifeGamemode.Client/Gui/cityhall.ts +++ b/ReallifeGamemode.Client/Gui/cityhall.ts @@ -11,7 +11,7 @@ const Color = NativeUI.Color; import InputHelper from '../inputhelper'; -export default function (globalData: GlobalData) { +export default function (globalData: IGlobalData) { var keyBound = false; var menu: NativeUI.Menu = null; diff --git a/ReallifeGamemode.Client/Gui/handmoney.ts b/ReallifeGamemode.Client/Gui/handmoney.ts index 4971a31e..a3d8e5e9 100644 --- a/ReallifeGamemode.Client/Gui/handmoney.ts +++ b/ReallifeGamemode.Client/Gui/handmoney.ts @@ -1,6 +1,6 @@ import moneyFormat from '../moneyformat'; -export default function handMoney(globalData: GlobalData) { +export default function handMoney(globalData: IGlobalData) { var currentMoney = null; var showMoneyChange = null; var difference; diff --git a/ReallifeGamemode.Client/Gui/house.ts b/ReallifeGamemode.Client/Gui/house.ts index a7906f08..a906ac2e 100644 --- a/ReallifeGamemode.Client/Gui/house.ts +++ b/ReallifeGamemode.Client/Gui/house.ts @@ -1,158 +1,146 @@ import { Menu, Point, UIMenuItem, Color } from '../libs/NativeUI'; import moneyFormat from '../moneyformat'; import InputHelper from '../inputhelper'; +import game from '..'; +import { Key } from '../game'; -export default function house(globalData: GlobalData) { +var houseMenu: Menu; +var houseData: any; +var houseState: number; - var houseMenu: Menu; - var houseData: any; - var houseState: number; +game.events.add("SERVER:ShowHouseMenu", () => { - var keyBound = false; + game.ui.setHelpText('Drücke ~INPUT_CONTEXT~, um das Hausmenü öffnen'); - mp.events.add("SERVER:ShowHouseMenu", () => { - mp.game.ui.setTextComponentFormat('STRING'); - mp.game.ui.addTextComponentSubstringPlayerName('Drücke ~INPUT_CONTEXT~, um das Hausmenü öffnen'); - mp.game.ui.displayHelpTextFromStringLabel(0, true, true, -1); + game.events.bindKey(Key.E, false, keyPressHandler); +}); - mp.keys.bind(0x45, false, keyPressHandler); - keyBound = true; - }); +game.events.add("SERVER:SetHouseData", (dataStr, state) => { + houseData = JSON.parse(dataStr); + houseState = state; +}); - mp.events.add("SERVER:SetHouseData", (dataStr, state) => { - houseData = JSON.parse(dataStr); - houseState = state; - }); +function keyPressHandler() { + if (game.ui.inMenu || game.ui.inChat) return; + game.ui.clearHelpText(); - function keyPressHandler() { - if (globalData.InMenu || globalData.InChat || globalData.InInput || !globalData.LoggedIn) return; - mp.game.ui.clearHelp(true); - - var subTitle = houseData.Type; - if (houseData.OwnerName) { - subTitle += " von " + houseData.OwnerName; - } - - houseMenu = new Menu("Hausverwaltung", subTitle, new Point(50, 50), null, null); - - globalData.InMenu = true; - - var rentInItem: UIMenuItem; - var cancelOwnRentalItem: UIMenuItem; - - var buyHouseItem: UIMenuItem; - - var setRentalFeeItem: UIMenuItem; - var cancelRentalsItem: UIMenuItem; - var sellHouseItem: UIMenuItem; - - var houseRentals = houseData.Rentals.length; - - if (houseState === -1) { // Keine Beziehung zum Haus - rentInItem = new UIMenuItem("Einmieten", "Miete dich in das Haus ein"); - rentInItem.SetRightLabel(moneyFormat(houseData.RentalFee.toString(), 0) + "$"); - houseMenu.AddItem(rentInItem); - } else if (houseState === 0) { // Haus hat keinen Eigentümer - buyHouseItem = new UIMenuItem("Haus kaufen", "Kaufe das Haus"); - buyHouseItem.SetRightLabel(moneyFormat(houseData.Price, 0) + "$"); - houseMenu.AddItem(buyHouseItem); - } else if (houseState === 1) { // Hausbesitzer - setRentalFeeItem = new UIMenuItem("Miete setzen", "Setze den Mietpreis"); - setRentalFeeItem.SetRightLabel(moneyFormat(houseData.RentalFee, 0) + "$"); - houseMenu.AddItem(setRentalFeeItem); - - if (houseRentals > 0) { - cancelRentalsItem = new UIMenuItem("Mieter", "Liste deine Mieter auf"); - cancelRentalsItem.SetRightLabel(houseRentals.toString()); - houseMenu.AddItem(cancelRentalsItem); - - var cancelRentalsMenu = new Menu("Mieter", "Kündige einen Mieter", new Point(50, 50), null, null); - cancelRentalsMenu.Visible = false; - - houseData.Rentals.forEach(rental => { - var item = new UIMenuItem(rental, ""); - item.SetRightLabel("Kündigen"); - cancelRentalsMenu.AddItem(item); - }); - - cancelRentalsMenu.ItemSelect.on((item: UIMenuItem, index: number) => { - mp.events.callRemote("CLIENT:House_CancelUserRental", item.Text); - houseRentals--; - cancelRentalsItem.SetRightLabel(houseRentals.toString()); - if (houseRentals === 0) { - cancelRentalsMenu.Visible = false; - houseMenu.Visible = true; - houseMenu.RemoveItem(cancelRentalsItem); - } - - cancelRentalsMenu.RemoveItem(item); - }); - - houseMenu.BindMenuToItem(cancelRentalsMenu, cancelRentalsItem); - } - - sellHouseItem = new UIMenuItem("Haus verkaufen"); - houseMenu.AddItem(sellHouseItem); - } else if (houseState === 2) { - cancelOwnRentalItem = new UIMenuItem("Mietvertrag kündigen", "Ziehe aus der Wohnung aus"); - houseMenu.AddItem(cancelOwnRentalItem); - } - - var cancelItem = new UIMenuItem("Abbrechen"); - cancelItem.BackColor = new Color(213, 0, 0); - cancelItem.HighlightedBackColor = new Color(229, 57, 53); - houseMenu.AddItem(cancelItem); - - houseMenu.Open(); - - houseMenu.ItemSelect.on((item, index) => { - if (item === cancelItem) { - mp.events.call("SERVER:CloseHouseMenu"); - houseMenu.Close(); - } else if (item === buyHouseItem) { - mp.events.callRemote("CLIENT:House_BuyHouse"); - mp.events.call("SERVER:CloseHouseMenu"); - houseMenu.Close(); - } else if (item === setRentalFeeItem) { - var rentalFeeInput = new InputHelper("Wie viel soll die Miete betragen?", globalData); - rentalFeeInput.show(); - rentalFeeInput.getValue(data => { - if (isNaN(data)) { - return; - } - - var rentalFee = parseInt(data); - - mp.events.callRemote("CLIENT:House_SetRentalFee", rentalFee); - mp.events.call("SERVER:CloseHouseMenu"); - houseMenu.Close(); - }); - } else if (item === rentInItem) { - mp.events.callRemote("CLIENT:House_RentInHouse"); - houseMenu.Close(); - } else if (item === cancelOwnRentalItem) { - mp.events.callRemote("CLIENT:House_CancelOwnRental"); - houseMenu.Close(); - } else if (item === sellHouseItem) { - mp.events.callRemote("CLIENT:House_SellHouse"); - houseMenu.Close(); - } - }); - - houseMenu.MenuClose.on(() => { - globalData.InMenu = false; - }); + var subTitle = houseData.Type; + if (houseData.OwnerName) { + subTitle += " von " + houseData.OwnerName; } - mp.events.add("SERVER:CloseHouseMenu", () => { - mp.game.ui.clearHelp(true); - if (houseMenu != null) { - houseMenu.Close(); + houseMenu = new Menu("Hausverwaltung", subTitle, new Point(50, 50), null, null); + + game.ui.inMenu = true; + + var rentInItem: UIMenuItem; + var cancelOwnRentalItem: UIMenuItem; + + var buyHouseItem: UIMenuItem; + + var setRentalFeeItem: UIMenuItem; + var cancelRentalsItem: UIMenuItem; + var sellHouseItem: UIMenuItem; + + var houseRentals = houseData.Rentals.length; + + if (houseState === -1) { // Keine Beziehung zum Haus + rentInItem = new UIMenuItem("Einmieten", "Miete dich in das Haus ein"); + rentInItem.SetRightLabel(moneyFormat(houseData.RentalFee.toString(), 0) + "$"); + houseMenu.AddItem(rentInItem); + } else if (houseState === 0) { // Haus hat keinen Eigentümer + buyHouseItem = new UIMenuItem("Haus kaufen", "Kaufe das Haus"); + buyHouseItem.SetRightLabel(moneyFormat(houseData.Price, 0) + "$"); + houseMenu.AddItem(buyHouseItem); + } else if (houseState === 1) { // Hausbesitzer + setRentalFeeItem = new UIMenuItem("Miete setzen", "Setze den Mietpreis"); + setRentalFeeItem.SetRightLabel(moneyFormat(houseData.RentalFee, 0) + "$"); + houseMenu.AddItem(setRentalFeeItem); + + if (houseRentals > 0) { + cancelRentalsItem = new UIMenuItem("Mieter", "Liste deine Mieter auf"); + cancelRentalsItem.SetRightLabel(houseRentals.toString()); + houseMenu.AddItem(cancelRentalsItem); + + var cancelRentalsMenu = new Menu("Mieter", "Kündige einen Mieter", new Point(50, 50), null, null); + cancelRentalsMenu.Visible = false; + + houseData.Rentals.forEach(rental => { + var item = new UIMenuItem(rental, ""); + item.SetRightLabel("Kündigen"); + cancelRentalsMenu.AddItem(item); + }); + + cancelRentalsMenu.ItemSelect.on((item: UIMenuItem, index: number) => { + game.events.callServer("House_CancelUserRental", item.Text); + houseRentals--; + cancelRentalsItem.SetRightLabel(houseRentals.toString()); + if (houseRentals === 0) { + cancelRentalsMenu.Visible = false; + houseMenu.Visible = true; + houseMenu.RemoveItem(cancelRentalsItem); + } + + cancelRentalsMenu.RemoveItem(item); + }); + + houseMenu.BindMenuToItem(cancelRentalsMenu, cancelRentalsItem); } - if (keyBound) { - keyBound = false; - mp.keys.unbind(0x45, false, keyPressHandler); + sellHouseItem = new UIMenuItem("Haus verkaufen"); + houseMenu.AddItem(sellHouseItem); + } else if (houseState === 2) { + cancelOwnRentalItem = new UIMenuItem("Mietvertrag kündigen", "Ziehe aus der Wohnung aus"); + houseMenu.AddItem(cancelOwnRentalItem); + } + + var cancelItem = new UIMenuItem("Abbrechen"); + cancelItem.BackColor = new Color(213, 0, 0); + cancelItem.HighlightedBackColor = new Color(229, 57, 53); + houseMenu.AddItem(cancelItem); + + houseMenu.Open(); + + houseMenu.ItemSelect.on((item, index) => { + if (item === cancelItem) { + houseMenu.Close(); + } else if (item === buyHouseItem) { + game.events.callServer("House_BuyHouse"); + houseMenu.Close(); + } else if (item === setRentalFeeItem) { + var rentalFeeInput = new InputHelper("Wie viel soll die Miete betragen?"); + rentalFeeInput.show(); + rentalFeeInput.getValue(data => { + if (isNaN(data)) { + return; + } + + var rentalFee = parseInt(data); + + game.events.callServer("House_SetRentalFee", rentalFee); + houseMenu.Close(); + }); + } else if (item === rentInItem) { + game.events.callServer("House_RentInHouse"); + houseMenu.Close(); + } else if (item === cancelOwnRentalItem) { + game.events.callServer("House_CancelOwnRental"); + houseMenu.Close(); + } else if (item === sellHouseItem) { + game.events.callServer("House_SellHouse"); + houseMenu.Close(); } }); -} \ No newline at end of file + + houseMenu.MenuClose.on(() => { + game.ui.inMenu = false; + }); +} + +game.events.add("SERVER:CloseHouseMenu", () => { + game.ui.clearHelpText(); + if (houseMenu != null) { + houseMenu.Close(); + } + game.events.unbindKey(Key.E, false, keyPressHandler); +}); \ No newline at end of file diff --git a/ReallifeGamemode.Client/Gui/infobox.ts b/ReallifeGamemode.Client/Gui/infobox.ts index 9f2fdc61..ba9f14a6 100644 --- a/ReallifeGamemode.Client/Gui/infobox.ts +++ b/ReallifeGamemode.Client/Gui/infobox.ts @@ -6,7 +6,7 @@ import moneyFormat from "../moneyformat"; -export default function (globalData: GlobalData): void { +export default function (globalData: IGlobalData): void { var currentdate; var dateString; var timeString; diff --git a/ReallifeGamemode.Client/Gui/interiors.ts b/ReallifeGamemode.Client/Gui/interiors.ts index a282cc47..b8ff1462 100644 --- a/ReallifeGamemode.Client/Gui/interiors.ts +++ b/ReallifeGamemode.Client/Gui/interiors.ts @@ -1,4 +1,4 @@ -export default function interiors(globalData: GlobalData) { +export default function interiors(globalData: IGlobalData) { var keyBound = false; var interiorId = -1; diff --git a/ReallifeGamemode.Client/Gui/licenses.ts b/ReallifeGamemode.Client/Gui/licenses.ts index b977d8c9..e48a0eea 100644 --- a/ReallifeGamemode.Client/Gui/licenses.ts +++ b/ReallifeGamemode.Client/Gui/licenses.ts @@ -1,7 +1,7 @@ import { isNull } from "util"; -export default function licenses(globalData: GlobalData): void { +export default function licenses(globalData: IGlobalData): void { var licenseBrowser: BrowserMp = null; var licenseTimer; diff --git a/ReallifeGamemode.Client/Gui/playerlist.ts b/ReallifeGamemode.Client/Gui/playerlist.ts index 689d6e1d..a674b624 100644 --- a/ReallifeGamemode.Client/Gui/playerlist.ts +++ b/ReallifeGamemode.Client/Gui/playerlist.ts @@ -4,7 +4,7 @@ * @copyright (c) 2008 - 2018 Life of German */ -export default function playerList(globalData: GlobalData): void { +export default function playerList(globalData: IGlobalData): void { var playerlistBrowser: BrowserMp = null; var pList; diff --git a/ReallifeGamemode.Client/Gui/taximeter.ts b/ReallifeGamemode.Client/Gui/taximeter.ts index f6781170..aca73950 100644 --- a/ReallifeGamemode.Client/Gui/taximeter.ts +++ b/ReallifeGamemode.Client/Gui/taximeter.ts @@ -7,7 +7,7 @@ let lastkilometer: Number = 0; let lastPrice: Number = 0; let totalPrice: Number = 0; var myVar; -export default function taximeterInput(globalData: GlobalData) { +export default function taximeterInput(globalData: IGlobalData) { mp.events.add("CLIENT:setFarePrice", () => { /* var textBox = new InputHelper("Setzen Sie ihre Fahrtkosten [2 - 50 $/km]", globalData); diff --git a/ReallifeGamemode.Client/Gui/vehiclemenu/main.ts b/ReallifeGamemode.Client/Gui/vehiclemenu/main.ts index 2220512d..c2a727a1 100644 --- a/ReallifeGamemode.Client/Gui/vehiclemenu/main.ts +++ b/ReallifeGamemode.Client/Gui/vehiclemenu/main.ts @@ -6,7 +6,7 @@ const UIMenuListItem = NativeUI.UIMenuListItem; const Point = NativeUI.Point; const ItemsCollection = NativeUI.ItemsCollection; -export default function vehicleMenu(globalData: GlobalData) { +export default function vehicleMenu(globalData: IGlobalData) { let menuBrowser: BrowserMp = null; mp.events.add('ToggleVehicleMenu', () => { diff --git a/ReallifeGamemode.Client/Gui/wanteds.ts b/ReallifeGamemode.Client/Gui/wanteds.ts index 71c7cf4d..3a33f5eb 100644 --- a/ReallifeGamemode.Client/Gui/wanteds.ts +++ b/ReallifeGamemode.Client/Gui/wanteds.ts @@ -1,4 +1,4 @@ -export default function wanteds(globalData: GlobalData) { +export default function wanteds(globalData: IGlobalData) { var browser = mp.browsers.new("package://assets/html/wanteds/index.html"); mp.events.add("SERVER:SetWanteds", (count: number) => { diff --git a/ReallifeGamemode.Client/Interaction/ItemShop.ts b/ReallifeGamemode.Client/Interaction/ItemShop.ts index edc38caa..a9a28ccd 100644 --- a/ReallifeGamemode.Client/Interaction/ItemShop.ts +++ b/ReallifeGamemode.Client/Interaction/ItemShop.ts @@ -9,7 +9,7 @@ const Point = NativeUI.Point; const ItemsCollection = NativeUI.ItemsCollection; const Color = NativeUI.Color; -export default function itemShopList(globalData: GlobalData) { +export default function itemShopList(globalData: IGlobalData) { const localPlayer = mp.players.local; diff --git a/ReallifeGamemode.Client/Interaction/clothes/ClotheShop.ts b/ReallifeGamemode.Client/Interaction/clothes/ClotheShop.ts index 59afd4fb..468be6a4 100644 --- a/ReallifeGamemode.Client/Interaction/clothes/ClotheShop.ts +++ b/ReallifeGamemode.Client/Interaction/clothes/ClotheShop.ts @@ -23,7 +23,7 @@ const ItemsCollection = NativeUI.ItemsCollection; const Color = NativeUI.Color; -export default function clotheShopList(globalData: GlobalData) { +export default function clotheShopList(globalData: IGlobalData) { const categoryTitles = { clothes: { 1: "Masks", diff --git a/ReallifeGamemode.Client/Interaction/drivingschool.ts b/ReallifeGamemode.Client/Interaction/drivingschool.ts index 30afd859..d789a20f 100644 --- a/ReallifeGamemode.Client/Interaction/drivingschool.ts +++ b/ReallifeGamemode.Client/Interaction/drivingschool.ts @@ -18,7 +18,7 @@ let cancelItem = new UIMenuItem("Abbrechen", ""); cancelItem.BackColor = new Color(213, 0, 0); cancelItem.HighlightedBackColor = new Color(229, 57, 53); -export default function drivingSchoolList(globalData: GlobalData) { +export default function drivingSchoolList(globalData: IGlobalData) { var drivingMenu: NativeUI.Menu; diff --git a/ReallifeGamemode.Client/Interaction/elevator.ts b/ReallifeGamemode.Client/Interaction/elevator.ts index aa97faf2..149e321d 100644 --- a/ReallifeGamemode.Client/Interaction/elevator.ts +++ b/ReallifeGamemode.Client/Interaction/elevator.ts @@ -18,7 +18,7 @@ let cancelItem = new UIMenuItem("Abbrechen", ""); cancelItem.BackColor = new Color(213, 0, 0); cancelItem.HighlightedBackColor = new Color(229, 57, 53); -export default function elevatorList(globalData: GlobalData) { +export default function elevatorList(globalData: IGlobalData) { var elevatorMenu: NativeUI.Menu; diff --git a/ReallifeGamemode.Client/Interaction/factioninteraction.ts b/ReallifeGamemode.Client/Interaction/factioninteraction.ts index 9b393a63..e2e4faf9 100644 --- a/ReallifeGamemode.Client/Interaction/factioninteraction.ts +++ b/ReallifeGamemode.Client/Interaction/factioninteraction.ts @@ -8,7 +8,7 @@ const Point = NativeUI.Point; const ItemsCollection = NativeUI.ItemsCollection; const Color = NativeUI.Color; -export default function factionInteraction(globalData: GlobalData) { +export default function factionInteraction(globalData: IGlobalData) { var screenRes = mp.game.graphics.getScreenResolution(0, 0); var player = mp.players.local; var tasks; diff --git a/ReallifeGamemode.Client/Interaction/interactionmenu.ts b/ReallifeGamemode.Client/Interaction/interactionmenu.ts index a3caeb76..20399db0 100644 --- a/ReallifeGamemode.Client/Interaction/interactionmenu.ts +++ b/ReallifeGamemode.Client/Interaction/interactionmenu.ts @@ -13,7 +13,7 @@ const Color = NativeUI.Color; import { getStreetName, getZoneName } from '../streetnames'; -export default function (globalData: GlobalData) { +export default function (globalData: IGlobalData) { var menuClose = false; diff --git a/ReallifeGamemode.Client/Interaction/playerinteraction.ts b/ReallifeGamemode.Client/Interaction/playerinteraction.ts index 7e28ec6a..4c1eb18c 100644 --- a/ReallifeGamemode.Client/Interaction/playerinteraction.ts +++ b/ReallifeGamemode.Client/Interaction/playerinteraction.ts @@ -19,7 +19,7 @@ let eY = sY - 0.1; let sizeMul = 0.08; let yMul = 1.8; -export default function playerInteraction(globalData: GlobalData) { +export default function playerInteraction(globalData: IGlobalData) { var nearbyPlayers = []; let screenRes = mp.game.graphics.getScreenResolution(0, 0); diff --git a/ReallifeGamemode.Client/Jobs/BusRouteSelect.ts b/ReallifeGamemode.Client/Jobs/BusRouteSelect.ts index aa9db219..7e43192e 100644 --- a/ReallifeGamemode.Client/Jobs/BusRouteSelect.ts +++ b/ReallifeGamemode.Client/Jobs/BusRouteSelect.ts @@ -20,7 +20,7 @@ cancelItem.BackColor = new Color(213, 0, 0); cancelItem.HighlightedBackColor = new Color(229, 57, 53); -export default function busRouteList(globalData: GlobalData) { +export default function busRouteList(globalData: IGlobalData) { var routeMenu: NativeUI.Menu; var routeTexts; diff --git a/ReallifeGamemode.Client/Jobs/PilotRouteSelect.ts b/ReallifeGamemode.Client/Jobs/PilotRouteSelect.ts index 177b46c0..3ed2554a 100644 --- a/ReallifeGamemode.Client/Jobs/PilotRouteSelect.ts +++ b/ReallifeGamemode.Client/Jobs/PilotRouteSelect.ts @@ -20,7 +20,7 @@ cancelItem.BackColor = new Color(213, 0, 0); cancelItem.HighlightedBackColor = new Color(229, 57, 53); -export default function PilotRouteList(globalData: GlobalData) { +export default function PilotRouteList(globalData: IGlobalData) { var routeMenu: NativeUI.Menu; var routeTexts; diff --git a/ReallifeGamemode.Client/Jobs/main.ts b/ReallifeGamemode.Client/Jobs/main.ts index ae878f40..6f167125 100644 --- a/ReallifeGamemode.Client/Jobs/main.ts +++ b/ReallifeGamemode.Client/Jobs/main.ts @@ -1,6 +1,6 @@ import * as NativeUI from '../libs/NativeUI'; -export default function (globalData: GlobalData) { +export default function (globalData: IGlobalData) { mp.events.add("SERVER:Job_ShowJobMenu", (jobName: string, data: any) => { if (globalData.InMenu) return; diff --git a/ReallifeGamemode.Client/Login/main.ts b/ReallifeGamemode.Client/Login/main.ts index 4733fe7f..8acc963a 100644 --- a/ReallifeGamemode.Client/Login/main.ts +++ b/ReallifeGamemode.Client/Login/main.ts @@ -4,7 +4,7 @@ * @copyright (c) 2008 - 2018 Life of German */ -export default function(globalData: GlobalData): void { +export default function(globalData: IGlobalData): void { var loginBrowser: BrowserMp; var loginCam: CameraMp = mp.cameras.new('login', new mp.Vector3(-1883.736, -781.4911, 78.27616), new mp.Vector3(3.185999, 0, -79.59519), 40); diff --git a/ReallifeGamemode.Client/Player/criminalrelease.ts b/ReallifeGamemode.Client/Player/criminalrelease.ts index f711dabc..26ca1f3c 100644 --- a/ReallifeGamemode.Client/Player/criminalrelease.ts +++ b/ReallifeGamemode.Client/Player/criminalrelease.ts @@ -18,7 +18,7 @@ let cancelItem = new UIMenuItem("Abbrechen", ""); cancelItem.BackColor = new Color(213, 0, 0); cancelItem.HighlightedBackColor = new Color(229, 57, 53); -export default function jailList(globalData: GlobalData) { +export default function jailList(globalData: IGlobalData) { var jailMenu: NativeUI.Menu; diff --git a/ReallifeGamemode.Client/Player/dutycloth.ts b/ReallifeGamemode.Client/Player/dutycloth.ts index c4991f56..c1f65361 100644 --- a/ReallifeGamemode.Client/Player/dutycloth.ts +++ b/ReallifeGamemode.Client/Player/dutycloth.ts @@ -24,7 +24,7 @@ let cancelItem = new UIMenuItem("Abbrechen", ""); cancelItem.BackColor = new Color(213, 0, 0); cancelItem.HighlightedBackColor = new Color(229, 57, 53); -export default function dutyCloth(globalData: GlobalData) { +export default function dutyCloth(globalData: IGlobalData) { var dutyMenu: NativeUI.Menu; diff --git a/ReallifeGamemode.Client/Player/keys.ts b/ReallifeGamemode.Client/Player/keys.ts index 3e56c64f..ae87a7f7 100644 --- a/ReallifeGamemode.Client/Player/keys.ts +++ b/ReallifeGamemode.Client/Player/keys.ts @@ -9,7 +9,7 @@ const player = mp.players.local; -export default function keys(globalData: GlobalData) { +export default function keys(globalData: IGlobalData) { var showInventory = false; var showGui = true; diff --git a/ReallifeGamemode.Client/Player/reportmenu.ts b/ReallifeGamemode.Client/Player/reportmenu.ts index c2731edd..05541dfb 100644 --- a/ReallifeGamemode.Client/Player/reportmenu.ts +++ b/ReallifeGamemode.Client/Player/reportmenu.ts @@ -27,7 +27,7 @@ let cancelItem = new UIMenuItem("Abbrechen", ""); cancelItem.BackColor = new Color(213, 0, 0); cancelItem.HighlightedBackColor = new Color(229, 57, 53); -export default function reportList(globalData: GlobalData) { +export default function reportList(globalData: IGlobalData) { var reportMenu: NativeUI.Menu; diff --git a/ReallifeGamemode.Client/Player/weaponlist.ts b/ReallifeGamemode.Client/Player/weaponlist.ts index e440009d..d9dbd111 100644 --- a/ReallifeGamemode.Client/Player/weaponlist.ts +++ b/ReallifeGamemode.Client/Player/weaponlist.ts @@ -18,7 +18,7 @@ let cancelItem = new UIMenuItem("Abbrechen", ""); cancelItem.BackColor = new Color(213, 0, 0); cancelItem.HighlightedBackColor = new Color(229, 57, 53); -export default function weaponList(globalData: GlobalData) { +export default function weaponList(globalData: IGlobalData) { var weaponMenu: NativeUI.Menu; diff --git a/ReallifeGamemode.Client/Speedometer/index.ts b/ReallifeGamemode.Client/Speedometer/index.ts index bc01c7f1..27827a12 100644 --- a/ReallifeGamemode.Client/Speedometer/index.ts +++ b/ReallifeGamemode.Client/Speedometer/index.ts @@ -1,6 +1,6 @@ let player = mp.players.local; -export default function speedometer(globalData: GlobalData) { +export default function speedometer(globalData: IGlobalData) { var dictLoaded = false; var lockStatus = false; diff --git a/ReallifeGamemode.Client/Tuning/main.ts b/ReallifeGamemode.Client/Tuning/main.ts index 6f2f124d..16ded592 100644 --- a/ReallifeGamemode.Client/Tuning/main.ts +++ b/ReallifeGamemode.Client/Tuning/main.ts @@ -10,7 +10,7 @@ const UIMenuItem = NativeUI.UIMenuItem; const BadgeStyle = NativeUI.BadgeStyle; const Point = NativeUI.Point; -export default function tuning(globalData: GlobalData) { +export default function tuning(globalData: IGlobalData) { var keyBound = false; const disableInput = [75, 278, 279, 280, 281, 23, 59, 60, 71, 72, 74]; diff --git a/ReallifeGamemode.Client/Voice/main.ts b/ReallifeGamemode.Client/Voice/main.ts index 25776574..97d902db 100644 --- a/ReallifeGamemode.Client/Voice/main.ts +++ b/ReallifeGamemode.Client/Voice/main.ts @@ -4,7 +4,7 @@ * @copyright (c) 2008 - 2019 Life of German */ -export default function voice(globalData: GlobalData) { +export default function voice(globalData: IGlobalData) { let dictLoaded = false; const Use3d = true; diff --git a/ReallifeGamemode.Client/core/rage-mp/ui.ts b/ReallifeGamemode.Client/core/rage-mp/ui.ts index 8b8ea990..369e620d 100644 --- a/ReallifeGamemode.Client/core/rage-mp/ui.ts +++ b/ReallifeGamemode.Client/core/rage-mp/ui.ts @@ -1,5 +1,6 @@ import { IUi, IBrowser } from "../../game"; import { Menu } from "../../libs/NativeUI/index"; +import { GlobalData } from "../.."; export default class RageUi implements IUi { setHelpText(text: string): void { @@ -11,9 +12,17 @@ export default class RageUi implements IUi { mp.game.ui.clearHelp(true); } private _inMenu: boolean = false; + private _inChat: boolean = false; private _activeMenu: Menu = null; - inChat: boolean = false; + get inChat() { + return this._inChat || GlobalData.InChat; + } + + set inChat(value: boolean) { + this._inChat = value; + GlobalData.InChat = value; + } get activeMenu(): Menu { return this._activeMenu; @@ -34,11 +43,12 @@ export default class RageUi implements IUi { } get inMenu() { - return this._inMenu; + return this._inMenu || GlobalData.InMenu; } set inMenu(value: boolean) { this._inMenu = value; + GlobalData.InMenu = value; this.toggleChat(!value); } diff --git a/ReallifeGamemode.Client/global.d.ts b/ReallifeGamemode.Client/global.d.ts index c4fa47e0..986ee13c 100644 --- a/ReallifeGamemode.Client/global.d.ts +++ b/ReallifeGamemode.Client/global.d.ts @@ -1,4 +1,4 @@ -declare interface GlobalData { +declare interface IGlobalData { InTuning: boolean, HideGui: boolean, InMenu: boolean, diff --git a/ReallifeGamemode.Client/index.ts b/ReallifeGamemode.Client/index.ts index 59e1737c..b4773109 100644 --- a/ReallifeGamemode.Client/index.ts +++ b/ReallifeGamemode.Client/index.ts @@ -7,7 +7,7 @@ import { IGame } from './game'; import RageGame from './core/rage-mp/game'; -let globalData: GlobalData = { +let globalData: IGlobalData = { InTuning: false, HideGui: false, InChat: false, @@ -26,6 +26,9 @@ let globalData: GlobalData = { const game: IGame = new RageGame(); export default game; +export { + globalData as GlobalData +} game.events.onPlayerCommand((cmd) => { game.events.callServer("Command", cmd.split(' ')); @@ -35,8 +38,7 @@ var inMenu = false; mp.game.vehicle.defaultEngineBehaviour = false; -import house from './Gui/house'; -house(globalData); +require('./Gui/house'); import vehicleEntering from './vehiclesync/entering'; vehicleEntering(globalData); diff --git a/ReallifeGamemode.Client/inputhelper/index.ts b/ReallifeGamemode.Client/inputhelper/index.ts index e2f18c0d..ee46c369 100644 --- a/ReallifeGamemode.Client/inputhelper/index.ts +++ b/ReallifeGamemode.Client/inputhelper/index.ts @@ -1,13 +1,15 @@ -export default class InputHelper { +import { GlobalData } from ".."; + +export default class InputHelper { private title: string; private value: string; private created: boolean; private browser: BrowserMp; - private data: GlobalData; + private data: IGlobalData; - constructor(title: string, globalData: GlobalData) { + constructor(title: string, globalData?: IGlobalData) { this.title = title; - this.data = globalData; + this.data = globalData || GlobalData; this.cefTitleCall = this.cefTitleCall.bind(this); mp.events.add('cef_request_title', this.cefTitleCall); diff --git a/ReallifeGamemode.Client/inventory/inventory.ts b/ReallifeGamemode.Client/inventory/inventory.ts index 895b3224..31845d1c 100644 --- a/ReallifeGamemode.Client/inventory/inventory.ts +++ b/ReallifeGamemode.Client/inventory/inventory.ts @@ -1,6 +1,6 @@  -export default function inventory(globalData: GlobalData): void { +export default function inventory(globalData: IGlobalData): void { var invBrowser: BrowserMp = null; var itemIdArr; diff --git a/ReallifeGamemode.Client/util/Gangwar.ts b/ReallifeGamemode.Client/util/Gangwar.ts index b3428de8..ee13e3b1 100644 --- a/ReallifeGamemode.Client/util/Gangwar.ts +++ b/ReallifeGamemode.Client/util/Gangwar.ts @@ -1,4 +1,4 @@ -export default function gangwarHandle(globalData: GlobalData) { +export default function gangwarHandle(globalData: IGlobalData) { function inside(point, vs) { let x = point[0], @@ -65,12 +65,12 @@ } _setup(name, id, x, y, range, color, rot, owner, edit, vector) { - + var self = this; self.name = name; self.id = id; self.range = range; - self.setColor(owner); + self.setColor(owner); self.x = x; self.y = y; self.rotation = rot; @@ -91,7 +91,7 @@ } else { self.leaderBlipVector = null; } - + self.leaderColShape = null; } @@ -122,11 +122,11 @@ loadArea() { var self = this; - self.blip = mp.game.ui.addBlipForRadius(self.x, self.y, 1, self.range); - mp.game.invoke(Natives.SET_BLIP_SPRITE, self.blip, 5); - mp.game.invoke(Natives.SET_BLIP_ALPHA, self.blip, 70); - mp.game.invoke(Natives.SET_BLIP_COLOUR, self.blip, self.color); - + self.blip = mp.game.ui.addBlipForRadius(self.x, self.y, 1, self.range); + mp.game.invoke(Natives.SET_BLIP_SPRITE, self.blip, 5); + mp.game.invoke(Natives.SET_BLIP_ALPHA, self.blip, 70); + mp.game.invoke(Natives.SET_BLIP_COLOUR, self.blip, self.color); + self._colshape = mp.colshapes.newCircle(self.x, self.y, self.range * 1.5); } render() { @@ -139,9 +139,9 @@ mp.game.invoke(Natives.SET_BLIP_COORDS, self.blip, mp.players.local.position.x, mp.players.local.position.y, 1); self.x = mp.players.local.position.x; self.y = mp.players.local.position.y; - } - mp.game.invoke(Natives.SET_BLIP_ROTATION, self.blip, self.rotation); - + } + mp.game.invoke(Natives.SET_BLIP_ROTATION, self.blip, self.rotation); + } @@ -192,10 +192,10 @@ a += 0.001 } */ - } - + } + } - + if (self.isInsideArea()) { mp.game.graphics.drawText(self.name, [self.x, self.y, mp.players.local.position.z + 20], { @@ -205,7 +205,7 @@ outline: true, centre: true }); - + } } } @@ -223,11 +223,11 @@ } } } - + } - startGangWar() { + startGangWar() { var self = this; if (self._status == "normal") { let dist = mp.game.gameplay.getDistanceBetweenCoords(mp.players.local.position.x, mp.players.local.position.y, 0, self.leaderBlipVector.x, self.leaderBlipVector.y, self.leaderBlipVector.z, false); @@ -251,7 +251,7 @@ } if (status == "normal") { self._status = "normal"; - mp.game.invoke(Natives.SET_BLIP_FLASHES, self.blip, false); + mp.game.invoke(Natives.SET_BLIP_FLASHES, self.blip, false); return; } if (status == "conquered") { @@ -296,19 +296,19 @@ self.setLeaderColShape(); mp.game.invoke(Natives.SET_BLIP_SPRITE, self.leaderBlip, 437); mp.game.invoke(Natives.SET_BLIP_AS_SHORT_RANGE, self.leaderBlip, false); - - } + + } } setLeaderColShape() { var self = this; - let newVector = new mp.Vector3(self.leaderBlipVector.x, self.leaderBlipVector.y, self.leaderBlipVector.z - 2) - - self.leaderColShape = mp.markers.new(1, newVector, 2, { - color: [255, 255, 0, 150], - visible: true, - dimension: 0 - }); + let newVector = new mp.Vector3(self.leaderBlipVector.x, self.leaderBlipVector.y, self.leaderBlipVector.z - 2) + + self.leaderColShape = mp.markers.new(1, newVector, 2, { + color: [255, 255, 0, 150], + visible: true, + dimension: 0 + }); } @@ -321,7 +321,7 @@ } check() { - var self = this + var self = this if (self._entered == true) { if (!self.isInsideArea() || (self.isNearGround() == false)) { self._entered = false; @@ -329,7 +329,7 @@ } } } - + enter() { var self = this; self._timerCheck = setInterval(function () { @@ -340,8 +340,8 @@ mp.game.audio.playSoundFrontend(1, "Enter_Capture_Zone", "DLC_Apartments_Drop_Zone_Sounds", true); mp.game.graphics.stopScreenEffect("MinigameTransitionIn"); mp.game.graphics.startScreenEffect("MinigameTransitionOut", 500, false); - - } + + } mp.events.callRemote("Gangarea:Enter", JSON.stringify(self.id)); } } else if (self._entered == true) { @@ -350,7 +350,7 @@ if (self._status === "attack") { mp.game.audio.playSoundFrontend(1, "Exit_Capture_Zone", "DLC_Apartments_Drop_Zone_Sounds", true); mp.game.graphics.startScreenEffect("MinigameTransitionIn", 500, false); - } + } mp.events.callRemote("Gangarea:Leave", JSON.stringify(self.id)); } } @@ -360,7 +360,7 @@ leave() { var self = this; clearInterval(self._timerCheck); - + self.check(); } isNearGround() { @@ -469,7 +469,7 @@ last_leaderBlip = mp.game.invoke(Natives.GET_NEXT_BLIP_INFO_ID, 437); } } - + mp.events.add('GangAreas:Create', (turfsJSON) => { var turfs = JSON.parse(turfsJSON); if (gangturfs.length > 0) { @@ -485,7 +485,7 @@ } clearBlips(); if (turfs.length > 0) { - + gangturfs = []; turfs.forEach(function (turf) { if (turf.Id != undefined) { @@ -505,7 +505,7 @@ if (gangturfs[gangturfs.length - 1].id == -1) { mp.events.callRemote("SERVER:SetTurf", JSON.stringify(gangturfs[gangturfs.length - 1].x), JSON.stringify(gangturfs[gangturfs.length - 1].y), JSON.stringify(gangturfs[gangturfs.length - 1].rotation), JSON.stringify(gangturfs[gangturfs.length - 1].range), name); - } + } }); mp.events.add('ADMIN:DeleteTurf', () => { @@ -541,13 +541,13 @@ mp.events.add('CLIENT:Turf_LoadLeaderBlip', () => { gangturfs.forEach(function (turf) { - turf.setLeaderBlip(false); + turf.setLeaderBlip(false); }); }); mp.events.add('ADMIN:Turf_CreateLeaderBlip', () => { gangturfs.forEach(function (turf) { - if (turf._entered == true) { + if (turf._entered == true) { turf.setLeaderBlip(true); } }); @@ -556,7 +556,7 @@ mp.events.add('CLIENT:StartGangwar', () => { gangturfs.forEach(function (turf) { if (turf._entered == true) { - turf.startGangWar(); + turf.startGangWar(); } }); }); diff --git a/ReallifeGamemode.Client/util/checkpoint.ts b/ReallifeGamemode.Client/util/checkpoint.ts index 232de497..ae5c3bf2 100644 --- a/ReallifeGamemode.Client/util/checkpoint.ts +++ b/ReallifeGamemode.Client/util/checkpoint.ts @@ -1,7 +1,7 @@ import * as NativeUI from '../libs/NativeUI'; import InputHelper from '../inputhelper'; -export default function checkpointHandle(globalData: GlobalData) { +export default function checkpointHandle(globalData: IGlobalData) { var count = 0; var myVar; var posCp; diff --git a/ReallifeGamemode.Client/util/drivingschool.ts b/ReallifeGamemode.Client/util/drivingschool.ts index cb71d4fc..883b3fbe 100644 --- a/ReallifeGamemode.Client/util/drivingschool.ts +++ b/ReallifeGamemode.Client/util/drivingschool.ts @@ -10,7 +10,7 @@ const ItemsCollection = NativeUI.ItemsCollection; const Color = NativeUI.Color; const ListItem = NativeUI.ListItem; -export default function drivingSchoolHandle(globalData: GlobalData) { +export default function drivingSchoolHandle(globalData: IGlobalData) { var keyBound = false; var mainMenu: NativeUI.Menu; diff --git a/ReallifeGamemode.Client/util/planeschool.ts b/ReallifeGamemode.Client/util/planeschool.ts index 919ef6c1..b564574f 100644 --- a/ReallifeGamemode.Client/util/planeschool.ts +++ b/ReallifeGamemode.Client/util/planeschool.ts @@ -10,7 +10,7 @@ const ItemsCollection = NativeUI.ItemsCollection; const Color = NativeUI.Color; const ListItem = NativeUI.ListItem; -export default function planeSchoolHandle(globalData: GlobalData) { +export default function planeSchoolHandle(globalData: IGlobalData) { var keyBound = false; var mainMenu: NativeUI.Menu; diff --git a/ReallifeGamemode.Client/vehiclesync/entering.ts b/ReallifeGamemode.Client/vehiclesync/entering.ts index f16a655c..a7e45bee 100644 --- a/ReallifeGamemode.Client/vehiclesync/entering.ts +++ b/ReallifeGamemode.Client/vehiclesync/entering.ts @@ -1,4 +1,4 @@ -export default function vehicleEntering(globalData: GlobalData) { +export default function vehicleEntering(globalData: IGlobalData) { mp.events.add('render', () => { const controls = mp.game.controls; if(globalData.InChat) return; diff --git a/ReallifeGamemode.Database/Entities/House.cs b/ReallifeGamemode.Database/Entities/House.cs index a0cd8c18..c4e8258c 100644 --- a/ReallifeGamemode.Database/Entities/House.cs +++ b/ReallifeGamemode.Database/Entities/House.cs @@ -2,6 +2,8 @@ using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using GTANetworkAPI; +using ReallifeGamemode.Server.Core.API; +using ReallifeGamemode.Server.Core.RageMP; namespace ReallifeGamemode.Database.Entities { @@ -28,11 +30,17 @@ namespace ReallifeGamemode.Database.Entities [NotMapped] public Vector3 Position => new Vector3(X, Y, Z); + [NotMapped] + public Position NewPosition => new Position(X, Y, Z); + [ForeignKey("Owner")] public int? OwnerId { get; set; } public User Owner { get; set; } [NotMapped] public Player User => Owner?.Player; + + [NotMapped] + public IPlayer OwnerPlayer => new RagePlayer(User); } } diff --git a/ReallifeGamemode.Database/Entities/User.cs b/ReallifeGamemode.Database/Entities/User.cs index a0767d65..3c10c896 100644 --- a/ReallifeGamemode.Database/Entities/User.cs +++ b/ReallifeGamemode.Database/Entities/User.cs @@ -4,6 +4,8 @@ using System.ComponentModel.DataAnnotations.Schema; using System.Linq; using GTANetworkAPI; using ReallifeGamemode.Database.Models; +using ReallifeGamemode.Server.Core.API; +using ReallifeGamemode.Server.Core.RageMP; using ReallifeGamemode.Server.Types; /** @@ -104,6 +106,9 @@ namespace ReallifeGamemode.Database.Entities get => NAPI.Pools.GetAllPlayers().Where(c => c.Name.ToLower() == this.Name.ToLower()).FirstOrDefault(); } + [NotMapped] + public IPlayer NewPlayer => new RagePlayer(Player); + public override string BankAccountName => Name; } } diff --git a/ReallifeGamemode.Database/ReallifeGamemode.Database.csproj b/ReallifeGamemode.Database/ReallifeGamemode.Database.csproj index e74ff86b..d397affe 100644 --- a/ReallifeGamemode.Database/ReallifeGamemode.Database.csproj +++ b/ReallifeGamemode.Database/ReallifeGamemode.Database.csproj @@ -17,6 +17,8 @@ + + diff --git a/ReallifeGamemode.Server.Core.API/IAPI.cs b/ReallifeGamemode.Server.Core.API/IAPI.cs index ecbcf353..ead38d21 100644 --- a/ReallifeGamemode.Server.Core.API/IAPI.cs +++ b/ReallifeGamemode.Server.Core.API/IAPI.cs @@ -17,6 +17,8 @@ namespace ReallifeGamemode.Server.Core.API ITextLabelAPI TextLabel { get; } + IBlipAPI Blip { get; } + void DisableDefaultCommandErrorMessages(); void DisableDefaultSpawnBehavior(); @@ -28,5 +30,7 @@ namespace ReallifeGamemode.Server.Core.API void SetTime(int hour, int minute, int second); void TriggerClientEventForAll(string eventName, params object[] args); + + TEntity ToEntity(ushort handle) where TEntity : class, IEntity; } } diff --git a/ReallifeGamemode.Server.Core.API/IBlip.cs b/ReallifeGamemode.Server.Core.API/IBlip.cs new file mode 100644 index 00000000..a04638f2 --- /dev/null +++ b/ReallifeGamemode.Server.Core.API/IBlip.cs @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace ReallifeGamemode.Server.Core.API +{ + public interface IBlip : IEntity + { + } +} diff --git a/ReallifeGamemode.Server.Core.API/IBlipAPI.cs b/ReallifeGamemode.Server.Core.API/IBlipAPI.cs new file mode 100644 index 00000000..ca2f4730 --- /dev/null +++ b/ReallifeGamemode.Server.Core.API/IBlipAPI.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace ReallifeGamemode.Server.Core.API +{ + public interface IBlipAPI + { + IBlip CreateBlip(uint sprite, Position position, string name, byte color, byte alpha, float scale, float drawDistance, bool shortRange); + } +} diff --git a/ReallifeGamemode.Server.Core.API/IEntity.cs b/ReallifeGamemode.Server.Core.API/IEntity.cs index d2831f14..14f0d1f5 100644 --- a/ReallifeGamemode.Server.Core.API/IEntity.cs +++ b/ReallifeGamemode.Server.Core.API/IEntity.cs @@ -12,6 +12,8 @@ namespace ReallifeGamemode.Server.Core.API double Heading { get; set; } + uint Dimension { get; set; } + void Remove(); void SetSharedData(string key, T data); diff --git a/ReallifeGamemode.Server.Core.API/IPlayer.cs b/ReallifeGamemode.Server.Core.API/IPlayer.cs index ca4ae3f8..b6029184 100644 --- a/ReallifeGamemode.Server.Core.API/IPlayer.cs +++ b/ReallifeGamemode.Server.Core.API/IPlayer.cs @@ -22,7 +22,19 @@ namespace ReallifeGamemode.Server.Core.API VehicleSeat VehicleSeat { get; } - void SendMessage(string message, ChatPrefix prefix = ChatPrefix.None) => SendRawMessage(prefix.GetValue() + message); + void SendMessage(string message, ChatPrefix prefix = ChatPrefix.None) + { + if (!message.EndsWith("!") || !message.EndsWith(".") || !message.EndsWith("?")) + { + message += prefix switch + { + ChatPrefix.Error => "!", + ChatPrefix.Usage => string.Empty, + _ => ".", + }; + } + SendRawMessage(prefix.GetValue() + message); + } void SendRawMessage(string message); diff --git a/ReallifeGamemode.Server.Core.Extensions/IntegerExtensions.cs b/ReallifeGamemode.Server.Core.Extensions/IntegerExtensions.cs new file mode 100644 index 00000000..85d27d3a --- /dev/null +++ b/ReallifeGamemode.Server.Core.Extensions/IntegerExtensions.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Text; + +namespace ReallifeGamemode.Server.Core.Extensions +{ + public static class IntegerExtensions + { + public static string ToMoneyString(this int? money) + { + return ToMoneyString(money ?? 0); + } + public static string ToMoneyString(this int money) + { + return "$" + string.Format(new CultureInfo("de-DE"), "{0:C0}", money).Replace("€", "").Trim(); + } + } +} diff --git a/ReallifeGamemode.Server.Core.Extensions/PlayerExtensions.cs b/ReallifeGamemode.Server.Core.Extensions/PlayerExtensions.cs index 60e094b5..5605805b 100644 --- a/ReallifeGamemode.Server.Core.Extensions/PlayerExtensions.cs +++ b/ReallifeGamemode.Server.Core.Extensions/PlayerExtensions.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using System.Linq.Expressions; +using Microsoft.EntityFrameworkCore; using ReallifeGamemode.Database.Entities; using ReallifeGamemode.Database.Models; using ReallifeGamemode.Server.Core.API; @@ -10,14 +11,26 @@ namespace ReallifeGamemode.Server.Core.Extensions { public static class PlayerExtensions { - public static User GetUser(this IPlayer player, DatabaseContext dbContext) + public static User GetUser(this IPlayer player, DatabaseContext dbContext, bool bankAccount = false, bool faction = false) { if (player == null) { return null; } - return dbContext.Users.Where(u => u.Name == player.Name).FirstOrDefault(); + var user = dbContext.Users.Where(u => u.Name == player.Name); + + if (bankAccount) + { + user = user.Include(u => u.BankAccount); + } + + if (faction) + { + user = user.Include(u => u.Faction); + } + + return user.FirstOrDefault(); } public static AdminLevel GetAdminLevel(this IPlayer player, DatabaseContext dbContext) @@ -39,5 +52,7 @@ namespace ReallifeGamemode.Server.Core.Extensions { return player.GetAdminLevel(dbContext) >= level; } + + public static bool IsLoggedIn(this IPlayer player) => player.GetSharedData("isLoggedIn", false); } } diff --git a/ReallifeGamemode.Server.Core.RageMP/RageAPI.cs b/ReallifeGamemode.Server.Core.RageMP/RageAPI.cs index 38beb468..1b804bff 100644 --- a/ReallifeGamemode.Server.Core.RageMP/RageAPI.cs +++ b/ReallifeGamemode.Server.Core.RageMP/RageAPI.cs @@ -16,6 +16,8 @@ namespace ReallifeGamemode.Server.Core.RageMP public ITextLabelAPI TextLabel => new RageTextLabelAPI(); + public IBlipAPI Blip => new RageBlipAPI(); + public void DisableDefaultCommandErrorMessages() { NAPI.Server.SetCommandErrorMessage(null); @@ -61,5 +63,18 @@ namespace ReallifeGamemode.Server.Core.RageMP { NAPI.ClientEvent.TriggerClientEventForAll("SERVER:" + eventName, args); } + + public TEntity ToEntity(ushort handle) where TEntity : class, IEntity + { + return typeof(TEntity).Name switch + { + "IPlayer" => new RagePlayer(new NetHandle(handle, EntityType.Player).Entity()) as TEntity, + "IVehicle" => new RageVehicle(new NetHandle(handle, EntityType.Vehicle).Entity()) as TEntity, + "IMarker" => new RageMarker(new NetHandle(handle, EntityType.Marker).Entity()) as TEntity, + "ITextLabel" => new RageTextLabel(new NetHandle(handle, EntityType.TextLabel).Entity()) as TEntity, + "IColShape" => new RageColShape(new NetHandle(handle, EntityType.Colshape).Entity()) as TEntity, + _ => null, + }; + } } } diff --git a/ReallifeGamemode.Server.Core.RageMP/RageBlip.cs b/ReallifeGamemode.Server.Core.RageMP/RageBlip.cs new file mode 100644 index 00000000..68a50bec --- /dev/null +++ b/ReallifeGamemode.Server.Core.RageMP/RageBlip.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Text; +using GTANetworkAPI; +using ReallifeGamemode.Server.Core.API; + +namespace ReallifeGamemode.Server.Core.RageMP +{ + class RageBlip : RageEntity, IBlip + { + private Blip blip; + + public RageBlip(Blip blip) : base(blip) + { + this.blip = blip; + } + } +} diff --git a/ReallifeGamemode.Server.Core.RageMP/RageBlipAPI.cs b/ReallifeGamemode.Server.Core.RageMP/RageBlipAPI.cs new file mode 100644 index 00000000..3de58500 --- /dev/null +++ b/ReallifeGamemode.Server.Core.RageMP/RageBlipAPI.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Text; +using GTANetworkAPI; +using ReallifeGamemode.Server.Core.API; + +namespace ReallifeGamemode.Server.Core.RageMP +{ + class RageBlipAPI : IBlipAPI + { + public IBlip CreateBlip(uint sprite, Position position, string name, byte color, byte alpha, float scale, float drawDistance, bool shortRange) + { + return new RageBlip(NAPI.Blip.CreateBlip(sprite, position.ToVector3(), scale, color, name, alpha, drawDistance, shortRange)); + } + } +} diff --git a/ReallifeGamemode.Server.Core.RageMP/RageEntity.cs b/ReallifeGamemode.Server.Core.RageMP/RageEntity.cs index 5881e38a..23308964 100644 --- a/ReallifeGamemode.Server.Core.RageMP/RageEntity.cs +++ b/ReallifeGamemode.Server.Core.RageMP/RageEntity.cs @@ -35,6 +35,8 @@ namespace ReallifeGamemode.Server.Core.RageMP } } + public uint Dimension { get => entity.Dimension; set => entity.Dimension = value; } + public RageEntity(GTANetworkAPI.Entity rageEntity) { entity = rageEntity; @@ -57,7 +59,9 @@ namespace ReallifeGamemode.Server.Core.RageMP return fallback; } - return (entity.GetSharedData(key)).DeserializeJson(); + var data = entity.GetSharedData(key); + + return data.DeserializeJson(); } } } diff --git a/ReallifeGamemode.Server.Core/Commands/Admin/HouseCommand.cs b/ReallifeGamemode.Server.Core/Commands/Admin/HouseCommand.cs new file mode 100644 index 00000000..07cbcf01 --- /dev/null +++ b/ReallifeGamemode.Server.Core/Commands/Admin/HouseCommand.cs @@ -0,0 +1,144 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Microsoft.EntityFrameworkCore; +using ReallifeGamemode.Database.Entities; +using ReallifeGamemode.Server.Core.API; +using ReallifeGamemode.Server.Core.Extensions; +using ReallifeGamemode.Server.Core.Managers; +using ReallifeGamemode.Server.Types; + +namespace ReallifeGamemode.Server.Core.Commands.Admin +{ + class HouseCommand : AdminCommand + { + public override string CommandName => "house"; + + protected override AdminLevel AdminLevel => AdminLevel.HEADADMIN; + + public override string HelpText => "[add / remove / price / type / reloadhouses]"; + + public void Handle(IPlayer player, string option1, string option2 = null) + { + using var dbContext = GetDbContext(); + + option1 = option1?.ToLower(); + + var houseManager = Main.GetScript(); + + if (option1 == "add") + { + House nearHouse = houseManager.GetNearHouse(player.Position, dbContext); + if (nearHouse != null) + { + player.SendMessage("In der Nähe ist schon ein Haus", ChatPrefix.Error); + return; + } + + House house = new House() + { + Price = 0, + Type = "Haus", + X = (float)player.Position.X, + Y = (float)player.Position.Y, + Z = (float)player.Position.Z + }; + + dbContext.Houses.Add(house); + dbContext.SaveChanges(); + + houseManager.LoadHouse(house); + + player.SendNotification("Das Haus wurde erstellt"); + + return; + } + else if (option1 == "remove") + { + House nearHouse = houseManager.GetNearHouse(player.Position, dbContext); + if (nearHouse == null) + { + player.SendMessage("In deiner Nähe befindet sich kein Haus", ChatPrefix.Error); + return; + } + + if (nearHouse.OwnerId != null) + { + dbContext.Users.Where(u => u.Id == nearHouse.OwnerId).First().HouseId = null; + } + + foreach (HouseRental rental in dbContext.HouseRentals.Include(r => r.User).Where(r => r.HouseId == nearHouse.Id)) + { + rental.User.NewPlayer.SendRawMessage("!{#81F7BE}* Dein Mietvertrag wurde administrativ aufgelöst!"); + dbContext.HouseRentals.Remove(rental); + } + + dbContext.Houses.Remove(nearHouse); + dbContext.SaveChanges(); + + houseManager.RemoveHouse(nearHouse); + + player.SendNotification("Das Haus wurde gelöscht"); + return; + } + else if (option1 == "price") + { + if (!int.TryParse(option2, out int price)) + { + player.SendMessage("/house price [Price]", ChatPrefix.Usage); + return; + } + + House nearHouse = houseManager.GetNearHouse(player.Position, dbContext); + if (nearHouse == null) + { + player.SendMessage("In deiner Nähe befindet sich kein Haus", ChatPrefix.Error); + return; + } + + nearHouse.Price = price; + dbContext.SaveChanges(); + + houseManager.RemoveHouse(nearHouse); + houseManager.LoadHouse(nearHouse); + + player.SendNotification("Der Hauspreis wurde gesetzt"); + return; + } + else if (option1 == "type") + { + if (option2 == null) + { + player.SendMessage("/house type [Type]", ChatPrefix.Usage); + return; + } + + House nearHouse = houseManager.GetNearHouse(player.Position, dbContext); + if (nearHouse == null) + { + player.SendMessage("In deiner Nähe befindet sich kein Haus", ChatPrefix.Error); + return; + } + + nearHouse.Type = option2; + dbContext.SaveChanges(); + + houseManager.RemoveHouse(nearHouse); + houseManager.LoadHouse(nearHouse); + + player.SendNotification("Der Haustyp wurde gesetzt"); + + return; + } + else if (option1 == "reloadhouses") + { + houseManager.ReloadAllHouses(); + player.SendNotification("Alle Häuser wurden neu geladen"); + return; + } + + player.SendMessage("/house [add / remove / price / type / reloadhouses]", ChatPrefix.Usage); + } + } +} diff --git a/ReallifeGamemode.Server.Core/Commands/Command.cs b/ReallifeGamemode.Server.Core/Commands/Command.cs index 546f09f9..92966605 100644 --- a/ReallifeGamemode.Server.Core/Commands/Command.cs +++ b/ReallifeGamemode.Server.Core/Commands/Command.cs @@ -23,6 +23,6 @@ namespace ReallifeGamemode.Server.Core.Commands Log = LogManager.GetLogger(this.GetType()); } - protected DatabaseContext GetDbContext() => Main.GetDbContext(); + protected DatabaseContext GetDbContext(bool useLoggerFactory = true) => Main.GetDbContext(useLoggerFactory); } } diff --git a/ReallifeGamemode.Server.Core/Commands/User/UserCommand.cs b/ReallifeGamemode.Server.Core/Commands/User/UserCommand.cs index ef928fc4..40cae0c2 100644 --- a/ReallifeGamemode.Server.Core/Commands/User/UserCommand.cs +++ b/ReallifeGamemode.Server.Core/Commands/User/UserCommand.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Text; using ReallifeGamemode.Server.Core.API; +using ReallifeGamemode.Server.Core.Extensions; namespace ReallifeGamemode.Server.Core.Commands.User { @@ -9,7 +10,7 @@ namespace ReallifeGamemode.Server.Core.Commands.User { public override bool CanExecute(IPlayer player) { - return player.GetSharedData("loggedIn", false); + return player.IsLoggedIn(); } } } diff --git a/ReallifeGamemode.Server.Core/Main.cs b/ReallifeGamemode.Server.Core/Main.cs index bceec473..128b4d58 100644 --- a/ReallifeGamemode.Server.Core/Main.cs +++ b/ReallifeGamemode.Server.Core/Main.cs @@ -64,7 +64,7 @@ namespace ReallifeGamemode.Server.Core } } - public static DatabaseContext GetDbContext(bool useLoggerFactory = false) + public static DatabaseContext GetDbContext(bool useLoggerFactory = true) { return new DatabaseContext(useLoggerFactory); } diff --git a/ReallifeGamemode.Server.Core/Managers/HouseManager.cs b/ReallifeGamemode.Server.Core/Managers/HouseManager.cs new file mode 100644 index 00000000..0f4afc02 --- /dev/null +++ b/ReallifeGamemode.Server.Core/Managers/HouseManager.cs @@ -0,0 +1,407 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using ReallifeGamemode.Database.Entities; +using ReallifeGamemode.Server.Core.API; +using ReallifeGamemode.Server.Types; +using ReallifeGamemode.Server.Core.Extensions; +using System.Linq; +using ReallifeGamemode.Database.Models; +using ReallifeGamemode.Server.Common; + +namespace ReallifeGamemode.Server.Core.Managers +{ + class HouseManager : Script + { + private readonly Dictionary houseMarkers = new Dictionary(); + private readonly Dictionary houseLabels = new Dictionary(); + private readonly Dictionary houseColShapes = new Dictionary(); + private readonly Dictionary houseBlips = new Dictionary(); + + private readonly Dictionary> playerInColShape = new Dictionary>(); + + public HouseManager() + { + EventHandler.RegisterClientEvent("House_BuyHouse", HouseManagerBuyHouseEvent); + EventHandler.RegisterClientEvent("House_SetRentalFee", HouseManagerSetRentalFeeEvent); + EventHandler.RegisterClientEvent("House_CancelUserRental", HouseManagerCancelUserRentalEvent); + EventHandler.RegisterClientEvent("House_RentInHouse", HouseManagerRentInHouseEvent); + EventHandler.RegisterClientEvent("House_CancelOwnRental", HouseManagerCancelOwnRentalEvent); + EventHandler.RegisterClientEvent("House_SellHouse", HouseManagerSellHouseEvent); + + LoadHouses(); + } + + private void LoadHouses() + { + using var dbContext = GetDbContext(); + var houses = dbContext.Houses.Include(h => h.Owner); + foreach (House house in houses) + { + LoadHouse(house); + } + } + + public void LoadHouse(House house) + { + Position housePos = new Position(house.X, house.Y, house.Z); + + playerInColShape[house.Id] = new List(); + + houseMarkers[house.Id] = Api.Marker.CreateMarker(MarkerType.VerticalCylinder, housePos.Subtract(new Position(0, 0, 1.7)), new Position(), new Position(), 1.6f, Color.White); + string text = $"~g~Zum Verkauf\n~s~{house.Type}\nPreis: ~y~{(house.Price == 0 ? "~r~Nicht verkäuflich" : house.Price.ToMoneyString())}"; + + if (house.OwnerId != null) + { + text = $"{house.Type}\n~s~Besitzer: ~y~{house.Owner.Name}"; + + if (house.RentalFee != 0) + { + text += $"\n~s~Mietpreis: ~g~{house.RentalFee.ToMoneyString()}"; + } + } + else + { + //houseBlips[house.Id] = NAPI.Blip.CreateBlip(40, house.Position, 0.7f, 11, "Haus", shortRange: true); too many blips + } + + houseLabels[house.Id] = Api.TextLabel.CreateTextLabel(text, housePos, 10f, 1f, 0, new Color(255, 255, 255)); + + if (house.Price != 0) + { + houseColShapes[house.Id] = Api.ColShape.CreateCyclinder(housePos.Subtract(new Position(0, 0, 2)), 4.0f, 2f); + + houseColShapes[house.Id].OnEntityEnter += HouseManager_OnEntityEnterColShape; + houseColShapes[house.Id].OnEntityExit += HouseManager_OnEntityExitColShape; + } + } + + private void HouseManager_OnEntityExitColShape(IColShape colShape, IPlayer client) + { + if (!client.IsLoggedIn() || client.IsInVehicle) return; + if (!houseColShapes.ContainsValue(colShape)) + { + return; + } + int houseId = houseColShapes.Where(p => p.Value.Handle == colShape.Handle).FirstOrDefault().Key; + playerInColShape[houseId].Remove(client); + + client.TriggerEvent("CloseHouseMenu"); + } + + private void HouseManager_OnEntityEnterColShape(IColShape colShape, IPlayer client) + { + if (!client.IsLoggedIn() || client.IsInVehicle) return; + if (!houseColShapes.ContainsValue(colShape)) + { + return; + } + + using (var dbContext = GetDbContext()) + { + int houseId = houseColShapes.Where(p => p.Value.Handle == colShape.Handle).FirstOrDefault().Key; + playerInColShape[houseId].Add(client); + House house = GetHouseById(houseId, dbContext); + User user = client.GetUser(dbContext); + + client.TriggerEvent("ShowHouseMenu"); + SendPlayerHouseData(client, house); + } + } + + public House GetHouseById(int id, DatabaseContext dbContext) + { + return dbContext.Houses.Where(h => h.Id == id).Include(h => h.Owner).FirstOrDefault(); + } + + private void SendPlayerHouseData(IPlayer player, House house) + { + using (var dbContext = new DatabaseContext()) + { + User user = player.GetUser(dbContext); + var userHouseStatus = -1; + + if (house.OwnerId == null) userHouseStatus = 0; + else if (house.OwnerId == user?.Id) userHouseStatus = 1; + else if (dbContext.HouseRentals.Where(h => h.HouseId == house.Id && h.UserId == user.Id).Count() == 1) userHouseStatus = 2; + + var rentals = dbContext.HouseRentals.Where(h => h.HouseId == house.Id).Include(h => h.User).Select(h => h.User.Name).ToList(); + + var newHouse = new + { + OwnerName = house.Owner?.Name, + house.RentalFee, + house.Price, + house.Type, + Rentals = rentals + }; + + player.TriggerEvent("SetHouseData", newHouse.SerializeJson(), userHouseStatus); + } + } + + public void RemoveHouse(House house) + { + if (houseMarkers.ContainsKey(house.Id)) + { + houseMarkers[house.Id].Remove(); + houseMarkers.Remove(house.Id); + } + + if (houseLabels.ContainsKey(house.Id)) + { + houseLabels[house.Id].Remove(); + houseLabels.Remove(house.Id); + } + + if (houseColShapes.ContainsKey(house.Id)) + { + houseColShapes[house.Id].Remove(); + houseColShapes.Remove(house.Id); + } + + if (houseBlips.ContainsKey(house.Id)) + { + houseBlips[house.Id].Remove(); + houseBlips.Remove(house.Id); + } + + foreach (IPlayer client in playerInColShape[house.Id]) + { + client.TriggerEvent("CloseHouseMenu"); + } + } + + public House GetNearHouse(Position position, DatabaseContext dbContext) + { + return dbContext.Houses.Where(h => h.NewPosition.DistanceTo(position) <= 5f).Include(h => h.Owner).OrderBy(h => h.NewPosition.DistanceTo(position)).FirstOrDefault(); + } + + public void ReloadAllHouses() + { + using (var dbContext = new DatabaseContext()) + { + foreach (House house in dbContext.Houses.Include(h => h.Owner).ToList()) + { + RemoveHouse(house); + LoadHouse(house); + } + } + } + + private void HouseManagerBuyHouseEvent(IPlayer player, params object[] args) + { + using var dbContext = new DatabaseContext(); + User user = player.GetUser(dbContext, bankAccount: true); + + if (user.HouseId != null) + { + player.SendMessage("Du kann nicht mehrere Häuser besitzen", ChatPrefix.Error); + return; + } + + House house = GetNearHouse(player.Position, dbContext); + + var userBank = user.BankAccount; + + if (userBank.Balance < house.Price) + { + player.SendMessage($"Du hast nicht genug Geld für das Haus ({house.Price.ToMoneyString()})", ChatPrefix.Error); + return; + } + + house.Owner = user; + user.House = house; + + userBank.Balance -= house.Price; + + dbContext.SaveChanges(); + + RemoveHouse(house); + LoadHouse(house); + } + + private void HouseManagerSetRentalFeeEvent(IPlayer player, params object[] args) + { + var rentalFee = args[0].ToInt(); + + using var dbContext = GetDbContext(); + User user = player.GetUser(dbContext); + + if (user.HouseId == null) + { + player.SendMessage("Du besitzt kein Haus", ChatPrefix.Error); + return; + } + + House house = GetHouseById(user.HouseId.Value, dbContext); + + if (DateTime.Now - house.LastRentSetTime < TimeSpan.FromDays(7)) + { + DateTime newPossibility = house.LastRentSetTime.AddDays(7); + string dateStr = newPossibility.ToLongDateString(); + string timeStr = newPossibility.ToShortTimeString(); + player.SendNotification( + $"~r~Die Miete wurde in den letzten 7 Tagen schon verändert. Die nächste Änderung kann am {dateStr} um {timeStr} Uhr geändert werden."); + return; + } + + if (rentalFee < 0) + { + player.SendNotification("~r~Die Miete darf kein negativer Betrag sein!"); + return; + } + + if (rentalFee > 5000) + { + player.SendNotification($"~r~Die Miete darf einen Preis von {5000.ToMoneyString()} nicht überschreiten!"); + return; + } + + house.LastRentSetTime = DateTime.Now; + house.RentalFee = rentalFee; + + dbContext.SaveChanges(); + + player.SendNotification($"Der Mietpreis wurde auf ~g~{rentalFee.ToMoneyString()}~s~ gesetzt"); + + RemoveHouse(house); + LoadHouse(house); + } + + private void HouseManagerCancelUserRentalEvent(IPlayer player, params object[] args) + { + string userName = args[0] as string; + using var dbContext = new DatabaseContext(); + User user = player.GetUser(dbContext); + if (user.HouseId == null) + { + player.SendMessage("Du besitzt kein Haus", ChatPrefix.Error); + return; + } + + User target = dbContext.Users.Where(u => u.Name == userName).FirstOrDefault(); + if (target == null) + { + player.SendNotification("~r~Dieser Spieler wurde nicht gefunden."); + return; + } + + House house = GetHouseById(user.HouseId.Value, dbContext); + + HouseRental rental = dbContext.HouseRentals.Where(h => h.HouseId == house.Id && h.UserId == target.Id).FirstOrDefault(); + if (rental == null) + { + player.SendNotification("~r~Der Spieler ist nicht in deinem Haus eingemietet"); + return; + } + + dbContext.HouseRentals.Remove(rental); + dbContext.SaveChanges(); + + target.NewPlayer?.SendNotification($"~y~{player.Name}~s~ hat deinen Mietvertrag ~g~gekündigt~s~."); + + player.SendNotification("Du hast dem Spieler ~y~" + target.Name + "~s~ den Mietvertrag gekündigt."); + SendPlayerHouseData(player, house); + } + + private void HouseManagerRentInHouseEvent(IPlayer player, params object[] args) + { + using var dbContext = new DatabaseContext(); + User user = player.GetUser(dbContext); + House house = GetNearHouse(player.Position, dbContext); + + if (house == null) + { + player.SendMessage("In deiner Nähe ist kein Haus", ChatPrefix.Error); + return; + } + + if (house.RentalFee == 0) + { + player.SendMessage("Dieses Haus hat keinen Platz für Mieter", ChatPrefix.Error); + return; + } + + HouseRental newRental = new HouseRental + { + HouseId = house.Id, + UserId = user.Id + }; + + dbContext.HouseRentals.Add(newRental); + + dbContext.SaveChanges(); + + player.SendNotification("~g~Du hast dich in das Haus eingemietet"); + + house.OwnerPlayer?.SendNotification($"~y~{player.Name}~s~ hat sich in dein Haus eingemietet."); + SendPlayerHouseData(player, house); + } + + private void HouseManagerCancelOwnRentalEvent(IPlayer player, params object[] args) + { + using var dbContext = GetDbContext(); + User user = player.GetUser(dbContext); + House house = GetNearHouse(player.Position, dbContext); + + if (house == null) + { + player.SendMessage("In deiner Nähe ist kein Haus", ChatPrefix.Error); + return; + } + + HouseRental rental = dbContext.HouseRentals.Where(h => h.HouseId == house.Id && h.UserId == user.Id).FirstOrDefault(); + + if (rental == null) + { + player.SendNotification("~r~Du bist nin diesem Haus nicht eingemietet"); + return; + } + + dbContext.HouseRentals.Remove(rental); + + dbContext.SaveChanges(); + + player.SendNotification("~g~Du hast den Mietvertrag gekündigt."); + house.OwnerPlayer?.SendNotification($"~y~{player.Name}~s~ hat seinen Mietvertrag gekündigt."); + + RemoveHouse(house); + LoadHouse(house); + + SendPlayerHouseData(player, house); + } + + private void HouseManagerSellHouseEvent(IPlayer player, params object[] args) + { + using var dbContext = GetDbContext(); + User user = player.GetUser(dbContext); + if (user.HouseId == null) + { + player.SendMessage("Du besitzt kein Haus", ChatPrefix.Error); + return; + } + + House house = GetHouseById(user.HouseId.Value, dbContext); + house.OwnerId = null; + user.HouseId = null; + + var backMoney = (int)(house.Price * 0.4); + + player.SendMessage("Du bekommst vom Hausverkauf ~g~" + backMoney.ToMoneyString() + "~s~ zurück."); + + user.BankAccount.Balance += backMoney; + + dbContext.SaveChanges(); + + player.SendMessage("!{#81F7BE}* Du hast dein Haus verkauft."); + + RemoveHouse(house); + LoadHouse(house); + + SendPlayerHouseData(player, house); + } + } +} diff --git a/ReallifeGamemode.Server.Core/Script.cs b/ReallifeGamemode.Server.Core/Script.cs index c7f3632d..cae8eded 100644 --- a/ReallifeGamemode.Server.Core/Script.cs +++ b/ReallifeGamemode.Server.Core/Script.cs @@ -21,6 +21,6 @@ namespace ReallifeGamemode.Server.Core Log = LogManager.GetLogger(GetType()); } - protected DatabaseContext GetDbContext() => Main.GetDbContext(); + protected DatabaseContext GetDbContext(bool useLoggerFactory = true) => Main.GetDbContext(useLoggerFactory); } } diff --git a/ReallifeGamemode.Server.Types/CommandArgumentCountMismatchException.cs b/ReallifeGamemode.Server.Types/CommandArgumentCountMismatchException.cs index e74f7636..310bfe83 100644 --- a/ReallifeGamemode.Server.Types/CommandArgumentCountMismatchException.cs +++ b/ReallifeGamemode.Server.Types/CommandArgumentCountMismatchException.cs @@ -4,7 +4,7 @@ using System.Text; namespace ReallifeGamemode.Server.Types { - public class CommandArgumentCountMismatchException : Exception + public class CommandArgumentCountMismatchException : SendHelpTextException { } diff --git a/ReallifeGamemode.Server/Commands/AdminCommands.cs b/ReallifeGamemode.Server/Commands/AdminCommands.cs index ecb04ae2..93a946f3 100644 --- a/ReallifeGamemode.Server/Commands/AdminCommands.cs +++ b/ReallifeGamemode.Server/Commands/AdminCommands.cs @@ -2793,144 +2793,10 @@ namespace ReallifeGamemode.Server.Commands ChatService.SendMessage(player, "~b~[ADMIN]~s~ Die Türen wurden erfolgreich neugeladen."); } - [Command("house", "~m~Benutzung: ~s~/house [add / remove / price / type / reloadhouses]", GreedyArg = true)] - public void CmdAdminHouse(Player player, string option1 = null, string option2 = null) - { - if (!player.GetUser()?.IsAdmin(AdminLevel.HEADADMIN) ?? true) - { - ChatService.NotAuthorized(player); - return; - } - - option1 = option1?.ToLower(); - - if (option1 == "add") - { - House nearHouse = HouseManager.GetNearHouse(player.Position); - if (nearHouse != null) - { - ChatService.ErrorMessage(player, "In der Nähe ist schon ein Haus"); - return; - } - - using (var dbContext = new DatabaseContext()) - { - House house = new House() - { - Price = 0, - Type = "Haus", - X = player.Position.X, - Y = player.Position.Y, - Z = player.Position.Z - }; - - dbContext.Houses.Add(house); - dbContext.SaveChanges(); - - HouseManager.LoadHouse(house); - - player.SendNotification("Das Haus wurde erstellt"); - } - - return; - } - else if (option1 == "remove") - { - using (var dbContext = new DatabaseContext()) - { - House nearHouse = HouseManager.GetNearHouse(player.Position, dbContext); - if (nearHouse == null) - { - ChatService.ErrorMessage(player, "In deiner Nähe befindet sich kein Haus"); - return; - } - - if (nearHouse.OwnerId != null) - { - dbContext.Users.Where(u => u.Id == nearHouse.OwnerId).First().HouseId = null; - } - - foreach (HouseRental rental in dbContext.HouseRentals.Include(r => r.User).Where(r => r.HouseId == nearHouse.Id)) - { - rental.User.Player?.SendChatMessage("!{#81F7BE}* Dein Mietvertrag wurde administrativ aufgelöst!"); - dbContext.HouseRentals.Remove(rental); - } - - dbContext.Houses.Remove(nearHouse); - dbContext.SaveChanges(); - - HouseManager.RemoveHouse(nearHouse); - - player.SendNotification("Das Haus wurde gelöscht"); - } - - return; - } - else if (option1 == "price") - { - if (!int.TryParse(option2, out int price)) - { - ChatService.SendMessage(player, "~m~Benutzung: ~s~/house price [Price]"); - return; - } - - using (var dbContext = new DatabaseContext()) - { - House nearHouse = HouseManager.GetNearHouse(player.Position, dbContext); - if (nearHouse == null) - { - ChatService.ErrorMessage(player, "In deiner Nähe befindet sich kein Haus"); - return; - } - - nearHouse.Price = price; - dbContext.SaveChanges(); - - HouseManager.RemoveHouse(nearHouse); - HouseManager.LoadHouse(nearHouse); - - player.SendNotification("Der Hauspreis wurde gesetzt"); - } - - return; - } - else if (option1 == "type") - { - if (option2 == null) - { - ChatService.ErrorMessage(player, "~m~Benutzung: ~s~/house type [Type]"); - return; - } - - using (var dbContext = new DatabaseContext()) - { - House nearHouse = HouseManager.GetNearHouse(player.Position, dbContext); - if (nearHouse == null) - { - ChatService.ErrorMessage(player, "In deiner Nähe befindet sich kein Haus"); - return; - } - - nearHouse.Type = option2; - dbContext.SaveChanges(); - - HouseManager.RemoveHouse(nearHouse); - HouseManager.LoadHouse(nearHouse); - - player.SendNotification("Der Haustyp wurde gesetzt"); - } - - return; - } - else if (option1 == "reloadhouses") - { - HouseManager.ReloadAllHouses(); - player.SendNotification("Alle Häuser wurden neu geladen"); - return; - } - - player.SendChatMessage("~m~Benutzung: ~s~/house [add / remove / price / type / reloadhouses]"); - } + //[Command("house", "~m~Benutzung: ~s~/house [add / remove / price / type / reloadhouses]", GreedyArg = true)] + //public void CmdAdminHouse(Player player, string option1 = null, string option2 = null) + //{ + //} [Command("paydaydrop", "~m~Benutzung: ~s~/paydaydrop")] public void CmdAdminPaydaydrop(Player player) diff --git a/ReallifeGamemode.Server/Events/Login.cs b/ReallifeGamemode.Server/Events/Login.cs index 19f9e61c..3e3e7a0a 100644 --- a/ReallifeGamemode.Server/Events/Login.cs +++ b/ReallifeGamemode.Server/Events/Login.cs @@ -10,6 +10,7 @@ using ReallifeGamemode.Server.Wanted; using ReallifeGamemode.Database; using ReallifeGamemode.Server.Types; using ReallifeGamemode.Database.Entities; +using Newtonsoft.Json; /** * @overview Life of German Reallife - Event Login (Login.cs) @@ -52,6 +53,7 @@ namespace ReallifeGamemode.Server.Events player.Name = username; player.TriggerEvent("SERVER:Login_Success"); player.SetData("isLoggedIn", true); + player.SetSharedData("isLoggedIn", JsonConvert.SerializeObject(true)); player.SetData("spec", true); player.SetData("duty", false); player.TriggerEvent("SERVER:SET_HANDMONEY", user.Handmoney, 0); diff --git a/ReallifeGamemode.Server/Main.cs b/ReallifeGamemode.Server/Main.cs index 34df3cdd..c9cfd7bc 100644 --- a/ReallifeGamemode.Server/Main.cs +++ b/ReallifeGamemode.Server/Main.cs @@ -96,7 +96,7 @@ namespace ReallifeGamemode.Server CityHallManager.LoadCityHall(); JobManager.LoadJobs(); TaxiDriverJob.StartTaxiTimer(); - HouseManager.LoadHouses(); + //HouseManager.LoadHouses(); DrivingSchool.DrivingSchool.Setup(); PlaneSchool.Setup(); Gangwar.Gangwar.loadTurfs(); diff --git a/ReallifeGamemode.Server/Managers/HouseManager.cs b/ReallifeGamemode.Server/Managers/HouseManager.cs index bed7a705..af4c81e2 100644 --- a/ReallifeGamemode.Server/Managers/HouseManager.cs +++ b/ReallifeGamemode.Server/Managers/HouseManager.cs @@ -12,439 +12,432 @@ using System.Text; namespace ReallifeGamemode.Server.Managers { - public class HouseManager : Script - { - private static readonly Dictionary houseMarkers = new Dictionary(); - private static readonly Dictionary houseLabels = new Dictionary(); - private static readonly Dictionary houseColShapes = new Dictionary(); - private static readonly Dictionary houseBlips = new Dictionary(); - - private static readonly Dictionary> playerInColShape = new Dictionary>(); - - public static async void LoadHouses() - { - using (var dbContext = new DatabaseContext()) - { - List houses = await dbContext.Houses.Include(h => h.Owner).ToListAsync(); - foreach (House house in houses) - { - LoadHouse(house, true); - } - } - } - - public static async void ReloadAllHouses() - { - using (var dbContext = new DatabaseContext()) - { - foreach (House house in await dbContext.Houses.Include(h => h.Owner).ToListAsync()) - { - RemoveHouse(house); - LoadHouse(house, false); - } - } - } - - public static House GetNearHouse(Vector3 position, DatabaseContext dbContext = null) - { - if (dbContext == null) - { - using (dbContext = new DatabaseContext()) - { - return dbContext.Houses.Where(h => h.Position.DistanceTo(position) <= 5f).Include(h => h.Owner).OrderBy(h => h.Position.DistanceTo(position)).FirstOrDefault(); - } - } - else - { - return dbContext.Houses.Where(h => h.Position.DistanceTo(position) <= 5f).Include(h => h.Owner).OrderBy(h => h.Position.DistanceTo(position)).FirstOrDefault(); - } - } - - public void AddHouse(string type, int price, Vector3 position) - { - using (var dbContext = new DatabaseContext()) - { - var house = new House() - { - Price = price, - Type = type, - X = position.X, - Y = position.Y, - Z = position.Z - }; - - dbContext.Houses.Add(house); - dbContext.SaveChanges(); - - LoadHouse(house); - } - } - - public static House GetHouseById(int id, DatabaseContext dbContext = null) - { - if (dbContext == null) - { - using (dbContext = new DatabaseContext()) - { - return dbContext.Houses.Where(h => h.Id == id).Include(h => h.Owner).FirstOrDefault(); - } - } - else - { - return dbContext.Houses.Where(h => h.Id == id).Include(h => h.Owner).FirstOrDefault(); - } - } - - public static void LoadHouse(House house, bool loadUser = true) - { - if (loadUser) house = house.Refresh(); - - playerInColShape[house.Id] = new List(); - - houseMarkers[house.Id] = NAPI.Marker.CreateMarker(MarkerType.VerticalCylinder, house.Position.Subtract(new Vector3(0, 0, 1.7)), new Vector3(), new Vector3(), 1.6f, new Color(255, 255, 255)).Handle; - string text = $"~g~Zum Verkauf\n~s~{house.Type}\nPreis: ~y~{(house.Price == 0 ? "~r~Nicht verkäuflich" : house.Price.ToMoneyString())}"; - - if (house.OwnerId != null) - { - text = $"{house.Type}\n~s~Besitzer: ~y~{house.Owner.Name}"; - - if (house.RentalFee != 0) - { - text += $"\n~s~Mietpreis: ~g~{house.RentalFee.ToMoneyString()}"; - } - } - else - { - //houseBlips[house.Id] = NAPI.Blip.CreateBlip(40, house.Position, 0.7f, 11, "Haus", shortRange: true); too many blips - - } - - - - houseLabels[house.Id] = NAPI.TextLabel.CreateTextLabel(text, house.Position, 10f, 1f, 0, new Color(255, 255, 255)); - - if (house.Price != 0) - { - houseColShapes[house.Id] = NAPI.ColShape.CreateCylinderColShape(house.Position.Subtract(new Vector3(0, 0, 2)), 2.0f, 5f); - - houseColShapes[house.Id].Entity().OnEntityEnterColShape += HouseManager_OnEntityEnterColShape; - houseColShapes[house.Id].Entity().OnEntityExitColShape += HouseManager_OnEntityExitColShape; - } - } - - private static void HouseManager_OnEntityExitColShape(ColShape colShape, Player client) - { - if (!client.IsLoggedIn() || client.IsInVehicle) return; - if (!houseColShapes.ContainsValue(colShape.Handle)) - { - return; - } - int houseId = houseColShapes.Where(p => p.Value.Value == colShape.Handle.Value).FirstOrDefault().Key; - playerInColShape[houseId].Remove(client); - - client.TriggerEvent("SERVER:CloseHouseMenu"); - } - - private static void HouseManager_OnEntityEnterColShape(ColShape colShape, Player client) - { - if (!client.IsLoggedIn() || client.IsInVehicle) return; - if (!houseColShapes.ContainsValue(colShape.Handle)) - { - return; - } - int houseId = houseColShapes.Where(p => p.Value.Value == colShape.Handle.Value).FirstOrDefault().Key; - playerInColShape[houseId].Add(client); - House house = GetHouseById(houseId); - User user = client.GetUser(); - - client.TriggerEvent("SERVER:ShowHouseMenu"); - SendPlayerHouseData(client, house); - } - - private static void SendPlayerHouseData(Player player, House house) - { - User user = player.GetUser(); - var userHouseStatus = -1; - - using (var dbContext = new DatabaseContext()) - { - if (house.OwnerId == null) userHouseStatus = 0; - else if (house.OwnerId == user?.Id) userHouseStatus = 1; - else if (dbContext.HouseRentals.Where(h => h.HouseId == house.Id && h.UserId == user.Id).Count() == 1) userHouseStatus = 2; - - var rentals = dbContext.HouseRentals.Where(h => h.HouseId == house.Id).Include(h => h.User).Select(h => h.User.Name).ToList(); - - var newHouse = new - { - OwnerName = house.Owner?.Name, - house.RentalFee, - house.Price, - house.Type, - Rentals = rentals - }; - - player.TriggerEvent("SERVER:SetHouseData", JsonConvert.SerializeObject(newHouse), userHouseStatus); - } - } - - public static void RemoveHouse(House house) - { - if (houseMarkers.ContainsKey(house.Id)) - { - houseMarkers[house.Id].Entity().Delete(); - houseMarkers.Remove(house.Id); - } - - if (houseLabels.ContainsKey(house.Id)) - { - houseLabels[house.Id].Entity().Delete(); - houseLabels.Remove(house.Id); - } - - if (houseColShapes.ContainsKey(house.Id)) - { - houseColShapes[house.Id].Entity().Delete(); - houseColShapes.Remove(house.Id); - } - - if (houseBlips.ContainsKey(house.Id)) - { - houseBlips[house.Id].Entity().Delete(); - houseBlips.Remove(house.Id); - } - - foreach (Player client in playerInColShape[house.Id]) - { - client.TriggerEvent("SERVER:CloseHouseMenu"); - } - } - - [RemoteEvent("CLIENT:House_BuyHouse")] - public void HouseManagerBuyHouseEvent(Player player) - { - using (var dbContext = new DatabaseContext()) - { - User user = player.GetUser(dbContext); - - if (user.HouseId != null) - { - ChatService.ErrorMessage(player, "Du kann nicht mehrere Häuser besitzen"); - return; - } - - House house = GetNearHouse(player.Position, dbContext); - - var userBank = user.BankAccount; - - if (userBank.Balance < house.Price) - { - ChatService.ErrorMessage(player, $"Du hast nicht genug Geld für das Haus ({house.Price.ToMoneyString()})"); - return; - } - - house.Owner = user; - user.House = house; - - userBank.Balance -= house.Price; - - dbContext.SaveChanges(); - - RemoveHouse(house); - LoadHouse(house); - } - } - - [RemoteEvent("CLIENT:House_SetRentalFee")] - public void HouseManagerSetRentalFeeEvent(Player player, int rentalFee) - { - using (var dbContext = new DatabaseContext()) - { - User user = player.GetUser(dbContext); - - if (user.HouseId == null) - { - ChatService.ErrorMessage(player, "Du besitzt kein Haus"); - return; - } - - House house = GetHouseById(user.HouseId.Value, dbContext); - - if (DateTime.Now - house.LastRentSetTime < TimeSpan.FromDays(7)) - { - DateTime newPossibility = house.LastRentSetTime.AddDays(7); - string dateStr = newPossibility.ToLongDateString(); - string timeStr = newPossibility.ToShortTimeString(); - player.SendNotification( - $"~r~Die Miete wurde in den letzten 7 Tagen schon verändert. Die nächste Änderung kann am {dateStr} um {timeStr} Uhr geändert werden."); - return; - } - - if (rentalFee < 0) - { - player.SendNotification("~r~Die Miete darf kein negativer Betrag sein!"); - return; - } - - if (rentalFee > 5000) - { - player.SendNotification($"~r~Die Miete darf einen Preis von {5000.ToMoneyString()} nicht überschreiten!"); - return; - } - - house.LastRentSetTime = DateTime.Now; - house.RentalFee = rentalFee; - - dbContext.SaveChanges(); - - player.SendNotification($"Der Mietpreis wurde auf ~g~{rentalFee.ToMoneyString()}~s~ gesetzt"); - - RemoveHouse(house); - LoadHouse(house); - } - } - - [RemoteEvent("CLIENT:House_CancelUserRental")] - public void HouseManagerCancelUserRentalEvent(Player player, string userName) - { - using (var dbContext = new DatabaseContext()) - { - User user = player.GetUser(dbContext); - if (user.HouseId == null) - { - ChatService.ErrorMessage(player, "Du besitzt kein Haus"); - return; - } - - User target = dbContext.Users.Where(u => u.Name == userName).FirstOrDefault(); - if (target == null) - { - player.SendNotification("~r~Dieser Spieler wurde nicht gefunden."); - return; - } - - House house = GetHouseById(user.HouseId.Value, dbContext); - - HouseRental rental = dbContext.HouseRentals.Where(h => h.HouseId == house.Id && h.UserId == target.Id).FirstOrDefault(); - if (rental == null) - { - player.SendNotification("~r~Der Spieler ist nicht in deinem Haus eingemietet"); - return; - } - - dbContext.HouseRentals.Remove(rental); - dbContext.SaveChanges(); - - target.Player?.SendNotification($"~y~{player.Name}~s~ hat deinen Mietvertrag ~g~gekündigt~s~."); - - player.SendNotification("Du hast dem Spieler ~y~" + target.Name + "~s~ den Mietvertrag gekündigt."); - SendPlayerHouseData(player, house); - } - } - - [RemoteEvent("CLIENT:House_RentInHouse")] - public void HouseManagerRentInHouseEvent(Player player) - { - using (var dbContext = new DatabaseContext()) - { - User user = player.GetUser(dbContext); - House house = GetNearHouse(player.Position, dbContext); - - if (house == null) - { - ChatService.ErrorMessage(player, "In deiner Nähe ist kein Haus"); - return; - } - - if (house.RentalFee == 0) - { - player.SendChatMessage("~r~Dieses Haus hat keinen Platz für Mieter!"); - return; - } - - HouseRental newRental = new HouseRental - { - HouseId = house.Id, - UserId = user.Id - }; - - dbContext.HouseRentals.Add(newRental); - - dbContext.SaveChanges(); - - player.SendNotification("~g~Du hast dich in das Haus eingemietet"); - - house.User?.SendNotification($"~y~{player.Name}~s~ hat sich in dein Haus eingemietet."); - SendPlayerHouseData(player, house); - } - } - - [RemoteEvent("CLIENT:House_CancelOwnRental")] - public void HouseManagerCancelOwnRentalEvent(Player player) - { - using (var dbContext = new DatabaseContext()) - { - User user = player.GetUser(dbContext); - House house = GetNearHouse(player.Position, dbContext); - - if (house == null) - { - ChatService.ErrorMessage(player, "In deiner Nähe ist kein Haus"); - return; - } - - HouseRental rental = dbContext.HouseRentals.Where(h => h.HouseId == house.Id && h.UserId == user.Id).FirstOrDefault(); - - if (rental == null) - { - player.SendNotification("~r~Du bist nin diesem Haus nicht eingemietet"); - return; - } - - dbContext.HouseRentals.Remove(rental); - - dbContext.SaveChanges(); - - player.SendNotification("~g~Du hast den Mietvertrag gekündigt."); - house.User?.SendNotification($"~y~{player.Name}~s~ hat seinen Mietvertrag gekündigt."); - - RemoveHouse(house); - LoadHouse(house); - - SendPlayerHouseData(player, house); - } - } - - [RemoteEvent("CLIENT:House_SellHouse")] - public void HouseManagerSellHouseEvent(Player player) - { - using (var dbContext = new DatabaseContext()) - { - User user = player.GetUser(dbContext); - if (user.HouseId == null) - { - ChatService.ErrorMessage(player, "Du besitzt kein Haus"); - return; - } - - House house = GetHouseById(user.HouseId.Value, dbContext); - house.OwnerId = null; - user.HouseId = null; + //public class HouseManager : Script + //{ + // private static readonly Dictionary houseMarkers = new Dictionary(); + // private static readonly Dictionary houseLabels = new Dictionary(); + // private static readonly Dictionary houseColShapes = new Dictionary(); + // private static readonly Dictionary houseBlips = new Dictionary(); + + // private static readonly Dictionary> playerInColShape = new Dictionary>(); + + // public static async void LoadHouses() + // { + + // } + + // public static async void ReloadAllHouses() + // { + // using (var dbContext = new DatabaseContext()) + // { + // foreach (House house in await dbContext.Houses.Include(h => h.Owner).ToListAsync()) + // { + // RemoveHouse(house); + // LoadHouse(house, false); + // } + // } + // } + + // public static House GetNearHouse(Vector3 position, DatabaseContext dbContext = null) + // { + // if (dbContext == null) + // { + // using (dbContext = new DatabaseContext()) + // { + // return dbContext.Houses.Where(h => h.Position.DistanceTo(position) <= 5f).Include(h => h.Owner).OrderBy(h => h.Position.DistanceTo(position)).FirstOrDefault(); + // } + // } + // else + // { + // return dbContext.Houses.Where(h => h.Position.DistanceTo(position) <= 5f).Include(h => h.Owner).OrderBy(h => h.Position.DistanceTo(position)).FirstOrDefault(); + // } + // } + + // public void AddHouse(string type, int price, Vector3 position) + // { + // using (var dbContext = new DatabaseContext()) + // { + // var house = new House() + // { + // Price = price, + // Type = type, + // X = position.X, + // Y = position.Y, + // Z = position.Z + // }; + + // dbContext.Houses.Add(house); + // dbContext.SaveChanges(); + + // LoadHouse(house); + // } + // } + + // public static House GetHouseById(int id, DatabaseContext dbContext = null) + // { + // if (dbContext == null) + // { + // using (dbContext = new DatabaseContext()) + // { + // return dbContext.Houses.Where(h => h.Id == id).Include(h => h.Owner).FirstOrDefault(); + // } + // } + // else + // { + // return dbContext.Houses.Where(h => h.Id == id).Include(h => h.Owner).FirstOrDefault(); + // } + // } + + // public static void LoadHouse(House house, bool loadUser = true) + // { + // if (loadUser) house = house.Refresh(); + + // playerInColShape[house.Id] = new List(); + + // houseMarkers[house.Id] = NAPI.Marker.CreateMarker(MarkerType.VerticalCylinder, house.Position.Subtract(new Vector3(0, 0, 1.7)), new Vector3(), new Vector3(), 1.6f, new Color(255, 255, 255)).Handle; + // string text = $"~g~Zum Verkauf\n~s~{house.Type}\nPreis: ~y~{(house.Price == 0 ? "~r~Nicht verkäuflich" : house.Price.ToMoneyString())}"; + + // if (house.OwnerId != null) + // { + // text = $"{house.Type}\n~s~Besitzer: ~y~{house.Owner.Name}"; + + // if (house.RentalFee != 0) + // { + // text += $"\n~s~Mietpreis: ~g~{house.RentalFee.ToMoneyString()}"; + // } + // } + // else + // { + // //houseBlips[house.Id] = NAPI.Blip.CreateBlip(40, house.Position, 0.7f, 11, "Haus", shortRange: true); too many blips + + // } + + + + // houseLabels[house.Id] = NAPI.TextLabel.CreateTextLabel(text, house.Position, 10f, 1f, 0, new Color(255, 255, 255)); + + // if (house.Price != 0) + // { + // houseColShapes[house.Id] = NAPI.ColShape.CreateCylinderColShape(house.Position.Subtract(new Vector3(0, 0, 2)), 2.0f, 5f); + + // houseColShapes[house.Id].Entity().OnEntityEnterColShape += HouseManager_OnEntityEnterColShape; + // houseColShapes[house.Id].Entity().OnEntityExitColShape += HouseManager_OnEntityExitColShape; + // } + // } + + // private static void HouseManager_OnEntityExitColShape(ColShape colShape, Player client) + // { + // if (!client.IsLoggedIn() || client.IsInVehicle) return; + // if (!houseColShapes.ContainsValue(colShape.Handle)) + // { + // return; + // } + // int houseId = houseColShapes.Where(p => p.Value.Value == colShape.Handle.Value).FirstOrDefault().Key; + // playerInColShape[houseId].Remove(client); + + // client.TriggerEvent("SERVER:CloseHouseMenu"); + // } + + // private static void HouseManager_OnEntityEnterColShape(ColShape colShape, Player client) + // { + // if (!client.IsLoggedIn() || client.IsInVehicle) return; + // if (!houseColShapes.ContainsValue(colShape.Handle)) + // { + // return; + // } + // int houseId = houseColShapes.Where(p => p.Value.Value == colShape.Handle.Value).FirstOrDefault().Key; + // playerInColShape[houseId].Add(client); + // House house = GetHouseById(houseId); + // User user = client.GetUser(); + + // client.TriggerEvent("SERVER:ShowHouseMenu"); + // SendPlayerHouseData(client, house); + // } + + // private static void SendPlayerHouseData(Player player, House house) + // { + // User user = player.GetUser(); + // var userHouseStatus = -1; + + // using (var dbContext = new DatabaseContext()) + // { + // if (house.OwnerId == null) userHouseStatus = 0; + // else if (house.OwnerId == user?.Id) userHouseStatus = 1; + // else if (dbContext.HouseRentals.Where(h => h.HouseId == house.Id && h.UserId == user.Id).Count() == 1) userHouseStatus = 2; + + // var rentals = dbContext.HouseRentals.Where(h => h.HouseId == house.Id).Include(h => h.User).Select(h => h.User.Name).ToList(); + + // var newHouse = new + // { + // OwnerName = house.Owner?.Name, + // house.RentalFee, + // house.Price, + // house.Type, + // Rentals = rentals + // }; + + // player.TriggerEvent("SERVER:SetHouseData", JsonConvert.SerializeObject(newHouse), userHouseStatus); + // } + // } + + // public static void RemoveHouse(House house) + // { + // if (houseMarkers.ContainsKey(house.Id)) + // { + // houseMarkers[house.Id].Entity().Delete(); + // houseMarkers.Remove(house.Id); + // } + + // if (houseLabels.ContainsKey(house.Id)) + // { + // houseLabels[house.Id].Entity().Delete(); + // houseLabels.Remove(house.Id); + // } + + // if (houseColShapes.ContainsKey(house.Id)) + // { + // houseColShapes[house.Id].Entity().Delete(); + // houseColShapes.Remove(house.Id); + // } + + // if (houseBlips.ContainsKey(house.Id)) + // { + // houseBlips[house.Id].Entity().Delete(); + // houseBlips.Remove(house.Id); + // } + + // foreach (Player client in playerInColShape[house.Id]) + // { + // client.TriggerEvent("SERVER:CloseHouseMenu"); + // } + // } + + // [RemoteEvent("CLIENT:House_BuyHouse")] + // public void HouseManagerBuyHouseEvent(Player player) + // { + // using (var dbContext = new DatabaseContext()) + // { + // User user = player.GetUser(dbContext); + + // if (user.HouseId != null) + // { + // ChatService.ErrorMessage(player, "Du kann nicht mehrere Häuser besitzen"); + // return; + // } + + // House house = GetNearHouse(player.Position, dbContext); + + // var userBank = user.BankAccount; + + // if (userBank.Balance < house.Price) + // { + // ChatService.ErrorMessage(player, $"Du hast nicht genug Geld für das Haus ({house.Price.ToMoneyString()})"); + // return; + // } + + // house.Owner = user; + // user.House = house; + + // userBank.Balance -= house.Price; + + // dbContext.SaveChanges(); + + // RemoveHouse(house); + // LoadHouse(house); + // } + // } + + // [RemoteEvent("CLIENT:House_SetRentalFee")] + // public void HouseManagerSetRentalFeeEvent(Player player, int rentalFee) + // { + // using (var dbContext = new DatabaseContext()) + // { + // User user = player.GetUser(dbContext); + + // if (user.HouseId == null) + // { + // ChatService.ErrorMessage(player, "Du besitzt kein Haus"); + // return; + // } + + // House house = GetHouseById(user.HouseId.Value, dbContext); + + // if (DateTime.Now - house.LastRentSetTime < TimeSpan.FromDays(7)) + // { + // DateTime newPossibility = house.LastRentSetTime.AddDays(7); + // string dateStr = newPossibility.ToLongDateString(); + // string timeStr = newPossibility.ToShortTimeString(); + // player.SendNotification( + // $"~r~Die Miete wurde in den letzten 7 Tagen schon verändert. Die nächste Änderung kann am {dateStr} um {timeStr} Uhr geändert werden."); + // return; + // } + + // if (rentalFee < 0) + // { + // player.SendNotification("~r~Die Miete darf kein negativer Betrag sein!"); + // return; + // } + + // if (rentalFee > 5000) + // { + // player.SendNotification($"~r~Die Miete darf einen Preis von {5000.ToMoneyString()} nicht überschreiten!"); + // return; + // } + + // house.LastRentSetTime = DateTime.Now; + // house.RentalFee = rentalFee; + + // dbContext.SaveChanges(); + + // player.SendNotification($"Der Mietpreis wurde auf ~g~{rentalFee.ToMoneyString()}~s~ gesetzt"); + + // RemoveHouse(house); + // LoadHouse(house); + // } + // } + + // [RemoteEvent("CLIENT:House_CancelUserRental")] + // public void HouseManagerCancelUserRentalEvent(Player player, string userName) + // { + // using (var dbContext = new DatabaseContext()) + // { + // User user = player.GetUser(dbContext); + // if (user.HouseId == null) + // { + // ChatService.ErrorMessage(player, "Du besitzt kein Haus"); + // return; + // } + + // User target = dbContext.Users.Where(u => u.Name == userName).FirstOrDefault(); + // if (target == null) + // { + // player.SendNotification("~r~Dieser Spieler wurde nicht gefunden."); + // return; + // } + + // House house = GetHouseById(user.HouseId.Value, dbContext); + + // HouseRental rental = dbContext.HouseRentals.Where(h => h.HouseId == house.Id && h.UserId == target.Id).FirstOrDefault(); + // if (rental == null) + // { + // player.SendNotification("~r~Der Spieler ist nicht in deinem Haus eingemietet"); + // return; + // } + + // dbContext.HouseRentals.Remove(rental); + // dbContext.SaveChanges(); + + // target.Player?.SendNotification($"~y~{player.Name}~s~ hat deinen Mietvertrag ~g~gekündigt~s~."); + + // player.SendNotification("Du hast dem Spieler ~y~" + target.Name + "~s~ den Mietvertrag gekündigt."); + // SendPlayerHouseData(player, house); + // } + // } + + // [RemoteEvent("CLIENT:House_RentInHouse")] + // public void HouseManagerRentInHouseEvent(Player player) + // { + // using (var dbContext = new DatabaseContext()) + // { + // User user = player.GetUser(dbContext); + // House house = GetNearHouse(player.Position, dbContext); + + // if (house == null) + // { + // ChatService.ErrorMessage(player, "In deiner Nähe ist kein Haus"); + // return; + // } + + // if (house.RentalFee == 0) + // { + // player.SendChatMessage("~r~Dieses Haus hat keinen Platz für Mieter!"); + // return; + // } + + // HouseRental newRental = new HouseRental + // { + // HouseId = house.Id, + // UserId = user.Id + // }; + + // dbContext.HouseRentals.Add(newRental); + + // dbContext.SaveChanges(); + + // player.SendNotification("~g~Du hast dich in das Haus eingemietet"); + + // house.User?.SendNotification($"~y~{player.Name}~s~ hat sich in dein Haus eingemietet."); + // SendPlayerHouseData(player, house); + // } + // } + + // [RemoteEvent("CLIENT:House_CancelOwnRental")] + // public void HouseManagerCancelOwnRentalEvent(Player player) + // { + // using (var dbContext = new DatabaseContext()) + // { + // User user = player.GetUser(dbContext); + // House house = GetNearHouse(player.Position, dbContext); + + // if (house == null) + // { + // ChatService.ErrorMessage(player, "In deiner Nähe ist kein Haus"); + // return; + // } + + // HouseRental rental = dbContext.HouseRentals.Where(h => h.HouseId == house.Id && h.UserId == user.Id).FirstOrDefault(); + + // if (rental == null) + // { + // player.SendNotification("~r~Du bist nin diesem Haus nicht eingemietet"); + // return; + // } + + // dbContext.HouseRentals.Remove(rental); + + // dbContext.SaveChanges(); + + // player.SendNotification("~g~Du hast den Mietvertrag gekündigt."); + // house.User?.SendNotification($"~y~{player.Name}~s~ hat seinen Mietvertrag gekündigt."); + + // RemoveHouse(house); + // LoadHouse(house); + + // SendPlayerHouseData(player, house); + // } + // } + + // [RemoteEvent("CLIENT:House_SellHouse")] + // public void HouseManagerSellHouseEvent(Player player) + // { + // using (var dbContext = new DatabaseContext()) + // { + // User user = player.GetUser(dbContext); + // if (user.HouseId == null) + // { + // ChatService.ErrorMessage(player, "Du besitzt kein Haus"); + // return; + // } + + // House house = GetHouseById(user.HouseId.Value, dbContext); + // house.OwnerId = null; + // user.HouseId = null; - var backMoney = (int)(house.Price * 0.4); - - ChatService.SendMessage(player, "Du bekommst vom Hausverkauf ~g~" + backMoney.ToMoneyString() + "~s~ zurück."); + // var backMoney = (int)(house.Price * 0.4); + + // ChatService.SendMessage(player, "Du bekommst vom Hausverkauf ~g~" + backMoney.ToMoneyString() + "~s~ zurück."); - user.BankAccount.Balance += backMoney; - - dbContext.SaveChanges(); - - player.SendChatMessage("!{#81F7BE}* Du hast dein Haus verkauft."); - - RemoveHouse(house); - LoadHouse(house); - - SendPlayerHouseData(player, house); - } - } - } + // user.BankAccount.Balance += backMoney; + + // dbContext.SaveChanges(); + + // player.SendChatMessage("!{#81F7BE}* Du hast dein Haus verkauft."); + + // RemoveHouse(house); + // LoadHouse(house); + + // SendPlayerHouseData(player, house); + // } + // } + //} }