Untitled

 avatar
unknown
python
10 months ago
10 kB
11
Indexable
import discord
from discord.ext import commands
from discord.ui import Button, Modal, TextInput
import asyncio
import random
import os
import json
from together import Together
from points_manager import PointsManager

class SubmissionModal(Modal):
    def __init__(self, clash_cog):
        super().__init__(title="Submit Your Creation")
        self.clash_cog = clash_cog
        self.creation_input = TextInput(
            label="Your Creation",
            placeholder="Enter your creation's name and key features",
            style=discord.TextStyle.long,
            max_length=200,
            required=True
        )
        self.add_item(self.creation_input)

    async def on_submit(self, interaction: discord.Interaction):
        creation = self.creation_input.value.strip()
        if not creation:
            await interaction.response.send_message("Creation cannot be empty!", ephemeral=True)
            return

        if interaction.user.id in self.clash_cog.submissions:
            await interaction.response.send_message("You've already submitted a creation!", ephemeral=True)
            return

        self.clash_cog.submissions[interaction.user.id] = {
            'name': creation,
            'power': random.randint(60, 100),
            'special_moves': random.randint(1, 3),
            'durability': random.randint(70, 100)
        }
        
        await interaction.response.send_message(
            f"✅ Your creation **{creation}** has been registered for battle!", 
            ephemeral=True
        )

class BattleSystem:
    def __init__(self):
        self.status_effects = ['stunned', 'powered_up', 'weakened']
        self.critical_threshold = 85

    def calculate_damage(self, attacker, defender, is_comeback=False):
        base_damage = attacker['power'] * random.uniform(0.8, 1.2)
        
        if random.randint(1, 100) > self.critical_threshold:
            base_damage *= 1.5
            
        if is_comeback:
            base_damage *= 1.3
            
        defense = defender['durability'] * random.uniform(0.7, 1.0)
        return max(int(base_damage - defense), 10)

    def generate_battle_stats(self, creation1, creation2):
        return {
            'rounds': random.randint(2, 4),
            'status_effects': random.sample(self.status_effects, 1)[0],
            'special_move_chance': 0.3
        }

class Clash(commands.Cog):
    def __init__(self, bot):
        self.bot = bot
        self.together_client = Together(api_key="")
        self.submissions = {}
        self.battle_system = BattleSystem()
        self.points_manager = PointsManager()
        self.winners = self.load_json("winners.json")
        self.game_active = False
        self.current_round = 0
        self.eliminated_players = []
        self.battle_logs = []

    def load_json(self, filename):
        if os.path.exists(filename):
            with open(filename, "r") as file:
                return json.load(file)
        return {}

    def save_json(self, filename, data):
        with open(filename, "w") as file:
            json.dump(data, file, indent=4)

    async def generate_battle_narrative(self, attacker, defender, damage, battle_stats):
        base_prompts = [
            f"{attacker['name']} unleashes a devastating attack on {defender['name']}, dealing {damage} damage!",
            f"In a brilliant display of power, {attacker['name']} strikes {defender['name']} for {damage} points!",
            f"{attacker['name']} executes a perfect maneuver against {defender['name']}, causing {damage} damage!"
        ]
        
        if damage > 50:
            base_prompts.append(f"An extraordinary move by {attacker['name']} deals a massive {damage} damage to {defender['name']}!")
        
        if battle_stats['status_effects'] == 'powered_up':
            base_prompts.append(f"{attacker['name']} enters a powered-up state, enhancing their next attack!")
            
        return random.choice(base_prompts)

    async def process_battle(self, ctx, battle_entries):
        self.current_round += 1
        next_round = []
        eliminated_this_round = []

        round_embed = discord.Embed(
            title=f"⚔️ Round {self.current_round}",
            description=f"**{len(battle_entries)} Creations Remain**",
            color=discord.Color.gold()
        )
        await ctx.send(embed=round_embed)

        for i in range(0, len(battle_entries) - 1, 2):
            user1, creation1 = battle_entries[i]
            user2, creation2 = battle_entries[i + 1]
            
            battle_stats = self.battle_system.generate_battle_stats(creation1, creation2)
            hp1, hp2 = 100, 100
            battle_log = []

            while hp1 > 0 and hp2 > 0:
                for attacker, defender, atk_hp, def_hp in [(creation1, creation2, hp1, hp2), (creation2, creation1, hp2, hp1)]:
                    if atk_hp <= 0:
                        continue
                        
                    damage = self.battle_system.calculate_damage(attacker, defender)
                    narrative = await self.generate_battle_narrative(attacker, defender, damage, battle_stats)
                    battle_log.append(narrative)
                    
                    if attacker == creation1:
                        hp2 -= damage
                    else:
                        hp1 -= damage

            winner = (user1, creation1) if hp1 > hp2 else (user2, creation2)
            loser = (user2, creation2) if hp1 > hp2 else (user1, creation1)
            
            battle_embed = discord.Embed(
                title=f"⚔️ {creation1['name']} vs {creation2['name']}",
                description="\n".join(battle_log[-3:]),
                color=discord.Color.blue()
            )
            battle_embed.add_field(name="Winner", value=f"🏆 {winner[1]['name']}", inline=False)
            await ctx.send(embed=battle_embed)
            
            next_round.append(winner)
            eliminated_this_round.append(loser)

            await asyncio.sleep(2)

        comeback_chance = 0.3 if self.current_round > 1 else 0
        if random.random() < comeback_chance and eliminated_this_round:
            comeback_fighter = random.choice(eliminated_this_round)
            comeback_embed = discord.Embed(
                title="🔥 Dramatic Comeback!",
                description=f"**{comeback_fighter[1]['name']}** refuses to give up!",
                color=discord.Color.red()
            )
            await ctx.send(embed=comeback_embed)
            next_round.append(comeback_fighter)

        return next_round

    async def start_submission_phase(self, ctx, duration=120):
        embed = discord.Embed(
            title="🎮 Creation Submission Phase",
            description="Click below to submit your creation!",
            color=discord.Color.blue()
        )
        
        view = discord.ui.View(timeout=duration)
        submit_button = Button(
            label="Submit Creation",
            style=discord.ButtonStyle.primary,
            emoji="⚔️"
        )

        async def button_callback(interaction):
            if interaction.user.id in self.submissions:
                await interaction.response.send_message("You've already submitted!", ephemeral=True)
                return
            await interaction.response.send_modal(SubmissionModal(self))

        submit_button.callback = button_callback
        view.add_item(submit_button)
        
        await ctx.send(embed=embed, view=view)
        await asyncio.sleep(duration)
        
        return len(self.submissions) >= 2

    @commands.command()
    async def clash(self, ctx):
        if self.game_active:
            await ctx.send("❌ A clash is already in progress!")
            return

        self.game_active = True
        self.submissions.clear()
        self.current_round = 0
        self.eliminated_players.clear()
        self.battle_logs.clear()

        start_embed = discord.Embed(
            title="🎮 Clash of Creations",
            description="The tournament is about to begin!\nSubmit your creation to participate!",
            color=discord.Color.green()
        )
        await ctx.send(embed=start_embed)

        if not await self.start_submission_phase(ctx):
            await ctx.send("Not enough participants to start the clash!")
            self.game_active = False
            return

        battle_entries = [(user, self.submissions[user.id]) for user in ctx.guild.members if user.id in self.submissions]
        random.shuffle(battle_entries)

        while len(battle_entries) > 1:
            battle_entries = await self.process_battle(ctx, battle_entries)

        if battle_entries:
            winner = battle_entries[0]
            prize = 100 + (self.current_round * 20)
            
            winner_embed = discord.Embed(
                title="🏆 Champion of the Clash!",
                description=f"**{winner[1]['name']}** emerges victorious!",
                color=discord.Color.gold()
            )
            winner_embed.add_field(name="Prize", value=f"{prize} points")
            await ctx.send(embed=winner_embed)
            
            self.points_manager.add_points(ctx.guild.id, winner[0].id, prize)
            
            winner_id = str(winner[0].id)
            self.winners[winner_id] = self.winners.get(winner_id, 0) + 1
            self.save_json("winners.json", self.winners)

        self.game_active = False

    @commands.command()
    async def clash_stats(self, ctx):
        if not self.winners:
            await ctx.send("No clash statistics available yet!")
            return

        stats_embed = discord.Embed(
            title="Clash Statistics",
            color=discord.Color.blue()
        )
        
        sorted_winners = sorted(self.winners.items(), key=lambda x: x[1], reverse=True)
        
        for i, (user_id, wins) in enumerate(sorted_winners[:5], 1):
            user = await self.bot.fetch_user(int(user_id))
            stats_embed.add_field(
                name=f"#{i} {user.name}",
                value=f"Wins: {wins}",
                inline=False
            )

        await ctx.send(embed=stats_embed)

async def setup(bot):
    await bot.add_cog(Clash(bot))
Editor is loading...
Leave a Comment