thirtyflightsofloving/3zb2/bot_fire.c
Knightmare66 eb97af1598 Added sources for Zaero mission pack and 3ZB2 bot DLLs.
Added GetFileList() to game function imports in misison pack DLL game.h.
2020-02-23 16:15:28 -05:00

1822 lines
46 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "bot.h"
#include "q_shared.h"
#include "m_player.h"
//======================================================================
//aimŒˆè
//ent entity
//aim aimƒXƒLƒ
//yaw dist
//wep weapon
void Get_AimAngle(edict_t *ent,float aim,float dist,int weapon)
{
edict_t *target;
vec3_t targaim,v;
trace_t rs_trace;
target = ent->client->zc.first_target;
switch(weapon)
{
//‘¦”»’è
case WEAP_SHOTGUN:
case WEAP_SUPERSHOTGUN:
case WEAP_RAILGUN:
if(target != ent->client->zc.last_target)
{
if(target->svflags & SVF_MONSTER)
{
VectorSubtract(target->s.old_origin,target->s.origin,targaim);
}
else
{
VectorCopy(target->velocity,targaim);
VectorInverse (targaim);
}
VectorNormalize(targaim);
VectorMA(target->s.origin,random() * aim * AIMING_POSGAP * random(),targaim,targaim);
}
else
{
VectorSubtract(ent->client->zc.last_pos,target->s.origin,targaim);
// VectorScale (targaim, vec_t scale, vec3_t out)
VectorMA(target->s.origin,aim * /*VectorLength(targaim)**/ random(),targaim,targaim);
}
VectorSubtract(targaim,ent->s.origin,targaim);
ent->s.angles[YAW] = Get_yaw(targaim);
ent->s.angles[PITCH] = Get_pitch(targaim);
ent->s.angles[YAW] += aim * AIMING_ANGLEGAP_S * (random() - 0.5) *2;
if(ent->s.angles[YAW] > 180) ent->s.angles[YAW] -= 360;
else if(ent->s.angles[YAW] < -180) ent->s.angles[YAW] += 360;
ent->s.angles[PITCH] += (aim * AIMING_ANGLEGAP_S * (random() - 0.5) * 2);
if(ent->s.angles[PITCH] > 90) ent->s.angles[PITCH] = 90;
else if(ent->s.angles[PITCH] < -90) ent->s.angles[PITCH] = -90;
break;
case WEAP_MACHINEGUN:
case WEAP_CHAINGUN:
if(target != ent->client->zc.last_target)
{
if(target->svflags & SVF_MONSTER)
{
VectorSubtract(target->s.old_origin,target->s.origin,targaim);
}
else
{
VectorCopy(target->velocity,targaim);
VectorInverse (targaim);
}
VectorNormalize(targaim);
VectorMA(target->s.origin,random() * aim * AIMING_POSGAP,targaim,targaim);
}
else
{
VectorSubtract(ent->client->zc.last_pos,target->s.origin,targaim);
VectorMA(target->s.origin,random() * aim /** VectorLength(targaim)*/,targaim,targaim);
}
VectorSubtract(targaim,ent->s.origin,targaim);
ent->s.angles[YAW] = Get_yaw(targaim);
ent->s.angles[PITCH] = Get_pitch(targaim);
ent->s.angles[YAW] += aim * AIMING_ANGLEGAP_M * (random() - 0.5) *2;
if(ent->s.angles[YAW] > 180) ent->s.angles[YAW] -= 360;
else if(ent->s.angles[YAW] < -180) ent->s.angles[YAW] += 360;
ent->s.angles[PITCH] += (aim * AIMING_ANGLEGAP_M * (random() - 0.5) * 2);
if(ent->s.angles[PITCH] > 90) ent->s.angles[PITCH] = 90;
else if(ent->s.angles[PITCH] < -90) ent->s.angles[PITCH] = -90;
break;
case WEAP_BLASTER:
case WEAP_GRENADES:
case WEAP_GRENADELAUNCHER:
case WEAP_ROCKETLAUNCHER:
case WEAP_PHALANX:
case WEAP_BOOMER:
if(target != ent->client->zc.last_target)
{
if(target->svflags & SVF_MONSTER)
{
VectorSubtract(target->s.origin,target->s.old_origin,targaim);
}
else
{
VectorCopy(target->velocity,targaim);
targaim[0] *= 32;
targaim[1] *= 32;
targaim[2] *= 32;
}
VectorNormalize(targaim);
VectorMA(target->s.origin,(11 - aim) * dist/25,targaim,targaim);
}
else
{
VectorSubtract(target->s.origin,ent->client->zc.last_pos,targaim);
targaim[2] /= 2;
VectorMA(target->s.origin,- aim * random() + dist/75,targaim,targaim);
}
rs_trace = gi.trace(target->s.origin,NULL,NULL,targaim,target,MASK_SHOT);
VectorCopy(rs_trace.endpos,targaim);
if(weapon == WEAP_GRENADELAUNCHER
|| weapon == WEAP_ROCKETLAUNCHER
|| weapon == WEAP_PHALANX)
{
if(targaim[2] < (ent->s.origin[2] + JumpMax))
{
targaim[2] -= 24;
VectorCopy(ent->s.origin,v);
v[2] += ent->viewheight - 8;
rs_trace = gi.trace(v,NULL,NULL,targaim,ent,MASK_SHOT);
if(rs_trace.fraction != 1.0) targaim[2] += 24;
}
else if(targaim[2] > (ent->s.origin[2] + JumpMax)) targaim[2] += 5;
}
VectorSubtract(targaim,ent->s.origin,targaim);
ent->s.angles[YAW] = Get_yaw(targaim);
ent->s.angles[PITCH] = Get_pitch(targaim);
ent->s.angles[YAW] += aim * AIMING_ANGLEGAP_M * (random() - 0.5) *2;
if(ent->s.angles[YAW] > 180) ent->s.angles[YAW] -= 360;
else if(ent->s.angles[YAW] < -180) ent->s.angles[YAW] += 360;
ent->s.angles[PITCH] += (aim * AIMING_ANGLEGAP_M * (random() - 0.5) * 2);
if(ent->s.angles[PITCH] > 90) ent->s.angles[PITCH] = 90;
else if(ent->s.angles[PITCH] < -90) ent->s.angles[PITCH] = -90;
break;
case WEAP_HYPERBLASTER:
if(target != ent->client->zc.last_target)
{
if(target->svflags & SVF_MONSTER)
{
VectorSubtract(target->s.origin,target->s.old_origin,targaim);
}
else
{
VectorCopy(target->velocity,targaim);
targaim[0] *= 32;
targaim[1] *= 32;
targaim[2] *= 32;
}
VectorNormalize(targaim);
VectorMA(target->s.origin,(11 - aim) * dist/100,targaim,targaim);
}
else
{
VectorSubtract(target->s.origin,ent->client->zc.last_pos,targaim);
targaim[2] /= 2;
VectorMA(target->s.origin,- aim + dist/115,targaim,targaim);
}
rs_trace = gi.trace(target->s.origin,NULL,NULL,targaim,target,MASK_SHOT);
VectorCopy(rs_trace.endpos,targaim);
VectorSubtract(targaim,ent->s.origin,targaim);
ent->s.angles[YAW] = Get_yaw(targaim);
ent->s.angles[PITCH] = Get_pitch(targaim);
ent->s.angles[YAW] += aim * AIMING_ANGLEGAP_M * (random() - 0.5) *2;
if(ent->s.angles[YAW] > 180) ent->s.angles[YAW] -= 360;
else if(ent->s.angles[YAW] < -180) ent->s.angles[YAW] += 360;
ent->s.angles[PITCH] += (aim * AIMING_ANGLEGAP_M * (random() - 0.5) * 2);
if(ent->s.angles[PITCH] > 90) ent->s.angles[PITCH] = 90;
else if(ent->s.angles[PITCH] < -90) ent->s.angles[PITCH] = -90;
break;
case WEAP_BFG:
VectorCopy(ent->client->zc.vtemp,targaim);
VectorSubtract(targaim,ent->s.origin,targaim);
ent->s.angles[YAW] = Get_yaw(targaim);
ent->s.angles[PITCH] = Get_pitch(targaim);
break;
default:
break;
}
}
//======================================================================
//•<>ŠíŽg—p‰Â”\<5C>H
int CanUsewep(edict_t *ent,int weapon)
{
gitem_t *item;
gclient_t *client;
int mywep,ammoindex;
client = ent->client;
mywep = Get_KindWeapon(client->pers.weapon);
switch(weapon)
{
case WEAP_BLASTER:
item = Fdi_BLASTER;//FindItem("Blaster");
if(client->pers.inventory[ITEM_INDEX(item)])
{
if(mywep == WEAP_BLASTER || client->weaponstate == WEAPON_READY)
{
item->use(ent,item);
if(client->weaponstate == WEAPON_READY) return true;
else return 2;
}
}
break;
case WEAP_SHOTGUN:
item = Fdi_SHOTGUN;//FindItem("Shotgun");
ammoindex = ITEM_INDEX(Fdi_SHELLS/*FindItem("Shells")*/);
if(client->pers.inventory[ITEM_INDEX(item)]
&& client->pers.inventory[ammoindex] > 0)
{
if(mywep == WEAP_SHOTGUN || client->weaponstate == WEAPON_READY)
{
item->use(ent,item);
if(client->weaponstate == WEAPON_READY) return true;
else return 2;
}
}
break;
case WEAP_SUPERSHOTGUN:
item = Fdi_SUPERSHOTGUN;//FindItem("Super Shotgun");
ammoindex = ITEM_INDEX(Fdi_SHELLS/*FindItem("Shells")*/);
if( client->pers.inventory[ITEM_INDEX(item)]
&& client->pers.inventory[ammoindex] > 1)
{
if(mywep == WEAP_SUPERSHOTGUN || client->weaponstate == WEAPON_READY)
{
item->use(ent,item);
if(client->weaponstate == WEAPON_READY) return true;
else return 2;
}
}
break;
case WEAP_MACHINEGUN:
item = Fdi_MACHINEGUN;//FindItem("Machinegun");
ammoindex = ITEM_INDEX(Fdi_BULLETS/*FindItem("Bullets")*/);
if( client->pers.inventory[ITEM_INDEX(item)]
&& client->pers.inventory[ammoindex] > 0)
{
if(client->pers.weapon != item) item->use(ent,item);
if(mywep == WEAP_MACHINEGUN || client->weaponstate == WEAPON_READY
|| client->weaponstate == WEAPON_FIRING)
{
// if(client->pers.weapon == item) return true;
// else {item->use(ent,item); return 2;}
if(client->weaponstate == WEAPON_READY || client->weaponstate == WEAPON_FIRING) return true;
else return 2;
}
}
break;
case WEAP_CHAINGUN:
item = FindItem("Chaingun");
ammoindex = ITEM_INDEX(Fdi_BULLETS/*FindItem("Bullets")*/);
if( client->pers.inventory[ITEM_INDEX(item)]
&& client->pers.inventory[ammoindex] > 0)
{
if(mywep == WEAP_CHAINGUN || client->weaponstate == WEAPON_READY)
{
item->use(ent,item);
if(client->weaponstate == WEAPON_READY || client->weaponstate == WEAPON_FIRING) return true;
else return 2;
}
}
break;
case WEAP_GRENADES:
item = Fdi_GRENADES;//FindItem("Grenades");
ammoindex = ITEM_INDEX(Fdi_GRENADES/*FindItem("Grenades")*/);
if(client->pers.inventory[ammoindex] > 0)
{
if(mywep == WEAP_GRENADES || client->weaponstate == WEAPON_READY)
{
item->use(ent,item);
if(client->weaponstate == WEAPON_READY) return true;
else return 2;
}
}
break;
case WEAP_TRAP:
item = Fdi_TRAP;//FindItem("Trap");
ammoindex = ITEM_INDEX(Fdi_TRAP/*FindItem("Trap")*/);
if(client->pers.inventory[ammoindex] > 0)
{
if(mywep == WEAP_GRENADES || client->weaponstate == WEAPON_READY)
{
item->use(ent,item);
if(client->weaponstate == WEAPON_READY) return true;
else return 2;
}
}
break;
case WEAP_GRENADELAUNCHER:
item = Fdi_GRENADELAUNCHER;//FindItem("Grenade Launcher");
ammoindex = ITEM_INDEX(Fdi_GRENADES/*FindItem("Grenades")*/);
if( client->pers.inventory[ITEM_INDEX(item)]
&& client->pers.inventory[ammoindex] > 0)
{
if(mywep == WEAP_GRENADELAUNCHER || client->weaponstate == WEAPON_READY)
{
item->use(ent,item);
if(client->weaponstate == WEAPON_READY) return true;
else return 2;
}
}
break;
case WEAP_ROCKETLAUNCHER:
item = Fdi_ROCKETLAUNCHER;//FindItem("Rocket Launcher");
ammoindex = ITEM_INDEX(Fdi_ROCKETS/*FindItem("Rockets")*/);
if( client->pers.inventory[ITEM_INDEX(item)]
&& client->pers.inventory[ammoindex] > 0)
{
if(mywep == WEAP_ROCKETLAUNCHER || client->weaponstate == WEAPON_READY)
{
item->use(ent,item);
if(client->weaponstate == WEAPON_READY) return true;
else return 2;
}
}
break;
case WEAP_HYPERBLASTER:
item = Fdi_HYPERBLASTER;//FindItem("HyperBlaster");
ammoindex = ITEM_INDEX(Fdi_CELLS/*FindItem("Cells")*/);
if( client->pers.inventory[ITEM_INDEX(item)]
&& client->pers.inventory[ammoindex] > 0)
{
if(mywep == WEAP_HYPERBLASTER || client->weaponstate == WEAPON_READY)
{
item->use(ent,item);
if(client->weaponstate == WEAPON_READY || client->weaponstate == WEAPON_FIRING) return true;
else return 2;
}
}
break;
case WEAP_BOOMER:
item = Fdi_BOOMER;//FindItem("Ionripper");
ammoindex = ITEM_INDEX(Fdi_CELLS/*FindItem("Cells")*/);
if( client->pers.inventory[ITEM_INDEX(item)]
&& client->pers.inventory[ammoindex] > 0)
{
if(mywep == WEAP_BOOMER || client->weaponstate == WEAPON_READY)
{
item->use(ent,item);
if(client->weaponstate == WEAPON_READY || client->weaponstate == WEAPON_FIRING) return true;
else return 2;
}
}
break;
case WEAP_RAILGUN:
item = Fdi_RAILGUN;//FindItem("Railgun");
ammoindex = ITEM_INDEX(Fdi_SLUGS/*FindItem("Slugs")*/);
if( client->pers.inventory[ITEM_INDEX(item)]
&& client->pers.inventory[ammoindex] > 0)
{
if(mywep == WEAP_RAILGUN || client->weaponstate == WEAPON_READY)
{
item->use(ent,item);
if(client->weaponstate == WEAPON_READY) return true;
else return 2;
}
}
break;
case WEAP_PHALANX:
item = Fdi_PHALANX;//FindItem("Phalanx");
ammoindex = ITEM_INDEX(Fdi_MAGSLUGS/*FindItem("Mag Slug")*/);
if( client->pers.inventory[ITEM_INDEX(item)]
&& client->pers.inventory[ammoindex] > 0)
{
if(mywep == WEAP_PHALANX || client->weaponstate == WEAPON_READY)
{
item->use(ent,item);
if(client->weaponstate == WEAPON_READY) return true;
else return 2;
}
}
break;
case WEAP_BFG:
item = Fdi_BFG;//FindItem("BFG10K");
ammoindex = ITEM_INDEX(Fdi_CELLS/*FindItem("Cells")*/);
if( client->pers.inventory[ITEM_INDEX(item)]
&& client->pers.inventory[ammoindex] >= 50)
{
if(mywep == WEAP_BFG || client->weaponstate == WEAPON_READY)
{
item->use(ent,item);
if(client->weaponstate == WEAPON_READY) return true;
else return 2;
}
}
break;
default: //case WEAP_BLASTER:
item = Fdi_BLASTER;//FindItem("Blaster");
if(client->pers.inventory[ITEM_INDEX(item)])
{
if(mywep == WEAP_BLASTER || client->weaponstate == WEAPON_READY)
{
item->use(ent,item);
if(client->weaponstate == WEAPON_READY) return true;
else return 2;
}
}
break;
}
return false;
}
//------------------------------------------------------------
// Use BFG
//------------------------------------------------------------
qboolean B_UseBfg(edict_t *ent,edict_t *target,int enewep,float aim,float distance,int skill)
{
int k,mywep;
zgcl_t *zc;
gclient_t *client;
client = ent->client;
zc = &client->zc;
if(k = CanUsewep(ent,WEAP_BFG))
{
mywep = Get_KindWeapon(client->pers.weapon);
Get_AimAngle(ent,aim,distance,mywep);
if(trace_priority < TRP_ANGLEKEEP) trace_priority = TRP_ANGLEKEEP;
if(k = Bot_traceS(ent,target)) VectorCopy(target->s.origin,zc->vtemp);
if(FFlg[skill] & FIRE_STAYFIRE)
{
if(k /*&& random() < 0.8*/)
{
client->buttons |= BUTTON_ATTACK;
zc->battlemode |= FIRE_STAYFIRE; //ƒ<C692>[ƒhJˆÚ
zc->battlecount = 8 + (int)(10 * random());
trace_priority = TRP_ALLKEEP;
return true;
}
}
//”š”­‰ñ”ð
else if((FFlg[skill] & FIRE_EXPAVOID)
&& distance < 300 /*&& random() < 0.5 */
&& Bot_traceS(ent,target))
{
if(ent->groundentity || zc->waterstate)
{
zc->battlemode |= FIRE_EXPAVOID;
zc->battlecount = 6 + (int)(6 * random());
trace_priority = TRP_ALLKEEP;
return true;
}
}
//•<>Ê
else if(!(FFlg[skill] &(FIRE_STAYFIRE | FIRE_EXPAVOID)))
{
if(k /*&& random() < 0.8*/)
{
zc->battlemode |= FIRE_BFG;
zc->battlecount = 6 + (int)(6 * random());
trace_priority = TRP_ANGLEKEEP;
return true;
}
}
else if((FFlg[skill] & FIRE_EXPAVOID)
&& Bot_traceS(ent,target))
{
if(k /*&& random() < 0.8*/)
{
zc->battlemode |= FIRE_BFG;
zc->battlecount = 6 + (int)(6 * random());
trace_priority = TRP_ANGLEKEEP;
return true;
}
}
}
return false;
}
//------------------------------------------------------------
// Use Hyper Blaster
//------------------------------------------------------------
qboolean B_UseHyperBlaster(edict_t *ent,edict_t *target,int enewep,float aim,float distance,int skill)
{
int k,mywep;
zgcl_t *zc;
gclient_t *client;
client = ent->client;
zc = &client->zc;
if(k = CanUsewep(ent,WEAP_HYPERBLASTER))
{
mywep = Get_KindWeapon(client->pers.weapon);
Get_AimAngle(ent,aim,distance,mywep);
client->buttons |= BUTTON_ATTACK;
if(trace_priority < TRP_ANGLEKEEP) trace_priority = TRP_ANGLEKEEP;
return true;
}
return false;
}
//------------------------------------------------------------
// Use Phalanx
//------------------------------------------------------------
qboolean B_UsePhalanx(edict_t *ent,edict_t *target,int enewep,float aim,float distance,int skill)
{
int k,mywep;
zgcl_t *zc;
gclient_t *client;
client = ent->client;
zc = &client->zc;
if(k = CanUsewep(ent,WEAP_PHALANX))
{
mywep = Get_KindWeapon(client->pers.weapon);
Get_AimAngle(ent,aim,distance,mywep);
if(trace_priority < TRP_ANGLEKEEP) trace_priority = TRP_ANGLEKEEP;
if((FFlg[skill] & FIRE_PRESTAYFIRE)
&& ((distance > 500 && random() < 0.1) || fabs(ent->s.angles[PITCH]) > 45 )
&& Bot_traceS(ent,target)
&& (enewep <= WEAP_MACHINEGUN || enewep == WEAP_GRENADES))
{
if(ent->groundentity || zc->waterstate)
{
zc->battlemode |= FIRE_PRESTAYFIRE;
zc->battlecount = 2 + (int)(6 * random());
trace_priority = TRP_ALLKEEP;
return true;
}
}
if((FFlg[skill] & FIRE_JUMPROC) && random() < 0.3
&& (target->s.origin[2] - ent->s.origin[2]) < JumpMax
&& !(client->ps.pmove.pm_flags && PMF_DUCKED))
{
if(ent->groundentity && !ent->waterlevel <= 1)
{
if(zc->route_trace)
{
if(Bot_Fall(ent,ent->s.origin,0))
{
trace_priority = TRP_ALLKEEP;
if(Bot_traceS(ent,target)) client->buttons |= BUTTON_ATTACK;
return true;
}
}
else
{
ent->moveinfo.speed = 0;
ent->velocity[2] += VEL_BOT_JUMP;
gi.sound(ent, CHAN_VOICE, gi.soundindex("*jump1.wav"), 1, ATTN_NORM, 0);
PlayerNoise(ent, ent->s.origin, PNOISE_SELF); //pon
Set_BotAnim(ent,ANIM_JUMP,FRAME_jump1-1,FRAME_jump6);
trace_priority = TRP_ALLKEEP;
if(Bot_traceS(ent,target)) client->buttons |= BUTTON_ATTACK;
return true;
}
}
}
else if((FFlg[skill] & FIRE_EXPAVOID)
&& distance < 300 && random() < 0.5
&& Bot_traceS(ent,target))
{
if(ent->groundentity || zc->waterstate)
{
zc->battlemode |= FIRE_EXPAVOID;
zc->battlecount = 4 + (int)(6 * random());
trace_priority = TRP_ALLKEEP;
return true;
}
}
if(Bot_traceS(ent,target)) client->buttons |= BUTTON_ATTACK;
return true;
}
return false;
}
//------------------------------------------------------------
// Use Rocket
//------------------------------------------------------------
qboolean B_UseRocket(edict_t *ent,edict_t *target,int enewep,float aim,float distance,int skill)
{
int k,mywep;
zgcl_t *zc;
gclient_t *client;
client = ent->client;
zc = &client->zc;
if(k = CanUsewep(ent,WEAP_ROCKETLAUNCHER))
{
mywep = Get_KindWeapon(client->pers.weapon);
Get_AimAngle(ent,aim,distance,mywep);
if(trace_priority < TRP_ANGLEKEEP) trace_priority = TRP_ANGLEKEEP;
if((FFlg[skill] & FIRE_PRESTAYFIRE)
&& ((distance > 500 && random() < 0.1) || fabs(ent->s.angles[PITCH]) > 45 )
&& Bot_traceS(ent,target)
&& (enewep <= WEAP_MACHINEGUN || enewep == WEAP_GRENADES))
{
if(ent->groundentity || zc->waterstate)
{
zc->battlemode |= FIRE_PRESTAYFIRE;
zc->battlecount = 2 + (int)(6 * random());
trace_priority = TRP_ALLKEEP;
return true;
}
}
if((FFlg[skill] & FIRE_JUMPROC) && random() < 0.3
&& (target->s.origin[2] - ent->s.origin[2]) < JumpMax
&& !(client->ps.pmove.pm_flags && PMF_DUCKED))
{
if(ent->groundentity && !ent->waterlevel <= 1)
{
if(zc->route_trace)
{
if(Bot_Fall(ent,ent->s.origin,0))
{
trace_priority = TRP_ALLKEEP;
if(Bot_traceS(ent,target)) client->buttons |= BUTTON_ATTACK;
return true;
}
}
else
{
ent->moveinfo.speed = 0;
ent->velocity[2] += VEL_BOT_JUMP;
gi.sound(ent, CHAN_VOICE, gi.soundindex("*jump1.wav"), 1, ATTN_NORM, 0);
PlayerNoise(ent, ent->s.origin, PNOISE_SELF); //pon
Set_BotAnim(ent,ANIM_JUMP,FRAME_jump1-1,FRAME_jump6);
trace_priority = TRP_ALLKEEP;
if(Bot_traceS(ent,target)) client->buttons |= BUTTON_ATTACK;
return true;
}
}
}
else if((FFlg[skill] & FIRE_EXPAVOID)
&& distance < 300 && random() < 0.5
&& Bot_traceS(ent,target))
{
if(ent->groundentity || zc->waterstate)
{
zc->battlemode |= FIRE_EXPAVOID;
zc->battlecount = 4 + (int)(6 * random());
trace_priority = TRP_ALLKEEP;
return true;
}
}
if(Bot_traceS(ent,target)) client->buttons |= BUTTON_ATTACK;
return true;
}
return false;
}
//------------------------------------------------------------
// Use Boomer
//------------------------------------------------------------
qboolean B_UseBoomer(edict_t *ent,edict_t *target,int enewep,float aim,float distance,int skill)
{
int k,mywep;
zgcl_t *zc;
gclient_t *client;
client = ent->client;
zc = &client->zc;
if(k = CanUsewep(ent,WEAP_BOOMER))
{
mywep = Get_KindWeapon(client->pers.weapon);
Get_AimAngle(ent,aim,distance,mywep);
client->buttons |= BUTTON_ATTACK;
if(trace_priority < TRP_ANGLEKEEP) trace_priority = TRP_ANGLEKEEP;
return true;
}
return false;
}
//------------------------------------------------------------
// Use Railgun
//------------------------------------------------------------
qboolean B_UseRailgun(edict_t *ent,edict_t *target,int enewep,float aim,float distance,int skill)
{
int k,mywep;
zgcl_t *zc;
gclient_t *client;
client = ent->client;
zc = &client->zc;
if(k = CanUsewep(ent,WEAP_RAILGUN))
{
mywep = Get_KindWeapon(client->pers.weapon);
Get_AimAngle(ent,aim,distance,mywep);
client->buttons |= BUTTON_ATTACK;
if(trace_priority < TRP_ANGLEKEEP) trace_priority = TRP_ANGLEKEEP;
return true;
}
return false;
}
//------------------------------------------------------------
// Use Grenade Launcher
//------------------------------------------------------------
qboolean B_UseGrenadeLauncher(edict_t *ent,edict_t *target,int enewep,float aim,float distance,int skill)
{
int k,mywep;
zgcl_t *zc;
gclient_t *client;
client = ent->client;
zc = &client->zc;
if(k = CanUsewep(ent,WEAP_GRENADELAUNCHER))
{
mywep = Get_KindWeapon(client->pers.weapon);
Get_AimAngle(ent,aim,distance,mywep);
if((FFlg[skill] & FIRE_STAYFIRE)
&& random() < 0.3 && target->s.origin[2] < ent->s.origin[2])
{
if(ent->groundentity || zc->waterstate)
{
if(Bot_traceS(ent,target))
{
zc->battlemode |= FIRE_STAYFIRE;
zc->battlecount = 5 + (int)(10 * random());
trace_priority = TRP_ALLKEEP;
client->buttons |= BUTTON_ATTACK;
return true;
}
}
}
else if((FFlg[skill] & FIRE_EXPAVOID)
&& distance < 300 && random() < 0.5
&& Bot_traceS(ent,target))
{
if(ent->groundentity || zc->waterstate)
{
zc->battlemode |= FIRE_EXPAVOID;
zc->battlecount = 2 + (int)(6 * random());
trace_priority = TRP_ALLKEEP;
return true;
}
}
client->buttons |= BUTTON_ATTACK;
if(trace_priority < TRP_ANGLEKEEP) trace_priority = TRP_ANGLEKEEP;
return true;
}
return false;
}
//------------------------------------------------------------
// Use Chain Gun
//------------------------------------------------------------
qboolean B_UseChainGun(edict_t *ent,edict_t *target,int enewep,float aim,float distance,int skill)
{
int k,mywep;
zgcl_t *zc;
gclient_t *client;
client = ent->client;
zc = &client->zc;
if(k = CanUsewep(ent,WEAP_CHAINGUN))
{
mywep = Get_KindWeapon(client->pers.weapon);
Get_AimAngle(ent,aim,distance,mywep);
client->buttons |= BUTTON_ATTACK;
if(trace_priority < TRP_ANGLEKEEP) trace_priority = TRP_ANGLEKEEP;
return true;
}
return false;
}
//------------------------------------------------------------
// Use Machine Gun
//------------------------------------------------------------
qboolean B_UseMachineGun(edict_t *ent,edict_t *target,int enewep,float aim,float distance,int skill)
{
int k,mywep;
zgcl_t *zc;
gclient_t *client;
client = ent->client;
zc = &client->zc;
if(k = CanUsewep(ent,WEAP_MACHINEGUN))
{
mywep = Get_KindWeapon(client->pers.weapon);
Get_AimAngle(ent,aim,distance,mywep);
if(k == true) client->buttons |= BUTTON_ATTACK;
if(trace_priority < TRP_ANGLEKEEP) trace_priority = TRP_ANGLEKEEP;
return true;
}
return false;
}
//------------------------------------------------------------
// Use S-Shotgun
//------------------------------------------------------------
qboolean B_UseSuperShotgun(edict_t *ent,edict_t *target,int enewep,float aim,float distance,int skill)
{
int k,mywep;
zgcl_t *zc;
gclient_t *client;
client = ent->client;
zc = &client->zc;
if(k = CanUsewep(ent,WEAP_SUPERSHOTGUN))
{
mywep = Get_KindWeapon(client->pers.weapon);
Get_AimAngle(ent,aim,distance,mywep);
client->buttons |= BUTTON_ATTACK;
if(trace_priority < TRP_ANGLEKEEP) trace_priority = TRP_ANGLEKEEP;
return true;
}
return false;
}
//------------------------------------------------------------
// Use Shotgun
//------------------------------------------------------------
qboolean B_UseShotgun(edict_t *ent,edict_t *target,int enewep,float aim,float distance,int skill)
{
int k,mywep;
zgcl_t *zc;
gclient_t *client;
client = ent->client;
zc = &client->zc;
if(k = CanUsewep(ent,WEAP_SHOTGUN))
{
mywep = Get_KindWeapon(client->pers.weapon);
Get_AimAngle(ent,aim,distance,mywep);
client->buttons |= BUTTON_ATTACK;
if(trace_priority < TRP_ANGLEKEEP) trace_priority = TRP_ANGLEKEEP;
return true;
}
return false;
}
//------------------------------------------------------------
// Use Hand Grenade
//------------------------------------------------------------
qboolean B_UseHandGrenade(edict_t *ent,edict_t *target,int enewep,float aim,float distance,int skill)
{
int k,mywep;
zgcl_t *zc;
gclient_t *client;
client = ent->client;
zc = &client->zc;
if(k = CanUsewep(ent,WEAP_GRENADES))
{
mywep = Get_KindWeapon(client->pers.weapon);
Get_AimAngle(ent,aim,distance,mywep);
if(ent->client->weaponstate == WEAPON_READY ) client->buttons |= BUTTON_ATTACK;
if(trace_priority < TRP_ANGLEKEEP) trace_priority = TRP_ANGLEKEEP;
return true;
}
return false;
}
//------------------------------------------------------------
// Use Trap
//------------------------------------------------------------
qboolean B_UseTrap(edict_t *ent,edict_t *target,int enewep,float aim,float distance,int skill)
{
int k,mywep;
zgcl_t *zc;
gclient_t *client;
client = ent->client;
zc = &client->zc;
if(k = CanUsewep(ent,WEAP_TRAP))
{
mywep = Get_KindWeapon(client->pers.weapon);
Get_AimAngle(ent,aim,distance,mywep);
if(ent->client->weaponstate == WEAPON_READY ) client->buttons |= BUTTON_ATTACK;
if(trace_priority < TRP_ANGLEKEEP) trace_priority = TRP_ANGLEKEEP;
return true;
}
return false;
}
//------------------------------------------------------------
// Use Blaster
//------------------------------------------------------------
qboolean B_UseBlaster(edict_t *ent,edict_t *target,int enewep,float aim,float distance,int skill)
{
int k,mywep;
zgcl_t *zc;
gclient_t *client;
client = ent->client;
zc = &client->zc;
if(k = CanUsewep(ent,WEAP_BLASTER))
{
mywep = Get_KindWeapon(client->pers.weapon);
Get_AimAngle(ent,aim,distance,mywep);
client->buttons |= BUTTON_ATTACK;
if(trace_priority < TRP_ANGLEKEEP) trace_priority = TRP_ANGLEKEEP;
return true;;
}
return false;
}
//return weapon
void Combat_LevelX(edict_t *ent,int foundedenemy,int enewep
,float aim,float distance,int skill)
{
gclient_t *client;
zgcl_t *zc;
edict_t *target;
int mywep,k;
vec3_t v;
qboolean mod = false;
client = ent->client;
zc = &client->zc;
target = zc->first_target;
//-----------------------------------------------------------------------
//ƒXƒe<C692>[ƒ^ƒX𔽉f
//-----------------------------------------------------------------------
k = false;
//—\‘ª========================
if(zc->battlemode & FIRE_ESTIMATE)
{
mywep = Get_KindWeapon(client->pers.weapon);
//Phalanx
if(distance > 100 || mywep == WEAP_PHALANX)
{
if(B_UsePhalanx(ent,target,enewep,aim,distance,skill)) k = true;
}
//Rocket
if(distance > 100 || mywep == WEAP_ROCKETLAUNCHER)
{
if(B_UseRocket(ent,target,enewep,aim,distance,skill)) k = true;
}
//Boomer
if(distance < 1200)
{
if(B_UseBoomer(ent,target,enewep,aim,distance,skill)) k = true;
}
//Grenade Launcher
if(distance > 100 && distance < 400 && (target->s.origin[2] - ent->s.origin[2]) < 200)
{
if(B_UseGrenadeLauncher(ent,target,enewep,aim,distance,skill)) k = true;
}
//Hand Grenade
if(distance < 1200)
{
if(B_UseHandGrenade(ent,target,enewep,aim,distance,skill)) k = true;
}
VectorSubtract(zc->vtemp,ent->s.origin,v);
ent->s.angles[YAW] = Get_yaw(v);
ent->s.angles[PITCH] = Get_pitch(v);
if(k) trace_priority = TRP_ALLKEEP;
else trace_priority = TRP_ANGLEKEEP;
return;
}
VectorSubtract(target->s.origin,ent->s.origin,v);
ent->s.angles[YAW] = Get_yaw(v);
ent->s.angles[PITCH] = Get_pitch(v);
trace_priority = TRP_ANGLEKEEP;
}
//return weapon
void Combat_Level0(edict_t *ent,int foundedenemy,int enewep
,float aim,float distance,int skill)
{
float f;
gclient_t *client;
zgcl_t *zc;
edict_t *target;
int mywep,i,j,k;
vec3_t v,vv,v1,v2;
qboolean mod = false;
trace_t rs_trace;
client = ent->client;
zc = &client->zc;
target = zc->first_target;
//-----------------------------------------------------------------------
//ƒXƒe<C692>[ƒ^ƒX𔽉f
//-----------------------------------------------------------------------
//ƒ`ƒLƒ“Í_¢ªƒLƒcƒC==============
if(zc->battlemode == FIRE_CHIKEN) aim *= 0.7;
//<2F>¶‰Eɉñ”ð========================
if(zc->battlemode & FIRE_SHIFT)
{
mywep = Get_KindWeapon(client->pers.weapon);
Get_AimAngle(ent,aim,distance,mywep);
if(--zc->battlesubcnt > 0)
{
if(ent->groundentity)
{
if(zc->battlemode & FIRE_SHIFT_R)
{
zc->moveyaw = ent->s.angles[YAW] + 90;
if(zc->moveyaw > 180) zc->moveyaw -= 360;
}
else
{
zc->moveyaw = ent->s.angles[YAW] - 90;
if(zc->moveyaw < -180) zc->moveyaw += 360;
}
trace_priority = TRP_MOVEKEEP; //ŒãÞ<E28098>ˆ<CB86>
}
}
else
{
zc->battlemode &= ~FIRE_SHIFT;
}
}
//dodge=============================
if(Bot[ent->client->zc.botindex].param[BOP_DODGE]
&& ent->groundentity && !ent->waterlevel)
{
AngleVectors (target->client->v_angle, v,NULL, NULL);
VectorScale (v, 300, v);
VectorSet(vv, 0, 0, target->viewheight-8);
VectorAdd(target->s.origin,vv,vv);
VectorAdd(vv,v,v);
VectorSet(v1, -4, -4,-4);
VectorSet(v2, 4, 4, 4);
rs_trace = gi.trace(vv,v1,v2,v,target,MASK_SHOT);
if(rs_trace.ent == ent)
{
if(rs_trace.endpos[2] > (ent->s.origin[2] + 4) && random() < 0.4)
{
client->ps.pmove.pm_flags |= PMF_DUCKED;
zc->battleduckcnt = 2 + 8 * random();
}
else if(rs_trace.endpos[2] < (ent->s.origin[2] + JumpMax - 24))
{
if(zc->route_trace)
{
if(Bot_Fall(ent,ent->s.origin,0)) trace_priority = TRP_MOVEKEEP;;
}
else
{
ent->moveinfo.speed = 0.5;
ent->velocity[2] += VEL_BOT_JUMP;
gi.sound(ent, CHAN_VOICE, gi.soundindex("*jump1.wav"), 1, ATTN_NORM, 0);
PlayerNoise(ent, ent->s.origin, PNOISE_SELF); //pon
Set_BotAnim(ent,ANIM_JUMP,FRAME_jump1-1,FRAME_jump6);
}
}
}
}
//–³Ž‹‚µ‚Ä‘–‚é========================
if(zc->battlemode & FIRE_IGNORE)
{
if(--zc->battlecount > 0)
{
if(zc->first_target != zc->last_target)
{
zc->battlemode = 0;
}
else return;
}
zc->battlemode = 0;
}
//—§‚¿Ž~ÜÁÄŒÂ<E2809A>€”õ========================
if(zc->battlemode & FIRE_PRESTAYFIRE)
{
if(--zc->battlecount > 0)
{
mywep = Get_KindWeapon(client->pers.weapon);
Get_AimAngle(ent,aim,distance,mywep);
if(target->client->weaponstate == WEAPON_FIRING && ent->groundentity) ent->client->ps.pmove.pm_flags |= PMF_DUCKED;
trace_priority = TRP_ALLKEEP; //“®‚©‚È‚¢
return;
}
if(!(zc->battlemode & FIRE_SHIFT)) zc->battlemode = FIRE_STAYFIRE; //ƒ<C692>[ƒhJˆÚ
zc->battlecount = 5 + (int)(20 * random());
}
//—§‚¿Ž~‚Ü‚Á‚ÄŒ‚‚Â========================
if(zc->battlemode & FIRE_STAYFIRE)
{
if(--zc->battlecount > 0)
{
mywep = Get_KindWeapon(client->pers.weapon);
if(1/*mywep == WEAP_BFG*/) CanUsewep(ent,WEAP_BFG);
aim *= 0.95;
Get_AimAngle(ent,aim,distance,mywep);
if(target->client->weaponstate == WEAPON_FIRING && ent->groundentity)
{
if(mywep == WEAP_BFG)
{
if(target->s.origin[2] > ent->s.origin[2]) client->ps.pmove.pm_flags |= PMF_DUCKED;
}
else client->ps.pmove.pm_flags |= PMF_DUCKED;
}
if(!(zc->battlemode & FIRE_SHIFT)) trace_priority = TRP_ALLKEEP; //“®‚©‚È‚¢
if(Bot_traceS(ent,target)
|| mywep == WEAP_BFG
|| mywep == WEAP_GRENADELAUNCHER) client->buttons |= BUTTON_ATTACK;
return;
}
zc->battlemode = 0;
}
//FIRE_RUSH ‚‚Á‚±‚Þ========================
if(zc->battlemode & FIRE_RUSH)
{
if(--zc->battlecount > 0)
{
mywep = Get_KindWeapon(client->pers.weapon);
if(1/*mywep == WEAP_BFG*/) CanUsewep(ent,WEAP_BFG);
aim *= 0.95;
Get_AimAngle(ent,aim,distance,mywep);
if(target->client->weaponstate == WEAPON_FIRING && ent->groundentity)
{
if(mywep == WEAP_BFG)
{
if(target->s.origin[2] > ent->s.origin[2]) client->ps.pmove.pm_flags |= PMF_DUCKED;
}
else client->ps.pmove.pm_flags |= PMF_DUCKED;
}
trace_priority = TRP_MOVEKEEP; //ŒãÞ<E28098>ˆ<CB86>
zc->moveyaw = ent->s.angles[YAW];
if(Bot_traceS(ent,target)) client->buttons |= BUTTON_ATTACK;
return;
}
zc->battlemode = 0;
}
//ŒãÞƒtƒ@ƒCƒA(”š”­‰ñ”ð)========================
if(zc->battlemode & FIRE_EXPAVOID)
{
if(--zc->battlecount > 0)
{
mywep = Get_KindWeapon(client->pers.weapon);
if(1/*mywep == WEAP_BFG*/) CanUsewep(ent,WEAP_BFG);
aim *= 0.95;
Get_AimAngle(ent,aim,distance,mywep);
if(target->client->weaponstate == WEAPON_FIRING && ent->groundentity)
{
if(mywep == WEAP_BFG)
{
if(target->s.origin[2] > ent->s.origin[2]) client->ps.pmove.pm_flags |= PMF_DUCKED;
}
else client->ps.pmove.pm_flags |= PMF_DUCKED;
}
trace_priority = TRP_MOVEKEEP; //ŒãÞ<E28098>ˆ<CB86>
zc->moveyaw = ent->s.angles[YAW] + 180;
if(zc->moveyaw > 180) zc->moveyaw -= 360;
if(Bot_traceS(ent,target)
|| mywep == WEAP_BFG
|| mywep == WEAP_GRENADELAUNCHER) client->buttons |= BUTTON_ATTACK;
return;
}
zc->battlemode = 0;
}
//aefƒtƒ@ƒCƒA(”š”­‰ñ”ð)========================
if(zc->battlemode & FIRE_BFG)
{
if(--zc->battlecount > 0)
{
mywep = Get_KindWeapon(client->pers.weapon);
if(1/*mywep == WEAP_BFG*/) CanUsewep(ent,WEAP_BFG);
aim *= 0.95;
Get_AimAngle(ent,aim,distance,mywep);
if(target->client->weaponstate == WEAPON_FIRING && ent->groundentity)
{
if(1/*mywep == WEAP_BFG*/)
{
if(target->s.origin[2] > ent->s.origin[2]) client->ps.pmove.pm_flags |= PMF_DUCKED;
}
else client->ps.pmove.pm_flags |= PMF_DUCKED;
}
trace_priority = TRP_ANGLEKEEP; //ŒãÞ<E28098>ˆ<CB86>
if(Bot_traceS(ent,target)
|| mywep == WEAP_BFG
|| mywep == WEAP_GRENADELAUNCHER) client->buttons |= BUTTON_ATTACK;
return;
}
zc->battlemode = 0;
}
//Œ‚‚Á‚Ä”ð“ï========================
if(zc->battlemode & FIRE_REFUGE)
{
if(--zc->battlecount > 0)
{
mywep = Get_KindWeapon(client->pers.weapon);
//CanUsewep(ent,WEAP_BFG);
aim *= 0.95;
Get_AimAngle(ent,aim,distance,mywep);
if(target->client->weaponstate == WEAPON_FIRING && ent->groundentity)
{
if(mywep == WEAP_BFG)
{
if(target->s.origin[2] > ent->s.origin[2]) client->ps.pmove.pm_flags |= PMF_DUCKED;
}
else client->ps.pmove.pm_flags |= PMF_DUCKED;
}
trace_priority = TRP_ANGLEKEEP; //“®‚©‚È‚¢
// trace_priority = TRP_ALLKEEP; //“®‚©‚È‚¢
if(Bot_traceS(ent,target)
|| mywep == WEAP_BFG
|| mywep == WEAP_GRENADELAUNCHER) client->buttons |= BUTTON_ATTACK;
return;
}
zc->battlemode = 0;
zc->routeindex -= 2;
}
if(!(client->zc.zccmbstt & CTS_ENEM_NSEE)
&& (zc->zcstate & STS_WAITSMASK2)
&& (target->s.origin[2] - ent->s.origin[2]) < -300)
{
if(k = CanUsewep(ent,WEAP_GRENADELAUNCHER))
{
mywep = Get_KindWeapon(client->pers.weapon);
Get_AimAngle(ent,aim,distance,mywep);
if((target->client->weaponstate == WEAPON_FIRING && ent->groundentity) || (zc->zcstate & STS_WAITSMASK2)) ent->client->ps.pmove.pm_flags |= PMF_DUCKED;
client->buttons |= BUTTON_ATTACK;
trace_priority = TRP_ANGLEKEEP;
return;
}
if(k = CanUsewep(ent,WEAP_GRENADES))
{
mywep = Get_KindWeapon(client->pers.weapon);
Get_AimAngle(ent,aim,distance,mywep);
if(target->client->weaponstate == WEAPON_FIRING && ent->groundentity) ent->client->ps.pmove.pm_flags |= PMF_DUCKED;
if(ent->client->weaponstate == WEAPON_READY ) client->buttons |= BUTTON_ATTACK;
trace_priority = TRP_ANGLEKEEP;
return;
}
}
//-----------------------------------------------------------------------
//“ÁŽêƒtƒ@ƒCƒAƒŠƒ“ƒO
//-----------------------------------------------------------------------
mywep = Get_KindWeapon(client->pers.weapon);
//<2F>¶‰E‰ñ”ðƒZƒbƒg========================
if(!(zc->battlemode & FIRE_SHIFT) && skill > (random() * skill) /*&& distance < 250*/
&& (30 * random()) < Bot[zc->botindex].param[BOP_OFFENCE])
{
k = false;
if(zc->route_trace && enewep != WEAP_RAILGUN)
{
for(i = zc->routeindex;i < (zc->routeindex + 10);i++)
{
if(i >= CurrentIndex) break;
if(Route[i].state == GRS_ITEMS)
{
if(Route[i].ent->solid == SOLID_TRIGGER)
{
k = true;
break;
}
}
}
}
if(!k)
{
Get_AimAngle(ent,aim,distance,mywep);
f =target->s.angles[YAW] - ent->s.angles[YAW];
if(f > 180)
{
f = -(360 - f);
}
if( f < -180)
{
f = -(f + 360);
}
//‰´ðÝÄ¢é<E2809A>I<EFBFBD>I
if(f <= -160)
{
zc->battlemode |= FIRE_SHIFT_L;
zc->battlesubcnt = 5 + (int)(16 * random());
}
else if(f >= 160)
{
zc->battlemode |= FIRE_SHIFT_R;
zc->battlesubcnt = 5 + (int)(16 * random());
}
}
}
//“Gªƒyƒ“ƒ^‚ð‚Æ‚Á‚Ä‚¢‚é========================
if((FFlg[skill] & FIRE_AVOIDINV)
&& target->client->invincible_framenum > level.framenum)
{
// mywep = Get_KindWeapon(client->pers.weapon);
Get_AimAngle(ent,aim,distance,mywep);
trace_priority = TRP_MOVEKEEP; //ŒãÞ<E28098>ˆ<CB86>
zc->moveyaw = ent->s.angles[YAW] + 180;
if(zc->moveyaw > 180) zc->moveyaw -= 360;
return;
}
//QuadŽžÌ<E2809A>ˆ<CB86>=================================
if((FFlg[skill] & FIRE_QUADUSE)
&& (ent->client->quad_framenum > level.framenum)
&& distance < 300)
{
j = false;
if(enewep < WEAP_MACHINEGUN || enewep == WEAP_GRENADES) j = true;
//Hyper Blaster
if(k = CanUsewep(ent,WEAP_HYPERBLASTER))
{
mywep = Get_KindWeapon(client->pers.weapon);
Get_AimAngle(ent,aim,distance,mywep);
client->buttons |= BUTTON_ATTACK;
trace_priority = TRP_ANGLEKEEP;
if(j)
{
zc->battlemode |= FIRE_RUSH;
zc->battlecount = 8 + (int)(10 * random());
}
return;
}
//Chain Gun
if(k = CanUsewep(ent,WEAP_CHAINGUN))
{
mywep = Get_KindWeapon(client->pers.weapon);
Get_AimAngle(ent,aim,distance,mywep);
client->buttons |= BUTTON_ATTACK;
trace_priority = TRP_ANGLEKEEP;
if(j)
{
zc->battlemode |= FIRE_RUSH;
zc->battlecount = 8 + (int)(10 * random());
}
return;
}
//Machine Gun
if(k = CanUsewep(ent,WEAP_MACHINEGUN))
{
mywep = Get_KindWeapon(client->pers.weapon);
Get_AimAngle(ent,aim,distance,mywep);
client->buttons |= BUTTON_ATTACK;
trace_priority = TRP_ANGLEKEEP;
if(j)
{
zc->battlemode |= FIRE_RUSH;
zc->battlecount = 8 + (int)(10 * random());
}
return;
}
//S-Shotgun
if(k = CanUsewep(ent,WEAP_SUPERSHOTGUN))
{
mywep = Get_KindWeapon(client->pers.weapon);
Get_AimAngle(ent,aim,distance,mywep);
client->buttons |= BUTTON_ATTACK;
trace_priority = TRP_ANGLEKEEP;
if(j)
{
zc->battlemode |= FIRE_RUSH;
zc->battlecount = 8 + (int)(10 * random());
}
return;
}
}
//ŒÁÄ“¦°é<E2809A>ˆ<CB86>=================================
if((FFlg[skill] & FIRE_REFUGE)
&& zc->battlemode == 0 && zc->route_trace && zc->routeindex > 1 )
{
j = false;
if(enewep >= WEAP_CHAINGUN && enewep != WEAP_GRENADES) j = true;
Get_RouteOrigin(zc->routeindex - 2,v);
if(fabs(v[2] - ent->s.origin[2]) < JumpMax && j)
{
mywep = Get_KindWeapon(client->pers.weapon);
if(mywep == WEAP_GRENADELAUNCHER
|| mywep == WEAP_ROCKETLAUNCHER
|| mywep == WEAP_PHALANX)
{
zc->battlemode |= FIRE_REFUGE; //ƒ<C692>[ƒhJˆÚ
zc->battlecount = 8 + (int)(10 * random());
trace_priority = TRP_ALLKEEP;
return;
}
}
}
//ƒgƒŒ<C692>[ƒXˆÈŠOÌƫɃOƒƒOƒðh®=================================
if(!zc->route_trace && distance < 100)
{
zc->battlemode |= FIRE_EXPAVOID; //ƒ<C692>[ƒhJˆÚ
zc->battlecount = 4 + (int)(8 * random());
trace_priority = TRP_ALLKEEP;
}
//-----------------------------------------------------------------------
//ƒvƒ‰ƒCƒIƒŠƒeƒB
//-----------------------------------------------------------------------
//BFG
if(distance > 200)
{
if(B_UseBfg(ent,target,enewep,aim,distance,skill)) goto FIRED;
}
for(i = 0;i < 3;i++)
{
mywep = Get_KindWeapon(client->pers.weapon);
if(i == 0 && zc->secwep_selected) continue;
//try to select secondary weapon
if(i == 0 && zc->secwep_selected) i = 1;
else if(i == 0 && foundedenemy < 3
&& target->health < 50 && !zc->secwep_selected
&& ent->health >= 50)
{
if((9 * random()) < Bot[zc->botindex].param[BOP_COMBATSKILL])
{
zc->secwep_selected = 2;
i = 1;
}
}
if(i == 2)
{
if(zc->secwep_selected)
{
zc->secwep_selected = 0;
j = 0;
}
else break;
}
else j = i;
if(distance > 100 && (mywep == WEAP_BFG || random() < 0.5))
{
if(B_UseBfg(ent,target,enewep,aim,distance,skill)) goto FIRED;
}
switch(Bot[zc->botindex].param[BOP_PRIWEP + j])
{
case WEAP_BFG:
if(distance > 100)
{
if(B_UseBfg(ent,target,enewep,aim,distance,skill)) goto FIRED;
}
break;
case WEAP_HYPERBLASTER:
if(distance < 1200)
{
if(B_UseHyperBlaster(ent,target,enewep,aim,distance,skill)) goto FIRED;
}
break;
case WEAP_PHALANX:
if(distance > 100 && distance < 1200/*|| mywep == WEAP_PHALANX*/)
{
if(B_UsePhalanx(ent,target,enewep,aim,distance,skill)) goto FIRED;
}
break;
case WEAP_ROCKETLAUNCHER:
if(distance > 100 && distance < 1200/*|| mywep == WEAP_ROCKETLAUNCHER*/)
{
if(B_UseRocket(ent,target,enewep,aim,distance,skill)) goto FIRED;
}
break;
case WEAP_BOOMER:
if(distance < 1200)
{
if(B_UseBoomer(ent,target,enewep,aim,distance,skill)) goto FIRED;
}
break;
case WEAP_RAILGUN:
if(distance < 1200)
{
if(B_UseRailgun(ent,target,enewep,aim,distance,skill)) goto FIRED;
}
break;
case WEAP_GRENADELAUNCHER:
if(distance > 100 && distance < 400 && (target->s.origin[2] - ent->s.origin[2]) < 200)
{
if(B_UseGrenadeLauncher(ent,target,enewep,aim,distance,skill)) goto FIRED;
}
break;
case WEAP_CHAINGUN:
case WEAP_MACHINEGUN:
if(distance < 1200)
{
if(B_UseChainGun(ent,target,enewep,aim,distance,skill)) goto FIRED;
}
if(distance < 1200)
{
if(B_UseMachineGun(ent,target,enewep,aim,distance,skill)) goto FIRED;
}
break;
case WEAP_SUPERSHOTGUN:
case WEAP_SHOTGUN:
if(distance < 1200)
{
if(B_UseSuperShotgun(ent,target,enewep,aim,distance,skill)) goto FIRED;
}
if(distance < 1200)
{
if(B_UseShotgun(ent,target,enewep,aim,distance,skill)) goto FIRED;
}
case WEAP_GRENADES:
if(distance < 1200)
{
if(B_UseHandGrenade(ent,target,enewep,aim,distance,skill)) goto FIRED;
}
break;
default:
break;
}
}
//-----------------------------------------------------------------------
//Ê<E28099>íƒtƒ@ƒCƒAƒŠƒ“ƒO
//-----------------------------------------------------------------------
zc->secwep_selected = 0;
//BFG
if(distance > 200)
{
if(B_UseBfg(ent,target,enewep,aim,distance,skill)) goto FIRED;
}
//Hyper Blaster
if(distance < 1200)
{
if(B_UseHyperBlaster(ent,target,enewep,aim,distance,skill)) goto FIRED;
}
//Phalanx
if((distance > 100 && distance < 1200)/*|| mywep == WEAP_PHALANX*/)
{
if(B_UsePhalanx(ent,target,enewep,aim,distance,skill)) goto FIRED;
}
//Rocket
if((distance > 100 && distance < 1200)/*|| mywep == WEAP_ROCKETLAUNCHER*/)
{
if(B_UseRocket(ent,target,enewep,aim,distance,skill)) goto FIRED;
}
//Boomer
if(distance < 1200)
{
if(B_UseBoomer(ent,target,enewep,aim,distance,skill)) goto FIRED;
}
//Railgun
if(distance < 1200)
{
if(B_UseRailgun(ent,target,enewep,aim,distance,skill)) goto FIRED;
}
//Grenade Launcher
if(distance > 100 && distance < 400 && (target->s.origin[2] - ent->s.origin[2]) < 200)
{
if(B_UseGrenadeLauncher(ent,target,enewep,aim,distance,skill)) goto FIRED;
}
//Chain Gun
if(distance < 1200)
{
if(B_UseChainGun(ent,target,enewep,aim,distance,skill)) goto FIRED;
}
//Machine Gun
if(distance < 1200)
{
if(B_UseMachineGun(ent,target,enewep,aim,distance,skill)) goto FIRED;
}
//S-Shotgun
if(distance < 1200)
{
if(B_UseSuperShotgun(ent,target,enewep,aim,distance,skill)) goto FIRED;
}
if((FFlg[skill] & FIRE_IGNORE)
&& distance > 400 && ent->groundentity
&& !(zc->zcstate & STS_WAITSMASK))
{
zc->battlemode = FIRE_IGNORE;
zc->battlecount = 5 + (int)(10 * random());
}
//Shotgun
if(distance < 1200)
{
if(B_UseShotgun(ent,target,enewep,aim,distance,skill)) goto FIRED;
}
//Hand Grenade
if(distance < 400)
{
if(B_UseHandGrenade(ent,target,enewep,aim,distance,skill)) goto FIRED;
}
//Trap
if(distance < 400)
{
if(B_UseTrap(ent,target,enewep,aim,distance,skill)) goto FIRED;
}
//Blaster
if(distance < 1200)
{
if(B_UseBlaster(ent,target,enewep,aim,distance,skill)) goto FIRED;
}
VectorSubtract(zc->vtemp,ent->s.origin,v);
ent->s.angles[YAW] = Get_yaw(v);
ent->s.angles[PITCH] = Get_pitch(v);
trace_priority = TRP_ANGLEKEEP;
return;
FIRED:
if(zc->secwep_selected == 2) zc->secwep_selected = 1;
//ƒ`ƒLƒ“âë¤========================
if(zc->battlemode == FIRE_CHIKEN)
{
if(--zc->battlesubcnt > 0 && ent->groundentity && ent->waterlevel < 2)
{
f =target->s.angles[YAW] - ent->s.angles[YAW];
if(f > 180)
{
f = -(360 - f);
}
if( f < -180)
{
f = -(f + 360);
}
if(fabs(f) >= 150)
{
zc->battlemode = 0;
}
else
{
if(client->weaponstate != WEAPON_READY
&& target->s.origin[2] < ent->s.origin[2] )
{
if(mywep == WEAP_ROCKETLAUNCHER
|| mywep == WEAP_PHALANX
|| mywep == WEAP_GRENADELAUNCHER
|| mywep == WEAP_RAILGUN)
client->ps.pmove.pm_flags |= PMF_DUCKED;
else if(Bot[zc->botindex].param[BOP_COMBATSKILL] >= 7)
{
if(mywep == WEAP_SHOTGUN
|| mywep == WEAP_SUPERSHOTGUN
|| mywep == WEAP_BLASTER)
client->ps.pmove.pm_flags |= PMF_DUCKED;
}
}
trace_priority = TRP_ALLKEEP;
}
return;
}
else zc->battlemode = 0;
}
else if(zc->battlemode == 0 && distance > 200
&& ent->groundentity && ent->waterlevel < 2
&& (9 * random()) > Bot[zc->botindex].param[BOP_OFFENCE])
{
mywep = Get_KindWeapon(client->pers.weapon);
if(mywep > WEAP_BLASTER && target->client->zc.first_target != ent)
{
f =target->s.angles[YAW] - ent->s.angles[YAW];
if(f > 180)
{
f = -(360 - f);
}
if( f < -180)
{
f = -(f + 360);
}
if(fabs(f) < 150)
{
zc->battlemode = FIRE_CHIKEN;
zc->battlesubcnt = 5 + (int)(random() * 8);
trace_priority = TRP_ALLKEEP;
}
}
}
}
void UsePrimaryWeapon(edict_t *ent)
{
int mywep = Get_KindWeapon(ent->client->pers.weapon);
if(CanUsewep(ent,WEAP_BFG)) return;
CanUsewep(ent,Bot[ent->client->zc.botindex].param[BOP_PRIWEP]);
}
/*------------------------------------------------------------------------------*/
void UpdateExplIndex(edict_t* ent)
{
int i;
qboolean mod = false;
for(i = 0;i < MAX_EXPLINDEX;i++)
{
if(ExplIndex[i] != NULL) {if(ExplIndex[i]->inuse == false) ExplIndex[i] = NULL;}
if(!mod && ExplIndex[i] == NULL) {ExplIndex[i] = ent;mod = true;}
}
}