Untitled

 avatar
unknown
python
2 months ago
10 kB
4
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