595 lines
16 KiB
JavaScript
595 lines
16 KiB
JavaScript
/**
|
|
* VehicleSystem.js
|
|
* ================
|
|
* KRVAVA ŽETEV - Complete Vehicle System (P14)
|
|
*
|
|
* Vehicle Types:
|
|
* - Animal Mounts (Horse, Donkey + mutants)
|
|
* - Carts & Wagons (Hand cart, Donkey cart, Horse wagon)
|
|
* - Bikes & Boards (Bicycle, Motorcycle, Skateboard, Scooter)
|
|
* - Water Vehicles (Kayak, SUP, Boat, Motorboat, Surfboard, Submarine)
|
|
* - Flying Vehicles (Glider, Balloon, Griffin, Pterodactyl, Dragon, Helicopter)
|
|
* - Train System (18 stations, fast travel)
|
|
*
|
|
* @author NovaFarma Team
|
|
* @date 2025-12-23
|
|
*/
|
|
|
|
export default class VehicleSystem {
|
|
constructor(scene) {
|
|
this.scene = scene;
|
|
|
|
// Current vehicle
|
|
this.currentVehicle = null;
|
|
this.isRiding = false;
|
|
|
|
// Vehicle registry
|
|
this.vehicles = new Map();
|
|
this.ownedVehicles = [];
|
|
|
|
// Train system
|
|
this.trainStations = [];
|
|
this.trainTickets = 0;
|
|
|
|
console.log('🚗 VehicleSystem initialized');
|
|
|
|
// Register all vehicle types
|
|
this.registerVehicles();
|
|
}
|
|
|
|
/**
|
|
* Register all vehicle types
|
|
*/
|
|
registerVehicles() {
|
|
// 14.1 - Animal Mounts
|
|
this.registerAnimalMounts();
|
|
|
|
// 14.2 - Carts & Wagons
|
|
this.registerCartsWagons();
|
|
|
|
// 14.3 - Bikes & Boards
|
|
this.registerBikesBoards();
|
|
|
|
// 14.4 - Water Vehicles
|
|
this.registerWaterVehicles();
|
|
|
|
// 14.5 - Flying Vehicles
|
|
this.registerFlyingVehicles();
|
|
|
|
// 14.6 - Train System
|
|
this.registerTrainStations();
|
|
|
|
console.log(`✅ Registered ${this.vehicles.size} vehicle types`);
|
|
}
|
|
|
|
/**
|
|
* 14.1 - Animal Mounts
|
|
*/
|
|
registerAnimalMounts() {
|
|
const mounts = [
|
|
{
|
|
id: 'horse',
|
|
name: 'Horse',
|
|
type: 'mount',
|
|
speed: 2.0,
|
|
stamina: 100,
|
|
requiresSaddle: true,
|
|
canCarry: 50,
|
|
icon: '🐴'
|
|
},
|
|
{
|
|
id: 'mutant_horse',
|
|
name: 'Mutant Horse',
|
|
type: 'mount',
|
|
speed: 3.0,
|
|
stamina: 150,
|
|
requiresSaddle: true,
|
|
canCarry: 75,
|
|
icon: '🦄',
|
|
special: 'Glows in the dark'
|
|
},
|
|
{
|
|
id: 'donkey',
|
|
name: 'Donkey',
|
|
type: 'mount',
|
|
speed: 1.5,
|
|
stamina: 120,
|
|
requiresSaddle: true,
|
|
canCarry: 100, // More cargo!
|
|
icon: '🫏'
|
|
},
|
|
{
|
|
id: 'mutant_donkey',
|
|
name: 'Mutant Donkey',
|
|
type: 'mount',
|
|
speed: 2.0,
|
|
stamina: 180,
|
|
requiresSaddle: true,
|
|
canCarry: 150,
|
|
icon: '🦓',
|
|
special: 'Never gets tired'
|
|
}
|
|
];
|
|
|
|
mounts.forEach(mount => this.vehicles.set(mount.id, mount));
|
|
}
|
|
|
|
/**
|
|
* 14.2 - Carts & Wagons
|
|
*/
|
|
registerCartsWagons() {
|
|
const carts = [
|
|
{
|
|
id: 'hand_cart',
|
|
name: 'Hand Cart',
|
|
type: 'cart',
|
|
speed: 0.8,
|
|
canCarry: 200,
|
|
requiresAnimal: false,
|
|
icon: '🛒'
|
|
},
|
|
{
|
|
id: 'donkey_cart',
|
|
name: 'Donkey Cart',
|
|
type: 'cart',
|
|
speed: 1.5,
|
|
canCarry: 500,
|
|
requiresAnimal: 'donkey',
|
|
icon: '🛺'
|
|
},
|
|
{
|
|
id: 'horse_wagon',
|
|
name: 'Horse Wagon',
|
|
type: 'cart',
|
|
speed: 2.0,
|
|
canCarry: 1000,
|
|
requiresAnimal: 'horse',
|
|
icon: '🚐'
|
|
}
|
|
];
|
|
|
|
carts.forEach(cart => this.vehicles.set(cart.id, cart));
|
|
}
|
|
|
|
/**
|
|
* 14.3 - Bikes & Boards
|
|
*/
|
|
registerBikesBoards() {
|
|
const bikes = [
|
|
{
|
|
id: 'bicycle',
|
|
name: 'Bicycle',
|
|
type: 'bike',
|
|
speed: 2.5,
|
|
stamina: -1, // Uses player stamina
|
|
icon: '🚲'
|
|
},
|
|
{
|
|
id: 'motorcycle',
|
|
name: 'Motorcycle',
|
|
type: 'bike',
|
|
speed: 4.0,
|
|
fuelType: 'gasoline',
|
|
fuelCapacity: 10,
|
|
icon: '🏍️',
|
|
sound: 'VROOOOM!'
|
|
},
|
|
{
|
|
id: 'skateboard',
|
|
name: 'Skateboard',
|
|
type: 'board',
|
|
speed: 2.0,
|
|
canDoTricks: true,
|
|
tricks: ['Ollie', 'Kickflip', '360 Spin'],
|
|
icon: '🛹'
|
|
},
|
|
{
|
|
id: 'scooter',
|
|
name: 'Delivery Scooter',
|
|
type: 'scooter',
|
|
speed: 2.2,
|
|
hasMailbox: true,
|
|
canCarry: 30,
|
|
icon: '🛴',
|
|
special: 'Perfect for deliveries!'
|
|
}
|
|
];
|
|
|
|
bikes.forEach(bike => this.vehicles.set(bike.id, bike));
|
|
}
|
|
|
|
/**
|
|
* 14.4 - Water Vehicles
|
|
*/
|
|
registerWaterVehicles() {
|
|
const waterVehicles = [
|
|
{
|
|
id: 'kayak',
|
|
name: 'Kayak',
|
|
type: 'water',
|
|
speed: 1.5,
|
|
waterOnly: true,
|
|
icon: '🛶'
|
|
},
|
|
{
|
|
id: 'sup',
|
|
name: 'SUP (Stand-Up Paddleboard)',
|
|
type: 'water',
|
|
speed: 1.2,
|
|
waterOnly: true,
|
|
icon: '🏄',
|
|
canFish: true
|
|
},
|
|
{
|
|
id: 'fishing_boat',
|
|
name: 'Fishing Boat',
|
|
type: 'water',
|
|
speed: 1.8,
|
|
waterOnly: true,
|
|
canCarry: 100,
|
|
unlocks: 'deep_sea_fishing',
|
|
icon: '⛵'
|
|
},
|
|
{
|
|
id: 'motorboat',
|
|
name: 'Motorboat',
|
|
type: 'water',
|
|
speed: 3.5,
|
|
waterOnly: true,
|
|
fuelType: 'gasoline',
|
|
fuelCapacity: 20,
|
|
icon: '🚤'
|
|
},
|
|
{
|
|
id: 'surfboard',
|
|
name: 'Surfboard',
|
|
type: 'water',
|
|
speed: 2.5,
|
|
waterOnly: true,
|
|
canRideWaves: true,
|
|
icon: '🏄♂️',
|
|
special: 'Catch waves!'
|
|
},
|
|
{
|
|
id: 'atlantis_submarine',
|
|
name: 'Atlantis Submarine',
|
|
type: 'water',
|
|
speed: 2.0,
|
|
waterOnly: true,
|
|
canDive: true,
|
|
maxDepth: 500,
|
|
icon: '🔱',
|
|
special: 'Access underwater ruins!',
|
|
unlocks: 'atlantis_zone'
|
|
}
|
|
];
|
|
|
|
waterVehicles.forEach(vehicle => this.vehicles.set(vehicle.id, vehicle));
|
|
}
|
|
|
|
/**
|
|
* 14.5 - Flying Vehicles
|
|
*/
|
|
registerFlyingVehicles() {
|
|
const flyingVehicles = [
|
|
{
|
|
id: 'hang_glider',
|
|
name: 'Hang Glider',
|
|
type: 'flying',
|
|
speed: 2.0,
|
|
maxHeight: 100,
|
|
glideOnly: true, // Can't gain altitude
|
|
icon: '🪂'
|
|
},
|
|
{
|
|
id: 'hot_air_balloon',
|
|
name: 'Hot Air Balloon',
|
|
type: 'flying',
|
|
speed: 1.0,
|
|
maxHeight: 200,
|
|
canHover: true,
|
|
icon: '🎈'
|
|
},
|
|
{
|
|
id: 'griffin',
|
|
name: 'Griffin Mount',
|
|
type: 'flying',
|
|
speed: 3.5,
|
|
maxHeight: 300,
|
|
stamina: 200,
|
|
icon: '🦅',
|
|
special: 'Mythical creature!',
|
|
unlocks: 'mythical_zone'
|
|
},
|
|
{
|
|
id: 'pterodactyl',
|
|
name: 'Pterodactyl Mount',
|
|
type: 'flying',
|
|
speed: 4.0,
|
|
maxHeight: 250,
|
|
stamina: 180,
|
|
icon: '🦕',
|
|
special: 'Prehistoric power!',
|
|
unlocks: 'dino_valley'
|
|
},
|
|
{
|
|
id: 'dragon',
|
|
name: 'Dragon Mount',
|
|
type: 'flying',
|
|
speed: 5.0,
|
|
maxHeight: 500,
|
|
stamina: 300,
|
|
canBreatheFire: true,
|
|
icon: '🐉',
|
|
special: 'ENDGAME MOUNT!',
|
|
unlocks: 'everywhere'
|
|
},
|
|
{
|
|
id: 'helicopter',
|
|
name: 'Atlantean Helicopter',
|
|
type: 'flying',
|
|
speed: 4.5,
|
|
maxHeight: 400,
|
|
fuelType: 'atlantean_crystal',
|
|
fuelCapacity: 10,
|
|
icon: '🚁',
|
|
special: 'Ancient technology!',
|
|
unlocks: 'fast_travel'
|
|
}
|
|
];
|
|
|
|
flyingVehicles.forEach(vehicle => this.vehicles.set(vehicle.id, vehicle));
|
|
}
|
|
|
|
/**
|
|
* 14.6 - Train System
|
|
*/
|
|
registerTrainStations() {
|
|
const stations = [
|
|
{ id: 'spawn_town', name: 'Spawn Town', x: 250, y: 250 },
|
|
{ id: 'desert', name: 'Desert Oasis', x: 150, y: 150 },
|
|
{ id: 'forest', name: 'Endless Forest', x: 350, y: 200 },
|
|
{ id: 'mountains', name: 'Mountain Peak', x: 200, y: 100 },
|
|
{ id: 'beach', name: 'Sunny Beach', x: 400, y: 300 },
|
|
{ id: 'swamp', name: 'Toxic Swamp', x: 100, y: 350 },
|
|
{ id: 'volcano', name: 'Volcano Station', x: 50, y: 50 },
|
|
{ id: 'snow', name: 'Frozen Tundra', x: 450, y: 100 },
|
|
{ id: 'jungle', name: 'Amazon Jungle', x: 300, y: 450 },
|
|
{ id: 'loch_ness', name: 'Loch Ness', x: 100, y: 200 },
|
|
{ id: 'egypt', name: 'Egyptian Pyramids', x: 200, y: 400 },
|
|
{ id: 'atlantis', name: 'Atlantis Port', x: 450, y: 450 },
|
|
{ id: 'dino_valley', name: 'Dino Valley', x: 50, y: 400 },
|
|
{ id: 'mythical', name: 'Mythical Realm', x: 400, y: 50 },
|
|
{ id: 'catacombs', name: 'Catacombs Entrance', x: 300, y: 300 },
|
|
{ id: 'chernobyl', name: 'Chernobyl Zone', x: 150, y: 450 },
|
|
{ id: 'scotland', name: 'Scottish Highlands', x: 450, y: 200 },
|
|
{ id: 'farm', name: 'Central Farm Hub', x: 250, y: 350 }
|
|
];
|
|
|
|
this.trainStations = stations;
|
|
console.log(`🚂 ${stations.length} train stations registered`);
|
|
}
|
|
|
|
/**
|
|
* Mount/ride a vehicle
|
|
*/
|
|
mountVehicle(vehicleId) {
|
|
const vehicle = this.vehicles.get(vehicleId);
|
|
if (!vehicle) {
|
|
console.error(`Vehicle ${vehicleId} not found!`);
|
|
return false;
|
|
}
|
|
|
|
// Check requirements
|
|
if (vehicle.requiresSaddle && !this.hasSaddle()) {
|
|
this.showNotification({
|
|
title: 'Need Saddle',
|
|
text: 'You need a saddle to ride this mount!',
|
|
icon: '🪢'
|
|
});
|
|
return false;
|
|
}
|
|
|
|
if (vehicle.requiresAnimal && !this.hasAnimal(vehicle.requiresAnimal)) {
|
|
this.showNotification({
|
|
title: 'Need Animal',
|
|
text: `You need a ${vehicle.requiresAnimal} to use this cart!`,
|
|
icon: '🐴'
|
|
});
|
|
return false;
|
|
}
|
|
|
|
// Mount!
|
|
this.currentVehicle = vehicle;
|
|
this.isRiding = true;
|
|
|
|
// Apply speed modifier
|
|
if (this.scene.player) {
|
|
this.scene.player.originalSpeed = this.scene.player.speed || 100;
|
|
this.scene.player.speed = this.scene.player.originalSpeed * vehicle.speed;
|
|
}
|
|
|
|
console.log(`${vehicle.icon} Mounted ${vehicle.name}!`);
|
|
|
|
this.showNotification({
|
|
title: 'Mounted!',
|
|
text: `${vehicle.icon} Riding ${vehicle.name}! Speed: ${vehicle.speed}x`,
|
|
icon: '🏇'
|
|
});
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Dismount vehicle
|
|
*/
|
|
dismountVehicle() {
|
|
if (!this.currentVehicle) return false;
|
|
|
|
const vehicle = this.currentVehicle;
|
|
|
|
// Restore speed
|
|
if (this.scene.player && this.scene.player.originalSpeed) {
|
|
this.scene.player.speed = this.scene.player.originalSpeed;
|
|
}
|
|
|
|
this.currentVehicle = null;
|
|
this.isRiding = false;
|
|
|
|
console.log(`Dismounted ${vehicle.name}`);
|
|
|
|
this.showNotification({
|
|
title: 'Dismounted',
|
|
text: `Left ${vehicle.name}`,
|
|
icon: ''
|
|
});
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Train fast travel
|
|
*/
|
|
fastTravel(stationId) {
|
|
const station = this.trainStations.find(s => s.id === stationId);
|
|
if (!station) {
|
|
console.error(`Station ${stationId} not found!`);
|
|
return false;
|
|
}
|
|
|
|
// Check tickets
|
|
if (this.trainTickets <= 0) {
|
|
this.showNotification({
|
|
title: 'No Tickets',
|
|
text: 'Buy train tickets! (10 Zlatniki/ticket)',
|
|
icon: '🎫'
|
|
});
|
|
return false;
|
|
}
|
|
|
|
// Use ticket
|
|
this.trainTickets--;
|
|
|
|
// Teleport player
|
|
if (this.scene.player) {
|
|
this.scene.player.x = station.x * 48; // Convert to pixels
|
|
this.scene.player.y = station.y * 48;
|
|
}
|
|
|
|
console.log(`🚂 Traveled to ${station.name}!`);
|
|
|
|
this.showNotification({
|
|
title: 'Fast Travel',
|
|
text: `🚂 Arrived at ${station.name}! (${this.trainTickets} tickets left)`,
|
|
icon: '🎫'
|
|
});
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Buy train tickets
|
|
*/
|
|
buyTrainTickets(amount) {
|
|
const cost = amount * 10; // 10 Zlatniki per ticket
|
|
|
|
// TODO: Check if player has money
|
|
// For now, just give tickets
|
|
this.trainTickets += amount;
|
|
|
|
this.showNotification({
|
|
title: 'Tickets Purchased',
|
|
text: `🎫 Bought ${amount} train tickets! Total: ${this.trainTickets}`,
|
|
icon: '💰'
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Do skateboard trick
|
|
*/
|
|
doSkateboardTrick() {
|
|
if (!this.currentVehicle || this.currentVehicle.id !== 'skateboard') {
|
|
return false;
|
|
}
|
|
|
|
const tricks = this.currentVehicle.tricks;
|
|
const trick = Phaser.Utils.Array.GetRandom(tricks);
|
|
|
|
console.log(`🛹 ${trick}!`);
|
|
|
|
this.showNotification({
|
|
title: 'Sick Trick!',
|
|
text: `🛹 ${trick}! +10 Style Points!`,
|
|
icon: '🤙'
|
|
});
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Use submarine dive
|
|
*/
|
|
diveSubmarine() {
|
|
if (!this.currentVehicle || this.currentVehicle.id !== 'atlantis_submarine') {
|
|
return false;
|
|
}
|
|
|
|
console.log('🔱 Diving to Atlantis!');
|
|
|
|
// TODO: Trigger underwater zone
|
|
this.showNotification({
|
|
title: 'Diving!',
|
|
text: '🔱 Descending to Atlantis ruins!',
|
|
icon: '🌊'
|
|
});
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Helper methods
|
|
*/
|
|
hasSaddle() {
|
|
// TODO: Check inventory
|
|
return true; // For now, always true
|
|
}
|
|
|
|
hasAnimal(animalType) {
|
|
// TODO: Check if player owns animal
|
|
return true; // For now, always true
|
|
}
|
|
|
|
/**
|
|
* Get all vehicles
|
|
*/
|
|
getAllVehicles() {
|
|
return Array.from(this.vehicles.values());
|
|
}
|
|
|
|
/**
|
|
* Get vehicles by type
|
|
*/
|
|
getVehiclesByType(type) {
|
|
return this.getAllVehicles().filter(v => v.type === type);
|
|
}
|
|
|
|
/**
|
|
* Get train stations
|
|
*/
|
|
getTrainStations() {
|
|
return this.trainStations;
|
|
}
|
|
|
|
/**
|
|
* Helper: Show notification
|
|
*/
|
|
showNotification(notification) {
|
|
console.log(`📢 ${notification.icon} ${notification.title}: ${notification.text}`);
|
|
|
|
const ui = this.scene.scene.get('UIScene');
|
|
if (ui && ui.showNotification) {
|
|
ui.showNotification(notification);
|
|
}
|
|
}
|
|
}
|