183 lines
5.9 KiB
JavaScript
183 lines
5.9 KiB
JavaScript
class OceanSystem {
|
|
constructor(scene) {
|
|
this.scene = scene;
|
|
|
|
this.isDiving = false;
|
|
this.oxygen = 100;
|
|
this.maxOxygen = 100;
|
|
this.oxygenDecayRate = 10; // Oxygen lost per second
|
|
this.oxygenRegenRate = 20; // Oxygen gained per second
|
|
|
|
this.damageTimer = 0;
|
|
|
|
// Visual Effects
|
|
this.overlay = null;
|
|
this.bubbleParticles = null;
|
|
|
|
// Boat
|
|
this.currentBoat = null;
|
|
this.isBoating = false;
|
|
|
|
// Init UI Event Listener
|
|
this.scene.events.on('update', (time, delta) => {
|
|
this.update(time, delta);
|
|
this.updateBoatVisuals();
|
|
});
|
|
}
|
|
|
|
update(time, delta) {
|
|
if (!this.scene.player || !this.scene.terrainSystem) return;
|
|
|
|
const playerPos = this.scene.player.getPosition();
|
|
const tile = this.scene.terrainSystem.getTile(playerPos.x, playerPos.y);
|
|
|
|
if (tile && tile.type && tile.type.name === 'water') {
|
|
|
|
// Check if boating
|
|
if (this.isBoating) {
|
|
// No drowning logic if in boat
|
|
this.oxygen = this.maxOxygen; // Regaining oxygen/safe
|
|
} else {
|
|
this.enterWater();
|
|
this.handleDiving(delta);
|
|
}
|
|
} else {
|
|
// LAND LOGIC
|
|
// If boating on land -> Beaching/Stop boating
|
|
if (this.isBoating) {
|
|
this.exitBoat();
|
|
}
|
|
this.exitWater();
|
|
this.handleRegen(delta);
|
|
}
|
|
|
|
// Update UI
|
|
if (this.isDiving || this.oxygen < this.maxOxygen) {
|
|
this.scene.events.emit('update-oxygen', { current: this.oxygen, max: this.maxOxygen });
|
|
} else {
|
|
this.scene.events.emit('hide-oxygen');
|
|
}
|
|
}
|
|
|
|
enterWater() {
|
|
if (this.isDiving) return;
|
|
this.isDiving = true;
|
|
console.log('🌊 Entered Water');
|
|
|
|
// Visuals
|
|
if (!this.overlay) {
|
|
this.overlay = this.scene.add.rectangle(0, 0, this.scene.scale.width, this.scene.scale.height, 0x0000FF, 0.3);
|
|
this.overlay.setScrollFactor(0);
|
|
this.overlay.setDepth(9000); // Above most things, below UI
|
|
}
|
|
this.overlay.setVisible(true);
|
|
|
|
// Slow player?
|
|
// Slow player?
|
|
this.scene.player.moveSpeed = 60; // Slower in water
|
|
}
|
|
|
|
useBoat(boatItem) {
|
|
if (this.isBoating) {
|
|
this.exitBoat();
|
|
return;
|
|
}
|
|
|
|
if (!this.scene.terrainSystem) return;
|
|
|
|
// Check if on water or near water?
|
|
// Actually, let's allow "deploying" boat anywhere, but only moving fast on water?
|
|
// OR: Only allow deploying on water tile.
|
|
|
|
const playerPos = this.scene.player.getPosition();
|
|
const tile = this.scene.terrainSystem.getTile(playerPos.x, playerPos.y);
|
|
|
|
if (tile && tile.type && tile.type.name === 'water') {
|
|
this.enterBoat(playerPos.x, playerPos.y);
|
|
} else {
|
|
this.scene.events.emit('show-floating-text', {
|
|
x: this.scene.player.sprite.x, y: this.scene.player.sprite.y - 50, text: 'Must be in water!', color: '#FF0000'
|
|
});
|
|
}
|
|
}
|
|
|
|
enterBoat() {
|
|
this.isBoating = true;
|
|
this.isDiving = false;
|
|
if (this.overlay) this.overlay.setVisible(false); // No blue overlay on boat
|
|
|
|
// Visual change
|
|
this.scene.player.moveSpeed = 200; // Fast speed!
|
|
|
|
// Create boat visual under player?
|
|
// Simplified: Change player texture or add container
|
|
if (!this.currentBoat) {
|
|
this.currentBoat = this.scene.add.sprite(0, 0, 'boat');
|
|
this.currentBoat.setDepth(this.scene.player.sprite.depth - 1);
|
|
}
|
|
this.currentBoat.setVisible(true);
|
|
|
|
this.scene.events.emit('show-floating-text', {
|
|
x: this.scene.player.sprite.x, y: this.scene.player.sprite.y - 50, text: 'Deployed Boat!', color: '#00FFFF'
|
|
});
|
|
}
|
|
|
|
exitBoat() {
|
|
this.isBoating = false;
|
|
if (this.currentBoat) this.currentBoat.setVisible(false);
|
|
|
|
// Return to normal or water speed?
|
|
// Logic in update loop will handle re-entering water state if still on water
|
|
this.scene.player.moveSpeed = 150;
|
|
}
|
|
|
|
exitWater() {
|
|
if (!this.isDiving) return;
|
|
this.isDiving = false;
|
|
console.log('🏖️ Exited Water');
|
|
|
|
if (this.overlay) this.overlay.setVisible(false);
|
|
|
|
// Restore speed
|
|
this.scene.player.moveSpeed = 150; // Normal speed
|
|
}
|
|
|
|
handleDiving(delta) {
|
|
this.oxygen -= (this.oxygenDecayRate * delta) / 1000;
|
|
|
|
if (this.oxygen <= 0) {
|
|
this.oxygen = 0;
|
|
this.damageTimer += delta;
|
|
if (this.damageTimer > 1000) {
|
|
this.damageTimer = 0;
|
|
this.scene.player.takeDamage(5);
|
|
this.scene.events.emit('show-floating-text', {
|
|
x: this.scene.player.sprite.x,
|
|
y: this.scene.player.sprite.y - 50,
|
|
text: 'Drowning!',
|
|
color: '#FF0000'
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
handleRegen(delta) {
|
|
if (this.oxygen < this.maxOxygen) {
|
|
this.oxygen += (this.oxygenRegenRate * delta) / 1000;
|
|
if (this.oxygen > this.maxOxygen) this.oxygen = this.maxOxygen;
|
|
}
|
|
}
|
|
|
|
updateBoatVisuals() {
|
|
if (this.isBoating && this.currentBoat && this.scene.player) {
|
|
this.currentBoat.x = this.scene.player.sprite.x;
|
|
this.currentBoat.y = this.scene.player.sprite.y + 10; // Slightly below
|
|
this.currentBoat.setDepth(this.scene.player.sprite.depth - 1);
|
|
|
|
// Flip based on movement
|
|
if (this.scene.input.keyboard.checkDown(this.scene.input.keyboard.addKey('A'), 100)) this.currentBoat.setFlipX(false);
|
|
if (this.scene.input.keyboard.checkDown(this.scene.input.keyboard.addKey('D'), 100)) this.currentBoat.setFlipX(true);
|
|
}
|
|
}
|
|
}
|