Botot_engineer.c

/*-------------------------------------------------------------------------------------
fichier créer par 3emeType le 22/04/04
Rassemble toutes les actions spécifiques à l'engineer
-------------------------------------------------------------------------------------*/

#include "../game/g_local.h"
#include "bobot.h"
extern int RandInt(int x,int y);
/*-------------------------------------------------------------------------------------
Pav: Gestion des messages de l'ingénieur.
-------------------------------------------------------------------------------------*/
char MessaDire[100];

void MessInge(int Type,int team)
{    char    AlliedConstruct[10][100]={" ^7Objective constructed guy..."," ^7Construction complete...",
                                    " ^7Yes I do, man..."," ^7Objectif construit les gars..."," ^7Do you see that guy ?",
                                    " ^7Yes, it's so easy."," ^7Je l'ai enfin construit, pas trop tot...",
                                    " ^7Objectif construit, on fonce les gars."," ^7Objective constructed guy, rush now !",
                                    " ^7T'as vu ca mon gars ?"};

    char    AlliedArme[10][100]={" ^7Dynamite planted... move guy !"," ^7Dynamite planted at objective ok...",
                               " ^7Yes I do, man !"," ^7J'ai mis une dynamite, tirez-vous les gars !",
                               " ^7Whaooo ! Do you see that guy ?"," ^7Yes, it's so easy.",
                               " ^7Dynamite en place, on se tire rapido !"," ^7Ca va peter les gars, fo pas rester ici.",
                               " ^7What are you doing here ? Dynamite ! move !"," ^7Dynamite Yeahhhh !!"};

    char    AlliedDefuse[10][100]={" ^7Dynamite defused..."," ^7Eheh dynamite defused man !"," ^7Yes man, c'est la vie...",
                                 " ^7Dynamite desamorcee les gars..."," ^7Dynamite planted ?? Where ?? ehehe !",
                                 " ^7Yes, it's so easy."," ^7Je l'ai desarmorcee de justesse..."," ^7Dynamite desarmorcee, cool !",
                                 " ^7No dynamite planted now, cool guy !"," ^7TEh hop! Plus de dynamite."};
   
    char    AxisConstruct[10][100]={" ^7Zielsetzung baut die Jungen..."," ^7beendete Konstruktion...",
                                    " ^7Ja mache ich es die Jungen..."," ^7vollständige Zielsetzung..."," ^7Sie sahen das die Jungen ?",
                                    " ^7Ja, war es einfach."," ^7Ich habe es schließlich gebaut, nicht zu früh...",
                                    " ^7Objectif construit, on fonce les gars."," ^7Konstruierte Zielsetzung geht man dahin die Jungen !",
                                    " ^7Du sahst das mein Junge ?"};

    char    AxisArme[10][100]={" ^7Dynamit in Stelle gehen Sie weg die Jungen !"," ^7Dynamit in Stelle auf der Zielsetzung...",
                               " ^7Ja kann ich es mein Junge !"," ^7Ich habe ein Dynamit gestellt, gehen Sie weg die Jungen !",
                               " ^7Whaooo ! Du sahst das ?"," ^7Ja, ist es einfach.",
                               " ^7Dynamit in Stelle, man muß schnell weggehen !"," ^7das wird explodieren die Jungen, man darf nicht hier bleiben.",
                               " ^7Was gemacht Sie dort? ? Dynamit ! gehen Sie weg !"," ^7Dynamit Jaahhhh !!"};

    char    AxisDefuse[10][100]={" ^7Entschärftes dynamit..."," ^7Jaahhh entschärftes dynamit !"," ^7Ja, c'est la vie...",
                                 " ^7Entschärftes dynamit die Jungen"," ^7In die Wege geleitetes dynamit ? oder das ?? ehehe !",
                                 " ^7Entschärftes dynamit !"," ^7Jentschärftes dynamit, guuuut !"," ^7Es gibt kein dynamit mehr !",
                                 " ^7Nicht ein Dynamit hier ahahah !"," ^7Neinnn dynamit !!"};
    int r;
    MessaDire[0]='\0';
    r=RandInt(0,9);
    if (team==TEAM_ALLIES)
    {    switch(Type)
        {    case 1: Q_strncpyz(MessaDire,AlliedConstruct[r],sizeof(AlliedConstruct[r]));
                    break;
            case 2:    Q_strncpyz(MessaDire,AlliedArme[r],sizeof(AlliedArme[r]));
                    break;
            case 3:    Q_strncpyz(MessaDire,AlliedDefuse[r],sizeof(AlliedDefuse[r]));
                    break;
            default : Q_strncpyz(MessaDire,"OK les gars, fo y aller.",sizeof("OK les gars, fo y aller."));
                    break;
        }
    }
    else if (team==TEAM_AXIS)
    {    switch(Type)
        {    case 1: Q_strncpyz(MessaDire,AxisConstruct[r],sizeof(AxisConstruct[r]));
                    break;
            case 2:    Q_strncpyz(MessaDire,AxisArme[r],sizeof(AxisArme[r]));
                    break;
            case 3:    Q_strncpyz(MessaDire,AxisDefuse[r],sizeof(AxisDefuse[r]));
                    break;
            default : Q_strncpyz(MessaDire,"OK les gars, fo y aller.",sizeof("OK les gars, fo y aller."));
                    break;
        }
    }
    else
    {    switch(Type)
        {    case 1: Q_strncpyz(MessaDire,AlliedConstruct[r],sizeof(AlliedConstruct[r]));
                    break;
            case 2:    Q_strncpyz(MessaDire,AlliedArme[r],sizeof(AlliedArme[r]));
                    break;
            case 3:    Q_strncpyz(MessaDire,AlliedDefuse[r],sizeof(AlliedDefuse[r]));
                    break;
            default : Q_strncpyz(MessaDire,"OK les gars, fo y aller.",sizeof("OK les gars, fo y aller."));
                    break;
        }
    }

}
/*-------------------------------------------------------------------------------------
Joc : L'ingé construit avec sa pince !
-------------------------------------------------------------------------------------*/
void BOBOT_ENGINEER_Construct(gentity_t *bobot, usercmd_t *ucmd)
{    Sbobot    *bobotAI;    
    vec3_t     dir,angles;
    vec_t    dist;
   
    bobotAI = &bobots[bobot->s.clientNum];
    bobotAI->DansTank = qfalse;
    if(BOBOT_AI_proposeActionToArms(bobotAI,BOBOT_OBEY_TO_ACTION,NULL))
    {    if(bobot->client->ps.weapon != WP_PLIERS)                                            //on prend la pince
        { ucmd->weapon = WP_PLIERS; }
        ucmd->buttons = BUTTON_ATTACK;                                                        //On appuie dessus
        VectorSubtract (nodes[bobot->current_node].origin, bobot->client->ps.origin, dir);    //On vise le centre du node
        dist = VectorLength(dir);
        vectoangles (dir, angles);
        AnglesSubtract (angles , bobot->s.angles , angles);
        BOBOT_MOVEMENT_ChangeBotAngle(angles,bobot);

        /* Si le bot se retrouve éloigné de l'objet à construire, alors il se rapproche. */
        if (dist > nodes[bobot->current_node].radius)
        { BOBOT_Move(bobot,ucmd); }
    }
    if(!(nodes[bobot->current_node].type & NODE_CONSTRUCTION))                                //On s'arrete quand l'objet est construit
    {    MessInge(1,bobot->client->sess.sessionTeam);
        G_Say(bobot, NULL, SAY_ALL, va("%s",MessaDire));
        G_Voice( bobot, NULL, SAY_ALL, "cheer", qtrue);
        BOBOT_AI_endOfCurrentAction(bobotAI);                                                //3emeType. action terminée
        if(bobotAI->prone == qtrue)
        {    ucmd->wbuttons |= WBUTTON_PRONE;
            bobotAI->prone = qfalse;
        }
        BOBOT_COMMON_TakeBestWeapon(bobot,bobotAI->myteam,ucmd);
    }
}

/*-------------------------------------------------------------------------------------
Joc : l'ingé pose sa dynamite
-------------------------------------------------------------------------------------*/
void BOBOT_ENGINEER_PlantDynamite(gentity_t *bobot, usercmd_t *ucmd)
{    Sbobot        *bobotAI;    
    vec3_t        dir,angles;
    gentity_t    *dyn;

    bobotAI = &bobots[bobot->s.clientNum];

    /*    PAV : Le covert plante un satchel sur un objectif à exploer NODE_CHARGE. */
    if(bobot->client->sess.playerType == PC_COVERTOPS)
    {    if(BOBOT_AI_proposeActionToArms(bobotAI,BOBOT_OBEY_TO_ACTION,NULL))
        {        if(bobot->client->ps.weapon != WP_SATCHEL)
                {    ucmd->weapon = WP_SATCHEL;
                    bobotAI->TimeSatchel = level.time + 3000;
                }
                VectorSubtract (nodes[bobotAI->goal_node].origin, bobot->client->ps.origin, dir);
                vectoangles (dir, angles);
                ucmd->buttons = (rand() % 2) * BUTTON_ATTACK;
                angles[PITCH] = 28;
                AnglesSubtract (angles , bobot->s.angles , angles);
                BOBOT_MOVEMENT_ChangeBotAngle(angles,bobot);
   
        }
        for (dyn = G_FindSatchels( NULL );dyn;dyn = G_FindSatchels(dyn))
        {    if (dyn->parent == bobot)
            {    BOBOT_AI_inhibitAction(&bobotAI->actions[bobotAI->currentAction.type]);
                BOBOT_AI_proposeAction(bobotAI,ARM_DYNAMITE,INVALID,dyn,dyn->r.currentOrigin,BOBOT_PLANT_DYNAMITE_PRIORITY);
            }
        }
    }

    /*    le déroulement de l'action dépend de la présence ou non d'un ennemi...
        s'il y en a un, les bras du bot donneront priorité au tir. */

    if(bobot->client->sess.playerType == PC_ENGINEER)
    {    /* S'il y a déjà un dynamite alors on se barre */
        if (BOBOT_ENGINEER_DynamitePlantedByTeam(bobot,bobot->current_node)!=0)
        {    BOBOT_AI_endOfCurrentAction(bobotAI);
            BOBOT_COMMON_TakeBestWeapon(bobot,bobotAI->myteam,ucmd);
            return;
        }
        if(BOBOT_AI_proposeActionToArms(bobotAI,BOBOT_OBEY_TO_ACTION,NULL))
        {    if(bobot->client->ps.weapon != WP_DYNAMITE)
            { ucmd->weapon = WP_DYNAMITE; }                                                        // On prend la dynamite
            VectorSubtract (nodes[bobotAI->goal_node].origin, bobot->client->ps.origin, dir);
            vectoangles (dir, angles);
            ucmd->buttons = (rand() % 2) * BUTTON_ATTACK;                                        // L'ingé lache sa dynamite : Il faut appuyer puis relacher le bouton, on vise le centre du node
            angles[PITCH] = 28;                                                                    // Ca évite de balancer la dynamite comme un bargeot, à 15 métres de soi (< à BOBOT_VIEW_MAX_ACCEL).
            AnglesSubtract (angles , bobot->s.angles , angles);
            BOBOT_MOVEMENT_ChangeBotAngle(angles,bobot);
        }
        for (dyn = G_FindDynamite( NULL );dyn;dyn = G_FindDynamite(dyn))
        {    if (dyn->s.teamNum < 4)                                                                // Si la dyna est déjà armée on passe
            { continue; }
            if (dyn->parent == bobot)                                                            // Le bobot arme sa dynamite en priorité
            {    BOBOT_AI_inhibitAction(&bobotAI->actions[bobotAI->currentAction.type]);            // On remplace la pose de dynamite par son amorçage parmi les actions
                BOBOT_AI_proposeAction(bobotAI,ARM_DYNAMITE,INVALID,dyn,dyn->r.currentOrigin,
                                       BOBOT_PLANT_DYNAMITE_PRIORITY);
            }
            VectorSubtract (nodes[bobot->current_node].origin, dyn->r.currentOrigin, dir);
            if(VectorLength(dir) < nodes[bobot->current_node].radius)                            // Si la dyna est dans le rayon du node (ie elle peut faire péter l'objectif)
            {    BOBOT_AI_inhibitAction(&bobotAI->actions[bobotAI->currentAction.type]);            // On remplace la pose de dynamite par son amorçage parmi les actions
                BOBOT_AI_proposeAction(bobotAI,ARM_DYNAMITE,INVALID,dyn,dyn->r.currentOrigin,
                                       BOBOT_PLANT_DYNAMITE_PRIORITY);
            }
        }
    }
}

/*-------------------------------------------------------------------------------------
pav : l'ingé pose sa mine
-------------------------------------------------------------------------------------*/
void BOBOT_ENGINEER_PlantMine(gentity_t *bobot, usercmd_t *ucmd)
{    Sbobot        *bobotAI;    
    vec3_t        dir,angles;
    gentity_t    *dyn;
    qboolean    actionAuthorizedByArms;
    bobotAI =    &bobots[bobot->s.clientNum];
   
    /*    le déroulement de l'action dépend de la présence ou non d'un ennemi...
        s'il y en a un, les bras du bot donneront priorité au tir. */

    if(bobot->client->sess.playerType == PC_ENGINEER)
    {    if(!(nodes[bobot->current_node].type & NODE_MINE))
        {    BOBOT_AI_endOfCurrentAction(bobotAI);
            BOBOT_COMMON_TakeBestWeapon(bobot,bobotAI->myteam,ucmd);
            return;
        }
        actionAuthorizedByArms = BOBOT_AI_proposeActionToArms(bobotAI,BOBOT_OBEY_TO_ACTION,NULL);
        if(actionAuthorizedByArms)   
        {    if(bobot->client->ps.weapon != WP_LANDMINE)
            { ucmd->weapon = WP_LANDMINE; }
        }
        else
        {    BOBOT_AI_endOfCurrentAction(bobotAI);
            BOBOT_COMMON_TakeBestWeapon(bobot,bobotAI->myteam,ucmd);
            return;
        }
        VectorSubtract (nodes[bobotAI->goal_node].origin, bobot->client->ps.origin, dir);
        vectoangles (dir, angles);
        if( random() < 0.03)                                                                    // Pour éviter les kokots...
        { ucmd->buttons = BUTTON_ATTACK; }
        angles[PITCH] = 28;                                                                        // Ca évite de balancer la mine comme un bargeot, à 15 métres de soi (< à BOBOT_VIEW_MAX_ACCEL).
        AnglesSubtract (angles , bobot->s.angles , angles);
        BOBOT_MOVEMENT_ChangeBotAngle(angles,bobot);
        for (dyn = G_FindLandmine( NULL );dyn;dyn = G_FindLandmine(dyn))
        {    if (dyn->s.teamNum < 4)                                                                // Si la mine est déjà armée on passe
            { continue; }
            if (dyn->parent == bobot)                                                            // Le bobot arme sa mine en priorité
            {    BOBOT_AI_inhibitAction(&bobotAI->actions[bobotAI->currentAction.type]);            // On remplace la pose de mine par son amorçage parmi les actions
                BOBOT_AI_proposeAction(bobotAI,ARM_MINE,INVALID,dyn,dyn->r.currentOrigin,
                                       BOBOT_PLANT_DYNAMITE_PRIORITY);
            }
            VectorSubtract (nodes[bobot->current_node].origin, dyn->r.currentOrigin, dir);
            if(VectorLength(dir) < nodes[bobot->current_node].radius)                            // Si la mine est dans le rayon du node...
            {    BOBOT_AI_inhibitAction(&bobotAI->actions[bobotAI->currentAction.type]);            // On remplace la pose de mine par son amorçage parmi les actions
                BOBOT_AI_proposeAction(bobotAI,ARM_MINE,INVALID,dyn,dyn->r.currentOrigin,
                                       BOBOT_PLANT_DYNAMITE_PRIORITY);
            }
        }
    }
}

/*-------------------------------------------------------------------------------------
Pav : l'ingé arme sa mine
-------------------------------------------------------------------------------------*/
void BOBOT_ENGINEER_ArmMine(gentity_t *bobot, usercmd_t *ucmd, qboolean barme)
{     vec3_t         dir,angles;
    trace_t        tr;
    gentity_t    *traceEnt;
    vec3_t        end,forward,right,up,muzzleTrace;
    Sbobot        *bobotAI = &bobots[bobot->s.clientNum];
    gentity_t    *goalentity = bobotAI->currentAction.ent;
    qboolean    actionAuthorizedByArms;
   
    bobotAI->DansTank = qfalse;
    if(bobot->client->sess.playerType == PC_ENGINEER)
    {    if(!(nodes[bobot->current_node].type & NODE_MINE))
        {    BOBOT_AI_endOfCurrentAction(bobotAI);
            BOBOT_COMMON_TakeBestWeapon(bobot,bobotAI->myteam,ucmd);
            return;
        }
        actionAuthorizedByArms = BOBOT_AI_proposeActionToArms(bobotAI,BOBOT_OBEY_TO_ACTION,NULL);
        if(actionAuthorizedByArms)           
        {    if(bobot->client->ps.weapon != WP_PLIERS)
            { ucmd->weapon = WP_PLIERS; }
        }
        if(goalentity == NULL || !goalentity->inuse || goalentity->s.weapon != WP_LANDMINE)
        {    BOBOT_AI_endOfCurrentAction(bobotAI);
            BOBOT_COMMON_TakeBestWeapon(bobot,bobotAI->myteam,ucmd);
            return;
        }
        AngleVectors (bobot->client->ps.viewangles, forward, right, up);
        VectorCopy( bobot->client->ps.origin, muzzleTrace );
        muzzleTrace[2] += bobot->client->ps.viewheight;
        VectorMA (muzzleTrace, 64, forward, end);
        trap_EngineerTrace( &tr, muzzleTrace, NULL,NULL,end,bobot->s.number,MASK_SHOT );
        traceEnt = &g_entities[ tr.entityNum ];
        VectorSubtract (goalentity->r.currentOrigin, bobot->client->ps.origin, dir);    // on vise la mine
        dir[2] -= bobot->client->ps.viewheight;                                            // la mine est 1 peu + haute
        if (traceEnt == goalentity)
        { if(actionAuthorizedByArms)
            { ucmd->buttons = BUTTON_ATTACK; }
        }
        else if (VectorLength(dir) > 64)
        { BOBOT_BasicMove(bobot,ucmd); }

        /*    le déroulement de l'action dépend de la présence ou non d'un ennemi...
            s'il y en a un, les bras du bot donneront priorité au tir. */

        if(BOBOT_AI_proposeActionToArms(bobotAI,BOBOT_OBEY_TO_ACTION,NULL))
        {    vectoangles (dir, angles);
            AnglesSubtract (angles , bobot->s.angles , angles);
            BOBOT_MOVEMENT_ChangeBotAngle(angles,bobot);
            ucmd->upmove = -48;                                                            // Pav: Le bot se met à genoux
        }
        if (goalentity->s.teamNum < 4 && barme)                                            // la mine est armée
        {    if(random() < 0.5)
            {    G_Voice( bobot, NULL, SAY_TEAM, "FTDeployLandmines", qtrue); }            // voice axis LandMine
            BOBOT_AI_endOfCurrentAction(bobotAI);                                        // action terminée
            BOBOT_COMMON_TakeBestWeapon(bobot,bobotAI->myteam,ucmd);
        }
        else if (goalentity->health > 248 && !barme)
        {    G_Voice( bobot, NULL, SAY_TEAM, "minescleared", qtrue);                        // la mine est defusée
            BOBOT_AI_endOfCurrentAction(bobotAI);                                        // action terminée
            BOBOT_COMMON_TakeBestWeapon(bobot,bobotAI->myteam,ucmd);
        }
    }
}

/*-------------------------------------------------------------------------------------
Joc : l'ingé arme sa dynamite
-------------------------------------------------------------------------------------*/
void BOBOT_ENGINEER_ArmDynamite(gentity_t *bobot, usercmd_t *ucmd, qboolean barme)
{     vec3_t         dir,angles;
    trace_t        tr;
    gentity_t    *traceEnt;
    vec3_t        end,forward,right,up,muzzleTrace;
    Sbobot        *bobotAI = &bobots[bobot->s.clientNum];
    gentity_t    *goalentity = bobotAI->currentAction.ent;
    qboolean    actionAuthorizedByArms;
    int            NodeEnCourt=bobot->current_node;
   
    bobotAI->DansTank = qfalse;
    // PAV : Le covert explose un objectif avec son détonateur.
    if(bobot->client->sess.playerType == PC_COVERTOPS)
    {    actionAuthorizedByArms = BOBOT_AI_proposeActionToArms(bobotAI,BOBOT_OBEY_TO_ACTION,NULL);
        if(actionAuthorizedByArms)
        {    if(bobot->client->ps.weapon != WP_SATCHEL_DET)
            { ucmd->weapon = WP_SATCHEL_DET; }
            ucmd->forwardmove+=200;                                                        // On ne reste pas à coté.
            if(level.time > bobotAI->TimeSatchel)                                        // on appuie après 3 secondes.
            { ucmd->buttons = (rand() % 2) * BUTTON_ATTACK; }
            if(!(nodes[NodeEnCourt].type & NODE_CHARGE))
            {    G_Voice( bobot, NULL, SAY_ALL, "cheer", qtrue);
                BOBOT_AI_endOfCurrentAction(bobotAI);
                BOBOT_COMMON_TakeBestWeapon(bobot,bobotAI->myteam,ucmd);
            }
        }
    }

    //-------------------------------------------------- copie de weapon_engineer
    if(bobot->client->sess.playerType == PC_ENGINEER)
    {    actionAuthorizedByArms = BOBOT_AI_proposeActionToArms(bobotAI,BOBOT_OBEY_TO_ACTION,NULL);
        if(actionAuthorizedByArms)           
        {    if(bobot->client->ps.weapon != WP_PLIERS)                                    //on prend la pince
            { ucmd->weapon = WP_PLIERS; }
        }
        if(goalentity == NULL || !goalentity->inuse ||
           goalentity->s.eType != ET_MISSILE || goalentity->s.weapon != WP_DYNAMITE)
        {    BOBOT_AI_endOfCurrentAction(bobotAI);                                        // 3emeType. action annulée
            BOBOT_COMMON_TakeBestWeapon(bobot,bobotAI->myteam,ucmd);
            return;
        }
        AngleVectors (bobot->client->ps.viewangles, forward, right, up);
        VectorCopy( bobot->client->ps.origin, muzzleTrace );
        muzzleTrace[2] += bobot->client->ps.viewheight;
        VectorMA (muzzleTrace, 64, forward, end);
        trap_EngineerTrace( &tr, muzzleTrace,NULL,NULL,end,bobot->s.number,MASK_SHOT );
        traceEnt = &g_entities[ tr.entityNum ];
        VectorSubtract (goalentity->r.currentOrigin, bobot->client->ps.origin, dir);    // on vise la dynamite
        dir[2] -= bobot->client->ps.viewheight;                                            // la dyna est 1 peu + haute
        if (traceEnt == goalentity)
        { if(actionAuthorizedByArms)
            { ucmd->buttons = BUTTON_ATTACK; }
        }
        else if (VectorLength(dir) > 64)
        { BOBOT_BasicMove(bobot,ucmd); }

        /*    Le déroulement de l'action dépend de la présence ou non d'un ennemi...
            s'il y en a un, les bras du bot donneront priorité au tir. */

        if(BOBOT_AI_proposeActionToArms(bobotAI,BOBOT_OBEY_TO_ACTION,NULL))
        {    vectoangles (dir, angles);
            AnglesSubtract (angles , bobot->s.angles , angles);
            BOBOT_MOVEMENT_ChangeBotAngle(angles,bobot);
            ucmd->upmove = -48;                                                            // Pav: Le bot se met à genoux 2 fois sur 3
        }
        if (goalentity->s.teamNum < 4 && barme)                                            // la dyna est armée
        {    MessInge(2,bobot->client->sess.sessionTeam);
            G_Say(bobot, NULL, SAY_ALL, va("%s",MessaDire));
            G_Voice( bobot, NULL, SAY_ALL, "cheer", qtrue);
            BOBOT_AI_endOfCurrentAction(bobotAI);                                        // 3emeType. action terminée
            BOBOT_COMMON_TakeBestWeapon(bobot,bobotAI->myteam,ucmd);
        }
        else if (goalentity->health > 248 && !barme)                                    // la dyna est defusée
        {    MessInge(3,bobot->client->sess.sessionTeam);
            G_Say(bobot, NULL, SAY_ALL, va("%s",MessaDire));
            G_Voice( bobot, NULL, SAY_ALL, "cheer", qtrue);
            BOBOT_AI_endOfCurrentAction(bobotAI);                                        // 3emeType. action terminée
            BOBOT_COMMON_TakeBestWeapon(bobot,bobotAI->myteam,ucmd);
        }
    }
}

/*-------------------------------------------------------------------------------------
Joc : cherche si il y a une dynamite prés du current_node
si oui il faut la defuser copie partielle de weapon_engineer
-------------------------------------------------------------------------------------*/
void BOBOT_ENGINEER_FindDynamite(gentity_t *bobot)
{    gentity_t    *dyn,*hit = NULL;
    vec3_t        diff;
    float        dist;
    float        mini;
    Sbobot        *bobotAI = &bobots[bobot->s.clientNum];

    mini = NO_CONNECTION;
    for (dyn = G_FindDynamite( NULL );dyn;dyn = G_FindDynamite(dyn))
    {    VectorSubtract(nodes[bobot->current_node].origin,dyn->r.currentOrigin,diff);
        dist = VectorLength(diff);
        if (dist < mini)
        {    mini = dist;
            hit = dyn;
        }
    }
    if (mini > 2*nodes[bobot->current_node].radius)
    { return; }
    /*    il y a une dynamite pres d'un objectif, defusons là ! */
    BOBOT_AI_proposeAction(bobotAI,DEFUSE_DYNAMITE,INVALID,hit,hit->r.currentOrigin,BOBOT_DEFUSE_DYNAMITE_PRIORITY);
}

/*-------------------------------------------------------------------------------------
Pav : Vérifie si il y a une dynamite déjà armée par un autre ingénieur
de sa team au node sur lequel il veut en poser une, si oui il n'en pose pas.
-------------------------------------------------------------------------------------*/
int BOBOT_ENGINEER_DynamitePlantedByTeam(gentity_t *bobot,int nodeDyna)
{    gentity_t    *dyn,*hit = NULL;
    vec3_t        diff;
    float        dist;
    int            r=0;

    if (nodeDyna==INVALID)
    { return INVALID;}
    if(!(nodes[nodeDyna].type & NODE_DYNAMITE))
    { return INVALID;}
    for (dyn = G_FindDynamite( NULL );dyn;dyn = G_FindDynamite(dyn))
    {    VectorSubtract(nodes[nodeDyna].origin,dyn->r.currentOrigin,diff);
        dist = VectorLength(diff);
        if (dist <= (2*nodes[nodeDyna].radius))
        {    hit=dyn;
            if(hit->s.teamNum < 4)
            { r=nodeDyna; }
        }
    }
    return r;
}

/*--------------------------------------------------------------------------------------------
Pav : cherche si il y a une mine près du node ou il doit en poser une, si oui il n'en pose pas
----------------------------------------------------------------------------------------------*/
int BOBOT_ENGINEER_FindMine(gentity_t *bobot,int nodeMine)
{    gentity_t    *dyn;
    vec3_t        diff;
    float        dist;
    int            r=0;

    if (nodeMine==INVALID)
    { return INVALID;}
    if(!(nodes[nodeMine].type & NODE_MINE))
    { return INVALID;}
    for (dyn = G_FindLandmine( NULL );dyn;dyn = G_FindLandmine(dyn))
    {    VectorSubtract(nodes[nodeMine].origin,dyn->r.currentOrigin,diff);
        dist = VectorLength(diff);
        if (dist <= nodes[nodeMine].radius)
        { r=nodeMine; }
    }
    return r;
}

/*-------------------------------------------------------------------------------------
Joc : le bot atteint le goal node, mais que va-t-il faire?
-------------------------------------------------------------------------------------*/
void BOBOT_ENGINEER_Choix_ActionGoal(gentity_t *bobot)
{    Sbobot    *bobotAI;    
    int        inmyteam,otherteam;
   
    bobotAI = &bobots[bobot->s.clientNum];
    inmyteam  = (bobotAI->myteam == TEAM_ALLIES ? NODE_TEAM_ALLIES : NODE_TEAM_AXIS);    //quelle team, quel node ?
    otherteam = (bobotAI->myteam == TEAM_ALLIES ? NODE_TEAM_AXIS : NODE_TEAM_ALLIES);

    /*    si on est ingé et qu'on peut construire ou dynamiter, c'est ici qu'il faut le faire */

    if(bobot->client->sess.playerType == PC_ENGINEER)
    {    if ((nodes[bobot->current_node].type & NODE_CONSTRUCTION) && (nodes[bobot->current_node].type & inmyteam))
        { BOBOT_AI_proposeAction(bobotAI,CONSTRUCT,bobot->current_node,NULL,NULL,BOBOT_CONSTRUCT_PRIORITY); }
        if ((nodes[bobot->current_node].type & NODE_DYNAMITE) && (nodes[bobot->current_node].type & otherteam))
        { BOBOT_AI_proposeAction(bobotAI,PLANT_DYNAMITE,bobot->current_node,NULL,NULL,BOBOT_PLANT_DYNAMITE_PRIORITY); }
        if (nodes[bobot->current_node].type & NODE_MINE)
        {    if((nodes[bobot->current_node].type & inmyteam ) || (nodes[bobot->current_node].type & NODE_ALLTEAM))
            { BOBOT_AI_proposeAction(bobotAI,PLANT_MINE,bobot->current_node,NULL,NULL,BOBOT_PLANT_MINE_PRIORITY); }
        }
        if ((nodes[bobot->current_node].type & NODE_DYNAMITE) && (nodes[bobot->current_node].type & inmyteam))
        { BOBOT_ENGINEER_FindDynamite(bobot); }                                            //on defuse la dyna
    }
    if(bobot->client->sess.playerType == PC_COVERTOPS)
    {    //si on est covert et qu'on peut dynamiter, c'est ici qu'il faut le faire
        if (nodes[bobot->current_node].type & NODE_CHARGE && nodes[bobot->current_node].type & otherteam)
        { BOBOT_AI_proposeAction(bobotAI,PLANT_DYNAMITE,bobot->current_node,NULL,NULL,BOBOT_PLANT_DYNAMITE_PRIORITY); }
    }
}

Créer un site gratuit avec e-monsite - Signaler un contenu illicite sur ce site