mirror of
https://github.com/sergeyyarkov/altv-copchase-mod.git
synced 2026-10-11 10:19:42 +03:00
328 lines
9.5 KiB
JavaScript
328 lines
9.5 KiB
JavaScript
import alt from 'alt-server'
|
|
import { send, broadcast } from 'chat'
|
|
|
|
import config from '../config.mjs'
|
|
import skins from '../skins.json'
|
|
|
|
class Copchase {
|
|
constructor({ dimension, waitingRoomDimension, minPlayers, maxPlayers, timeRemaining, timeToStart }) {
|
|
this.dimension = dimension
|
|
this.waitingRoomDimension = waitingRoomDimension
|
|
this.minPlayers = minPlayers
|
|
this.maxPlayers = maxPlayers
|
|
this.timeRemaining = timeRemaining
|
|
this.timeRemainingInterval = null
|
|
this.timeToStart = timeToStart
|
|
this.isStarted = false
|
|
this.isTimeToStartStarted = false
|
|
this.suspectCars = [
|
|
'asea',
|
|
'tornado',
|
|
'futo',
|
|
'taxi',
|
|
'picador',
|
|
'phoenix',
|
|
'ruiner',
|
|
'sabregt',
|
|
'rancherxl',
|
|
'regina',
|
|
'stanier',
|
|
'washington',
|
|
'emperor',
|
|
'blista',
|
|
'tulip',
|
|
'vamos',
|
|
'chino',
|
|
'moonbeam',
|
|
'dubsta',
|
|
'dominator',
|
|
'rebla',
|
|
'sanchez',
|
|
'superd',
|
|
'dilettante',
|
|
'huntley',
|
|
'monroe',
|
|
'windsor',
|
|
'novak',
|
|
'gauntlet3'
|
|
]
|
|
this.policeCars = [
|
|
'police2',
|
|
'police3'
|
|
]
|
|
this.weather = [
|
|
'EXTRASUNNY',
|
|
'CLEAR',
|
|
'CLOUDS',
|
|
'SMOG',
|
|
'FOGGY',
|
|
'OVERCAST',
|
|
'RAIN',
|
|
'THUNDER',
|
|
'CLEARING',
|
|
'NEUTRAL',
|
|
'SNOW',
|
|
'BLIZZARD',
|
|
'SNOWLIGHT',
|
|
'XMAS',
|
|
'HALLOWEEN'
|
|
]
|
|
this.players = []
|
|
this.waitingPlayers = []
|
|
this.cars = []
|
|
this.suspect = null
|
|
this.positions = {
|
|
suspect: [
|
|
{ x: 387.006, y: -766.760, z: 28.723 },
|
|
{ x: 442.483, y: -1507.068, z: 28.605 },
|
|
{ x: 1924.773, y: 3819.125, z: 31.588 }
|
|
],
|
|
police: [
|
|
{ x: 442.308, y: -1025.066, z: 28.231 },
|
|
{ x: 396.105, y: -1643.973, z: 28.757 },
|
|
{ x: 1847.670, y: 3671.854, z: 33.172 }
|
|
]
|
|
}
|
|
}
|
|
|
|
setDefaultState() {
|
|
this.timeRemainingInterval = null
|
|
this.isStarted = false
|
|
this.suspect = null
|
|
this.players = []
|
|
|
|
setTimeout(() => {
|
|
this.cars.forEach(car => car.destroy())
|
|
this.cars = []
|
|
}, 5000)
|
|
}
|
|
|
|
isPlayerInGame(player) {
|
|
if(this.players.find(_player => _player.id === player.id) !== undefined) {
|
|
send(player, '{EE9A00}[COPCHASE]: {FF0000}Дождитесь окончания игры!')
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
}
|
|
|
|
isPlayerInWaitingRoom(player) {
|
|
if(this.waitingPlayers.find(_player => _player.id === player.id) !== undefined) {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
}
|
|
|
|
addPlayerToWaitingRoom(player) {
|
|
this.waitingPlayers.push(player)
|
|
}
|
|
|
|
pushWaitingPlayersToGame(waitingPlayers) {
|
|
waitingPlayers.forEach(_player => this.players.push(_player))
|
|
this.waitingPlayers = []
|
|
}
|
|
|
|
selectSuspect() {
|
|
this.suspect = this.players[Math.floor(Math.random() * this.players.length)]
|
|
}
|
|
|
|
messageToPlayersInGame(message) {
|
|
this.players.forEach(_player => send(_player, message))
|
|
}
|
|
|
|
messageToWaitingPlayers(message) {
|
|
this.waitingPlayers.forEach(_player => send(_player, message))
|
|
}
|
|
|
|
midsizedMessageToWaitingPlayers(message, description, delay) {
|
|
this.waitingPlayers.forEach(_player => {
|
|
alt.emitClient(_player, 'player:showMidsizedMessage', message, description, delay)
|
|
})
|
|
}
|
|
|
|
notifyPolicePlayers(message) {
|
|
this.players.forEach(_player => _player.id !== this.suspect.id ? alt.emitClient(_player, 'player:notify', message) : false)
|
|
}
|
|
|
|
notifySuspectPlayer(message) {
|
|
alt.emitClient(this.suspect, 'player:notify', message)
|
|
}
|
|
|
|
spawnPlayers() {
|
|
let posX = 0
|
|
let suspectRandomNumber = Math.floor(Math.random() * this.positions.suspect.length)
|
|
let suspectPosition = this.positions.suspect[suspectRandomNumber]
|
|
|
|
return new Promise((resolve, reject) => {
|
|
this.players.forEach(_player => {
|
|
if (_player.id === this.suspect.id) {
|
|
_player.pos = suspectPosition
|
|
setTimeout(() => _player.health = 200, 300)
|
|
_player.dimension = this.dimension
|
|
_player.model = skins[Math.floor(Math.random() * (430 - 1 - 422) + 422)]
|
|
alt.emitClient(_player, 'player:delInvincible')
|
|
alt.emitClient(_player, 'player:showMidsizedMessage', '~r~Вы саспект!', 'Уйдите от полицейских.', 5000)
|
|
} else {
|
|
posX = posX + 3
|
|
_player.pos = {
|
|
x: this.positions.police[suspectRandomNumber].x + posX,
|
|
y: this.positions.police[suspectRandomNumber].y,
|
|
z: this.positions.police[suspectRandomNumber].z
|
|
}
|
|
setTimeout(() => _player.armour = 100, 300)
|
|
setTimeout(() => _player.health = 200, 300)
|
|
_player.dimension = this.dimension
|
|
_player.model = 's_m_y_cop_01'
|
|
_player.giveWeapon('0x3656C8C1', 100, true)
|
|
alt.emitClient(_player, 'player:delInvincible')
|
|
alt.emitClient(_player, 'player:showMidsizedMessage', `~w~Саспект: ~r~${this.suspect.name}`, 'Нейтрализуйте саспекта.', 5000)
|
|
alt.emitClient(_player, 'player:createBlipPlayers', {
|
|
players: this.players.filter(player => player.id !== this.suspect.id),
|
|
color: 38
|
|
}) // create friendly blips
|
|
alt.emitClient(_player, 'player:createBlipPlayers', {
|
|
players: this.players.filter(player => player.id === this.suspect.id),
|
|
color: 1
|
|
}) // create suspec blip
|
|
}
|
|
})
|
|
|
|
resolve()
|
|
})
|
|
}
|
|
|
|
spawnCars() {
|
|
this.players.forEach(_player => {
|
|
if (_player.id === this.suspect.id) {
|
|
const carSuspect = new alt.Vehicle(
|
|
this.suspectCars[Math.floor(Math.random() * (this.suspectCars.length - 1 - 0) + 0)],
|
|
_player.pos.x, _player.pos.y, _player.pos.z,
|
|
0, 0, 0
|
|
)
|
|
|
|
carSuspect.numberPlateText = 'SUSPECT'
|
|
carSuspect.dimension = this.dimension
|
|
|
|
alt.emitClient(_player, 'vehicle:setInto', carSuspect)
|
|
carSuspect.engineHealth = 500
|
|
|
|
this.cars.push(carSuspect)
|
|
} else {
|
|
const carPolice = new alt.Vehicle(
|
|
this.policeCars[Math.floor(Math.random() * (this.policeCars.length - 1 - 0) + 0)],
|
|
_player.pos.x, _player.pos.y, _player.pos.z,
|
|
0, 0, 0
|
|
)
|
|
|
|
carPolice.numberPlateText = 'POLICE'
|
|
carPolice.dimension = this.dimension
|
|
|
|
alt.emitClient(_player, 'vehicle:setInto', carPolice)
|
|
this.cars.push(carPolice)
|
|
}
|
|
})
|
|
}
|
|
|
|
startGame() {
|
|
let timeToStart = this.timeToStart
|
|
this.isTimeToStartStarted = true
|
|
const interval = setInterval(() => {
|
|
timeToStart = timeToStart - 1
|
|
|
|
if (this.waitingPlayers.length < this.minPlayers) {
|
|
this.midsizedMessageToWaitingPlayers('~r~Недостаточно игроков для старта!', '', 3000)
|
|
this.isTimeToStartStarted = false
|
|
|
|
clearInterval(interval)
|
|
return
|
|
}
|
|
|
|
if (timeToStart <= 0) {
|
|
|
|
this.isStarted = true
|
|
this.isTimeToStartStarted = false
|
|
|
|
this.pushWaitingPlayersToGame(this.waitingPlayers)
|
|
this.selectSuspect()
|
|
|
|
this.notifyPolicePlayers(`~w~ Остановите саспекта!`)
|
|
this.notifySuspectPlayer(`~w~ Уйдите от полицейских!`)
|
|
|
|
this.spawnPlayers().then(() => this.spawnCars())
|
|
|
|
let timeRemaining = this.timeRemaining
|
|
this.timeRemainingInterval = setInterval(() => {
|
|
timeRemaining = timeRemaining - 1
|
|
if (timeRemaining !== 0) {
|
|
this.players.forEach(_player => alt.emitClient(_player, 'player:showMidsizedMessage', `Осталось: ~b~${timeRemaining} ~w~мин.`, '', 5000))
|
|
}
|
|
|
|
if (timeRemaining <= 0) {
|
|
this.stopGame({ winner: 'suspect' })
|
|
|
|
clearInterval(this.timeRemainingInterval)
|
|
return true
|
|
}
|
|
}, 60000)
|
|
|
|
clearInterval(interval)
|
|
return true
|
|
}
|
|
this.midsizedMessageToWaitingPlayers(timeToStart, '', 1000)
|
|
}, 1000)
|
|
}
|
|
|
|
stopGame({ winner }) {
|
|
clearInterval(this.timeRemainingInterval)
|
|
|
|
alt.Player.all.forEach(_player => alt.emitClient(_player, 'player:deleteBlipPlayers'))
|
|
|
|
this.players.forEach(_player => {
|
|
_player.removeAllWeapons()
|
|
|
|
alt.setTimeout(() => {
|
|
_player.spawn(config.spawn.x, config.spawn.y,config.spawn.z)
|
|
_player.dimension = 0
|
|
alt.emitClient(_player, 'player:setInvincible')
|
|
}, 5000)
|
|
|
|
})
|
|
|
|
if (winner === 'police') {
|
|
this.players.forEach(_player => {
|
|
if (_player.id !== this.suspect.id) {
|
|
alt.emitClient(_player, 'player:showMidsizedMessage', '~g~Вы выиграли', 'Саспект был нейтрализован.')
|
|
}
|
|
})
|
|
console.log(`[COPCHASE]: Игра закончилась! Саспект был нейтрализован.`)
|
|
}
|
|
|
|
if (winner === 'suspect') {
|
|
this.players.forEach(_player => {
|
|
if (_player.id === this.suspect.id) {
|
|
alt.emitClient(_player, 'player:showMidsizedMessage', '~g~Вы выиграли', 'Вы успешно ушли от полиции.')
|
|
} else {
|
|
alt.emitClient(_player, 'player:showMidsizedMessage', '~r~Вы проиграли', 'Саспект скрылся.')
|
|
}
|
|
})
|
|
console.log(`[COPCHASE]: Игра закончилась! Саспект скрылся.`)
|
|
}
|
|
|
|
this.setDefaultState()
|
|
}
|
|
|
|
}
|
|
|
|
const copchase = new Copchase({
|
|
dimension: 10,
|
|
waitingRoomDimension: 5,
|
|
maxPlayers: 11,
|
|
minPlayers: 2,
|
|
timeRemaining: 10,
|
|
timeToStart: 5
|
|
})
|
|
|
|
export {
|
|
copchase
|
|
} |