#include "g_local.h" #include "m_player.h" #include "bot.h" void droptofloor (edict_t *ent); edict_t *bot_team_flag1; edict_t *bot_team_flag2; void SetBotFlag1(edict_t *ent) //チーム1の旗 { bot_team_flag1 = ent; } void SetBotFlag2(edict_t *ent) //チーム2の旗 { bot_team_flag2 = ent; } edict_t *GetBotFlag1() //チーム1の旗 { return bot_team_flag1; } edict_t *GetBotFlag2() //チーム2の旗 { return bot_team_flag2; } qboolean ChkTFlg( void ) { if(bot_team_flag1 != NULL && bot_team_flag2 != NULL) return true; else return false; } void SpawnItem2 (edict_t *ent, gitem_t *item) { // PrecacheItem (item); ent->item = item; ent->nextthink = level.time ; // items start after other solids ent->think = droptofloor; ent->s.effects = 0; ent->s.renderfx = RF_GLOW; // if (ent->model) // gi.modelindex (ent->model); droptofloor (ent); ent->s.modelindex = 0; ent->nextthink = level.time + 100 * FRAMETIME; // items start after other solids ent->think = G_FreeEdict; } //===================================== // // BOT用可視判定 // qboolean Bot_trace (edict_t *ent,edict_t *other) { trace_t rs_trace; vec3_t ttx; vec3_t tty; VectorCopy (ent->s.origin,ttx); VectorCopy (other->s.origin,tty); if(ent->maxs[2] >=32) { if(tty[2] > ttx[2] ) tty[2] += 16; // else if(ttx[2] > tty[2] > 100 ) tty[2] += 32; ttx[2] += 30; } else { ttx[2] -= 12; } rs_trace = gi.trace (ttx, NULL, NULL, tty ,ent, CONTENTS_SOLID | CONTENTS_WINDOW | CONTENTS_LAVA | CONTENTS_SLIME /*| CONTENTS_TRANSLUCENT*/); if(rs_trace.fraction == 1.0 && !rs_trace.allsolid && !rs_trace.startsolid) return true; if( ent->maxs[2] < 32 ) return false; if(other->classname[6] == 'F' || other->classname[0] == 'w') {} else if(other->classname[0]=='i') { if(other->classname[5]=='q' || other->classname[5]=='f' || other->classname[5]=='t' || other->classname[5]=='i' || other->classname[5]=='h' || other->classname[5]=='a'){} else return false; } else return false; if(rs_trace.ent != NULL) { if(rs_trace.ent->classname[0] == 'f' && rs_trace.ent->classname[5] == 'd' && rs_trace.ent->targetname == NULL) return true; } if(ent->s.origin[2] < other->s.origin[2] || ent->s.origin[2]-24 > other->s.origin[2]) return false; ttx[2] -= 36; rs_trace = gi.trace (ttx, NULL, NULL, other->s.origin ,ent, CONTENTS_SOLID | CONTENTS_WINDOW | CONTENTS_LAVA | CONTENTS_SLIME /*|CONTENTS_TRANSLUCENT*/); if(rs_trace.fraction == 1.0 && !rs_trace.allsolid && !rs_trace.startsolid) return true; return false; } qboolean Bot_traceX (edict_t *ent,edict_t *other) { trace_t rs_trace; vec3_t ttx,tty; VectorCopy (ent->s.origin,ttx); VectorCopy (other->s.origin,tty); ttx[2] += 16; tty[2] += 16; rs_trace = gi.trace (ttx, NULL, NULL, tty ,ent, CONTENTS_SOLID | CONTENTS_WINDOW | CONTENTS_LAVA | CONTENTS_SLIME); if(rs_trace.fraction == 1.0 ) return true; return false; } qboolean Bot_traceY (edict_t *ent,edict_t *other) { trace_t rs_trace; vec3_t ttx,tty; VectorCopy (ent->s.origin,ttx); VectorCopy (other->s.origin,tty); if(ent->maxs[2] >=32) ttx[2] += 24; else ttx[2] -= 12; tty[2] += 16; rs_trace = gi.trace (ttx, NULL, NULL, tty ,ent, CONTENTS_SOLID | CONTENTS_WINDOW | CONTENTS_LAVA | CONTENTS_SLIME); if(rs_trace.fraction == 1.0 ) return true; return false; } // // BOT用可視判定 2 // qboolean Bot_trace2 (edict_t *ent,vec3_t ttz) { trace_t rs_trace; vec3_t ttx; VectorCopy (ent->s.origin,ttx); if(ent->maxs[2] >=32) ttx[2] += 24; else ttx[2] -= 12; rs_trace = gi.trace (ttx, NULL, NULL, ttz ,ent, CONTENTS_SOLID | CONTENTS_LAVA | CONTENTS_SLIME /*| CONTENTS_TRANSLUCENT*/); if(rs_trace.fraction != 1.0 ) return false; return true; } // // BOT用可視判定 3 // qboolean Bot_traceS (edict_t *ent,edict_t *other) { trace_t rs_trace; vec3_t start,end; int mycont; VectorCopy(ent->s.origin,start); VectorCopy(other->s.origin,end); start[2] += ent->viewheight - 8; end[2] += other->viewheight - 8; if(Bot[ent->client->zc.botindex].param[BOP_NOSTHRWATER]) goto WATERMODE; rs_trace = gi.trace (start, NULL, NULL, end ,ent,CONTENTS_SOLID | CONTENTS_WINDOW | CONTENTS_LAVA | CONTENTS_SLIME); if(rs_trace.fraction != 1.0 ) return false; return true; WATERMODE: mycont = gi.pointcontents(start); if((mycont & CONTENTS_WATER) && !other->waterlevel) { rs_trace = gi.trace (end, NULL, NULL, start ,ent,CONTENTS_SOLID | CONTENTS_WINDOW | CONTENTS_LAVA | CONTENTS_SLIME | CONTENTS_WATER); if(rs_trace.surface) { if(rs_trace.surface->flags & SURF_WARP) return false; } rs_trace = gi.trace (start, NULL, NULL, end ,ent,CONTENTS_SOLID | CONTENTS_WINDOW | CONTENTS_LAVA | CONTENTS_SLIME); if(rs_trace.fraction != 1.0 ) return false; return true; } else if((mycont & CONTENTS_WATER) && other->waterlevel) { VectorCopy(other->s.origin,end); end[2] -= 16; rs_trace = gi.trace (start, NULL, NULL, end ,ent,CONTENTS_SOLID | CONTENTS_WINDOW ); if(rs_trace.fraction != 1.0 ) return false; return true; } if(other->waterlevel) { VectorCopy(other->s.origin,end); end[2] += 32; rs_trace = gi.trace (start, NULL, NULL, end ,ent,CONTENTS_SOLID | CONTENTS_WINDOW | CONTENTS_WATER); if(rs_trace.surface) { if(rs_trace.surface->flags & SURF_WARP) return false; } // if(rs_trace.fraction != 1.0 ) return false; // return true; } rs_trace = gi.trace (start, NULL, NULL, end ,ent,CONTENTS_SOLID | CONTENTS_WINDOW | CONTENTS_LAVA | CONTENTS_SLIME); if(rs_trace.fraction != 1.0 ) return false; return true; } // // VEC値からyawを得る // float Get_yaw (vec3_t vec) { vec3_t out; double yaw; VectorCopy(vec,out); out[2] = 0; VectorNormalize2 (out, out); yaw = acos((double) out[0]); // yaw = (float) yaw; yaw = yaw / M_PI * 180; if(asin((double) out[1]) < 0 ) yaw *= -1; return (float)yaw; } float Get_pitch (vec3_t vec) { vec3_t out; float pitch; VectorNormalize2 (vec, out); pitch = acos((double) out[2]); // yaw = (float) yaw; pitch = ((float)pitch) / M_PI * 180; // if(asin((double) out[0]) < 0 ) pitch *= -1; pitch -= 90; if(pitch < -180) pitch += 360; return pitch; } // // VEC値とyaw値の角度差を得る // float Get_vec_yaw (vec3_t vec,float yaw) { float vecsyaw; vecsyaw = Get_yaw (vec); if(vecsyaw > yaw) vecsyaw -= yaw; else vecsyaw = yaw - vecsyaw; if(vecsyaw >180 ) vecsyaw = 360 - vecsyaw; return vecsyaw; } //yaw に対するvecの相対 float Get_vec_yaw2 (vec3_t vec,float yaw) { float vecsyaw; vecsyaw = Get_yaw (vec); vecsyaw -= yaw; if(vecsyaw >180 ) vecsyaw -= 360; else if(vecsyaw <-180 ) vecsyaw += 360; return vecsyaw; } //======================================================== //============= BOT TALKING/TAUNTING ROUTINES ============ //======================================================== //===================================================== // Returns Player with Highest Score. //===================================================== edict_t *BestScoreEnt(void) { edict_t *bestplayer=NULL; int i, bestscore=-999; edict_t *ent; // Search thru all clients for(i=0;i < game.maxclients; i++) { ent=g_edicts+i+1; // if (!G_EntExists(ent)) continue; if (ent->client->resp.score > bestscore) { bestplayer=ent; // Found one! bestscore=ent->client->resp.score; } } return bestplayer; } //======================================================= // Taunt your victim! Called from ClientObituary().. //======================================================= void bTaunt(edict_t *bot, edict_t *other) { if ((rand()%5) >= 2) return; if (level.time < bot->last_taunt) return; // If killed enemy then Taunt them!! if ((other->client) && (random() < 0.4)) switch (rand()%4) { case 0: // flipoff bot->s.frame = FRAME_flip01-1; bot->client->anim_end = FRAME_flip12; break; case 1: // salute bot->s.frame = FRAME_salute01-1; bot->client->anim_end = FRAME_salute11; break; case 2: // taunt bot->s.frame = FRAME_taunt01-1; bot->client->anim_end = FRAME_taunt17; break; case 3: // point bot->s.frame = FRAME_point01-1; bot->client->anim_end = FRAME_point12; break; } // Taunt victim but not too often.. bot->last_taunt = level.time + 60 + 35; } //======================================================== void bFakeChat(edict_t *bot) { gclient_t *bclient=bot->client; if (random() < .1) gi.bprintf(PRINT_CHAT, "%s: Bunch of Chicken Shits!\n", bclient->pers.netname); else if (random() < .2) gi.bprintf(PRINT_CHAT, "%s: Tu madre!!!\n", bclient->pers.netname); else if (random() < .3) gi.bprintf(PRINT_CHAT, "%s: Who wants a piece of me?\n", bclient->pers.netname); else if (random() < .4) gi.bprintf(PRINT_CHAT, "%s: Where'd everybody go?\n", bclient->pers.netname); else if (random() < .5) gi.bprintf(PRINT_CHAT, "%s: Yeee pendejos venid por mi! pateare vuestro gordo culo\n", bclient->pers.netname); else gi.bprintf(PRINT_CHAT, "%s: Kickin' Ass!\n", bclient->pers.netname); // Random chats between 2 minutes and 10 minutes bot->last_chat = level.time + 120 + (60*(rand()%8)); } //======================================================== // Insult the player that the bot just fragged... //======================================================== void bInsult(edict_t *bot, edict_t *loser) { gclient_t *bclient=bot->client; gclient_t *lclient=loser->client; if ((rand()%5) > 3) return; if (level.time < bot->last_insult) return; if (bclient->resp.score < lclient->resp.score) { if (bclient->resp.score < lclient->resp.score - 20) { if (random() < .1) gi.bprintf(PRINT_CHAT, "%s: Heh... I'm all luck, %s\n", bclient->pers.netname, lclient->pers.netname); else if (random() < .2) gi.bprintf(PRINT_CHAT, "%s: WHEW! Finally got ya, %s!\n", bclient->pers.netname, lclient->pers.netname); else if (random() < .3) gi.bprintf(PRINT_CHAT, "%s: I...I killed %s? I...don't remember... it all happened so fast!\n", bclient->pers.netname, lclient->pers.netname); else if (random() < .4) gi.bprintf(PRINT_CHAT, "%s: Only pussies on this server!\n", bclient->pers.netname, lclient->pers.netname); else if (random() < .5) gi.bprintf(PRINT_CHAT, "%s: Sure, I'm losing by a ton, but does that mean I suck? Probably.\n", bclient->pers.netname); else gi.bprintf(PRINT_CHAT, "%s: Not bad for a beginner, eh %s?\n", bclient->pers.netname, lclient->pers.netname); } else if (bclient->resp.score < lclient->resp.score - 10) { if (random() < .1) gi.bprintf(PRINT_CHAT, "%s: Well, %s, what can I say? You're good... but not good enough\n", bclient->pers.netname, lclient->pers.netname); else if (random() < .2) gi.bprintf(PRINT_CHAT, "%s: I'll get you %s, and your little dog, too\n", bclient->pers.netname, lclient->pers.netname); else if (random() < .3) gi.bprintf(PRINT_CHAT, "%s: Oh, I get how you play now, %s... you're mine.\n", bclient->pers.netname, lclient->pers.netname); else if (random() < .4) gi.bprintf(PRINT_CHAT, "%s: What's that, %s? Do I smell smoke?\n", bclient->pers.netname, lclient->pers.netname); else if (random() < .5) gi.bprintf(PRINT_CHAT, "%s: Oops! Sorry %s, You REALLY suck!\n", bclient->pers.netname, lclient->pers.netname); else gi.bprintf(PRINT_CHAT, "%s: YEAH BABY, YEAH!\n", bclient->pers.netname); } else if (bclient->resp.score < lclient->resp.score - 5) { if (random() < .1) gi.bprintf(PRINT_CHAT, "%s: Ok, %s, I'm back on track now\n", bclient->pers.netname, lclient->pers.netname); else if (random() < .2) gi.bprintf(PRINT_CHAT, "%s: You aren't gonna win THAT easy, %s.\n", bclient->pers.netname, lclient->pers.netname); else if (random() < .3) gi.bprintf(PRINT_CHAT, "%s: Umm, ok %s, I'd appreciate it if you could not bleed on my clothes next time.\n", bclient->pers.netname, lclient->pers.netname); else if (random() < .4) gi.bprintf(PRINT_CHAT, "%s: You might wanna get that fixed, %s\n", bclient->pers.netname, lclient->pers.netname); else if (random() < .5) gi.bprintf(PRINT_CHAT, "%s: Uh oh... BRB, I have to clean this %s off my shirt before it sets in.\n", bclient->pers.netname, lclient->pers.netname); else gi.bprintf(PRINT_CHAT, "%s: hiiiiiihaaaaaa\n", bclient->pers.netname, lclient->pers.netname); } else { if (random() < .1) gi.bprintf(PRINT_CHAT, "%s: I can still catch up with you, %s, don't get cocky\n", bclient->pers.netname, lclient->pers.netname); else if (random() < .2) gi.bprintf(PRINT_CHAT, "%s: You're alllll mine, %s.\n", bclient->pers.netname, lclient->pers.netname); else if (random() < .3) gi.bprintf(PRINT_CHAT, "%s: Come on, %s, just you and me.\n", bclient->pers.netname, lclient->pers.netname); else if (random() < .4) gi.bprintf(PRINT_CHAT, "%s: The best part of wakin' uuup is %s gibs in your cuuup!\n", bclient->pers.netname, lclient->pers.netname); else if (random() < .5) gi.bprintf(PRINT_CHAT, "%s: Oh my, %s, that didn't look like it felt very nice.\n", bclient->pers.netname, lclient->pers.netname); else gi.bprintf(PRINT_CHAT, "%s: Well, %s, looks like things might even up.\n", bclient->pers.netname, lclient->pers.netname); } } else if (bclient->resp.score > lclient->resp.score) { if (bclient->resp.score > lclient->resp.score + 10) { if (random() < .1) gi.bprintf(PRINT_CHAT, "%s: You're never going to catch up to me, %s. Just give up.\n", bclient->pers.netname, lclient->pers.netname); else if (random() < .2) gi.bprintf(PRINT_CHAT, "%s: Hey %s, have you tried reading one of those ""DeathMatch for Dummies"" books? HeeeeHaaaaa\n", bclient->pers.netname, lclient->pers.netname); else if (random() < .3) gi.bprintf(PRINT_CHAT, "%s: Oh %s, you make me feel so... alive!\n", bclient->pers.netname, lclient->pers.netname); else if (random() < .4) gi.bprintf(PRINT_CHAT, "%s: Me? Using a bot? No way %s, I'm all skill!\n", bclient->pers.netname, lclient->pers.netname); else if (random() < .5) gi.bprintf(PRINT_CHAT, "%s: Hey %s, are you letting your mom play again?\n", bclient->pers.netname, lclient->pers.netname); else gi.bprintf(PRINT_CHAT, "%s: You do know there's an autorun option, don't you?\n", bclient->pers.netname, lclient->pers.netname); } else if (bclient->resp.score > lclient->resp.score + 5) { if (random() < .1) gi.bprintf(PRINT_CHAT, "%s: HeeeeHaaaaa\n", bclient->pers.netname); else if (random() < .2) gi.bprintf(PRINT_CHAT, "%s: Don't feel bad %s, you just aren't gifted like me\n", bclient->pers.netname, lclient->pers.netname); else if (random() < .3) gi.bprintf(PRINT_CHAT, "%s: Come on %s, don't give up now!\n", bclient->pers.netname, lclient->pers.netname); else if (random() < .4) gi.bprintf(PRINT_CHAT, "%s: I think you just need to practice more, %s. muhhhhaahhhaaa\n", bclient->pers.netname, lclient->pers.netname); else if (random() < .5) gi.bprintf(PRINT_CHAT, "%s: I just want you to know that I think you're taking this beating very well, %s\n", bclient->pers.netname, lclient->pers.netname); else gi.bprintf(PRINT_CHAT, "%s: Is that freshly cooked whupass I smell, %s?\n", bclient->pers.netname, lclient->pers.netname); } else { if (random() < .1) gi.bprintf(PRINT_CHAT, "%s: Come on, %s, ajajajaaaaaaja I can take you\n", bclient->pers.netname, lclient->pers.netname); else if (random() < .2) gi.bprintf(PRINT_CHAT, "%s: You're goin' down, %s.\n", bclient->pers.netname, lclient->pers.netname); else if (random() < .3) gi.bprintf(PRINT_CHAT, "%s: Oh, so %s, you want some?\n", bclient->pers.netname, lclient->pers.netname); else if (random() < .4) gi.bprintf(PRINT_CHAT, "%s: That's right %s, you know who yo daddy is\n", bclient->pers.netname, lclient->pers.netname); else if (random() < .5) gi.bprintf(PRINT_CHAT, "%s: Better get that taken care of, %s. It could get infected.\n", bclient->pers.netname, lclient->pers.netname); else gi.bprintf(PRINT_CHAT, "%s: Don't ya just love it?\n", bclient->pers.netname, lclient->pers.netname); } } else { if (random() < .1) gi.bprintf(PRINT_CHAT, "%s: Oh look, a tie! Well %s, we'll just have to fix that!\n", bclient->pers.netname, lclient->pers.netname); else if (random() < .2) gi.bprintf(PRINT_CHAT, "%s: Time to pay your pimp, %s\n", bclient->pers.netname, lclient->pers.netname); else if (random() < .3) gi.bprintf(PRINT_CHAT, "%s: Come on %s, it's time to ride daddy's rocket\n", bclient->pers.netname, lclient->pers.netname); else if (random() < .4) gi.bprintf(PRINT_CHAT, "%s: Look %s, we're tied... want me to fix that? Ok then!\n", bclient->pers.netname, lclient->pers.netname); else if (random() < .5) gi.bprintf(PRINT_CHAT, "%s: Damn %s, I thought you were better than this\n", bclient->pers.netname, lclient->pers.netname); else gi.bprintf(PRINT_CHAT, "%s: Alright, %s, I'm not showing any mercy this time.\n", bclient->pers.netname, lclient->pers.netname); } // Next insult between 30 sec and 5 minutes bot->last_insult = level.time + 30 + (60*(rand()%5)); }