1
0
mirror of https://github.com/ineedbots/iw5_bot_warfare.git synced 2025-07-07 19:11:48 +00:00

Compare commits

13 Commits

Author SHA1 Message Date
c8df9ef311 cleanup 2024-04-05 14:11:28 -06:00
0b22a6b8a6 small fix 2024-04-04 17:02:46 -06:00
60a8f65180 update bones 2024-04-04 14:51:37 -06:00
5719080f45 update bones 2024-04-04 14:38:55 -06:00
1bf8314acd Cleanup trace for bones
Cleanup waypointcount
cleanup str concat
2024-04-04 13:19:51 -06:00
f31a306b0a missing 2024-03-20 15:24:20 -06:00
c4a222089c use options 2024-03-20 15:14:00 -06:00
a1651baa5a fix 2024-03-20 13:13:08 -06:00
748d261c02 add 2024-03-20 13:04:31 -06:00
06dfea7790 update 2024-03-20 13:04:27 -06:00
a9ea7acec3 pregsc 2024-03-20 12:57:08 -06:00
26a5adae13 waittillframeend bot events 2024-03-12 15:06:30 -06:00
a37aadfc2b Update README.md 2024-03-11 13:17:13 -06:00
10 changed files with 174 additions and 98 deletions

View File

@ -1,10 +1,10 @@
name: main name: gsc-tool
on: [push] on: [push]
jobs: jobs:
main-win: main-win:
name: Test on Windows name: Compile on Windows
runs-on: windows-latest runs-on: windows-latest
steps: steps:
@ -18,4 +18,4 @@ jobs:
- name: Run script - name: Run script
run: | run: |
ci/main.bat ci/gsc-tool.bat

16
.github/workflows/pregsc.ymloff vendored Normal file
View File

@ -0,0 +1,16 @@
name: pregsc
on: [push]
jobs:
main-win:
name: Run on Windows
runs-on: windows-latest
steps:
- name: Check out files
uses: actions/checkout@main
- name: Run script
run: |
ci/pregsc.bat

8
.gitignore vendored
View File

@ -1,8 +1,14 @@
*.zip *.zip
*.log *.log
*.stat *.stat
*.exe
*.gscbin
!ci/
out/
logs/ logs/
demos/ demos/
missingasset.csv missingasset.csv
*.exe
compiled/ compiled/
source/
pregsc/
pregsc.dat

View File

@ -87,7 +87,7 @@ You can find the ModDB release post [here](https://www.moddb.com/mods/bot-warfar
| bots_team_amount | When `bots_team` is set to `custom`. The amount of bots to be placed on the axis team. The remainder will be placed on the allies team. | 0 | | bots_team_amount | When `bots_team` is set to `custom`. The amount of bots to be placed on the axis team. The remainder will be placed on the allies team. | 0 |
| bots_team_force | If the server should force bots' teams according to the `bots_team` value. When `bots_team` is `autoassign`, unbalanced teams will be balanced. This dvar is ignored when `bots_team` is `custom`. | 0 | | bots_team_force | If the server should force bots' teams according to the `bots_team` value. When `bots_team` is `autoassign`, unbalanced teams will be balanced. This dvar is ignored when `bots_team` is `custom`. | 0 |
| bots_team_mode | When `bots_team_force` is `true` and `bots_team` is `autoassign`, players/bots counting method. <ul><li>`0` - counts both players and bots.</li><li>`1` - only counts bots</li></ul> | 0 | | bots_team_mode | When `bots_team_force` is `true` and `bots_team` is `autoassign`, players/bots counting method. <ul><li>`0` - counts both players and bots.</li><li>`1` - only counts bots</li></ul> | 0 |
| bots_skill | Bots' difficulty.<ul><li>`0` - Random difficulty for each bot.</li><li>`1` - Easiest difficulty for all bots.</li><li>`2` to `6` - Between easy and hard difficulty for all bots.</li><li>`7` - The hardest difficulty for all bots.</li><li>`8` - custom (look at the `bots_skill_<team>_<difficulty>` dvars</li></ul> | 0 | | bots_skill | Bots' difficulty.<ul><li>`0` - Random difficulty for each bot.</li><li>`1` - Easiest difficulty for all bots.</li><li>`2` to `6` - Between easy and hard difficulty for all bots.</li><li>`7` - The hardest difficulty for all bots.</li><li>`8` - custom (look at the `bots_skill_<team>_<difficulty>` dvars)</li></ul> | 0 |
| bots_skill_axis_hard | When `bots_skill` is set to `8`, the amount of hard difficulty bots to set on the axis team. | 0 | | bots_skill_axis_hard | When `bots_skill` is set to `8`, the amount of hard difficulty bots to set on the axis team. | 0 |
| bots_skill_axis_med | When `bots_skill` is set to `8`, the amount of medium difficulty bots to set on the axis team. The remaining bots on the team will be set to easy difficulty. | 0 | | bots_skill_axis_med | When `bots_skill` is set to `8`, the amount of medium difficulty bots to set on the axis team. The remaining bots on the team will be set to easy difficulty. | 0 |
| bots_skill_allies_hard | When `bots_skill` is set to `8`, the amount of hard difficulty bots to set on the allies team. | 0 | | bots_skill_allies_hard | When `bots_skill` is set to `8`, the amount of hard difficulty bots to set on the allies team. | 0 |
@ -115,7 +115,6 @@ You can find the ModDB release post [here](https://www.moddb.com/mods/bot-warfar
- v2.2.0 - v2.2.0
- Bots can now melee lunge - Bots can now melee lunge
- Fixed some chat related script runtime errors - Fixed some chat related script runtime errors
- Waypoints only load from csv now
- Fix bots possibly being stuck in sab - Fix bots possibly being stuck in sab
- Major cleanup - Major cleanup
@ -131,6 +130,7 @@ You can find the ModDB release post [here](https://www.moddb.com/mods/bot-warfar
- apdonato - http://rsebots.blogspot.ca/ - apdonato - http://rsebots.blogspot.ca/
- Ability - Ability
- Salvation - Salvation
- Xensik - https://github.com/xensik/gsc-tool
### Waypoint Creators ### Waypoint Creators
- FragsAreUs - https://github.com/FragsAreUs - FragsAreUs - https://github.com/FragsAreUs

6
ci/gsc-tool.bat Normal file
View File

@ -0,0 +1,6 @@
@echo off
xcopy /y .\ci\*.gscbin .\
rm .\scripts\mp\bots_adapter_piw5.gsc
gsc-tool.exe -m comp -g iw5 -s pc .\

View File

@ -1,6 +0,0 @@
@echo off
xcopy /y ci .
rm scripts\mp\bots_adapter_piw5.gsc
gsc-tool.exe -m comp -g iw5 -s pc .

10
ci/pregsc.bat Normal file
View File

@ -0,0 +1,10 @@
@echo off
if not exist ".\source\" mkdir .\source\
if not exist ".\source\scripts\" mkdir .\source\scripts\
if not exist ".\source\maps\" mkdir .\source\maps\
xcopy /y /s /e .\scripts\ .\source\scripts\
xcopy /y /s /e .\maps\ .\source\maps\
preGSC.exe -noforeach -nopause -infold .\source\ -outfold .\pregsc\

View File

@ -235,6 +235,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
{ {
@ -1177,12 +1183,14 @@ updateBones()
self endon( "disconnect" ); self endon( "disconnect" );
self endon( "spawned_player" ); self endon( "spawned_player" );
bones = strtok( self.pers[ "bots" ][ "skill" ][ "bones" ], "," );
waittime = self.pers[ "bots" ][ "skill" ][ "bone_update_interval" ];
for ( ;; ) for ( ;; )
{ {
self waittill_any_timeout( waittime, "new_enemy" ); oldbones = self.pers[ "bots" ][ "skill" ][ "bones" ];
bones = strtok( oldbones, "," );
while ( oldbones == self.pers[ "bots" ][ "skill" ][ "bones" ] )
{
self waittill_any_timeout( self.pers[ "bots" ][ "skill" ][ "bone_update_interval" ], "new_enemy" );
if ( !isalive( self ) ) if ( !isalive( self ) )
{ {
@ -1196,6 +1204,7 @@ updateBones()
self.bot.target.bone = random( bones ); self.bot.target.bone = random( bones );
} }
}
} }
/* /*
@ -1303,6 +1312,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.
*/ */
@ -1447,21 +1473,9 @@ target_loop()
} }
else else
{ {
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" ) )
&& ( ignoreSmoke || && ( ignoreSmoke ||
SmokeTrace( myEye, player.origin, level.smokeradius ) || SmokeTrace( myEye, player.origin, level.smokeradius ) ||
@ -2137,6 +2151,7 @@ aim()
for ( ;; ) for ( ;; )
{ {
wait 0.05; wait 0.05;
waittillframeend;
if ( !isalive( self ) ) if ( !isalive( self ) )
{ {
@ -2372,9 +2387,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

@ -356,12 +356,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 );
} }
/* /*
@ -1252,7 +1262,6 @@ readWpsFromFile( mapname )
*/ */
load_waypoints() load_waypoints()
{ {
level.waypointcount = 0;
level.waypointusage = []; level.waypointusage = [];
level.waypointusage[ "allies" ] = []; level.waypointusage[ "allies" ] = [];
level.waypointusage[ "axis" ] = []; level.waypointusage[ "axis" ] = [];
@ -1291,9 +1300,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 ) )
{ {
@ -1390,7 +1397,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 ];
@ -2107,16 +2114,18 @@ RemoveWaypointUsage( wp, team )
return; return;
} }
if ( !isdefined( level.waypointusage[ team ][ wp + "" ] ) ) wpstr = 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;
} }
} }
@ -2128,7 +2137,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 ) )
{ {
@ -2157,7 +2166,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 );
@ -2242,7 +2251,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
@ -2252,14 +2262,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
@ -2275,6 +2287,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;
@ -2283,9 +2296,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 )
@ -2304,16 +2317,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;
} }
@ -2322,11 +2335,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
{ {
@ -2342,19 +2355,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

@ -77,7 +77,7 @@ init()
level.waypoints = []; level.waypoints = [];
} }
level.waypointcount = 0; level.waypointcount = level.waypoints.size;
level waittill( "connected", player ); level waittill( "connected", player );
player thread onPlayerSpawned(); player thread onPlayerSpawned();
@ -153,29 +153,29 @@ watchAstarCommand()
self endon( "death" ); self endon( "death" );
self notifyonplayercommand( "astar", "+gostand" ); self notifyonplayercommand( "astar", "+gostand" );
self.astar = undefined;
for ( ;; ) for ( ;; )
{ {
self waittill( "astar" ); self waittill( "astar" );
if ( 1 ) if ( isdefined( self.astar ) )
{ {
continue; self iprintln( "Clear AStar" );
self.astar = undefined;
self waittill( "astar" );
} }
self iprintln( "Start AStar" ); self iprintln( "Start AStar" );
self.astar = undefined; self.astar = spawnstruct();
astar = spawnstruct(); self.astar.start = self.origin;
astar.start = self.origin;
self waittill( "astar" ); self waittill( "astar" );
self iprintln( "End AStar" ); self iprintln( "End AStar" );
astar.goal = self.origin; self.astar.goal = self.origin;
astar.nodes = AStarSearch( astar.start, astar.goal, undefined, true ); self.astar.nodes = AStarSearch( self.astar.start, self.astar.goal, undefined, true );
self iprintln( "AStar size: " + astar.nodes.size ); self iprintln( "AStar size: " + self.astar.nodes.size );
self.astar = astar;
} }
} }
@ -405,14 +405,28 @@ updateWaypointsStats()
if ( isdefined( self.astar ) ) if ( isdefined( self.astar ) )
{ {
// print3d(self.astar.start + (0, 0, 35), "start", (0,0,1), 2); if ( isdefined( self.astar.start ) )
// print3d(self.astar.goal + (0, 0, 35), "goal", (0,0,1), 2); {
// print3d( self.astar.start + ( 0, 0, 35 ), "start", ( 0, 0, 1 ), 2 );
if ( timeToUpdate ) if ( timeToUpdate )
{ {
drawPath( self.astar.start ); drawPath( self.astar.start );
drawPath( self.astar.goal ); }
} }
if ( isdefined( self.astar.goal ) )
{
// print3d( self.astar.goal + ( 0, 0, 35 ), "goal", ( 0, 0, 1 ), 2 );
if ( timeToUpdate )
{
drawPath( self.astar.goal );
}
}
if ( isdefined( self.astar.start ) && isdefined( self.astar.goal ) && isdefined( self.astar.nodes ) )
{
prev = self.astar.start + ( 0, 0, 35 ); prev = self.astar.start + ( 0, 0, 35 );
for ( i = self.astar.nodes.size - 1; i >= 0; i-- ) for ( i = self.astar.nodes.size - 1; i >= 0; i-- )
@ -431,6 +445,7 @@ updateWaypointsStats()
// line(prev, self.astar.goal + (0, 0, 35), (0,1,1)); // line(prev, self.astar.goal + (0, 0, 35), (0,1,1));
} }
} }
}
} }
watchLoadWaypointsCommand() watchLoadWaypointsCommand()
@ -646,6 +661,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;
@ -934,7 +950,7 @@ DeleteAllWaypoints()
self iprintln( "DelAllWps" ); self iprintln( "DelAllWps" );
} }
buildChildCountString ( wp ) buildChildCountString( wp )
{ {
if ( wp == -1 ) if ( wp == -1 )
{ {