338 lines
11 KiB
JavaScript
338 lines
11 KiB
JavaScript
/**
|
|
* COURIER & DELIVERY SYSTEM
|
|
* Mrtva Dolina - Side-Quest Material Deliveries
|
|
*
|
|
* Features:
|
|
* - Random delivery quests from NPCs
|
|
* - Rewards: Hearts (social status) OR random materials
|
|
* - Material types: wheat, water, glass, steel, wood, plastic
|
|
* - Reputation system
|
|
*/
|
|
|
|
export class CourierSystem {
|
|
constructor(scene) {
|
|
this.scene = scene;
|
|
|
|
// Social status (hearts)
|
|
this.socialStatus = 0; // 0-100
|
|
this.hearts = 0; // Visual hearts earned
|
|
|
|
// Active courier quests
|
|
this.activeDeliveries = [];
|
|
|
|
// NPC delivery requests database
|
|
this.deliveryTemplates = [
|
|
// PEK
|
|
{ npc: 'pek', item: 'wheat', quantity: [5, 10], reward: { type: 'hearts', amount: 2 }, message: 'Rabim pšenico za kruh!' },
|
|
{ npc: 'pek', item: 'water', quantity: [3, 5], reward: { type: 'material', pool: ['wood', 'stone'] }, message: 'Dej mi vodo, pa ti dam material!' },
|
|
|
|
// ŠIVILJA
|
|
{ npc: 'sivilja', item: 'cloth', quantity: [10, 20], reward: { type: 'hearts', amount: 3 }, message: 'Material rabim za šivanje, prosim!' },
|
|
{
|
|
npc: 'sivilja', item: 'water', quantity: [2, 4], reward: { type: 'material', pool: ['cloth', 'leather'] }, message: 'Vodo za barv
|
|
|
|
anje potrebujem!' },
|
|
|
|
// TEHNIK
|
|
{ npc: 'tehnik', item: 'glass', quantity: [3, 7], reward: { type: 'hearts', amount: 4 }, message: 'Steklo za elektroniko!' },
|
|
{ npc: 'tehnik', item: 'steel', quantity: [5, 10], reward: { type: 'material', pool: ['circuit_board', 'wire'] }, message: 'Jeklo za stroje!' },
|
|
|
|
// IVAN KOVAČ
|
|
{ npc: 'ivan_kovac', item: 'steel', quantity: [8, 15], reward: { type: 'hearts', amount: 3 }, message: 'Potrebujem jeklo za kovačijo!' },
|
|
{ npc: 'ivan_kovac', item: 'wood', quantity: [10, 20], reward: { type: 'material', pool: ['steel', 'iron_ore'] }, message: 'Les za oglje!' },
|
|
|
|
// KUSTOS
|
|
{ npc: 'kustos', item: 'glass', quantity: [2, 5], reward: { type: 'hearts', amount: 2 }, message: 'Steklo za razstavne omare!' },
|
|
{ npc: 'kustos', item: 'rare_artifact', quantity: [1, 1], reward: { type: 'material', pool: ['ancient_relic', 'museum_piece'] }, message: 'Artefakt za muzejsko zbirko!' },
|
|
|
|
// SMETAR
|
|
{ npc: 'glavni_smetar', item: 'plastic', quantity: [15, 30], reward: { type: 'hearts', amount: 1 }, message: 'Plastiko moram zbrat iz ruševin!' },
|
|
{ npc: 'glavni_smetar', item: 'wood', quantity: [5, 10], reward: { type: 'material', pool: ['broom', 'cleaning_supplies'] }, message: 'Les za nove metle!' }
|
|
];
|
|
|
|
// Material loot pools
|
|
this.materialPools = {
|
|
common: ['wood', 'stone', 'plastic', 'water'],
|
|
uncommon: ['steel', 'glass', 'cloth', 'leather'],
|
|
rare: ['circuit_board', 'wire', 'ancient_relic', 'museum_piece']
|
|
};
|
|
|
|
this.init();
|
|
}
|
|
|
|
init() {
|
|
// Start quest generation
|
|
this.startQuestGeneration();
|
|
|
|
// Listen for delivery completions
|
|
this.scene.events.on('courier:delivery_complete', this.onDeliveryComplete, this);
|
|
|
|
console.log('✅ CourierSystem initialized - Side-quests active');
|
|
}
|
|
|
|
/**
|
|
* QUEST GENERATION
|
|
*/
|
|
startQuestGeneration() {
|
|
// Generate random delivery quest every 2-5 minutes
|
|
const generateQuest = () => {
|
|
if (this.activeDeliveries.length < 5) { // Max 5 active
|
|
this.generateDeliveryQuest();
|
|
}
|
|
|
|
// Schedule next generation
|
|
const nextTime = Phaser.Math.Between(120000, 300000); // 2-5 minutes
|
|
setTimeout(generateQuest, nextTime);
|
|
};
|
|
|
|
// Start initial quest immediately
|
|
generateQuest();
|
|
}
|
|
|
|
generateDeliveryQuest() {
|
|
const template = Phaser.Utils.Array.GetRandom(this.deliveryTemplates);
|
|
|
|
const quest = {
|
|
id: `delivery_${Date.now()}`,
|
|
npc: template.npc,
|
|
item: template.item,
|
|
quantity: Phaser.Math.Between(template.quantity[0], template.quantity[1]),
|
|
reward: template.reward,
|
|
message: template.message,
|
|
timeCreated: Date.now(),
|
|
expiresIn: 600000, // 10 minutes
|
|
completed: false
|
|
};
|
|
|
|
this.activeDeliveries.push(quest);
|
|
|
|
// Notify player
|
|
this.scene.events.emit('show-notification', {
|
|
title: '📦 Nova Dostava',
|
|
message: `${template.npc}: ${template.message}`,
|
|
icon: '📬',
|
|
duration: 5000,
|
|
color: '#FFD700'
|
|
});
|
|
|
|
// Show on NPC
|
|
this.scene.events.emit('npc:show_quest_marker', template.npc);
|
|
|
|
console.log(`📦 New delivery quest: ${template.npc} needs ${quest.quantity}x ${quest.item}`);
|
|
|
|
return quest;
|
|
}
|
|
|
|
/**
|
|
* ACCEPT DELIVERY QUEST
|
|
*/
|
|
acceptQuest(questId) {
|
|
const quest = this.activeDeliveries.find(q => q.id === questId);
|
|
if (!quest) return false;
|
|
|
|
quest.accepted = true;
|
|
|
|
// Add to player's active quest log
|
|
if (this.scene.questSystem) {
|
|
this.scene.questSystem.startQuest(questId);
|
|
}
|
|
|
|
console.log(`✅ Accepted delivery quest: ${questId}`);
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* DELIVER ITEMS
|
|
*/
|
|
deliverItems(questId) {
|
|
const quest = this.activeDeliveries.find(q => q.id === questId);
|
|
if (!quest || quest.completed) return false;
|
|
|
|
// Check if player has items
|
|
if (!this.scene.inventorySystem.hasItem(quest.item, quest.quantity)) {
|
|
this.scene.events.emit('show-notification', {
|
|
title: '❌ Ni dovolj',
|
|
message: `Rabiš še ${quest.quantity}x ${quest.item}!`,
|
|
icon: '📦',
|
|
duration: 3000,
|
|
color: '#FF4444'
|
|
});
|
|
return false;
|
|
}
|
|
|
|
// Remove items from inventory
|
|
this.scene.inventorySystem.removeItem(quest.item, quest.quantity);
|
|
|
|
// Mark as complete
|
|
quest.completed = true;
|
|
|
|
// Award reward
|
|
this.awardReward(quest.reward);
|
|
|
|
// Remove from active
|
|
this.activeDeliveries = this.activeDeliveries.filter(q => q.id !== questId);
|
|
|
|
// Notify completion
|
|
this.scene.events.emit('show-notification', {
|
|
title: '✅ Dostava Končana',
|
|
message: `${quest.npc} je zadovoljen!`,
|
|
icon: '🎉',
|
|
duration: 4000,
|
|
color: '#00FF00'
|
|
});
|
|
|
|
// Remove quest marker
|
|
this.scene.events.emit('npc:remove_quest_marker', quest.npc);
|
|
|
|
console.log(`✅ Delivery completed: ${questId}`);
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* AWARD REWARD
|
|
*/
|
|
awardReward(reward) {
|
|
if (reward.type === 'hearts') {
|
|
this.addHearts(reward.amount);
|
|
} else if (reward.type === 'material') {
|
|
this.awardRandomMaterial(reward.pool);
|
|
}
|
|
}
|
|
|
|
addHearts(amount) {
|
|
this.hearts += amount;
|
|
this.socialStatus = Math.min(100, this.socialStatus + (amount * 5));
|
|
|
|
// Visual heart animation
|
|
for (let i = 0; i < amount; i++) {
|
|
setTimeout(() => {
|
|
this.spawnHeart();
|
|
}, i * 300);
|
|
}
|
|
|
|
// Show status update
|
|
this.scene.events.emit('show-floating-text', {
|
|
x: this.scene.player.x,
|
|
y: this.scene.player.y - 50,
|
|
text: `+${amount} ❤️`,
|
|
color: '#FF69B4',
|
|
fontSize: '32px'
|
|
});
|
|
|
|
console.log(`❤️ +${amount} hearts (Total: ${this.hearts}, Status: ${this.socialStatus}%)`);
|
|
}
|
|
|
|
spawnHeart() {
|
|
const heart = this.scene.add.sprite(
|
|
this.scene.player.x + Phaser.Math.Between(-30, 30),
|
|
this.scene.player.y - 50,
|
|
'heart_icon'
|
|
);
|
|
heart.setScale(0);
|
|
heart.setDepth(50);
|
|
|
|
// Animate heart
|
|
this.scene.tweens.add({
|
|
targets: heart,
|
|
scaleX: 1,
|
|
scaleY: 1,
|
|
y: heart.y - 100,
|
|
alpha: 0,
|
|
duration: 1500,
|
|
ease: 'Cubic.easeOut',
|
|
onComplete: () => heart.destroy()
|
|
});
|
|
}
|
|
|
|
awardRandomMaterial(pool) {
|
|
// Random material from pool
|
|
const material = Phaser.Utils.Array.GetRandom(pool);
|
|
const quantity = Phaser.Math.Between(1, 5);
|
|
|
|
if (this.scene.inventorySystem) {
|
|
this.scene.inventorySystem.addItem(material, quantity);
|
|
}
|
|
|
|
// Show notification
|
|
this.scene.events.emit('show-notification', {
|
|
title: '🎁 Material',
|
|
message: `Prejel si: ${quantity}x ${material}`,
|
|
icon: '🔧',
|
|
duration: 4000,
|
|
color: '#FFD700'
|
|
});
|
|
|
|
console.log(`🎁 Awarded random material: ${quantity}x ${material}`);
|
|
}
|
|
|
|
/**
|
|
* QUEST EXPIRATION
|
|
*/
|
|
update(delta) {
|
|
const now = Date.now();
|
|
|
|
// Check for expired quests
|
|
this.activeDeliveries.forEach(quest => {
|
|
if (!quest.completed && (now - quest.timeCreated) > quest.expiresIn) {
|
|
// Quest expired
|
|
this.expireQuest(quest.id);
|
|
}
|
|
});
|
|
}
|
|
|
|
expireQuest(questId) {
|
|
const quest = this.activeDeliveries.find(q => q.id === questId);
|
|
if (!quest) return;
|
|
|
|
this.activeDeliveries = this.activeDeliveries.filter(q => q.id !== questId);
|
|
|
|
// Notify player
|
|
this.scene.events.emit('show-notification', {
|
|
title: '⏰ Quest Expired',
|
|
message: `${quest.npc} je našel drugega kurirja.`,
|
|
icon: '😞',
|
|
duration: 3000,
|
|
color: '#999999'
|
|
});
|
|
|
|
// Remove marker
|
|
this.scene.events.emit('npc:remove_quest_marker', quest.npc);
|
|
|
|
console.log(`⏰ Quest expired: ${questId}`);
|
|
}
|
|
|
|
/**
|
|
* GET SOCIAL STATUS BENEFITS
|
|
*/
|
|
getSocialBenefits() {
|
|
const benefits = [];
|
|
|
|
if (this.socialStatus >= 20) benefits.push('5% discount at shops');
|
|
if (this.socialStatus >= 40) benefits.push('Priority quests from NPCs');
|
|
if (this.socialStatus >= 60) benefits.push('Access to VIP areas');
|
|
if (this.socialStatus >= 80) benefits.push('Rare gift chance +10%');
|
|
if (this.socialStatus >= 100) benefits.push('Maximum respect - All NPCs love you!');
|
|
|
|
return benefits;
|
|
}
|
|
|
|
/**
|
|
* GET UI DATA
|
|
*/
|
|
getActiveQuests() {
|
|
return this.activeDeliveries.filter(q => !q.completed).map(q => ({
|
|
id: q.id,
|
|
npc: q.npc,
|
|
item: q.item,
|
|
quantity: q.quantity,
|
|
reward: q.reward,
|
|
timeRemaining: q.expiresIn - (Date.now() - q.timeCreated)
|
|
}));
|
|
}
|
|
|
|
destroy() {
|
|
this.activeDeliveries = [];
|
|
}
|
|
}
|