347 lines
No EOL
15 KiB
Python
347 lines
No EOL
15 KiB
Python
import random
|
|
import asyncio
|
|
import discord
|
|
from redbot.core import commands, bank, Config
|
|
from redbot.core.utils.chat_formatting import humanize_number
|
|
from datetime import datetime, timedelta
|
|
|
|
class Business(commands.Cog):
|
|
"""Business system for UnbelievaBoat economy"""
|
|
|
|
def __init__(self, bot):
|
|
self.bot = bot
|
|
self.config = Config.get_conf(self, identifier=95932766180346, force_registration=True)
|
|
|
|
default_global = {
|
|
"business_types": {
|
|
"Restaurant": {
|
|
"cost": 25000,
|
|
"daily_revenue": {"min": 1000, "max": 3000},
|
|
"employees": {"min": 2, "max": 8},
|
|
"upkeep": 500
|
|
},
|
|
"Retail Store": {
|
|
"cost": 35000,
|
|
"daily_revenue": {"min": 2000, "max": 4000},
|
|
"employees": {"min": 3, "max": 10},
|
|
"upkeep": 750
|
|
},
|
|
"Tech Startup": {
|
|
"cost": 50000,
|
|
"daily_revenue": {"min": 3000, "max": 8000},
|
|
"employees": {"min": 4, "max": 15},
|
|
"upkeep": 1500
|
|
}
|
|
},
|
|
"upgrades": {
|
|
"Marketing": {
|
|
"cost": 10000,
|
|
"revenue_multiplier": 1.2
|
|
},
|
|
"Training": {
|
|
"cost": 15000,
|
|
"efficiency_boost": 1.15
|
|
},
|
|
"Automation": {
|
|
"cost": 25000,
|
|
"upkeep_reduction": 0.8
|
|
}
|
|
}
|
|
}
|
|
|
|
default_user = {
|
|
"businesses": {}, # {"business_name": {"type": "type", "employees": 0, "upgrades": [], "last_collection": null}}
|
|
"total_revenue": 0,
|
|
"total_expenses": 0
|
|
}
|
|
|
|
self.config.register_global(**default_global)
|
|
self.config.register_user(**default_user)
|
|
|
|
# Start background task for passive income
|
|
self.income_task = self.bot.loop.create_task(self.generate_passive_income())
|
|
|
|
def cog_unload(self):
|
|
if self.income_task:
|
|
self.income_task.cancel()
|
|
|
|
async def generate_passive_income(self):
|
|
"""Background task to generate passive income for businesses"""
|
|
while True:
|
|
try:
|
|
all_users = await self.config.all_users()
|
|
for user_id, user_data in all_users.items():
|
|
if not user_data["businesses"]:
|
|
continue
|
|
|
|
user = self.bot.get_user(user_id)
|
|
if not user:
|
|
continue
|
|
|
|
for business_name, business in user_data["businesses"].items():
|
|
last_collection = datetime.fromisoformat(business["last_collection"]) if business["last_collection"] else None
|
|
if not last_collection or (datetime.now() - last_collection).total_seconds() >= 86400: # 24 hours
|
|
await self.collect_revenue(user, business_name, business)
|
|
|
|
await asyncio.sleep(3600) # Check every hour
|
|
except Exception as e:
|
|
print(f"Error in passive income task: {e}")
|
|
await asyncio.sleep(60)
|
|
|
|
async def collect_revenue(self, user, business_name, business):
|
|
"""Collect revenue for a business"""
|
|
business_types = await self.config.business_types()
|
|
business_type = business_types[business["type"]]
|
|
|
|
# Calculate base revenue
|
|
base_revenue = random.randint(
|
|
business_type["daily_revenue"]["min"],
|
|
business_type["daily_revenue"]["max"]
|
|
)
|
|
|
|
# Apply employee bonus
|
|
employee_bonus = 1 + (business["employees"] / business_type["employees"]["max"] * 0.5)
|
|
revenue = base_revenue * employee_bonus
|
|
|
|
# Apply upgrades
|
|
upgrades = await self.config.upgrades()
|
|
for upgrade in business["upgrades"]:
|
|
if upgrade == "Marketing":
|
|
revenue *= upgrades["Marketing"]["revenue_multiplier"]
|
|
elif upgrade == "Training":
|
|
revenue *= upgrades["Training"]["efficiency_boost"]
|
|
|
|
# Calculate upkeep
|
|
upkeep = business_type["upkeep"] * business["employees"]
|
|
if "Automation" in business["upgrades"]:
|
|
upkeep *= upgrades["Automation"]["upkeep_reduction"]
|
|
|
|
# Calculate net profit
|
|
net_profit = revenue - upkeep
|
|
|
|
# Update user's balance and statistics
|
|
try:
|
|
await bank.deposit_credits(user, int(net_profit))
|
|
async with self.config.user(user).all() as user_data:
|
|
user_data["total_revenue"] += revenue
|
|
user_data["total_expenses"] += upkeep
|
|
user_data["businesses"][business_name]["last_collection"] = datetime.now().isoformat()
|
|
except Exception as e:
|
|
print(f"Error collecting revenue for {user.name}'s business: {e}")
|
|
|
|
@commands.group()
|
|
async def business(self, ctx):
|
|
"""Business management commands"""
|
|
pass
|
|
|
|
@business.command(name="types")
|
|
async def list_business_types(self, ctx):
|
|
"""List available business types"""
|
|
business_types = await self.config.business_types()
|
|
|
|
embed = discord.Embed(
|
|
title="Available Business Types",
|
|
color=discord.Color.blue(),
|
|
description="Choose your business type wisely!"
|
|
)
|
|
|
|
for name, data in business_types.items():
|
|
embed.add_field(
|
|
name=name,
|
|
value=f"Cost: ${data['cost']:,}\n"
|
|
f"Daily Revenue: ${data['daily_revenue']['min']:,}-${data['daily_revenue']['max']:,}\n"
|
|
f"Employees: {data['employees']['min']}-{data['employees']['max']}\n"
|
|
f"Daily Upkeep per Employee: ${data['upkeep']:,}",
|
|
inline=False
|
|
)
|
|
|
|
await ctx.send(embed=embed)
|
|
|
|
@business.command(name="create")
|
|
async def create_business(self, ctx, business_type: str, *, business_name: str):
|
|
"""Create a new business"""
|
|
business_types = await self.config.business_types()
|
|
if business_type not in business_types:
|
|
return await ctx.send("Invalid business type! Use `!business types` to see available types.")
|
|
|
|
async with self.config.user(ctx.author).businesses() as businesses:
|
|
if business_name in businesses:
|
|
return await ctx.send("You already have a business with that name!")
|
|
|
|
if len(businesses) >= 3:
|
|
return await ctx.send("You can only own up to 3 businesses!")
|
|
|
|
cost = business_types[business_type]["cost"]
|
|
if not await bank.can_spend(ctx.author, cost):
|
|
return await ctx.send(f"You need ${cost:,} to start this business!")
|
|
|
|
await bank.withdraw_credits(ctx.author, cost)
|
|
businesses[business_name] = {
|
|
"type": business_type,
|
|
"employees": business_types[business_type]["employees"]["min"],
|
|
"upgrades": [],
|
|
"last_collection": None
|
|
}
|
|
|
|
await ctx.send(f"Congratulations! You are now the proud owner of {business_name}!")
|
|
|
|
@business.command(name="view")
|
|
async def view_business(self, ctx, *, business_name: str = None):
|
|
"""View your business(es)"""
|
|
businesses = await self.config.user(ctx.author).businesses()
|
|
if not businesses:
|
|
return await ctx.send("You don't own any businesses!")
|
|
|
|
if business_name and business_name not in businesses:
|
|
return await ctx.send("You don't own a business with that name!")
|
|
|
|
business_types = await self.config.business_types()
|
|
|
|
if business_name:
|
|
# View specific business
|
|
business = businesses[business_name]
|
|
business_type = business_types[business["type"]]
|
|
|
|
embed = discord.Embed(
|
|
title=f"{business_name} ({business['type']})",
|
|
color=discord.Color.green()
|
|
)
|
|
|
|
embed.add_field(name="Employees", value=f"{business['employees']}/{business_type['employees']['max']}")
|
|
embed.add_field(name="Daily Revenue Range",
|
|
value=f"${business_type['daily_revenue']['min']:,}-${business_type['daily_revenue']['max']:,}")
|
|
embed.add_field(name="Upgrades", value=", ".join(business["upgrades"]) or "None")
|
|
|
|
if business["last_collection"]:
|
|
last_collection = datetime.fromisoformat(business["last_collection"])
|
|
time_since = datetime.now() - last_collection
|
|
embed.add_field(name="Time Since Last Collection",
|
|
value=f"{time_since.days}d {time_since.seconds//3600}h")
|
|
else:
|
|
# View all businesses
|
|
embed = discord.Embed(
|
|
title=f"{ctx.author.name}'s Business Empire",
|
|
color=discord.Color.green()
|
|
)
|
|
|
|
for name, business in businesses.items():
|
|
business_type = business_types[business["type"]]
|
|
embed.add_field(
|
|
name=name,
|
|
value=f"Type: {business['type']}\n"
|
|
f"Employees: {business['employees']}/{business_type['employees']['max']}\n"
|
|
f"Upgrades: {len(business['upgrades'])}",
|
|
inline=False
|
|
)
|
|
|
|
# Add overall statistics
|
|
user_data = await self.config.user(ctx.author).all()
|
|
embed.add_field(
|
|
name="Overall Statistics",
|
|
value=f"Total Revenue: ${user_data['total_revenue']:,}\n"
|
|
f"Total Expenses: ${user_data['total_expenses']:,}\n"
|
|
f"Net Profit: ${user_data['total_revenue']-user_data['total_expenses']:,}",
|
|
inline=False
|
|
)
|
|
|
|
await ctx.send(embed=embed)
|
|
|
|
@business.command(name="hire")
|
|
async def hire_employees(self, ctx, business_name: str, amount: int):
|
|
"""Hire employees for your business"""
|
|
if amount <= 0:
|
|
return await ctx.send("Please specify a positive number of employees to hire!")
|
|
|
|
async with self.config.user(ctx.author).businesses() as businesses:
|
|
if business_name not in businesses:
|
|
return await ctx.send("You don't own a business with that name!")
|
|
|
|
business = businesses[business_name]
|
|
business_type = (await self.config.business_types())[business["type"]]
|
|
|
|
current_employees = business["employees"]
|
|
max_employees = business_type["employees"]["max"]
|
|
|
|
if current_employees + amount > max_employees:
|
|
return await ctx.send(f"You can only have up to {max_employees} employees in this business!")
|
|
|
|
hire_cost = amount * business_type["upkeep"] * 2 # Hiring cost = 2x daily upkeep
|
|
|
|
if not await bank.can_spend(ctx.author, hire_cost):
|
|
return await ctx.send(f"You need ${hire_cost:,} to hire {amount} employees!")
|
|
|
|
await bank.withdraw_credits(ctx.author, hire_cost)
|
|
business["employees"] += amount
|
|
|
|
await ctx.send(f"Successfully hired {amount} employees for {business_name}!")
|
|
|
|
@business.command(name="upgrade")
|
|
async def upgrade_business(self, ctx, business_name: str, upgrade_name: str):
|
|
"""Purchase an upgrade for your business"""
|
|
upgrades = await self.config.upgrades()
|
|
if upgrade_name not in upgrades:
|
|
return await ctx.send("Invalid upgrade! Available upgrades: " + ", ".join(upgrades.keys()))
|
|
|
|
async with self.config.user(ctx.author).businesses() as businesses:
|
|
if business_name not in businesses:
|
|
return await ctx.send("You don't own a business with that name!")
|
|
|
|
business = businesses[business_name]
|
|
if upgrade_name in business["upgrades"]:
|
|
return await ctx.send("You already have this upgrade!")
|
|
|
|
upgrade_cost = upgrades[upgrade_name]["cost"]
|
|
if not await bank.can_spend(ctx.author, upgrade_cost):
|
|
return await ctx.send(f"You need ${upgrade_cost:,} to purchase this upgrade!")
|
|
|
|
await bank.withdraw_credits(ctx.author, upgrade_cost)
|
|
business["upgrades"].append(upgrade_name)
|
|
|
|
await ctx.send(f"Successfully purchased the {upgrade_name} upgrade for {business_name}!")
|
|
|
|
@business.command(name="sell")
|
|
async def sell_business(self, ctx, *, business_name: str):
|
|
"""Sell one of your businesses"""
|
|
async with self.config.user(ctx.author).businesses() as businesses:
|
|
if business_name not in businesses:
|
|
return await ctx.send("You don't own a business with that name!")
|
|
|
|
business = businesses[business_name]
|
|
business_type = (await self.config.business_types())[business["type"]]
|
|
|
|
# Calculate sell value (50% of initial cost plus 25% per upgrade)
|
|
sell_value = business_type["cost"] * 0.5
|
|
sell_value += len(business["upgrades"]) * (business_type["cost"] * 0.25)
|
|
|
|
await bank.deposit_credits(ctx.author, int(sell_value))
|
|
del businesses[business_name]
|
|
|
|
await ctx.send(f"Successfully sold {business_name} for ${int(sell_value):,}!")
|
|
|
|
@business.command(name="upgrades")
|
|
async def list_upgrades(self, ctx):
|
|
"""List available business upgrades"""
|
|
upgrades = await self.config.upgrades()
|
|
|
|
embed = discord.Embed(
|
|
title="Available Business Upgrades",
|
|
color=discord.Color.blue()
|
|
)
|
|
|
|
for name, data in upgrades.items():
|
|
effects = []
|
|
if "revenue_multiplier" in data:
|
|
effects.append(f"+{(data['revenue_multiplier']-1)*100}% Revenue")
|
|
if "efficiency_boost" in data:
|
|
effects.append(f"+{(data['efficiency_boost']-1)*100}% Efficiency")
|
|
if "upkeep_reduction" in data:
|
|
effects.append(f"-{(1-data['upkeep_reduction'])*100}% Upkeep")
|
|
|
|
embed.add_field(
|
|
name=name,
|
|
value=f"Cost: ${data['cost']:,}\n"
|
|
f"Effects: {', '.join(effects)}",
|
|
inline=False
|
|
)
|
|
|
|
await ctx.send(embed=embed) |