9 Commits

Author SHA1 Message Date
b3967606f4 small fixes 2024-04-04 16:54:29 -06:00
fcd130a132 update bones 2024-04-04 15:38:50 -06:00
f39a4d008c waittillframeend for event 2024-03-12 14:58:28 -06:00
cff61ab690 modwarfare support 2024-01-20 00:17:29 -06:00
f044af8aea update gsc version 2024-01-18 15:08:18 -06:00
1d464fca49 check for target knife 2024-01-18 14:53:07 -06:00
538269517a Merge branch 'master' of github.com:ineedbots/iw3_bot_warfare 2024-01-18 14:13:04 -06:00
9efda21175 move scripts to mp folder 2024-01-18 14:13:01 -06:00
f536f2b65d Update main.yml 2024-01-15 15:26:03 -06:00
12 changed files with 127 additions and 65 deletions

View File

@ -13,7 +13,9 @@ jobs:
- name: Setup gsc-tool - name: Setup gsc-tool
uses: xensik/setup-gsc-tool@v1 uses: xensik/setup-gsc-tool@v1
with:
version: '1.4.0'
- name: Compile test script - name: Compile test script
run: | run: |
gsc-tool.exe parse iw5 pc . gsc-tool.exe -m parse -g iw5 -s pc .

View File

@ -8,7 +8,7 @@
*/ */
init() init()
{ {
level.bw_version = "2.1.0"; level.bw_version = "2.2.0";
if ( getdvar( "bots_main" ) == "" ) if ( getdvar( "bots_main" ) == "" )
{ {

View File

@ -485,7 +485,7 @@ IsWeapSniper( weap )
return false; return false;
} }
if ( maps\mp\gametypes\_missions::getweaponclass( weap ) != "weapon_sniper" ) if ( getweaponclass( weap ) != "weapon_sniper" )
{ {
return false; return false;
} }
@ -556,6 +556,12 @@ onWeaponChange()
{ {
first = false; first = false;
newWeapon = self getcurrentweapon(); newWeapon = self getcurrentweapon();
// hack fix for botstop overridding weapon
if ( newWeapon != "none" )
{
self switchtoweapon( newWeapon );
}
} }
else else
{ {
@ -902,20 +908,23 @@ updateBones()
{ {
self endon( "disconnect" ); self endon( "disconnect" );
self endon( "death" ); self endon( "death" );
bones = strtok( self.pers[ "bots" ][ "skill" ][ "bones" ], "," );
waittime = self.pers[ "bots" ][ "skill" ][ "bone_update_interval" ];
for ( ;; ) for ( ;; )
{ {
self waittill_notify_or_timeout( "new_enemy", waittime ); oldbones = self.pers[ "bots" ][ "skill" ][ "bones" ];
bones = strtok( oldbones, "," );
if ( !isdefined( self.bot.target ) )
while ( oldbones == self.pers[ "bots" ][ "skill" ][ "bones" ] )
{ {
continue; self waittill_notify_or_timeout( "new_enemy", self.pers[ "bots" ][ "skill" ][ "bone_update_interval" ] );
if ( !isdefined( self.bot.target ) )
{
continue;
}
self.bot.target.bone = random( bones );
} }
self.bot.target.bone = random( bones );
} }
} }
@ -1024,6 +1033,23 @@ targetObjUpdateNoTrace( obj )
obj.didlook = false; obj.didlook = false;
} }
/*
Returns true if myEye can see the bone of self
*/
checkTraceForBone( myEye, bone )
{
boneLoc = self gettagorigin( bone );
if ( !isdefined( boneLoc ) )
{
return false;
}
trace = bullettrace( myEye, boneLoc, false, undefined );
return ( sighttracepassed( myEye, boneLoc, false, undefined ) && ( trace[ "fraction" ] >= 1.0 || trace[ "surfacetype" ] == "glass" ) );
}
/* /*
The main target thread, will update the bot's main target. Will auto target enemy players and handle script targets. The main target thread, will update the bot's main target. Will auto target enemy players and handle script targets.
*/ */
@ -1135,21 +1161,9 @@ target_loop()
continue; continue;
} }
targetHead = player gettagorigin( "j_head" ); canTargetPlayer = ( ( player checkTraceForBone( myEye, "j_head" ) ||
targetAnkleLeft = player gettagorigin( "j_ankle_le" ); player checkTraceForBone( myEye, "j_ankle_le" ) ||
targetAnkleRight = player gettagorigin( "j_ankle_ri" ); player checkTraceForBone( myEye, "j_ankle_ri" ) )
traceHead = bullettrace( myEye, targetHead, false, undefined );
traceAnkleLeft = bullettrace( myEye, targetAnkleLeft, false, undefined );
traceAnkleRight = bullettrace( myEye, targetAnkleRight, false, undefined );
canTargetPlayer = ( ( sighttracepassed( myEye, targetHead, false, undefined ) ||
sighttracepassed( myEye, targetAnkleLeft, false, undefined ) ||
sighttracepassed( myEye, targetAnkleRight, false, undefined ) )
&& ( ( traceHead[ "fraction" ] >= 1.0 || traceHead[ "surfacetype" ] == "glass" ) ||
( traceAnkleLeft[ "fraction" ] >= 1.0 || traceAnkleLeft[ "surfacetype" ] == "glass" ) ||
( traceAnkleRight[ "fraction" ] >= 1.0 || traceAnkleRight[ "surfacetype" ] == "glass" ) )
&& ( SmokeTrace( myEye, player.origin, level.smokeradius ) || && ( SmokeTrace( myEye, player.origin, level.smokeradius ) ||
daDist < level.bots_maxknifedistance * 4 ) daDist < level.bots_maxknifedistance * 4 )
@ -1508,7 +1522,7 @@ aim_loop()
} }
else if ( curweap != "none" && weaponclass( curweap ) == "grenade" ) else if ( curweap != "none" && weaponclass( curweap ) == "grenade" )
{ {
if ( maps\mp\gametypes\_missions::getweaponclass( curweap ) == "weapon_projectile" ) if ( getweaponclass( curweap ) == "weapon_projectile" )
{ {
nadeAimOffset = dist / 16000; nadeAimOffset = dist / 16000;
} }
@ -1582,7 +1596,7 @@ aim_loop()
conedot = getConeDot( aimpos, eyePos, angles ); conedot = getConeDot( aimpos, eyePos, angles );
if ( isdefined( self.bot.knifing_target ) ) if ( isdefined( self.bot.knifing_target ) && self.bot.knifing_target == target )
{ {
self thread bot_lookat( target gettagorigin( "j_spine4" ), 0.05 ); self thread bot_lookat( target gettagorigin( "j_spine4" ), 0.05 );
} }
@ -1680,7 +1694,7 @@ aim_loop()
} }
else if ( curweap != "none" && weaponclass( curweap ) == "grenade" ) else if ( curweap != "none" && weaponclass( curweap ) == "grenade" )
{ {
if ( maps\mp\gametypes\_missions::getweaponclass( curweap ) == "weapon_projectile" ) if ( getweaponclass( curweap ) == "weapon_projectile" )
{ {
nadeAimOffset = dist / 16000; nadeAimOffset = dist / 16000;
} }
@ -1773,6 +1787,7 @@ aim()
for ( ;; ) for ( ;; )
{ {
wait 0.05; wait 0.05;
waittillframeend;
if ( level.inprematchperiod || level.gameended || self.bot.isfrozen || self maps\mp\_flashgrenades::isflashbanged() ) if ( level.inprematchperiod || level.gameended || self.bot.isfrozen || self maps\mp\_flashgrenades::isflashbanged() )
{ {
@ -1954,9 +1969,9 @@ walk_loop()
dist = 16; dist = 16;
if ( level.waypointcount ) if ( level.waypoints.size )
{ {
goal = level.waypoints[ randomint( level.waypointcount ) ].origin; goal = level.waypoints[ randomint( level.waypoints.size ) ].origin;
} }
else else
{ {

View File

@ -347,6 +347,21 @@ classWatch()
if ( !maps\mp\gametypes\_globallogic::isvalidclass( self.class ) || !isdefined( self.bot_change_class ) ) if ( !maps\mp\gametypes\_globallogic::isvalidclass( self.class ) || !isdefined( self.bot_change_class ) )
{ {
// mod warfare shtuff
if ( isdefined( level.serverdvars ) )
{
a = [];
a[ a.size ] = "assault";
a[ a.size ] = "specops";
a[ a.size ] = "heavygunner";
a[ a.size ] = "demolitions";
a[ a.size ] = "sniper";
self notify( "menuresponse", game[ "menu_changeclass_" + self.pers[ "team" ] ], random( a ) );
wait 0.5;
}
self notify( "menuresponse", game[ "menu_changeclass" ], self chooseRandomClass() ); self notify( "menuresponse", game[ "menu_changeclass" ], self chooseRandomClass() );
} }

View File

@ -426,12 +426,22 @@ BotStopMoving( what )
} }
} }
/*
Waits till frame end so that if two notifies happen in the same frame, the other will not be missed.
*/
BotNotifyBotEvent_( msg, a, b, c, d, e, f, g )
{
self endon( "disconnect" );
waittillframeend; // wait for the waittills to setup again
self notify( "bot_event", msg, a, b, c, d, e, f, g );
}
/* /*
Notify the bot chat message Notify the bot chat message
*/ */
BotNotifyBotEvent( msg, a, b, c, d, e, f, g ) BotNotifyBotEvent( msg, a, b, c, d, e, f, g )
{ {
self notify( "bot_event", msg, a, b, c, d, e, f, g ); self thread BotNotifyBotEvent_( msg, a, b, c, d, e, f, g );
} }
/* /*
@ -1029,6 +1039,22 @@ isItemUnlocked( what, lvl )
} }
} }
/*
ModWarfare removes this func from _missions
*/
getweaponclass( weapon )
{
tokens = strtok( weapon, "_" );
weaponClass = tablelookup( "mp/statstable.csv", 4, tokens[ 0 ], 2 );
if ( ismg( weapon ) )
{
weaponClass = "weapon_mg";
}
return weaponClass;
}
/* /*
If the weapon is allowed to be dropped If the weapon is allowed to be dropped
*/ */
@ -1724,7 +1750,6 @@ load_waypoints()
{ {
mapname = getdvar( "mapname" ); mapname = getdvar( "mapname" );
level.waypointcount = 0;
level.waypointusage = []; level.waypointusage = [];
level.waypointusage[ "allies" ] = []; level.waypointusage[ "allies" ] = [];
level.waypointusage[ "axis" ] = []; level.waypointusage[ "axis" ] = [];
@ -1771,9 +1796,7 @@ load_waypoints()
BotBuiltinPrintConsole( "No waypoints loaded!" ); BotBuiltinPrintConsole( "No waypoints loaded!" );
} }
level.waypointcount = level.waypoints.size; for ( i = level.waypoints.size - 1; i >= 0; i-- )
for ( i = 0; i < level.waypointcount; i++ )
{ {
if ( !isdefined( level.waypoints[ i ].children ) || !isdefined( level.waypoints[ i ].children.size ) ) if ( !isdefined( level.waypoints[ i ].children ) || !isdefined( level.waypoints[ i ].children.size ) )
{ {
@ -1872,7 +1895,7 @@ getWaypointsOfType( type )
{ {
answer = []; answer = [];
for ( i = 0; i < level.waypointcount; i++ ) for ( i = level.waypoints.size - 1; i >= 0; i-- )
{ {
wp = level.waypoints[ i ]; wp = level.waypoints[ i ];
@ -2678,17 +2701,19 @@ RemoveWaypointUsage( wp, team )
{ {
return; return;
} }
wpstr = wp + "";
if ( !isdefined( level.waypointusage[ team ][ wp + "" ] ) ) if ( !isdefined( level.waypointusage[ team ][ wpstr ] ) )
{ {
return; return;
} }
level.waypointusage[ team ][ wp + "" ]--; level.waypointusage[ team ][ wpstr ]--;
if ( level.waypointusage[ team ][ wp + "" ] <= 0 ) if ( level.waypointusage[ team ][ wpstr ] <= 0 )
{ {
level.waypointusage[ team ][ wp + "" ] = undefined; level.waypointusage[ team ][ wpstr ] = undefined;
} }
} }
@ -2700,7 +2725,7 @@ GetNearestWaypointWithSight( pos )
candidate = undefined; candidate = undefined;
dist = 2147483647; dist = 2147483647;
for ( i = 0; i < level.waypointcount; i++ ) for ( i = level.waypoints.size - 1; i >= 0; i-- )
{ {
if ( !bullettracepassed( pos + ( 0, 0, 15 ), level.waypoints[ i ].origin + ( 0, 0, 15 ), false, undefined ) ) if ( !bullettracepassed( pos + ( 0, 0, 15 ), level.waypoints[ i ].origin + ( 0, 0, 15 ), false, undefined ) )
{ {
@ -2729,7 +2754,7 @@ getNearestWaypoint( pos )
candidate = undefined; candidate = undefined;
dist = 2147483647; dist = 2147483647;
for ( i = 0; i < level.waypointcount; i++ ) for ( i = level.waypoints.size - 1; i >= 0; i-- )
{ {
curdis = distancesquared( level.waypoints[ i ].origin, pos ); curdis = distancesquared( level.waypoints[ i ].origin, pos );
@ -2814,7 +2839,8 @@ AStarSearch( start, goal, team, greedy_path )
// pop bestnode from queue // pop bestnode from queue
bestNode = open.data[ 0 ]; bestNode = open.data[ 0 ];
open HeapRemove(); open HeapRemove();
openset[ bestNode.index + "" ] = undefined; bestNodeStr = bestNode.index + "";
openset[ bestNodeStr ] = undefined;
wp = level.waypoints[ bestNode.index ]; wp = level.waypoints[ bestNode.index ];
// check if we made it to the goal // check if we made it to the goal
@ -2824,14 +2850,16 @@ AStarSearch( start, goal, team, greedy_path )
while ( isdefined( bestNode ) ) while ( isdefined( bestNode ) )
{ {
bestNodeStr = bestNode.index + "";
if ( isdefined( team ) && isdefined( level.waypointusage ) ) if ( isdefined( team ) && isdefined( level.waypointusage ) )
{ {
if ( !isdefined( level.waypointusage[ team ][ bestNode.index + "" ] ) ) if ( !isdefined( level.waypointusage[ team ][ bestNodeStr ] ) )
{ {
level.waypointusage[ team ][ bestNode.index + "" ] = 0; level.waypointusage[ team ][ bestNodeStr ] = 0;
} }
level.waypointusage[ team ][ bestNode.index + "" ]++; level.waypointusage[ team ][ bestNodeStr ]++;
} }
// construct path // construct path
@ -2847,6 +2875,7 @@ AStarSearch( start, goal, team, greedy_path )
for ( i = wp.children.size - 1; i >= 0; i-- ) for ( i = wp.children.size - 1; i >= 0; i-- )
{ {
child = wp.children[ i ]; child = wp.children[ i ];
childStr = child + "";
childWp = level.waypoints[ child ]; childWp = level.waypoints[ child ];
penalty = 1; penalty = 1;
@ -2855,9 +2884,9 @@ AStarSearch( start, goal, team, greedy_path )
{ {
temppen = 1; temppen = 1;
if ( isdefined( level.waypointusage[ team ][ child + "" ] ) ) if ( isdefined( level.waypointusage[ team ][ childStr ] ) )
{ {
temppen = level.waypointusage[ team ][ child + "" ]; // consider how many bots are taking this path temppen = level.waypointusage[ team ][ childStr ]; // consider how many bots are taking this path
} }
if ( temppen > 1 ) if ( temppen > 1 )
@ -2876,16 +2905,16 @@ AStarSearch( start, goal, team, greedy_path )
newg = bestNode.g + distancesquared( wp.origin, childWp.origin ) * penalty; // bots on same team's path are more expensive newg = bestNode.g + distancesquared( wp.origin, childWp.origin ) * penalty; // bots on same team's path are more expensive
// check if this child is in open or close with a g value less than newg // check if this child is in open or close with a g value less than newg
inopen = isdefined( openset[ child + "" ] ); inopen = isdefined( openset[ childStr ] );
if ( inopen && openset[ child + "" ].g <= newg ) if ( inopen && openset[ childStr ].g <= newg )
{ {
continue; continue;
} }
inclosed = isdefined( closed[ child + "" ] ); inclosed = isdefined( closed[ childStr ] );
if ( inclosed && closed[ child + "" ].g <= newg ) if ( inclosed && closed[ childStr ].g <= newg )
{ {
continue; continue;
} }
@ -2894,11 +2923,11 @@ AStarSearch( start, goal, team, greedy_path )
if ( inopen ) if ( inopen )
{ {
node = openset[ child + "" ]; node = openset[ childStr ];
} }
else if ( inclosed ) else if ( inclosed )
{ {
node = closed[ child + "" ]; node = closed[ childStr ];
} }
else else
{ {
@ -2914,19 +2943,19 @@ AStarSearch( start, goal, team, greedy_path )
// check if in closed, remove it // check if in closed, remove it
if ( inclosed ) if ( inclosed )
{ {
closed[ child + "" ] = undefined; closed[ childStr ] = undefined;
} }
// check if not in open, add it // check if not in open, add it
if ( !inopen ) if ( !inopen )
{ {
open HeapInsert( node ); open HeapInsert( node );
openset[ child + "" ] = node; openset[ childStr ] = node;
} }
} }
// done with children, push onto closed // done with children, push onto closed
closed[ bestNode.index + "" ] = bestNode; closed[ bestNodeStr ] = bestNode;
} }
return []; return [];

View File

@ -461,6 +461,7 @@ LoadWaypoints()
self deleteAllWaypoints(); self deleteAllWaypoints();
self iprintlnbold( "Loading WPS..." ); self iprintlnbold( "Loading WPS..." );
load_waypoints(); load_waypoints();
level.waypointcount = level.waypoints.size;
wait 1; wait 1;

View File

@ -17,11 +17,11 @@ CodeCallback_StartGameType()
level.gametypestarted = true; // so we know that the gametype has been started up level.gametypestarted = true; // so we know that the gametype has been started up
level thread scripts\bots_adapter_cod4x::init(); level thread scripts\mp\bots_adapter_cod4x::init();
level thread scripts\bots_chat::init(); level thread scripts\mp\bots_chat::init();
level thread scripts\bots_menu::init(); level thread scripts\mp\bots_menu::init();
level thread scripts\bots_wp_editor::init(); level thread scripts\mp\bots_wp_editor::init();
level thread scripts\bots::init(); level thread scripts\mp\bots::init();
} }
} }