export default function gangwarHandle(globalData: IGlobalData) { var gangwarKillCounter = 0; function inside(point, vs) { let x = point[0], y = point[1]; let inside = false; for (let i = 0, j = vs.length - 1; i < vs.length; j = i++) { let xi = vs[i][0], yi = vs[i][1]; let xj = vs[j][0], yj = vs[j][1]; let intersect = ((yi > y) != (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi); if (intersect) inside = !inside; } return inside; }; const Natives = { SET_BLIP_CATEGORY: "0x234CDD44D996FD9A", SHOW_HEADING_INDICATOR_ON_BLIP: "0x5FBCA48327B914DF", SET_BLIP_AS_SHORT_RANGE: "0xBE8BE4FE60E27B72", SET_BLIP_DISPLAY: "0x9029B2F3DA924928", SET_BLIP_SPRITE: "0xDF735600A4696DAF", SET_BLIP_ALPHA: "0x45FF974EEE1C8734", ADD_BLIP_FOR_RADIUS: "0x46818D79B1F7499A", SET_BLIP_COLOUR: "0x03D7FB09E75D6B7E", SET_BLIP_ROTATION: "0xF87683CDF73C3F6E", SET_BLIP_FLASHES: "0xB14552383D39CE3E", GET_FIRST_BLIP_INFO_ID: "0x1BEDE233E6CD2A1F", GET_NEXT_BLIP_INFO_ID: "0x14F96AA50D6FBEA7", DOES_BLIP_EXIST: "0xA6DB27D19ECBB7DA", SET_BLIP_COORDS: "0xAE2AF67E9D9AF65D", SET_BLIP_FLASH_INTERVAL: "0xAA51DB313C010A7E", REMOVE_BLIP: "0x86A652570E5F25DD", SET_THIS_SCRIPT_CAN_REMOVE_BLIPS_CREATED_BY_ANY_SCRIPT: "0xB98236CAAECEF897" }; var Gangturf = class { name: string; id: number; range: number; x: number; y: number; color: number; colorZone_r: number; colorZone_g: number; colorZone_b: number; rotation: number; owner: string; attacker: string; blip: BlipMp; _colshape: ColshapeMp; _marker: MarkerMp; vector: Vector3Mp; value: number; _status: string; _entered: boolean; _isEntering: boolean; _inColshape: boolean; _timerCheck; edit: boolean; attackBlip: BlipMp; leaderBlip: BlipMp; leaderBlipVector: Vector3Mp; leaderColShape: MarkerMp; constructor(name, id, x, y, range, color, rot, owner, edit, vector, value) { this._setup(name, id, x, y, range, color, rot, owner, edit, vector, value); } _setup(name, id, x, y, range, color, rot, owner, edit, vector, value) { var self = this; self.name = name; self.id = id; self.range = range; self.setColor(owner); self.x = x; self.y = y; self.rotation = rot; self._colshape = null; self._status = "normal"; self._entered = false; self._isEntering = false; self._inColshape = false; self._timerCheck; self.owner = owner; self.attacker = null; self.edit = edit; self.loadArea(); self.attackBlip = null; self.leaderBlip = null; self.value = value; if (vector != null) { self.leaderBlipVector = JSON.parse(vector); } else { self.leaderBlipVector = null; } self.leaderColShape = null; } setColor(owner) { var self = this; if (owner === "Ballas") { self.color = 83; self.colorZone_r = 143; self.colorZone_g = 0; self.colorZone_b = 199; } else if (owner === "Grove") { self.color = 2; self.colorZone_r = 22; self.colorZone_g = 87; self.colorZone_b = 0; } else if (owner === "Vagos") { self.color = 33; self.colorZone_r = 255; self.colorZone_g = 255; self.colorZone_b = 100; } else if (owner === "Neutral") { self.color = 0; self.colorZone_r = 255; self.colorZone_g = 255; self.colorZone_b = 255; } } scoreUpdate(attackerScore, defenderScore) { mp.gui.chat.push(this.owner + " " + defenderScore + " : " + attackerScore + " " + this.attacker); } 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._colshape = mp.colshapes.newCircle(self.x, self.y, self.range * 1.5); } render() { var self = this; if (self._colshape) { if (self.edit == true) { let vector3 = mp.players.local.getRotation(2); self.rotation = Math.round(vector3.z); //self.blip.setPosition(mp.players.local.position.x, mp.players.local.position.y, 1); 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; } //self.blip.setRotation(self.rotation); mp.game.invoke(Natives.SET_BLIP_ROTATION, self.blip, self.rotation); } if (self._status == "attack" || self.edit == true) { if (self._colshape) { if (mp.game.gameplay.getDistanceBetweenCoords(mp.players.local.position.x, mp.players.local.position.y, 0, self.x, self.y, 0, true) < self.range * 1.5) { var range = Math.sqrt(((self.range * 1.2) * (self.range * 1.2)) + (((self.range * 1.2) / 2) * ((self.range * 1.2) / 2))); let degrees = (self.rotation + 45) * (Math.PI / 180); let top_right = { x: self.x + range * Math.cos(degrees), y: self.y + range * Math.sin(degrees) } degrees = (self.rotation + 135) * (Math.PI / 180); let top_left = { x: self.x + range * Math.cos(degrees), y: self.y + range * Math.sin(degrees) } degrees = (self.rotation + 225) * (Math.PI / 180); let bottom_left = { x: self.x + range * Math.cos(degrees), y: self.y + range * Math.sin(degrees) } degrees = (self.rotation + 315) * (Math.PI / 180); let bottom_right = { x: self.x + range * Math.cos(degrees), y: self.y + range * Math.sin(degrees) } let z = mp.game.gameplay.getGroundZFor3dCoord(mp.players.local.position.x, mp.players.local.position.y, mp.players.local.position.z, 0, false); if (self.edit) { mp.game.graphics.drawLine(bottom_right.x, bottom_right.y, z, bottom_right.x, bottom_right.y, z + 25, 0, 255, 0, 255); mp.game.graphics.drawLine(top_left.x, top_left.y, z, top_left.x, top_left.y, z + 25, 0, 0, 255, 255); for (var i = z; i < z + 25; i += 0.5) { mp.game.graphics.drawLine(top_left.x, top_left.y, i, top_right.x, top_right.y, i, 255, 0, 0, 255); mp.game.graphics.drawLine(top_right.x, top_right.y, i, bottom_right.x, bottom_right.y, i, 255, 0, 0, 255); mp.game.graphics.drawLine(bottom_right.x, bottom_right.y, i, bottom_left.x, bottom_left.y, i, 255, 0, 0, 255); mp.game.graphics.drawLine(bottom_left.x, bottom_left.y, i, top_left.x, top_left.y, i, 255, 0, 0, 255); } } else { /* let a = 0; for (var i = z; i < z + 1; i += 0.001) { mp.game.graphics.drawLine(top_left.x, top_left.y, i, top_right.x, top_right.y, i, self.colorZone_r, self.colorZone_g, self.colorZone_b, 60 - a * 100); mp.game.graphics.drawLine(top_right.x, top_right.y, i, bottom_right.x, bottom_right.y, i, self.colorZone_r, self.colorZone_g, self.colorZone_b, 60 - a * 100); mp.game.graphics.drawLine(bottom_right.x, bottom_right.y, i, bottom_left.x, bottom_left.y, i, self.colorZone_r, self.colorZone_g, self.colorZone_b, 60 - a * 100); mp.game.graphics.drawLine(bottom_left.x, bottom_left.y, i, top_left.x, top_left.y, i, self.colorZone_r, self.colorZone_g, self.colorZone_b, 60 - a * 100); a += 0.001 } */ } } if (self.isInsideArea()) { mp.game.graphics.drawText(self.name, [self.x, self.y, mp.players.local.position.z + 20], { font: 7, color: [255, 255, 255, 185], scale: [0.4, 0.4], outline: true, centre: true }); } } } if (self.leaderBlipVector != null) { let dist = mp.game.gameplay.getDistanceBetweenCoords(mp.players.local.position.x, mp.players.local.position.y, mp.players.local.position.z, self.leaderBlipVector.x, self.leaderBlipVector.y, self.leaderBlipVector.z, false); if (self.isInsideArea() && self._status != "attack" && dist <= 6) { if (self.leaderBlipVector != null) { mp.game.graphics.drawText(self.name + "\n~y~Gang: ~s~" + self.owner + "\n~y~Wert: ~s~$~g~" + self.value, [self.leaderBlipVector.x, self.leaderBlipVector.y, self.leaderBlipVector.z], { font: 7, color: [255, 255, 255, 185], scale: [0.4, 0.4], outline: true, centre: true }); } } } } 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); if (dist <= 3) { mp.events.callRemote("SERVER:StartGangwar"); } } } updateArea(status, ...args) { var self = this; if (status == "attack") { if (self.leaderColShape != null) { self.leaderColShape.destroy(); self.leaderColShape = null; } self._status = "attack"; self.attacker = args[1]; //self.blip.setFlashes(true); //self.blip.setFlashInterval(1000); mp.game.invoke(Natives.SET_BLIP_FLASHES, self.blip, true); mp.game.invoke(Natives.SET_BLIP_FLASH_INTERVAL, self.blip, 1000) return; } if (status == "normal") { self._status = "normal"; //self.blip.setFlashes(false); mp.game.invoke(Natives.SET_BLIP_FLASHES, self.blip, false); return; } if (status == "conquered") { //mp.game.graphics.stopScreenEffect("MinigameTransitionIn"); self._status = "normal"; self.owner = args[0]; self.attacker = null; //self.blip.setFlashes(false); mp.game.invoke(Natives.SET_BLIP_FLASHES, self.blip, false); //self.blip.destroy(); self.setColor(self.owner); //self.blip.setColour(self.color); mp.game.invoke(Natives.SET_BLIP_COLOUR, self.blip, self.color); self.setLeaderColShape(); return; } } setAttackBlip(bool) { var self = this; if (bool) { self.attackBlip = mp.game.ui.addBlipForCoord(self.x, self.y, 0); mp.game.invoke(Natives.SET_BLIP_SPRITE, self.attackBlip, 378); mp.game.invoke(Natives.SET_BLIP_AS_SHORT_RANGE, self.attackBlip, false); } else if (!bool) { mp.game.invoke(Natives.SET_BLIP_SPRITE, self.attackBlip, 5); } } setLeaderBlip(bool) { var self = this; if (this.leaderColShape != null) { this.leaderColShape.destroy(); this.leaderColShape = null; } if (bool) { self.leaderBlipVector = mp.players.local.position; mp.events.callRemote("SERVER:Turf_SetNewLeaderPoint", JSON.stringify(self.leaderBlipVector), JSON.stringify(self.id)); return; } if (self.leaderBlipVector != null) { self.leaderBlip = mp.game.ui.addBlipForRadius(self.leaderBlipVector.x, self.leaderBlipVector.y, 1, 60); 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 }); } isTurfArea(shape) { return (shape == this._colshape) } isOwner(gang) { return (gang == this.owner) } check() { var self = this if (self._entered == true) { if (!self.isInsideArea() || (self.isNearGround() == false)) { self._entered = false; mp.events.callRemote("Gangarea:Leave", self.id); } } } enter() { var self = this; self._timerCheck = setInterval(function () { if ((!self._entered)) { if (self.isInsideArea() && (self.isNearGround() == true)) { self._entered = true; if (self._status == "attack") { 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) { if (!self.isInsideArea() || (self.isNearGround() == false)) { self._entered = false; 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)); } } }, 1000); } leave() { var self = this; clearInterval(self._timerCheck); self.check(); } isNearGround() { let self = this; let ground = mp.game.gameplay.getGroundZFor3dCoord(self.x, self.y, 9000, 0, false); let max_diff = 75; let dist = mp.game.system.vdist(0, 0, ground, 0, 0, mp.players.local.position.z); if (dist <= max_diff) { return true; } return false; } isInsideArea() { var self = this; let player = { x: mp.players.local.position.x, y: mp.players.local.position.y, z: mp.players.local.position.z }; var range = Math.sqrt(((self.range * 1.2) * (self.range * 1.2)) + (((self.range * 1.2) / 2) * ((self.range * 1.2) / 2))); let degrees = (self.rotation + 45) * (Math.PI / 180); let top_right = { x: self.x + range * Math.cos(degrees), y: self.y + range * Math.sin(degrees) } degrees = (self.rotation + 135) * (Math.PI / 180); let top_left = { x: self.x + range * Math.cos(degrees), y: self.y + range * Math.sin(degrees) } degrees = (self.rotation + 225) * (Math.PI / 180); let bottom_left = { x: self.x + range * Math.cos(degrees), y: self.y + range * Math.sin(degrees) } degrees = (self.rotation + 315) * (Math.PI / 180); let bottom_right = { x: self.x + range * Math.cos(degrees), y: self.y + range * Math.sin(degrees) } let turf = [ [top_right.x, top_right.y], [top_left.x, top_left.y], [bottom_left.x, bottom_left.y], [bottom_right.x, bottom_right.y] ] if (inside([player.x, player.y], turf)) { return true; } return false; } setValue(value) { var self = this; self.value = value; } } var gangturfs = []; mp.events.add('playerEnterColshape', (shape) => { let turfEntered; gangturfs.forEach(function (turf) { if (turf.isTurfArea(shape) == true) { turfEntered = turf; turfEntered.enter() } }); }); mp.events.add('playerExitColshape', (shape) => { let turfExitted; gangturfs.forEach(function (turf) { if (turf.isTurfArea(shape) == true) { turfExitted = turf; turfExitted.leave() } }); }); mp.events.add('render', () => { gangturfs.forEach(function (turf, id) { turf.render(); }); }); mp.events.add('CLIENT:loose', () => { mp.game.audio.playSoundFrontend(1, "Zone_Enemy_Capture", "DLC_Apartments_Drop_Zone_Sounds", true); }); mp.events.add('CLIENT:win', () => { mp.game.audio.playSoundFrontend(1, "Zone_Team_Capture", "DLC_Apartments_Drop_Zone_Sounds", true); }); function clearBlips() { mp.game.invoke(Natives.SET_THIS_SCRIPT_CAN_REMOVE_BLIPS_CREATED_BY_ANY_SCRIPT, 1); mp.game.gameplay.setThisScriptCanRemoveBlipsCreatedByAnyScript(true); var x = 0; var y = 0; var z = 0; var n = 0; let last_blip = mp.game.invoke(Natives.GET_FIRST_BLIP_INFO_ID, 5); gangturfs.forEach(function (turf) { mp.game.invoke(Natives.REMOVE_BLIP, turf.blip); mp.game.ui.removeBlip(turf.blip); n++; }); while (mp.game.invoke(Natives.DOES_BLIP_EXIST, last_blip)) { mp.game.invoke(Natives.SET_BLIP_SPRITE, last_blip, -1); mp.game.invoke(Natives.REMOVE_BLIP, last_blip, -1); mp.game.invoke(Natives.SET_BLIP_ALPHA, last_blip, 0); mp.game.ui.removeBlip(last_blip); mp.game.invoke(Natives.REMOVE_BLIP, last_blip); last_blip = mp.game.invoke(Natives.GET_NEXT_BLIP_INFO_ID, 5); x++; } let last_attackBlip = mp.game.invoke(Natives.GET_FIRST_BLIP_INFO_ID, 378); while (mp.game.invoke(Natives.DOES_BLIP_EXIST, last_attackBlip)) { mp.game.invoke(Natives.SET_BLIP_SPRITE, last_attackBlip, -1); mp.game.ui.removeBlip(last_attackBlip); last_attackBlip = mp.game.invoke(Natives.GET_NEXT_BLIP_INFO_ID, 378); y++ } let last_leaderBlip = mp.game.invoke(Natives.GET_FIRST_BLIP_INFO_ID, 437); while (mp.game.invoke(Natives.DOES_BLIP_EXIST, last_leaderBlip)) { mp.game.invoke(Natives.SET_BLIP_SPRITE, last_leaderBlip, -1); mp.game.ui.removeBlip(last_leaderBlip); last_leaderBlip = mp.game.invoke(Natives.GET_NEXT_BLIP_INFO_ID, 437); mp.game.invoke(Natives.SET_BLIP_SPRITE, last_attackBlip, -1); mp.game.ui.removeBlip(last_attackBlip); last_attackBlip = mp.game.invoke(Natives.GET_NEXT_BLIP_INFO_ID, 378); y++ z++ } } mp.events.add('GangAreas:Create', (turfsJSON) => { var turfs = JSON.parse(turfsJSON); if (gangturfs.length > 0) { gangturfs[gangturfs.length - 1].edit = false; gangturfs.forEach(function (turf) { turf._status = "disabled"; turf.id = null; //Due to garbage collecting this value needs to be negative, so that the Server doesn't find multiple Turfs in the Database with same ID's. if (turf.leaderColShape != null) { turf.leaderColShape.destroy(); turf.leaderColShape = null; } if (turf._marker) if (turf.blip != null) { mp.game.ui.removeBlip(turf.blip); } if (turf.leaderBlip != null) { mp.game.ui.removeBlip(turf.leaderBlip); } if (turf.attackBlip != null) { mp.game.ui.removeBlip(turf.attackBlip); } }); } clearBlips(); if (turfs.length > 0) { gangturfs = []; turfs.forEach(function (turf) { if (turf.Id != undefined) { gangturfs[gangturfs.length] = new Gangturf(turf.Name, turf.Id, turf.X, turf.Y, turf.Range, turf.Color, turf.Rotation, turf.Owner, false, turf.Vector, turf.Value); } }); } }); mp.events.add('ADMIN:CreateTurf', (rangeJSON) => { var range = JSON.parse(rangeJSON); gangturfs[gangturfs.length] = new Gangturf("Reload For Name", -1, mp.players.local.position.x, mp.players.local.position.y, range, 0, mp.players.local.getHeading(), "Neutral", true, null, 0); }); mp.events.add('ADMIN:SetTurf', (name) => { gangturfs[gangturfs.length - 1].edit = false; 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', () => { gangturfs.forEach(function (turf) { if (turf._entered == true) { mp.events.callRemote("SERVER:DeleteTurf", JSON.stringify(turf.id)); return; } }); mp.events.callRemote("SERVER:DeleteTurf", JSON.stringify(-1)); }); mp.events.add('CLIENT:Turf_Update', (jsonId, jsonStatus, jsonOwner, jsonAttacker) => { var id = JSON.parse(jsonId); var status = JSON.parse(jsonStatus); var owner = JSON.parse(jsonOwner); var attacker = JSON.parse(jsonAttacker); gangturfs.forEach(function (turf) { if (turf.id == id) { turf.updateArea(status, owner, attacker); } }); }); mp.events.add('CLIENT:Turf_Conquered', (jsonId, jsonStatus, jsonOwner) => { var id = JSON.parse(jsonId); var status = JSON.parse(jsonStatus); var owner = JSON.parse(jsonOwner); gangturfs.forEach(function (turf) { if (turf.id == id) { turf.updateArea(status, owner); } }); }); mp.events.add('CLIENT:setAttackBlip', (bool, id) => { gangturfs.forEach(function (turf) { if (turf.id == id) { turf.setAttackBlip(bool); } }); }); mp.events.add('CLIENT:Turf_LoadLeaderBlip', () => { gangturfs.forEach(function (turf) { turf.setLeaderBlip(false); }); }); mp.events.add('ADMIN:Turf_CreateLeaderBlip', () => { gangturfs.forEach(function (turf) { if (turf._entered == true) { turf.setLeaderBlip(true); } }); }); mp.events.add('CLIENT:StartGangwar', () => { gangturfs.forEach(function (turf) { if (turf._entered == true) { turf.startGangWar(); } }); }); mp.events.add('CLIENT:UpdateTurfValue', (jsonValues) => { let values = JSON.parse(jsonValues); for (var i = 0; i < gangturfs.length; i++) { let turf = gangturfs[i]; turf.setValue(values[i]); //turf.render(); } }); mp.events.add("gangWarKillNotification", (deathPlayername) => { mp.events.call("BN_Show", "~y~GANGWAR~w~: Du hast ~r~" + deathPlayername + " ~w~getötet. Kills: " + ++gangwarKillCounter); }); mp.events.add("resetKillcounter", () => { gangwarKillCounter = 0; }); }