narejeno
This commit is contained in:
467
src/systems/MultiplayerSocialSystem.js
Normal file
467
src/systems/MultiplayerSocialSystem.js
Normal file
@@ -0,0 +1,467 @@
|
||||
/**
|
||||
* MULTIPLAYER & SOCIAL SYSTEM
|
||||
* Co-op mode, trading, leaderboards, and social features
|
||||
*/
|
||||
class MultiplayerSocialSystem {
|
||||
constructor(scene) {
|
||||
this.scene = scene;
|
||||
this.enabled = true;
|
||||
|
||||
// Multiplayer
|
||||
this.isHost = false;
|
||||
this.isConnected = false;
|
||||
this.players = new Map();
|
||||
this.maxPlayers = 4;
|
||||
|
||||
// Trading
|
||||
this.tradeOffers = new Map();
|
||||
this.activeTrade = null;
|
||||
|
||||
// Leaderboards
|
||||
this.leaderboards = new Map();
|
||||
|
||||
// Social
|
||||
this.friends = new Set();
|
||||
this.gifts = [];
|
||||
|
||||
// Events
|
||||
this.activeEvent = null;
|
||||
|
||||
this.loadProgress();
|
||||
this.init();
|
||||
|
||||
console.log('✅ Multiplayer & Social System initialized');
|
||||
}
|
||||
|
||||
init() {
|
||||
this.defineLeaderboards();
|
||||
this.defineEvents();
|
||||
console.log('🌐 Multiplayer & Social ready');
|
||||
}
|
||||
|
||||
// ========== CO-OP MODE ==========
|
||||
|
||||
hostGame() {
|
||||
this.isHost = true;
|
||||
this.isConnected = true;
|
||||
|
||||
// Add host player
|
||||
this.players.set('host', {
|
||||
id: 'host',
|
||||
name: 'Player 1',
|
||||
x: 50,
|
||||
y: 50,
|
||||
isHost: true
|
||||
});
|
||||
|
||||
console.log('🎮 Hosting game...');
|
||||
return true;
|
||||
}
|
||||
|
||||
joinGame(hostId) {
|
||||
this.isHost = false;
|
||||
this.isConnected = true;
|
||||
|
||||
console.log(`🎮 Joining game ${hostId}...`);
|
||||
return true;
|
||||
}
|
||||
|
||||
addPlayer(playerId, playerData) {
|
||||
if (this.players.size >= this.maxPlayers) {
|
||||
console.log('❌ Game is full');
|
||||
return false;
|
||||
}
|
||||
|
||||
this.players.set(playerId, {
|
||||
id: playerId,
|
||||
name: playerData.name || `Player ${this.players.size + 1}`,
|
||||
x: playerData.x || 50,
|
||||
y: playerData.y || 50,
|
||||
isHost: false
|
||||
});
|
||||
|
||||
console.log(`✅ Player joined: ${playerData.name}`);
|
||||
return true;
|
||||
}
|
||||
|
||||
removePlayer(playerId) {
|
||||
this.players.delete(playerId);
|
||||
console.log(`👋 Player left: ${playerId}`);
|
||||
}
|
||||
|
||||
syncWorldState() {
|
||||
// Sync game state between players
|
||||
const worldState = {
|
||||
time: this.scene.weatherSystem?.currentTime || 0,
|
||||
weather: this.scene.weatherSystem?.currentWeather || 'clear',
|
||||
players: Array.from(this.players.values())
|
||||
};
|
||||
|
||||
return worldState;
|
||||
}
|
||||
|
||||
updatePlayerPosition(playerId, x, y) {
|
||||
const player = this.players.get(playerId);
|
||||
if (player) {
|
||||
player.x = x;
|
||||
player.y = y;
|
||||
}
|
||||
}
|
||||
|
||||
// ========== CO-OP QUESTS ==========
|
||||
|
||||
startCoopQuest(questId) {
|
||||
console.log(`🤝 Co-op quest started: ${questId}`);
|
||||
|
||||
const coopQuests = {
|
||||
'farm_together': {
|
||||
name: 'Farm Together',
|
||||
objective: 'Harvest 100 crops as a team',
|
||||
reward: { xp: 500, gold: 1000 }
|
||||
},
|
||||
'boss_raid': {
|
||||
name: 'Boss Raid',
|
||||
objective: 'Defeat boss together',
|
||||
reward: { xp: 2000, legendary_item: 1 }
|
||||
}
|
||||
};
|
||||
|
||||
return coopQuests[questId];
|
||||
}
|
||||
|
||||
// ========== TRADING ==========
|
||||
|
||||
createTradeOffer(targetPlayerId, offeredItems, requestedItems) {
|
||||
const tradeId = `trade_${Date.now()}`;
|
||||
|
||||
this.tradeOffers.set(tradeId, {
|
||||
id: tradeId,
|
||||
from: 'local_player',
|
||||
to: targetPlayerId,
|
||||
offered: offeredItems,
|
||||
requested: requestedItems,
|
||||
status: 'pending',
|
||||
createdAt: Date.now()
|
||||
});
|
||||
|
||||
console.log(`💱 Trade offer created: ${tradeId}`);
|
||||
return tradeId;
|
||||
}
|
||||
|
||||
acceptTrade(tradeId) {
|
||||
const trade = this.tradeOffers.get(tradeId);
|
||||
if (!trade || trade.status !== 'pending') return false;
|
||||
|
||||
// Execute trade
|
||||
this.executeTrade(trade);
|
||||
|
||||
trade.status = 'completed';
|
||||
console.log(`✅ Trade completed: ${tradeId}`);
|
||||
return true;
|
||||
}
|
||||
|
||||
rejectTrade(tradeId) {
|
||||
const trade = this.tradeOffers.get(tradeId);
|
||||
if (!trade) return false;
|
||||
|
||||
trade.status = 'rejected';
|
||||
console.log(`❌ Trade rejected: ${tradeId}`);
|
||||
return true;
|
||||
}
|
||||
|
||||
executeTrade(trade) {
|
||||
// Transfer items between players
|
||||
console.log(`💱 Executing trade...`);
|
||||
|
||||
// Remove offered items from local player
|
||||
if (this.scene.inventorySystem) {
|
||||
for (const [item, amount] of Object.entries(trade.offered)) {
|
||||
this.scene.inventorySystem.removeItem(item, amount);
|
||||
}
|
||||
|
||||
// Add requested items to local player
|
||||
for (const [item, amount] of Object.entries(trade.requested)) {
|
||||
this.scene.inventorySystem.addItem(item, amount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ========== GLOBAL MARKETPLACE ==========
|
||||
|
||||
listItemOnMarket(item, amount, price) {
|
||||
console.log(`🏪 Listed ${amount}x ${item} for ${price} gold`);
|
||||
|
||||
const listing = {
|
||||
id: `listing_${Date.now()}`,
|
||||
seller: 'local_player',
|
||||
item,
|
||||
amount,
|
||||
price,
|
||||
listedAt: Date.now()
|
||||
};
|
||||
|
||||
return listing;
|
||||
}
|
||||
|
||||
buyFromMarket(listingId) {
|
||||
console.log(`💰 Purchased item from market: ${listingId}`);
|
||||
}
|
||||
|
||||
// ========== AUCTION HOUSE ==========
|
||||
|
||||
createAuction(item, startingBid, duration) {
|
||||
console.log(`🔨 Auction created: ${item} starting at ${startingBid} gold`);
|
||||
|
||||
const auction = {
|
||||
id: `auction_${Date.now()}`,
|
||||
seller: 'local_player',
|
||||
item,
|
||||
currentBid: startingBid,
|
||||
highestBidder: null,
|
||||
endsAt: Date.now() + duration,
|
||||
bids: []
|
||||
};
|
||||
|
||||
return auction;
|
||||
}
|
||||
|
||||
placeBid(auctionId, bidAmount) {
|
||||
console.log(`💰 Bid placed: ${bidAmount} gold on ${auctionId}`);
|
||||
}
|
||||
|
||||
// ========== PRICE FLUCTUATION ==========
|
||||
|
||||
updateMarketPrices() {
|
||||
// Simulate market price changes
|
||||
const priceChanges = {
|
||||
wheat: 1.0 + (Math.random() - 0.5) * 0.2,
|
||||
iron: 1.0 + (Math.random() - 0.5) * 0.3,
|
||||
gold: 1.0 + (Math.random() - 0.5) * 0.1
|
||||
};
|
||||
|
||||
return priceChanges;
|
||||
}
|
||||
|
||||
// ========== LEADERBOARDS ==========
|
||||
|
||||
defineLeaderboards() {
|
||||
this.leaderboards.set('productivity', {
|
||||
name: 'Farm Productivity',
|
||||
entries: []
|
||||
});
|
||||
|
||||
this.leaderboards.set('speedrun', {
|
||||
name: 'Fastest Speedruns',
|
||||
entries: []
|
||||
});
|
||||
|
||||
this.leaderboards.set('survival', {
|
||||
name: 'Highest Survival Days',
|
||||
entries: []
|
||||
});
|
||||
|
||||
this.leaderboards.set('wealth', {
|
||||
name: 'Richest Players',
|
||||
entries: []
|
||||
});
|
||||
|
||||
this.leaderboards.set('boss_kills', {
|
||||
name: 'Boss Kill Times',
|
||||
entries: []
|
||||
});
|
||||
}
|
||||
|
||||
submitScore(leaderboardId, score) {
|
||||
const leaderboard = this.leaderboards.get(leaderboardId);
|
||||
if (!leaderboard) return false;
|
||||
|
||||
leaderboard.entries.push({
|
||||
player: 'local_player',
|
||||
score,
|
||||
timestamp: Date.now()
|
||||
});
|
||||
|
||||
// Sort by score (descending)
|
||||
leaderboard.entries.sort((a, b) => b.score - a.score);
|
||||
|
||||
// Keep top 100
|
||||
leaderboard.entries = leaderboard.entries.slice(0, 100);
|
||||
|
||||
console.log(`🏆 Score submitted to ${leaderboard.name}: ${score}`);
|
||||
return true;
|
||||
}
|
||||
|
||||
getLeaderboard(leaderboardId) {
|
||||
return this.leaderboards.get(leaderboardId);
|
||||
}
|
||||
|
||||
// ========== SOCIAL INTEGRATION ==========
|
||||
|
||||
shareScreenshot() {
|
||||
console.log('📸 Screenshot shared!');
|
||||
// Steam overlay integration
|
||||
}
|
||||
|
||||
visitFarm(playerId) {
|
||||
console.log(`🚜 Visiting ${playerId}'s farm...`);
|
||||
}
|
||||
|
||||
sendGift(playerId, item, amount) {
|
||||
const gift = {
|
||||
id: `gift_${Date.now()}`,
|
||||
from: 'local_player',
|
||||
to: playerId,
|
||||
item,
|
||||
amount,
|
||||
message: '',
|
||||
sentAt: Date.now()
|
||||
};
|
||||
|
||||
console.log(`🎁 Gift sent to ${playerId}: ${amount}x ${item}`);
|
||||
return gift;
|
||||
}
|
||||
|
||||
receiveGift(giftId) {
|
||||
console.log(`🎁 Gift received: ${giftId}`);
|
||||
|
||||
// Add to inventory
|
||||
if (this.scene.inventorySystem) {
|
||||
// this.scene.inventorySystem.addItem(gift.item, gift.amount);
|
||||
}
|
||||
}
|
||||
|
||||
addFriend(playerId) {
|
||||
this.friends.add(playerId);
|
||||
console.log(`👥 Added friend: ${playerId}`);
|
||||
this.saveProgress();
|
||||
}
|
||||
|
||||
removeFriend(playerId) {
|
||||
this.friends.delete(playerId);
|
||||
console.log(`👋 Removed friend: ${playerId}`);
|
||||
this.saveProgress();
|
||||
}
|
||||
|
||||
// ========== COMMUNITY EVENTS ==========
|
||||
|
||||
defineEvents() {
|
||||
this.events = {
|
||||
'harvest_festival': {
|
||||
name: 'Harvest Festival',
|
||||
duration: 604800000, // 7 days
|
||||
bonuses: { crop_yield: 2.0, xp: 1.5 }
|
||||
},
|
||||
'zombie_invasion': {
|
||||
name: 'Zombie Invasion',
|
||||
duration: 259200000, // 3 days
|
||||
bonuses: { zombie_spawn: 3.0, loot: 2.0 }
|
||||
},
|
||||
'winter_wonderland': {
|
||||
name: 'Winter Wonderland',
|
||||
duration: 1209600000, // 14 days
|
||||
bonuses: { snow_items: true, special_decorations: true }
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
startEvent(eventId) {
|
||||
const event = this.events[eventId];
|
||||
if (!event) return false;
|
||||
|
||||
this.activeEvent = {
|
||||
id: eventId,
|
||||
...event,
|
||||
startTime: Date.now(),
|
||||
endTime: Date.now() + event.duration
|
||||
};
|
||||
|
||||
console.log(`🎉 Event started: ${event.name}`);
|
||||
return true;
|
||||
}
|
||||
|
||||
endEvent() {
|
||||
if (!this.activeEvent) return;
|
||||
|
||||
console.log(`🎉 Event ended: ${this.activeEvent.name}`);
|
||||
this.activeEvent = null;
|
||||
}
|
||||
|
||||
// ========== SEASONAL CHALLENGES ==========
|
||||
|
||||
getWeeklyChallenges() {
|
||||
return [
|
||||
{ name: 'Harvest 500 crops', reward: { gold: 1000 } },
|
||||
{ name: 'Defeat 50 zombies', reward: { xp: 500 } },
|
||||
{ name: 'Craft 20 items', reward: { blueprint: 'rare_item' } }
|
||||
];
|
||||
}
|
||||
|
||||
getMonthlyChallenges() {
|
||||
return [
|
||||
{ name: 'Reach level 50', reward: { legendary_item: 1 } },
|
||||
{ name: 'Complete all quests', reward: { title: 'Quest Master' } },
|
||||
{ name: 'Defeat all bosses', reward: { mount: 'dragon' } }
|
||||
];
|
||||
}
|
||||
|
||||
completeChallenge(challengeId) {
|
||||
console.log(`✅ Challenge completed: ${challengeId}`);
|
||||
}
|
||||
|
||||
// ========== UPDATE ==========
|
||||
|
||||
update(delta) {
|
||||
// Update active event
|
||||
if (this.activeEvent) {
|
||||
const now = Date.now();
|
||||
if (now >= this.activeEvent.endTime) {
|
||||
this.endEvent();
|
||||
}
|
||||
}
|
||||
|
||||
// Update market prices periodically
|
||||
// this.updateMarketPrices();
|
||||
}
|
||||
|
||||
// ========== PERSISTENCE ==========
|
||||
|
||||
saveProgress() {
|
||||
const data = {
|
||||
friends: Array.from(this.friends),
|
||||
leaderboards: Array.from(this.leaderboards.entries()).map(([id, lb]) => ({
|
||||
id,
|
||||
entries: lb.entries
|
||||
}))
|
||||
};
|
||||
|
||||
localStorage.setItem('novafarma_multiplayer', JSON.stringify(data));
|
||||
}
|
||||
|
||||
loadProgress() {
|
||||
const saved = localStorage.getItem('novafarma_multiplayer');
|
||||
if (saved) {
|
||||
try {
|
||||
const data = JSON.parse(saved);
|
||||
this.friends = new Set(data.friends || []);
|
||||
|
||||
if (data.leaderboards) {
|
||||
data.leaderboards.forEach(lb => {
|
||||
const leaderboard = this.leaderboards.get(lb.id);
|
||||
if (leaderboard) {
|
||||
leaderboard.entries = lb.entries;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
console.log('✅ Multiplayer progress loaded');
|
||||
} catch (error) {
|
||||
console.error('Failed to load multiplayer progress:', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.saveProgress();
|
||||
console.log('🌐 Multiplayer & Social System destroyed');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user