Bobot_spawn.c

#include "../game/g_local.h"
// 3emeType
#include "bobot.h"
#include "bobot_utils.h"

Sbobot            bobots[MAX_CLIENTS];

/*===========================================================================
 Routine      : BOBOT_SPAWN_PutClientInServer
 Description  : Just a modified version of id's code
 Joc j'ai nettoyé tout comme un gros bourrin
 Si ya un bug il faut voir dans /fusion/fusionspawn.c
 (j'en ai ptet retiré un peu trop ;)
===========================================================================*/

void BOBOT_SPAWN_PutClientInServer (gentity_t *bobot, qboolean respawn, weapon_t weapon, weapon_t weapon2)
{   gclient_t             *client;
    clientPersistant_t    saved;
    Sbobot                *bobotAI;

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

    /*    clear everything but the persistant data */
    saved = client->pers;
    memset (client, 0, sizeof(*client));
    client->pers = saved;
    if (bobotAI->classe >= 0)
    {    client->ps.stats[STAT_PLAYER_CLASS] = bobotAI->classe;
        client->sess.latchPlayerType = bobotAI->classe;
        client->sess.playerType = bobotAI->classe;
    }
    else
    {    client->ps.stats[STAT_PLAYER_CLASS] = PC_ENGINEER;
        client->sess.latchPlayerType = PC_ENGINEER;
        client->sess.playerType = PC_ENGINEER;
    }
    // pav
    client->sess.playerWeapon        = weapon;        //arme principale passée en paramétre
    client->sess.latchPlayerWeapon  = weapon;        //arme principale passée en paramétre
    client->sess.playerWeapon2         = weapon2;        //arme secondaire passée en paramétre
    client->sess.latchPlayerWeapon2 = weapon2;        //arme secondaire passée en paramétre
    client->sess.referee=3;                            // pour éviter qu'il soit muté ou kické
    /*    clear entity values */
    //fretnbobot->groundentity = NULL;
    //fretnbobot->client = &game.clients[index];
    bobot->takedamage = qtrue;
    bobotAI->lastMedicVoiceChat = level.time;
    //bobot->movetype = MOVETYPE_WALK;
    //bobot->viewheight = 24;
    bobot->classname = "bot";
    //bobot->mass = 200;
    bobot->solid = SOLID_BBOX;
    //bobot->deadflag = DEAD_NO;
    //bobot->air_finished = level.time + 12;
    bobot->r.contents = CONTENTS_SOLID;
    bobot->clipmask = MASK_PLAYERSOLID;
    //bobot->model = "players/male/tris.md2";
    bobot->pain = FUSION_AI_BotPain;
       bobot->die = player_die;
       bobot->waterlevel = 0;
    bobot->watertype = 0;
    bobot->flags &= ~FL_NO_KNOCKBACK;
    //bobot->svFlags &= ~SVF_CORPSE;
    bobotAI->is_jumping = qfalse;
    //bobot->enemy = NULL;

    bobotAI->state = BOT_STATE_POSITION;
    ClientUserinfoChanged( bobot->s.number );
}
extern qboolean BOBOT_heavy_weapon(int weapon);
int BOBOT_SPAWN_SpawnBot (char *team, char *name, int skill, int classe, weapon_t weapon, weapon_t weapon2)
{    gentity_t    *bobot;
    Sbobot        *bobotAI;
    int            clientNum,i;
    char        userinfo[MAX_INFO_STRING];

    userinfo[0] = '\0';
    clientNum = trap_BotAllocateClient(0);
    if ( clientNum == -1 )
    {    G_Printf( S_COLOR_RED "Impossible d'ajouter un bot, tous les slots sont utilisés.\n" );
        return -1;
    }

    /*    We found an empty client slot, go create a nice lil' backward running bot */
    bobot     = &g_entities[clientNum];
    bobotAI    = &bobots[clientNum];
    if (!bobot)
    {      G_Printf("FUSION BOT : Problème de création du bot, bot non créé !\n");
           return -1;
    }
    Info_SetValueForKey( userinfo, "name", name );        // This be taking care of the bot's name
    Info_SetValueForKey( userinfo, "ip", "localhost" );    // Bots behave like local clients, they are in fact !
    Info_SetValueForKey( userinfo, "team", team );
    Info_SetValueForKey( userinfo, "rate", "25000" );
    Info_SetValueForKey( userinfo, "snaps", "20" );

    /*    joc : le skill change apres un map restart ! */
    Info_SetValueForKey( userinfo, "skill", va("%i", skill) );
    //Info_SetValueForKey( userinfo, "model", "multi" );
    //Info_SetValueForKey( userinfo, "head", "default" );
    trap_SetUserinfo( clientNum, userinfo );
    bobot->inuse                            = qtrue;
    bobot->is_bot                            = qtrue;
    bobot->scriptStatus.scriptEventIndex    = -1;
    bobot->s.number                            = bobot - g_entities;
    bobot->r.ownerNum                        = ENTITYNUM_NONE;
    bobot->headshotDamageScale                = 1.0;
    bobotAI->skill                            = skill;
    bobot->r.svFlags                        |= SVF_BOT;
    bobot->client->pers.localClient            = qtrue;
    bobotAI->classe                            = classe;
    bobot->s.clientNum                        = clientNum;

    /*    Now 'connect' the bot */
    ClientConnect( clientNum, qtrue, qfalse );
    BOBOT_SPAWN_PutClientInServer (bobot, qfalse, weapon, weapon2);

    /*    Not entirely sure about this one */
    trap_SetUserinfo( clientNum, userinfo );

    /*    Set the nodes to invalid */
    bobot->current_node = INVALID;
    bobotAI->next_node    = INVALID;
    bobotAI->goal_node    = INVALID;
    bobotAI->last_node    = INVALID;
    SetTeam( bobot, team, qtrue, -1, -1, qfalse);
    if( random() < 0.5)
    {    //    Pav: Séries de messages de salut.
        i=RandInt(0,5);
        if (Q_stricmp(team,"allies")==0)
        {    switch(i)
            {    case 0 :
                    G_Say(bobot, NULL, SAY_ALL, "Hi!");
                    break;
                case 1 :
                    G_Say(bobot, NULL, SAY_ALL, "Salut!");
                    break;
                case 2 :
                    G_Say(bobot, NULL, SAY_ALL, "Im here now.");
                    break;
                case 3 :
                    G_Say(bobot, NULL, SAY_ALL, "Salut les gars!");
                    break;
                case 4 :
                    G_Say(bobot, NULL, SAY_ALL, "Hi evrybody!");
                    break;
                case 5 :
                    G_Say(bobot, NULL, SAY_ALL, "Me vl'a les gars...");
                    break;
                default:
                    G_Say(bobot, NULL, SAY_ALL, "Hi!");
                    break;
            }
        }
        else if (Q_stricmp(team,"axis")==0)
        {    switch(i)
            {    case 0 :
                    G_Say(bobot, NULL, SAY_ALL, "Heil die Jungen!");
                    break;
                case 1 :
                    G_Say(bobot, NULL, SAY_ALL, "Heil !");
                    break;
                case 2 :
                    G_Say(bobot, NULL, SAY_ALL, "ich komme an...");
                    break;
                case 3 :
                    G_Say(bobot, NULL, SAY_ALL, "Salut les gars!");
                    break;
                case 4 :
                    G_Say(bobot, NULL, SAY_ALL, "Hi!");
                    break;
                case 5 :
                    G_Say(bobot, NULL, SAY_ALL, "Guten Tag!");
                    break;
                default:
                    G_Say(bobot, NULL, SAY_ALL, "Guten Tag!");
                    break;
            }
        }
        else
        { G_Say(bobot, NULL, SAY_ALL, "Hi!"); }
        G_Voice( bobot, NULL, SAY_ALL, "Hi", qtrue);
    }
    BOBOT_SPAWN_initBot(bobotAI);
    bobot->nextthink = level.time + FRAMETIME;
    bobot->think      = BOBOT_AI_Think;
    return(clientNum);
}

void BOBOT_SPAWN_RemoveBot (int clientNum)
{    gclient_t    *cl;
    char        netname[36];

    cl = level.clients + clientNum;
    strcpy(netname, cl->pers.netname);
    Q_CleanStr(netname);
    trap_SendConsoleCommand( EXEC_INSERT, va("kick %s\n", netname) );
}

/*===============
BobotAISetupClient
===============*/
qboolean BobotAISetupClient( int clientNum)
{    char        userinfo[MAX_INFO_STRING];
    //c des essai pour faire marcher le map_restart
    gentity_t    *bobot;
    Sbobot        *bobotAI;
    //int            weapon,i;

    trap_GetUserinfo( clientNum, userinfo, sizeof( userinfo ) );

    /*    We found an empty client slot, go create a nice lil' backward running bot */
    bobot = &g_entities[clientNum];
    bobotAI    = &bobots[clientNum];

    /*    Joc on récupere le niveau du bobot */
    bobotAI->skill = atoi(Info_ValueForKey(userinfo,"skill"));
    //bobot->inuse = qtrue;
   
    /*    reset all the nodes to invalid */
    bobot->current_node = INVALID;
    bobotAI->next_node  = INVALID;
    bobotAI->goal_node  = INVALID;
    bobotAI->last_node  = INVALID;
    bobot->s.clientNum  = clientNum;
    bobotAI->goalentity = NULL;
    bobotAI->state         = BOT_STATE_POSITION;
    //G_Printf("BOBOT_CONTROL_AddBot bobot_spawn");
    BOBOT_CONTROL_AddBot(clientNum);    //chargement du réseau de neurones

    /*    Pav: on met des pings bidons entre 50 et 180 pour faire croire que se sont de vrais joueurs connectés. */
    bobot->client->ps.ping  = RandInt(50,180);

    /*if(bobotAI->skill>=4)
        weapon=BG_AkimboForSideArm( bobot->client->sess.playerWeapon2);
    if(weapon>0)
        bobot->client->sess.playerWeapon2=weapon;*/

    //PAV skill bot
    /*for(i=0; i<SK_NUM_SKILLS; i++)
    {    bobot->client->sess.skill[i]=bobotAI->skill; }

    switch(bobotAI->classe)
    {    case PC_SOLDIER:
            bobot->client->sess.skill[1]        = 0;
            bobot->client->sess.skill[2]        = 0;
            bobot->client->sess.skill[3]        = 0;
            if(!BOBOT_heavy_weapon(weapon))
                bobot->client->sess.skill[5]    = 0;
            bobot->client->sess.skill[6]        = 0;
            break;
        case PC_MEDIC:
            bobot->client->sess.skill[1]        = 0;
            bobot->client->sess.skill[5]        = 0;
            bobot->client->sess.skill[3]        = 0;
            bobot->client->sess.skill[6]        = 0;
            break;
        case PC_ENGINEER:
            bobot->client->sess.skill[2]        = 0;
            bobot->client->sess.skill[5]        = 0;
            bobot->client->sess.skill[3]        = 0;
            bobot->client->sess.skill[6]        = 0;
            break;
    case PC_FIELDOPS:
            bobot->client->sess.skill[2]        = 0;
            bobot->client->sess.skill[5]        = 0;
            bobot->client->sess.skill[1]        = 0;
            bobot->client->sess.skill[6]        = 0;
            break;
    case PC_COVERTOPS:
            bobot->client->sess.skill[2]        = 0;
            bobot->client->sess.skill[5]        = 0;
            bobot->client->sess.skill[1]        = 0;
            bobot->client->sess.skill[3]        = 0;
            break;
    }*/

    bobot->nextthink    = level.time + FRAMETIME;
    bobot->think        = BOBOT_AI_Think;

    /*     Okay, determine the team*/
    bobotAI->myteam        = bobot->client->ps.persistant[PERS_TEAM];    // this SHOULD be set for a bot
    bobotAI->otherteam    = (bobotAI->myteam == TEAM_ALLIES ? TEAM_AXIS : TEAM_ALLIES);
    return qtrue;
}

/***************************************************************************
3emeType
renvoie l'entité la plus proche de la position *origin*
***************************************************************************/
gentity_t* BOBOT_findClosestEntity(vec3_t origin,int type)
{    int            i;
    vec_t        dist,distMin = 999999999.9f;
    gentity_t    *closest = NULL, *ent;
       
    for(i=MAX_CLIENTS; i < level.num_entities; i++)
    {    ent = &g_entities[i];
        if(ent->s.eType != type)
        { continue; }
        dist = Distance(origin,ent->r.currentOrigin);
        if (dist < distMin)
        {    distMin = dist;
            closest = ent;
        }
    }
    return closest;
}

/***************************************************************************
3emeType
initialise qq trucs nécessaires
***************************************************************************/
void BOBOT_SPAWN_initBot(Sbobot *bobotAI)
{    int        i,h,s;
    gentity_t    *ent;

    BOBOT_AI_initBot(bobotAI);

    /*    initialisation des connaissances des emplacements des cabinets dans la map */
    for(i=0; i< MAX_CABINETS; i++)
    {    bobotAI->cabinets_heal[i].node     = INVALID;
        bobotAI->cabinets_heal[i].ent      = NULL;
        bobotAI->cabinets_supply[i].node = INVALID;
        bobotAI->cabinets_supply[i].ent  = NULL;
    }
    for(i=0,h=0,s=0; i<MAX_NODES && h<MAX_CABINETS && s<MAX_CABINETS; i++)
    {    if(nodes[i].type & NODE_HEALER)
        {    bobotAI->cabinets_heal[h].node = i;
            ent = BOBOT_findClosestEntity(nodes[i].origin,ET_HEALER);
            if(ent == NULL)
            {    if (PrintDebug)
                { Fuzzy_Printf("Aucune armoire de soins n'a été trouvé dans la map.\n"); }
            }
            else
            { bobotAI->cabinets_heal[h].ent = ent;}
            h++;
        }
        else if(nodes[i].type & NODE_SUPPLIER)
        {    bobotAI->cabinets_supply[s].node = i;
            ent = BOBOT_findClosestEntity(nodes[i].origin,ET_SUPPLIER);
            if(ent == NULL)
            {    if (PrintDebug)
                { Fuzzy_Printf("Aucune armoire de munitions n'a été trouvé dans la map\n"); }
            }
            else
            { bobotAI->cabinets_supply[s].ent = ent; }
            s++;
        }
    }
}

/*===============
G_BobotConnect
===============*/
qboolean G_BobotConnect( int clientNum, qboolean restart )
{    Sbobot *bobotAI;

    if (restart)
    {    if (!BobotAISetupClient( clientNum))
        {    trap_DropClient( clientNum, "BobotAISetupClient failed", 0 );
            return qfalse;
        }
        bobotAI    = &bobots[clientNum];
        BOBOT_SPAWN_initBot(bobotAI);
    }
    return qtrue;
}

/*===============
BOBOT_KickByTeam
===============*/
void BOBOT_KickByTeam(int team) {
    int         i;
    gclient_t    *cl;

    for ( i=0 ; i< g_maxclients.integer ; i++ )
    {    cl = level.clients + i;
        if ( cl->pers.connected != CON_CONNECTED )
        { continue; }
        if ( !(g_entities[cl->ps.clientNum].r.svFlags & SVF_BOT) )
        { continue; }
        if ( team >= 0 && cl->sess.sessionTeam != team )
        { continue; }
        trap_DropClient( cl->ps.clientNum, "kicked", 0 ); //soyons bourrin ;)
        return ;
    }
}

/*===============
BOBOT_KickAll
===============*/
void BOBOT_KickAll()
{    int         i;
    gclient_t    *cl;

    for ( i=0 ; i< g_maxclients.integer ; i++ )
    {    cl = level.clients + i;
        if ( cl->pers.connected != CON_CONNECTED )
        { continue; }
        if ( !(g_entities[cl->ps.clientNum].r.svFlags & SVF_BOT) )
        { continue; }
        trap_DropClient( cl->ps.clientNum, "kicked", 0 ); //soyons bourrin ;)
    }
}

/*===============
BOBOT_ChangeSkill
team = 0  => axis
team = 1  => allies
team = -1 => all
===============*/

void BOBOT_ChangeSkill(int team, int skill)
{    int         i;
    gclient_t    *cl;
    Sbobot        *bobotAI;
    char        userinfo[MAX_INFO_STRING];

    for ( i=0 ; i< g_maxclients.integer ; i++ )
    {    cl = level.clients + i;
        if ( cl->pers.connected != CON_CONNECTED )
        { continue;    }
        if ( !(g_entities[cl->ps.clientNum].r.svFlags & SVF_BOT) )
        { continue; }
        if(team == 0 && cl->sess.sessionTeam != TEAM_AXIS)
        { continue; }
        if(team == 1 && cl->sess.sessionTeam != TEAM_ALLIES)
        { continue; }
        //je suis pas sur de ca (joc)
        bobotAI = &bobots[g_entities[cl->ps.clientNum].s.clientNum];
        bobotAI->skill = skill;
       
        /*    joc : le skill change apres un map restart ! il faut stocker le nouveau skill ! */
        trap_GetUserinfo( cl->ps.clientNum, userinfo, sizeof(userinfo) );
        Info_SetValueForKey( userinfo, "skill", va("%i", skill) );
        trap_SetUserinfo( cl->ps.clientNum, userinfo );
        ClientUserinfoChanged(cl->ps.clientNum);
    }
}

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