#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;

init()
{
    level.dr_version = "1.3.0";
    level.admin_version = "0.11.5 Beta";
    
    // Set some global variables
    level.dr_timer = 300; // 5 minute round timer
    level.activator_picked = false;
    level.dr_points_per_kill = 50;
    level.dr_points_per_finish = 200;
    level.dr_freerun = false; // Free run mode
    level.xp_multiplier = 1; // Default XP multiplier
    
    // Initialize Stats (Fixes "missing tables" error)
    thread maps\mp\_stats::init();
    
    // Initialize Admin Mod
    thread maps\mp\_admin::init();
    
    // Initialize Plugins
    thread initPlugins();
    
    // Register player connect callback
    level thread onPlayerConnect();
    
    // Initialize traps
    thread initTraps();
    
    // Anti-Block system
    thread antiBlock();
    
    // Finish Triggers
    thread initFinishTriggers();
    
    // Start game logic
    thread gameStartLogic();
    
    // Admin command for Free Run (CoD4X)
    if(isDefined(level.addscriptcommand))
    {
        addScriptCommand("freerun", 100); // Admin only (power 100)
    }
    
    print("Deathrun Mod " + level.dr_version + " initialized.");
}

initPlugins()
{
    // Load and initialize plugins from manumod/plugins
    // No plugins currently loaded.
}

CodeCallback_ScriptCommand(command, arguments)
{
    if(command == "freerun")
    {
        level.dr_freerun = !level.dr_freerun;
        if(level.dr_freerun)
            iprintlnbold("^2FREE RUN MODE ENABLED^7: Traps are disabled!");
        else
            iprintlnbold("^1FREE RUN MODE DISABLED^7: Traps are active!");
    }
}


antiBlock()
{
    for(;;)
    {
        players = getEntArray("player", "classname");
        for(i = 0; i < players.size; i++)
        {
            for(j = i + 1; j < players.size; j++)
            {
                p1 = players[i];
                p2 = players[j];
                
                if(!isDefined(p1) || !isAlive(p1) || !isDefined(p2) || !isAlive(p2))
                    continue;
                    
                if(p1.pers["team"] != p2.pers["team"])
                    continue; // Let them collide with enemies
                    
                dist = distance(p1.origin, p2.origin);
                if(dist < 50)
                {
                    // Simple push apart logic
                    dir = vectorNormalize(p1.origin - p2.origin);
                    p1 setOrigin(p1.origin + dir * 5);
                    p2 setOrigin(p2.origin - dir * 5);
                }
            }
        }
        wait 0.1;
    }
}

initFinishTriggers()
{
    triggers = getEntArray("dr_finish", "targetname");
    for(i = 0; i < triggers.size; i++)
    {
        triggers[i] thread onFinishTrigger();
    }
}

onFinishTrigger()
{
    for(;;)
    {
        self waittill("trigger", player);
        if(player.pers["team"] != "allies")
            continue;
            
        if(!isDefined(player.finished))
        {
            player.finished = true;
            player addPoints(level.dr_points_per_finish);
            iprintlnbold("^2" + player.name + " ^7has finished the map!");
            player thread finish_camera();
        }
    }
}

finish_camera()
{
    // Basic finish logic - maybe move player to a special room
    self iprintlnbold("You received ^2" + level.dr_points_per_finish + " ^7points!");
}

addPoints(amount)
{
    if(!isDefined(self.pers["dr_points"]))
        self.pers["dr_points"] = 0;
        
    // Apply multiplier
    points = amount * level.xp_multiplier;
    self.pers["dr_points"] += points;
    
    if(level.xp_multiplier > 1)
        self iprintln("Points: ^2+" + points + " ^7(^3" + level.xp_multiplier + "XP ACTIVE^7) (Total: " + self.pers["dr_points"] + ")");
    else
        self iprintln("Points: ^2+" + points + " ^7(Total: " + self.pers["dr_points"] + ")");
    
    // Save points to database
    self thread maps\mp\_stats::savePlayerData();
}

gameStartLogic()
{
    level waittill("prematch_done");
    
    // Choose activator
    thread chooseActivator();
    
    // Start timer
    thread gameTimer();
    
    // Round end monitoring
    thread roundEndLogic();
}

roundEndLogic()
{
    level endon("game_ended");
    for(;;)
    {
        wait 1;
        
        allies = getTeamPlayers("allies");
        axis = getTeamPlayers("axis");
        
        if(allies.size == 0 && level.activator_picked)
        {
            iprintlnbold("^1ACTIVATOR WINS^7: All Jumpers are dead!");
            wait 2;
            level notify("game_ended");
            exitLevel(false);
        }
        
        if(axis.size == 0 && level.activator_picked)
        {
            iprintlnbold("^2JUMPERS WIN^7: Activator has disconnected!");
            wait 2;
            level notify("game_ended");
            exitLevel(false);
        }
    }
}

getTeamPlayers(team)
{
    players = getEntArray("player", "classname");
    list = [];
    for(i = 0; i < players.size; i++)
    {
        if(isAlive(players[i]) && players[i].pers["team"] == team)
            list[list.size] = players[i];
    }
    return list;
}

chooseActivator()
{
    players = getEntArray("player", "classname");
    
    if(players.size < 1)
        return;
        
    activator = players[randomInt(players.size)];
    
    // For simplicity, we just set the player to Axis
    // In a real mod, we'd handle team changes and respawns properly
    activator setTeam("axis");
    activator.pers["team"] = "axis";
    activator spawnPlayer();
    
    level.activator_picked = true;
    level.activator = activator;
    
    iprintlnbold("^1" + activator.name + " ^7is the ^1ACTIVATOR^7!");
}

gameTimer()
{
    level.timerHUD = createServerFontString("objective", 1.5);
    level.timerHUD setPoint("TOPRIGHT", "TOPRIGHT", -10, 10);
    level.timerHUD.label = &"Time Left: ";
    
    while(level.dr_timer > 0)
    {
        level.timerHUD setValue(level.dr_timer);
        wait 1;
        level.dr_timer--;
    }
    
    level.timerHUD destroy();
    iprintlnbold("^1ROUND ENDED^7: Time's Up!");
    // logic to end round or switch teams
}

onPlayerConnect()
{
    for(;;)
    {
        level waittill("connected", player);
        player thread onPlayerSpawned();
    }
}

onPlayerSpawned()
{
    self endon("disconnect");
    
    if(!isDefined(self.pers["dr_points"]))
        self.pers["dr_points"] = 0;
        
    for(;;)
    {
        self waittill("spawned_player");
        
        self.finished = undefined;
        
        // Basic player setup for Deathrun
        if(self.pers["team"] == "axis") // Activator
        {
            self iprintlnbold("You are the ^1ACTIVATOR^7!");
            self setClientDvar("cg_drawGun", 1);
        }
        else if(self.pers["team"] == "allies") // Jumper
        {
            self iprintlnbold("You are a ^2JUMPER^7!");
            self takeAllWeapons();
            self giveWeapon("knife_mp");
            self switchToWeapon("knife_mp");
        }
        
        // Shop initialization
        self thread playerShop();
    }
}

playerShop()
{
    self endon("disconnect");
    self endon("death");
    
    self notifyOnPlayerCommand("open_shop", "+activate"); // Press 'F' to open shop (simple way)
    
    for(;;)
    {
        self waittill("open_shop");
        
        if(self.pers["dr_points"] >= 100)
        {
            self.pers["dr_points"] -= 100;
            self giveWeapon("colt45_mp");
            self giveMaxAmmo("colt45_mp");
            self switchToWeapon("colt45_mp");
            self iprintlnbold("You bought a ^2Pistol^7 for 100 points!");
        }
        else
        {
            self iprintln("Not enough points! You need 100.");
        }
        wait 0.5;
    }
}

initTraps()
{
    // Find all trap triggers in the map
    traps = getEntArray("dr_trap", "targetname");
    
    if(traps.size > 0)
    {
        for(i = 0; i < traps.size; i++)
        {
            traps[i].activated = false;
            traps[i] thread trap_think();
        }
    }
}

trap_think()
{
    self setHintString("Press [^3USE^7] to Activate Trap");
    
    for(;;)
    {
        self waittill("trigger", player);
        
        // Disable traps in free run
        if(level.dr_freerun)
        {
            player iprintln("^1Traps are currently disabled!");
            continue;
        }
        
        // Only Activator can activate traps
        if(player.pers["team"] != "axis")
            continue;

        if(self.activated)
        {
            player iprintln("^1Trap already activated!");
            continue;
        }

        self.activated = true;
        self setHintString("^1ACTIVATED");
        
        // Find the objects linked to this trap
        if(isDefined(self.target))
        {
            parts = getEntArray(self.target, "targetname");
            for(i = 0; i < parts.size; i++)
            {
                // Simple animation: move part down and back up
                parts[i] thread trap_part_move();
            }
        }
        
        // Reward activator for trap activation
        player addPoints(10);
        iprintlnbold("^1" + player.name + " ^7activated a trap!");
        
        // Wait until next round starts to reset
        level waittill("prematch_done");
        self.activated = false;
        self setHintString("Press [^3USE^7] to Activate Trap");
    }
}

trap_part_move()
{
    self moveZ(-100, 1);
    wait 2;
    self moveZ(100, 1);
}

