Bobot_medic.c

/******************************************************************
Fichier créé par 3emeType le 22/04/04
Rassemble toutes les actions spécifiques au medic
*******************************************************************/
#include "../game/g_local.h"
#include "bobot.h"

void BOBOT_MEDIC_GoToTeammate(gentity_t *bobot,gentity_t *goalentity,int mode)
{    vec3_t        dir;
    Sbobot        *bobotAI = &bobots[bobot->s.clientNum];
    int r;

    if(mode<1)
    {    return; }
    if( !bobot || !bobot->client || !bobot->inuse)
    {    return; }
    if( bobot->client->sess.playerType == PC_ENGINEER)
    {    return; }
    if( !goalentity || !goalentity->client || !goalentity->inuse)
    {    return; }
    if(!OnSameTeam(goalentity,bobot))
    {    return; }
    /* Pas s'il est dans l'eau */
    if(goalentity->waterlevel>2)
    {    return;    }
    if ((goalentity->client->ps.pm_flags & PMF_LIMBO) || (goalentity->client->ps.pm_type & PM_DEAD))
    {    return; }

    if(mode==3)    // need Backup
    {    VectorSubtract (goalentity->r.currentOrigin, bobot->client->ps.origin, dir);
        if (VectorLength(dir) > 2000)
        {    return;    }
        r=RandInt(0,2);
        if(r>0)
        {    G_Say(bobot, NULL, SAY_TEAM, va("Affirmative %s I go to back you!",goalentity->client->pers.netname));
            G_Voice( bobot, NULL, SAY_TEAM, "Affirmative", qtrue);
            bobotAI->TimeFollow=level.time+90000;
            BOBOT_AI_proposeAction(bobotAI,BACKUP,INVALID,goalentity,goalentity->client->ps.origin,60);
        }
    }
    if(mode==2) //need Ammo
    {    if( bobot->client->sess.playerType != PC_FIELDOPS)
        {return;}
        VectorSubtract (goalentity->r.currentOrigin, bobot->client->ps.origin, dir);
        if (VectorLength(dir) > 2000)
        {    G_Say(bobot, NULL, SAY_TEAM, va("Sorry %s I'm too far!",goalentity->client->pers.netname));
            return;
        }
        G_Say(bobot, NULL, SAY_TEAM, "I'am a Fieldops!");
        G_Voice( bobot, NULL, SAY_TEAM, "IamFieldops", qtrue);
        bobotAI->TimeFollow=level.time+90000;
        BOBOT_AI_proposeAction(bobotAI,FOLLOW_TEAMMATE,INVALID,goalentity,goalentity->client->ps.origin,50);
    }
    else if(mode==1) //need a Medic
    {    if(bobot->client->sess.playerType != PC_MEDIC)
        {return;}
        if(goalentity->health >= 100)
        {    return;    }
        VectorSubtract (goalentity->r.currentOrigin, bobot->client->ps.origin, dir);
        if (VectorLength(dir) > 2000)
        {    G_Say(bobot, NULL, SAY_TEAM, va("Sorry %s I'm too far!",goalentity->client->pers.netname));
            return;
        }
        G_Say(bobot, NULL, SAY_TEAM, "I'am a Medic!");
        G_Voice( bobot, NULL, SAY_TEAM, "IamMedic", qtrue);
        bobotAI->TimeFollow=level.time+90000;
        BOBOT_AI_proposeAction(bobotAI,FOLLOW_TEAMMATE,INVALID,goalentity,goalentity->client->ps.origin,50);
    }
    else if(mode==8) // follow me
    {    if(bobot->client->sess.playerType != PC_SOLDIER && bobot->client->sess.playerType != PC_COVERTOPS)
        {return;}
        VectorSubtract (goalentity->r.currentOrigin, bobot->client->ps.origin, dir);
        if (VectorLength(dir) >= 1500)
        {    return;    }
        r=RandInt(0,1);
        if(r==0)
        {    G_Say(bobot, NULL, SAY_TEAM, va("Negative to follow you %s!",goalentity->client->pers.netname));
            G_Voice( bobot, NULL, SAY_TEAM, "Negative", qtrue);
            return;
        }
        else
        {    G_Say(bobot, NULL, SAY_TEAM, va("Ok %s I'm your shadow now!",goalentity->client->pers.netname));
            G_Voice( bobot, NULL, SAY_TEAM, "Affirmative", qtrue);
            BOBOT_AI_proposeAction(bobotAI,FOLLOW_TEAMMATE,INVALID,goalentity,goalentity->client->ps.origin,70);
        }
    }
}

/*******************************************************************
Joc: le medic soigne un coequipier
//goalentity peut être lui même ou un équipier.
*******************************************************************/
void BOBOT_MEDIC_GiveHealth(gentity_t *bobot, usercmd_t *ucmd)
{    Sbobot        *bobotAI = &bobots[bobot->s.clientNum];
    vec3_t        dir,angles;
    vec_t        dist;
    gentity_t    *goalentity = bobotAI->currentAction.ent;
    qboolean    actionAuthorizedByArms;

    if((goalentity == NULL) || (goalentity->client == NULL) || (!goalentity->inuse))
    {    BOBOT_AI_endOfCurrentAction(bobotAI);                        // 3emeType : on stoppe l'action
        BOBOT_COMMON_TakeBestWeapon(bobot,bobotAI->myteam,ucmd);
        return;
    }

    /* Pas s'il est dans l'eau */
    if(goalentity->waterlevel>1)
    {    BOBOT_AI_endOfCurrentAction(bobotAI);                        // on stoppe l'action
        BOBOT_COMMON_TakeBestWeapon(bobot,bobotAI->myteam,ucmd);
        return;
    }

    if(goalentity->health >= 100)                                    // On ne donne plus de medipack si il est à fond en vie
    {    BOBOT_AI_endOfCurrentAction(bobotAI);                        // on stoppe l'action
        BOBOT_COMMON_TakeBestWeapon(bobot,bobotAI->myteam,ucmd);
        return;
    }
    VectorSubtract (goalentity->r.currentOrigin, bobot->client->ps.origin, dir);

    /*    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.*/
    actionAuthorizedByArms = BOBOT_AI_proposeActionToArms(bobotAI,BOBOT_OBEY_TO_ACTION,NULL);
   
    /*    On vise le gars à soigner, il est un peu plus haut */
    dir[2] -= bobot->client->ps.viewheight;
    if(actionAuthorizedByArms)
    {    vectoangles (dir, angles);
        AnglesSubtract (angles , bobot->s.angles , angles);
        BOBOT_MOVEMENT_ChangeBotAngle(angles,bobot);
    }
    dist = VectorLengthSquared(dir);
    if (dist < BOBOT_DIST_CARRY_PACK)
    { if(actionAuthorizedByArms)                // Si proche et si ses bras acceptent
        { ucmd->weapon = WP_MEDKIT; }            // Prend le pack en main juste avant de le donner
    }
    if ((dist < BOBOT_DIST_GIVE_PACK) && (bobot->client->ps.weapon == WP_MEDKIT))
    {    if(actionAuthorizedByArms)                // Si ses bras acceptent
        {    if(random() < 0.5)                    // Il doit appuyer et relacher lorsqu'il est revivé pour qu'il se soigne après
            { ucmd->buttons = BUTTON_ATTACK; }    // Donne le pack
        }
    }
    else if(goalentity != bobot)                // Si ce n'est pas lui-même qu'il soigne
    {    /* Pas à un autre Medic qui peut s'en donner lui même, il n'a qu'à le faire lui même */
        if(goalentity->client->sess.playerType == PC_MEDIC)
        {    BOBOT_AI_endOfCurrentAction(bobotAI);
            BOBOT_COMMON_TakeBestWeapon(bobot,bobotAI->myteam,ucmd);
            return;
        }
        BOBOT_Move(bobot,ucmd);                    // Il va vers son équipier
    }
}

/*******************************************************************
Joc: le medic revive un coequipier
*******************************************************************/
void BOBOT_MEDIC_Revive(gentity_t *bobot, usercmd_t *ucmd)
{    Sbobot        *bobotAI = &bobots[bobot->s.clientNum];    
    vec3_t        dir,angles;
    vec_t         dist;
    gentity_t    *goalentity = bobotAI->currentAction.ent;
    qboolean    actionAuthorizedByArms;
    vec3_t        end;
    trace_t        tr;
    gentity_t    *traceEnt;
    vec3_t        forward, right, up;
    vec3_t        muzzleTrace;

    if(goalentity == NULL)
    {    BOBOT_AI_endOfCurrentAction(bobotAI);                            // 3emeType : on stoppe l'action
        BOBOT_COMMON_TakeBestWeapon(bobot,bobotAI->myteam,ucmd);        // was : bobotAI->state = BOT_STATE_MOVE;
        return;
    }
    if(goalentity->client == NULL || !goalentity->inuse)
    {    BOBOT_AI_endOfCurrentAction(bobotAI);
        BOBOT_COMMON_TakeBestWeapon(bobot,bobotAI->myteam,ucmd);
        return;
    }

    /* Zombi */
    if((g_dedicated.integer>0) && (goalentity->client->ps.ping>=900))
    {    BOBOT_AI_endOfCurrentAction(bobotAI);
        BOBOT_COMMON_TakeBestWeapon(bobot,bobotAI->myteam,ucmd);
        return;
    }

    /* Pas s'il est dans l'eau */
    if(goalentity->waterlevel>1)        //0=pas dans l'eau 1=eau aux genoux 2=eau à la poitrine 3=sous l'eau
    {    BOBOT_AI_endOfCurrentAction(bobotAI);
        BOBOT_COMMON_TakeBestWeapon(bobot,bobotAI->myteam,ucmd);
        return;
    }

    if(goalentity->client->ps.pm_type != PM_DEAD)
    {    BOBOT_AI_endOfCurrentAction(bobotAI);
        BOBOT_COMMON_TakeBestWeapon(bobot,bobotAI->myteam,ucmd);
        return;
    }

    /*    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.*/
    actionAuthorizedByArms = BOBOT_AI_proposeActionToArms(bobotAI,BOBOT_OBEY_TO_ACTION,NULL);
    AngleVectors (bobot->client->ps.viewangles, forward, right, up);
    CalcMuzzlePointForActivate( bobot, forward, right, up, muzzleTrace );
    VectorMA (muzzleTrace, 48, forward, end);
    trap_Trace (&tr, muzzleTrace, NULL, NULL, end, bobot->s.number, MASK_SHOT);
    if (tr.startsolid)
    {    VectorMA (muzzleTrace, 8, forward, end);
        trap_Trace(&tr, muzzleTrace, NULL, NULL, end, bobot->s.number, MASK_SHOT);
    }
    if (tr.fraction < 1.0)
    {    traceEnt = &g_entities[ tr.entityNum ];
        if (traceEnt == goalentity)
        {    ucmd->buttons = BUTTON_ATTACK;                                            // On peut le ressuciter
            if (goalentity->r.svFlags & SVF_BOT)
            {    G_Voice( goalentity, NULL, SAY_TEAM, "thanks", qtrue); }            // Et on dit merci.
            return;
        }
    }
    VectorSubtract (goalentity->r.currentOrigin, bobot->client->ps.origin, dir);
    dist = VectorLengthSquared(dir);
    if(dist < BOBOT_DIST_CARRY_PACK)
    {    if(actionAuthorizedByArms)                                    // Si proche et si ses bras acceptent
        { ucmd->weapon = WP_MEDIC_SYRINGE; }                        // Prend la seringue
    }
    else
    { BOBOT_COMMON_TakeBestWeapon(bobot,bobotAI->myteam,ucmd); }    // hop on reprend la best weapon
    if (dist < BOBOT_MEDIC_DIST_REVIVE)                                // Le bot va vers le gars
        BOBOT_SpecialMove(bobot,ucmd);                                // on va tout droit s'il est près
    else
        BOBOT_Move(bobot,ucmd);                                        // On utilise le réseau de neurones pour éviter les blocages
   
    /*    Si ses bras acceptent on vise le gars à ressuciter */
    if(actionAuthorizedByArms)
    {    dir[2] -= bobot->client->ps.viewheight;                        // le mec est un peu plus haut
        vectoangles (dir, angles);
        AnglesSubtract (angles , bobot->s.angles , angles);
        BOBOT_MOVEMENT_ChangeBotAngle(angles,bobot);
    }
    else
    {    BOBOT_AI_endOfCurrentAction(bobotAI);
        BOBOT_COMMON_TakeBestWeapon(bobot,bobotAI->myteam,ucmd);
        return;
    }
}

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