diff --git a/.astylerc b/.astylerc index c0e7be1..4e00611 100644 --- a/.astylerc +++ b/.astylerc @@ -1,21 +1,27 @@ # try to mimic the original gsc provided +# mode=ghc mode=c style=allman -indent=tab +indent=force-tab=2 lineend=windows pad-oper pad-paren-in pad-header - -# delete-empty-lines +# pad-brackets-in +fill-empty-lines +squeeze-lines=2 +squeeze-ws +break-one-line-headers +add-braces +remove-comment-prefix break-blocks -# remove-braces indent-switches indent-cases indent-after-parens +indent-col1-comments remove-comment-prefix diff --git a/.editorconfig b/.editorconfig index bb97c78..be8eb14 100644 --- a/.editorconfig +++ b/.editorconfig @@ -4,7 +4,7 @@ root = true indent_style = tab indent_size = 2 charset = latin1 -trim_trailing_whitespace = true +trim_trailing_whitespace = false insert_final_newline = true [*.md] diff --git a/.vscode/settings.json b/.vscode/settings.json index 17fcd69..2f316e2 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -13,687 +13,3 @@ }, "vscode-codscript.use_builtin_completionItems": false } - -// use below to verify no single line blocks with no braces -// /^\s*(if|while|for|switch|else)(?!\w).*\s*[\r\n]+\s*[^\s{]/gm - -// use below to verify array indexing spacing style -// $ egrep -ron "(\[\S|\S\])" --include \*.gsc ./ | egrep -v "\[\[" | egrep -v "\]\]" | egrep -v "\[\]" | egrep -v "\[\{" | egrep -v "\}\]" - -// python script for casing fixes i did -/* -import sys -import re - -builtins = """ -assert -isdefined -println -getentitynumber -delete -spawnstruct -getdvar -setdvar -visionsetnaked -visionsetnight -int -setsunlight -gettime -assertex -isalive -assertmsg -issubstr -istouching -savegame~ -getdebugdvar -getarraykeys -print3d -getentarray -spawn -getorigin -setmodel -distance -vectortoangles -anglestoforward -vectordot -getaiarray -distancesquared -bloodimpact -isai -issentient -randomint -radiusdamage -activateclientexploder -deactivateclientexploder -playloopsound -connectpaths -hide -notsolid -show -solid -disconnectpaths -getent -physicslaunch -rotatevelocity -movegravity -ambientplay -getnode -shellshock -iswaitingonsound -linkto -playsound -stopsounds -stoploopsound -playsoundasmaster -iprintlnbold -useanimtree -getaispeciesarray -line -anglestoright -anglestoup -clearenemy -setfriendlychain -strtok -getvehiclenode -soundexists -newhudelem -setclock -missionfailed -randomfloatrange -clearfixednodesafevolume -tolower -playrumbleonentity -setflashbanged -getthreatbiasgroup -getentnum -createthreatbiasgroup -setthreatbiasgroup -setthreatbias -bullettrace -playerphysicstrace -unlink -precachestring -vectornormalize -settext -destroy -setshader -threatbiasgroupexists -setignoremegroup -getcurrentweapon -getfractionmaxammo -givemaxammo -getspawnerarray -isplayer -dodamage -dospawn -getdvarfloat -getspeedmph -setgoalentity -getplayerangles -playerlinkto -rotateto -playerlinktodelta -gettagorigin -gettagangles -stalingradspawn -setblur -setgoalnode -setgoalpos -objective_state -setanimrestart -getdvarint -fadeovertime -getplayerviewheight -setsaveddvar -stopanimscripted -setlightintensity -playerads -geteye -earthquake -getvelocity -playfx -setsoundblend -getweaponslist -getweaponammoclip -iscoopepd -giveachievement -issplitscreen -detach -musicplay -setvolfog -setculldist -splitviewallowed -getplayers -freezecontrols -setdoublevision -visionsetnaked -clientsysregister -clientsyssetstate -clientsyssetstate -getsnapshotindexarray -snapshotacknowledged -oktospawn -getturretowner -useby -stopusingturret -setorigin -setplayerangles -setvolfog -enableinvulnerability -disableweapons -newclienthudelem -enableweapons -disableinvulnerability -setprintchannel -randomfloat -openfile -fprintln -closefile -spawnfx -triggerfx -playfxontag -moveovertime -scaleovertime -clearanim -setanim -setproneanimnodes -setanimknoball -getattachsize -getattachmodelname -weaponclass -localtoworldcoords -getshootatpos -canshoot -getdebugdvarint -angleclamp180 -isstanceallowed -getweaponmodel -nearnode -floor -cos -sin -setflaggedanimknoballrestart -getanimlength -getdebugeye -orientmode -isingoal -useturret -setmode -shoot -randomintrange -stopshoot -bulletspread -issuppressed -cansee -sighttracepassed -abs -canattackenemynode -length -weaponisboltaction -weaponisgasweapon -weaponcliptype -enterprone -exitprone -isarray -getmovedelta -startragdoll -physicsexplosionsphere -setflaggedanimknoball -setanimknoblimited -setanimknob -getmotionangle -maymovetopoint -animhasnotetrack -setflaggedanimknob -setanimlimited -updateplayersightaccuracy -absangleclamp180 -getanimtime -weaponclipsize -getclosestenemysqdist -setflaggedanimknobrestart -hidepart -updateprone -getthreatbias -max -physicstrace -checkgrenadethrowpos -checkgrenadethrow -min -getattachtagname -throwgrenade -print -attach -magicgrenademanual -findbestcovernode -usecovernode -findreacquiredirectpath -findreacquireproximatepath -reacquiremove -badplace_cylinder -badplace_delete -getcurrentweaponclipammo -getflashbangedstrength -setflaggedanimknoblimitedrestart -logstring -setburn -startfadingblur -setnormalhealth -iprintln -changefontscaleovertime -getkeybinding -getscoremultiplier -setclientdvars -newscorehudelem -ban -coopinfo -setvalue -setscoremultiplier -playlocalsound -closemenu -closeingamemenu -setdepthoffield -resettimeout -stopshellshock -stoprumble -spawn -getcurrentarcadehighscore -uploadscore -loadfx -setcollectible -hascollectible -tablelookup -sethintstring -usetriggerrequirelookat -takeallweapons -giveweapon -allowsprint -setmovespeedscale -setclientdvar -visionsetberserker -disableberserker -enableberserker -unsetcollectible -switchtoweapon -getweaponammostock -setweaponammoclip -setweaponammostock -getweaponslistprimaries -takeweapon -switchtooffhand -precacheitem -allowjump -visionsetlaststand -weapontype -isthrowinggrenade -setcursorhint -enablelinkto -depthinwater -disableweaponcycling -disableoffhandweapons -enableweaponcycling -enableoffhandweapons -bullettracepassed -usebuttonpressed -hasperk -startrevive -stoprevive -reviveplayer -setrank -precacheshader -getstat -setstat -tablelookupistring -setstatbit -getsubstr -iprintlnbold -setpulsefx -weaponissemiauto -weaponfiretime -getweaponclipmodel -precachemodel -createprintchannel -precacheheadicon -precacheshellshock -precacherumble -watersimenable -getnodearray -detachall -itemweaponsetammo -setexploderid -transmittargetname -isweapondetonationtimed -allowprone -allowcrouch -allowstand -getallnodes -buttonpressed -changelevel -newdebughudelem -eqoff -eqon -allowads -setspreadoverride -resetspreadoverride -setmapcenter -numremoteclients -getspawnerteamarray -settimescale -getnumconnectedplayers -getnumexpectedplayers -dropweapon -animmode -asin -geteyeapprox -lengthsquared -getanglestolikelyenemypath -showpart -teleport -trackscriptstate -setflaggedanimlimited -setanimknoballrestart -sqrt -reacquirestep -findreacquirenode -getreacquirenode -usereacquirenode -flagenemyunattackable -getstance -animcustom -getnorthyaw -stopsound -getnotetracktimes -vectorcross -isgodmode -viewkick -getpersistentprofilevar -setpersistentprofilevar -updategamerprofile -meleebuttonpressed -setcandamage -clearpitchorient -setstance -playerlinktoabsolute -allowlean -allowmelee -enablehealthshield -hideviewmodel -showviewmodel -acos -findpath -settargetentity -cleartargetentity -isfiringturret -shootturret -stopfiring -startfiring -isturretactive -canuseturret -getdifficulty -getturrettarget -restoredefaultdroppitch -stopuseturret -getstartorigin -setruntopos -animscripted -maketurretunusable -setdefaultdroppitch -maketurretusable -isturretfiring -pushplayer -setgoalvolume -makefakeai -getstartangles -setanimknobrestart -setflaggedanim -setanimtime -setflaggedanimrestart -getvehicleowner -allowedstances -magicgrenade -weaponfightdist -getangledelta -playrumbleonposition -canspawnturret -spawnturret -getnegotiationstartnode -startcoverarrival -atan -checkcoverexitposwithpath -maymovefrompointtopoint -issaverecentlyloaded -musicstop -setexpfog -setswitchnode -setwaitnode -setspeed -clearlookatent -sethoverparams -setneargoalnotifydist -setairresistance -cleartargetyaw -setgoalyaw -cleargoalyaw -settargetyaw -attachpath -setspeedimmediate -startpath -spawnvehicle -setvehicleteam -freevehicle -clearturrettarget -setvehgoalpos -getspeed -resumespeed -getallvehiclenodes -setshadowhint -setturretteam -precacheturret -playrumblelooponentity -badplace_arc -fireweapon -addvehicletocompass -removevehiclefromcompass -getattachpos -dontinterpolate -precachevehicle -setlookatent -setturrettargetent -setenginevolume -joltbody -isragdoll -setwaitspeed -setturretignoregoals -getturret -makevehicleunusable -isturretready -setvehiclelookattext -clearalltextafterhudelem -devaddpitch -devaddyaw -devaddroll -isstring -playloopedfx -precachemenu -playerpositionvalid -allowspectateteam -finishplayerdamage -openmenu -reportclientdisconnected -setactionslot -setviewmodel -getcurrentoffhand -damageconetrace -detonate -distance2d -rotateyaw -modelhasphyspreset -launchragdoll -beginprediction -endprediction -getpartname -createdynentandlaunch -starttanning -weaponmountable -playsoundatposition -isbeingwatched -pointonsegmentnearesttopoint -predictanim -predictoriginandangles -gethitenttype -gethityaw -isdeflected -lerpposition -getvisionsetnaked -savegamenocommit -commitsave -issavesuccessful -ismeleeing -isfiring -deactivatereverb -setreverb -forcelevelend -makedvarserverinfo -exitlevel -getreflectionlocs -getreflectionorigin -setdebugangles -setdebugorigin -weaponbayonetinfo -hasusedweapon -getnumrestarts -setuinextlevel -missionsuccess -setmissiondvar -attackbuttonpressed -rotateroll -getlightintensity -setcontents -radiusdamage -vibrate -disableaimassist -enableaimassist -setfixednodesafevolume -isknownenemyinradius -isknownenemyinvolume -setlightcolor -getlightcolor -vectorlerp -pickupgrenade -startscriptedanim -spawncollision -rotatepitch -setelectrified -movez -isnotarget -hasweapon -setvisibletoplayer -bbprint -setvisibletoall -setinvisibletoplayer -weaponmaxammo -getammocount -isswitchingweapons -setperk -unsetperk -forceteleport -iprintln -cleargoalvolume -settalktospecies -setailimit -disablegrenadesuicide -adsbuttonpressed -playersetgroundreferenceent -isonground -resetmissiledetonationtime -settransported -setengagementmindist -setengagementmaxdist -setspawnerteam -traversemode -getnegotiationendnode -getnormalhealth -animrelative -getaivelocity -finishactordamage -isdedicated -getfunction -replacefunc -disabledetouronce -cmdexec -getguid -logprint -printconsole -isweaponcliponly -botaction -botstop -botmovement -botmeleeparams -generatepath -getmins -getmaxs -setallowedtraversals -setignoredlinks -getnodenumber -getlinkednodes -addtestclient -notifyonplayercommand -ishost -closer -""".split() - -if sys.argv[1] == '1': # checks for capitals in builtins - for fn in sys.argv[2:]: - whole_file = '' - - with open(fn, 'r') as file: - whole_file = file.read() - - seen = {} - file.seek(0) - for line in file: - toks = line.split() - - for tok in toks: - matches = re.findall(r'\w+', tok) - - for match in matches: - if any(char.isupper() for char in match) and match.lower() in builtins: - print(match, match.lower()) - whole_file = whole_file.replace(match, match.lower()) - - with open(fn, 'w') as file: - file.write(whole_file) -elif sys.argv[1] == '2': # checks for capital letters for field names - for fn in sys.argv[2:]: - whole_file = '' - - with open(fn, 'r') as file: - whole_file = file.read() - file.seek(0) - - for line in file: - toks = line.split() - - for tok in toks: - matches = re.findall(r'(\S+(\.\w+)+)', tok) - - for match in matches: - toks2 = match[0].split('.') - left = toks2[0] - - if left.isnumeric(): - continue - - right = '.'.join(toks2[1:]) - - if not any(char.isupper() for char in right): - continue - - print(match[0], left + '.' + right.lower()) - whole_file = whole_file.replace(match[0], left + '.' + right.lower()) - - with open(fn, 'w') as file: - file.write(whole_file) - -*/ diff --git a/maps/mp/bots/_bot.gsc b/maps/mp/bots/_bot.gsc index 0ea2ea3..d56df29 100644 --- a/maps/mp/bots/_bot.gsc +++ b/maps/mp/bots/_bot.gsc @@ -7,183 +7,183 @@ init() { level.bw_version = "2.1.0"; - + if ( getcvar( "bots_main" ) == "" ) { setcvar( "bots_main", true ); } - + if ( !getcvarint( "bots_main" ) ) { return; } - + if ( !wait_for_builtins() ) { println( "FATAL: NO BUILT-INS FOR BOTS" ); } - + thread load_waypoints(); thread hook_callbacks(); - + if ( getcvar( "bots_main_GUIDs" ) == "" ) { - setcvar( "bots_main_GUIDs", "" ); // guids of players who will be given host powers, comma seperated + setcvar( "bots_main_GUIDs", "" ); // guids of players who will be given host powers, comma seperated } - + if ( getcvar( "bots_main_firstIsHost" ) == "" ) { - setcvar( "bots_main_firstIsHost", true ); // first player to connect is a host + setcvar( "bots_main_firstIsHost", true ); // first player to connect is a host } - + if ( getcvar( "bots_main_waitForHostTime" ) == "" ) { - setcvar( "bots_main_waitForHostTime", 10.0 ); // how long to wait to wait for the host player + setcvar( "bots_main_waitForHostTime", 10.0 ); // how long to wait to wait for the host player } - + if ( getcvar( "bots_main_kickBotsAtEnd" ) == "" ) { - setcvar( "bots_main_kickBotsAtEnd", false ); // kicks the bots at game end + setcvar( "bots_main_kickBotsAtEnd", false ); // kicks the bots at game end } - + if ( getcvar( "bots_manage_add" ) == "" ) { - setcvar( "bots_manage_add", 0 ); // amount of bots to add to the game + setcvar( "bots_manage_add", 0 ); // amount of bots to add to the game } - + if ( getcvar( "bots_manage_fill" ) == "" ) { - setcvar( "bots_manage_fill", 0 ); // amount of bots to maintain + setcvar( "bots_manage_fill", 0 ); // amount of bots to maintain } - + if ( getcvar( "bots_manage_fill_spec" ) == "" ) { - setcvar( "bots_manage_fill_spec", true ); // to count for fill if player is on spec team + setcvar( "bots_manage_fill_spec", true ); // to count for fill if player is on spec team } - + if ( getcvar( "bots_manage_fill_mode" ) == "" ) { - setcvar( "bots_manage_fill_mode", 0 ); // fill mode, 0 adds everyone, 1 just bots, 2 maintains at maps, 3 is 2 with 1 + setcvar( "bots_manage_fill_mode", 0 ); // fill mode, 0 adds everyone, 1 just bots, 2 maintains at maps, 3 is 2 with 1 } - + if ( getcvar( "bots_manage_fill_kick" ) == "" ) { - setcvar( "bots_manage_fill_kick", false ); // kick bots if too many + setcvar( "bots_manage_fill_kick", false ); // kick bots if too many } - + if ( getcvar( "bots_team" ) == "" ) { - setcvar( "bots_team", "autoassign" ); // which team for bots to join + setcvar( "bots_team", "autoassign" ); // which team for bots to join } - + if ( getcvar( "bots_team_amount" ) == "" ) { - setcvar( "bots_team_amount", 0 ); // amount of bots on axis team + setcvar( "bots_team_amount", 0 ); // amount of bots on axis team } - + if ( getcvar( "bots_team_force" ) == "" ) { - setcvar( "bots_team_force", false ); // force bots on team + setcvar( "bots_team_force", false ); // force bots on team } - + if ( getcvar( "bots_team_mode" ) == "" ) { - setcvar( "bots_team_mode", 0 ); // counts just bots when 1 + setcvar( "bots_team_mode", 0 ); // counts just bots when 1 } - + if ( getcvar( "bots_skill" ) == "" ) { - setcvar( "bots_skill", 0 ); // 0 is random, 1 is easy 7 is hard, 8 is custom, 9 is completely random + setcvar( "bots_skill", 0 ); // 0 is random, 1 is easy 7 is hard, 8 is custom, 9 is completely random } - + if ( getcvar( "bots_skill_axis_hard" ) == "" ) { - setcvar( "bots_skill_axis_hard", 0 ); // amount of hard bots on axis team + setcvar( "bots_skill_axis_hard", 0 ); // amount of hard bots on axis team } - + if ( getcvar( "bots_skill_axis_med" ) == "" ) { setcvar( "bots_skill_axis_med", 0 ); } - + if ( getcvar( "bots_skill_allies_hard" ) == "" ) { setcvar( "bots_skill_allies_hard", 0 ); } - + if ( getcvar( "bots_skill_allies_med" ) == "" ) { setcvar( "bots_skill_allies_med", 0 ); } - + if ( getcvar( "bots_skill_min" ) == "" ) { setcvar( "bots_skill_min", 1 ); } - + if ( getcvar( "bots_skill_max" ) == "" ) { setcvar( "bots_skill_max", 7 ); } - + if ( getcvar( "bots_loadout_rank" ) == "" ) // what rank the bots should be around, -1 is around the players, 0 is all random { setcvar( "bots_loadout_rank", -1 ); } - + if ( getcvar( "bots_play_move" ) == "" ) // bots move { setcvar( "bots_play_move", true ); } - + if ( getcvar( "bots_play_knife" ) == "" ) // bots knife { setcvar( "bots_play_knife", true ); } - + if ( getcvar( "bots_play_fire" ) == "" ) // bots fire { setcvar( "bots_play_fire", true ); } - + if ( getcvar( "bots_play_nade" ) == "" ) // bots grenade { setcvar( "bots_play_nade", true ); } - + if ( getcvar( "bots_play_obj" ) == "" ) // bots play the obj { setcvar( "bots_play_obj", true ); } - + if ( getcvar( "bots_play_camp" ) == "" ) // bots camp and follow { setcvar( "bots_play_camp", true ); } - + if ( getcvar( "bots_play_jumpdrop" ) == "" ) // bots jump and dropshot { setcvar( "bots_play_jumpdrop", true ); } - + if ( getcvar( "bots_play_ads" ) == "" ) // bot ads { setcvar( "bots_play_ads", true ); } - + if ( getcvar( "bots_play_aim" ) == "" ) { setcvar( "bots_play_aim", true ); } - + if ( !isdefined( game[ "botWarfare" ] ) ) { game[ "botWarfare" ] = true; } - + level.defuseobject = undefined; level.bots_smokelist = List(); - + level.bots_mingrenadedistance = 256; level.bots_mingrenadedistance *= level.bots_mingrenadedistance; level.bots_maxgrenadedistance = 1024; @@ -197,12 +197,12 @@ init() level.bots_maxshotgundistance = 500; level.bots_maxshotgundistance *= level.bots_maxshotgundistance; level.bots_listendist = 100; - + level.smokeradius = 255; - + level.bots = []; level.players = []; - + level.bots_fullautoguns = []; level.bots_fullautoguns[ "greasegun" ] = true; level.bots_fullautoguns[ "thompson" ] = true; @@ -213,7 +213,7 @@ init() level.bots_fullautoguns[ "mp44" ] = true; level.bots_fullautoguns[ "ppsh" ] = true; level.bots_fullautoguns[ "mp40" ] = true; - + level.bots_weapon_clip_sizes = []; level.bots_weapon_clip_sizes[ "m1carbine_mp" ] = 15; level.bots_weapon_clip_sizes[ "m1garand_mp" ] = 8; @@ -240,7 +240,7 @@ init() level.bots_weapon_clip_sizes[ "luger_mp" ] = 8; level.bots_weapon_clip_sizes[ "tt30_mp" ] = 8; level.bots_weapon_clip_sizes[ "greasegun_mp" ] = 32; - + level.bots_weapon_class_names = []; level.bots_weapon_class_names[ "m1carbine_mp" ] = "rifle"; level.bots_weapon_class_names[ "m1garand_mp" ] = "rifle"; @@ -267,16 +267,16 @@ init() level.bots_weapon_class_names[ "luger_mp" ] = "pistol"; level.bots_weapon_class_names[ "tt30_mp" ] = "pistol"; level.bots_weapon_class_names[ "greasegun_mp" ] = "smg"; - + level thread fixGamemodes(); - + level thread onPlayerConnect(); level thread handleBots(); level thread watchNades(); level thread watchGameEnded(); - + level.teambased = true; - + if ( getcvar( "g_gametype" ) == "dm" ) { level.teambased = false; @@ -291,21 +291,21 @@ handleBots() level thread teamBots(); level thread diffBots(); level addBots(); - + while ( !level.mapended ) { wait 0.05; } - + setcvar( "bots_manage_add", getBotArray().size ); - + if ( !getcvarint( "bots_main_kickBotsAtEnd" ) ) { return; } - + bots = getBotArray(); - + for ( i = 0; i < bots.size; i++ ) { kick( bots[ i ] getentitynumber() ); @@ -322,7 +322,7 @@ onPlayerDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, self maps\mp\bots\_bot_internal::onDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, timeOffset ); self maps\mp\bots\_bot_script::onDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, timeOffset ); } - + self [[ level.prevcallbackplayerdamage ]]( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, timeOffset ); } @@ -336,7 +336,7 @@ onPlayerKilled( eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sH self maps\mp\bots\_bot_internal::onKilled( eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration ); self maps\mp\bots\_bot_script::onKilled( eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration ); } - + self [[ level.prevcallbackplayerkilled ]]( eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration ); } @@ -348,7 +348,7 @@ hook_callbacks() wait 0.05; level.prevcallbackplayerdamage = level.callbackplayerdamage; level.callbackplayerdamage = ::onPlayerDamage; - + level.prevcallbackplayerkilled = level.callbackplayerkilled; level.callbackplayerkilled = ::onPlayerKilled; } @@ -372,7 +372,7 @@ onPlayerConnect() for ( ;; ) { level waittill( "connected", player ); - + player thread onWeaponFired(); player thread connected(); player thread onDeath(); @@ -400,17 +400,17 @@ doPlayerModelFix() watchWeapons() { self endon( "disconnect" ); - + for ( ;; ) { weap = self getcurrentweapon(); self thread watchAmmoUsage( weap ); - + while ( weap == self getcurrentweapon() ) { wait 0.05; } - + self notify( "weapon_change", self getcurrentweapon() ); } } @@ -422,18 +422,18 @@ watchAmmoUsage( weap ) { self endon( "disconnect" ); self endon( "weapon_change" ); - + slot = self getWeaponSlot( weap ); - + for ( ;; ) { aCount = self getweaponslotclipammo( slot ); - + while ( aCount == self getweaponslotclipammo( slot ) ) { wait 0.05; } - + if ( self getweaponslotclipammo( slot ) < aCount ) { self notify( "weapon_fired" ); @@ -451,11 +451,11 @@ watchAmmoUsage( weap ) watchVars() { self endon( "disconnect" ); - + for ( ;; ) { self.team = self.pers[ "team" ]; - + wait 0.05; } } @@ -466,9 +466,9 @@ watchVars() watchVelocity() { self endon( "disconnect" ); - + lastOrigin = self.origin; - + for ( ;; ) { wait 0.05; @@ -488,7 +488,7 @@ killTags() { self.tags[ i ] delete(); } - + self.tags = undefined; self.tagmap = undefined; } @@ -500,11 +500,11 @@ killTags() onDeath() { self endon( "disconnect" ); - + for ( ;; ) { self waittill( "death" ); - + self killTags(); } } @@ -516,7 +516,7 @@ onDisconnectPlayer() { self waittill( "disconnect" ); self killTags(); - + level.players = array_remove( level.players, self ); } @@ -526,7 +526,7 @@ onDisconnectPlayer() onDisconnect() { self waittill( "disconnect" ); - + level.bots = array_remove( level.bots, self ); } @@ -536,40 +536,40 @@ onDisconnect() connected() { self endon( "disconnect" ); - + level.players[ level.players.size ] = self; self thread onDisconnectPlayer(); - + if ( !isdefined( self.pers[ "bot_host" ] ) ) { self thread doHostCheck(); } - + if ( !self is_bot() ) { return; } - + if ( !isdefined( self.pers[ "isBot" ] ) ) { // fast restart... self.pers[ "isBot" ] = true; } - + if ( !isdefined( self.pers[ "isBotWarfare" ] ) ) { self.pers[ "isBotWarfare" ] = true; self thread added(); } - + self thread maps\mp\bots\_bot_internal::connected(); self thread maps\mp\bots\_bot_script::connected(); - + level.bots[ level.bots.size ] = self; self thread onDisconnect(); - + level notify( "bot_connected", self ); - + self thread watchBotDebugEvent(); } @@ -579,50 +579,50 @@ connected() watchBotDebugEvent() { self endon( "disconnect" ); - + for ( ;; ) { self waittill( "bot_event", msg, str, b, c, d, e, f, g ); - + if ( getcvarint( "bots_main_debug" ) >= 2 ) { big_str = "Bot Warfare debug: " + self.name + ": " + msg; - + if ( isdefined( str ) && isstring( str ) ) { big_str += ", " + str; } - + if ( isdefined( b ) && isstring( b ) ) { big_str += ", " + b; } - + if ( isdefined( c ) && isstring( c ) ) { big_str += ", " + c; } - + if ( isdefined( d ) && isstring( d ) ) { big_str += ", " + d; } - + if ( isdefined( e ) && isstring( e ) ) { big_str += ", " + e; } - + if ( isdefined( f ) && isstring( f ) ) { big_str += ", " + f; } - + if ( isdefined( g ) && isstring( g ) ) { big_str += ", " + g; } - + BotBuiltinPrintConsole( big_str ); } else if ( msg == "debug" && getcvarint( "bots_main_debug" ) ) @@ -638,7 +638,7 @@ watchBotDebugEvent() added() { self endon( "disconnect" ); - + self thread maps\mp\bots\_bot_internal::added(); self thread maps\mp\bots\_bot_script::added(); } @@ -649,7 +649,7 @@ added() add_bot() { bot = addtestclient(); - + if ( isdefined( bot ) ) { bot.pers[ "isBot" ] = true; @@ -668,30 +668,30 @@ diffBots_loop() var_axis_hard = getcvarint( "bots_skill_axis_hard" ); var_axis_med = getcvarint( "bots_skill_axis_med" ); var_skill = getcvarint( "bots_skill" ); - + allies_hard = 0; allies_med = 0; axis_hard = 0; axis_med = 0; - + if ( var_skill == 8 ) { playercount = level.players.size; - + for ( i = 0; i < playercount; i++ ) { player = level.players[ i ]; - + if ( !isdefined( player.pers[ "team" ] ) ) { continue; } - + if ( !player is_bot() ) { continue; } - + if ( player.pers[ "team" ] == "axis" ) { if ( axis_hard < var_axis_hard ) @@ -731,33 +731,33 @@ diffBots_loop() else if ( var_skill != 0 && var_skill != 9 ) { playercount = level.players.size; - + for ( i = 0; i < playercount; i++ ) { player = level.players[ i ]; - + if ( !player is_bot() ) { continue; } - + player.pers[ "bots" ][ "skill" ][ "base" ] = var_skill; } } - + playercount = level.players.size; min_diff = getcvarint( "bots_skill_min" ); max_diff = getcvarint( "bots_skill_max" ); - + for ( i = 0; i < playercount; i++ ) { player = level.players[ i ]; - + if ( !player is_bot() ) { continue; } - + player.pers[ "bots" ][ "skill" ][ "base" ] = int( clamp( player.pers[ "bots" ][ "skill" ][ "base" ], min_diff, max_diff ) ); } } @@ -770,7 +770,7 @@ diffBots() for ( ;; ) { wait 1.5; - + diffBots_loop(); } } @@ -782,23 +782,23 @@ teamBots_loop() { teamAmount = getcvarint( "bots_team_amount" ); toTeam = getcvar( "bots_team" ); - + alliesbots = 0; alliesplayers = 0; axisbots = 0; axisplayers = 0; - + playercount = level.players.size; - + for ( i = 0; i < playercount; i++ ) { player = level.players[ i ]; - + if ( !isdefined( player.pers[ "team" ] ) ) { continue; } - + if ( player is_bot() ) { if ( player.pers[ "team" ] == "allies" ) @@ -822,16 +822,16 @@ teamBots_loop() } } } - + allies = alliesbots; axis = axisbots; - + if ( !getcvarint( "bots_team_mode" ) ) { allies += alliesplayers; axis += axisplayers; } - + if ( toTeam != "custom" ) { if ( getcvarint( "bots_team_force" ) ) @@ -841,37 +841,37 @@ teamBots_loop() if ( abs( axis - allies ) > 1 ) { toTeam = "axis"; - + if ( axis > allies ) { toTeam = "allies"; } } } - + if ( toTeam != "autoassign" ) { playercount = level.players.size; - + for ( i = 0; i < playercount; i++ ) { player = level.players[ i ]; - + if ( !isdefined( player.pers[ "team" ] ) ) { continue; } - + if ( !player is_bot() ) { continue; } - + if ( player.pers[ "team" ] == toTeam ) { continue; } - + if ( toTeam == "allies" ) { player thread [[ level.allies ]](); @@ -884,7 +884,7 @@ teamBots_loop() { player thread [[ level.spectator ]](); } - + break; } } @@ -893,21 +893,21 @@ teamBots_loop() else { playercount = level.players.size; - + for ( i = 0; i < playercount; i++ ) { player = level.players[ i ]; - + if ( !isdefined( player.pers[ "team" ] ) ) { continue; } - + if ( !player is_bot() ) { continue; } - + if ( player.pers[ "team" ] == "axis" ) { if ( axis > teamAmount ) @@ -941,7 +941,7 @@ teamBots() for ( ;; ) { wait 1.5; - + teamBots_loop(); } } @@ -952,42 +952,42 @@ teamBots() addBots_loop() { botsToAdd = getcvarint( "bots_manage_add" ); - + if ( botsToAdd > 0 ) { setcvar( "bots_manage_add", 0 ); - + if ( botsToAdd > 64 ) { botsToAdd = 64; } - + for ( ; botsToAdd > 0; botsToAdd-- ) { level add_bot(); wait 0.25; } } - + fillMode = getcvarint( "bots_manage_fill_mode" ); - + if ( fillMode == 2 || fillMode == 3 ) { setcvar( "bots_manage_fill", getGoodMapAmount() ); } - + fillAmount = getcvarint( "bots_manage_fill" ); - + players = 0; bots = 0; spec = 0; - + playercount = level.players.size; - + for ( i = 0; i < playercount; i++ ) { player = level.players[ i ]; - + if ( player is_bot() ) { bots++; @@ -1001,7 +1001,7 @@ addBots_loop() players++; } } - + if ( !randomint( 999 ) ) { setcvar( "testclients_doreload", true ); @@ -1009,28 +1009,28 @@ addBots_loop() setcvar( "testclients_doreload", false ); doExtraCheck(); } - + if ( fillMode == 4 ) { axisplayers = 0; alliesplayers = 0; - + playercount = level.players.size; - + for ( i = 0; i < playercount; i++ ) { player = level.players[ i ]; - + if ( player is_bot() ) { continue; } - + if ( !isdefined( player.pers[ "team" ] ) ) { continue; } - + if ( player.pers[ "team" ] == "axis" ) { axisplayers++; @@ -1040,9 +1040,9 @@ addBots_loop() alliesplayers++; } } - + result = fillAmount - abs( axisplayers - alliesplayers ) + bots; - + if ( players == 0 ) { if ( bots < fillAmount ) @@ -1058,22 +1058,22 @@ addBots_loop() result = fillAmount; } } - + bots = result; } - + amount = bots; - + if ( fillMode == 0 || fillMode == 2 ) { amount += players; } - + if ( getcvarint( "bots_manage_fill_spec" ) ) { amount += spec; } - + if ( amount < fillAmount ) { setcvar( "bots_manage_add", 1 ); @@ -1081,7 +1081,7 @@ addBots_loop() else if ( amount > fillAmount && getcvarint( "bots_manage_fill_kick" ) ) { tempBot = getBotToKick(); - + if ( isdefined( tempBot ) ) { kick( tempBot getentitynumber() ); @@ -1095,13 +1095,13 @@ addBots_loop() addBots() { level endon( "game_ended" ); - + bot_wait_for_host(); - + for ( ;; ) { wait 1.5; - + addBots_loop(); } } @@ -1113,7 +1113,7 @@ onWeaponFired() { self endon( "disconnect" ); self.bots_firing = false; - + for ( ;; ) { self waittill( "weapon_fired" ); @@ -1140,11 +1140,11 @@ launchSmoke( org ) { nade = spawnstruct(); nade.origin = org; - + level.bots_smokelist ListAdd( nade ); - + wait 11.5; - + level.bots_smokelist ListRemove( nade ); } @@ -1154,18 +1154,18 @@ launchSmoke( org ) watchNade() { self endon( "death" ); - + lastOrigin = self.origin; creationTime = gettime(); timeSlow = 0; - + wait 0.05; - + while ( isdefined( self ) ) { velocity = vector_scale( self.origin - lastOrigin, 20 ); lastOrigin = self.origin; - + if ( gettime() - creationTime > 4000 ) { if ( lengthsquared( velocity ) <= 0.05 ) @@ -1177,13 +1177,13 @@ watchNade() timeSlow = 0; } } - + if ( timeSlow > 1 ) { thread launchSmoke( lastOrigin ); self delete(); } - + wait 0.05; } } @@ -1194,23 +1194,23 @@ watchNade() watchNades_loop() { nades = getentarray( "grenade", "classname" ); - + for ( i = 0; i < nades.size; i++ ) { nade = nades[ i ]; - + if ( !isdefined( nade ) ) { continue; } - + if ( isdefined( nade.bot_audit ) ) { continue; } - + nade.bot_audit = true; - + nade thread watchNade(); } } @@ -1223,7 +1223,7 @@ watchNades() for ( ;; ) { wait 0.05; - + watchNades_loop(); } } @@ -1234,11 +1234,11 @@ watchNades() watchGameEnded() { level.gameended = false; - + for ( ;; ) { wait 0.05; - + if ( isdefined( level.roundended ) ) { if ( level.roundended ) @@ -1254,7 +1254,7 @@ watchGameEnded() } } } - + level.gameended = true; level notify( "game_ended" ); } diff --git a/maps/mp/bots/_bot_internal.gsc b/maps/mp/bots/_bot_internal.gsc index fc1867f..8135838 100644 --- a/maps/mp/bots/_bot_internal.gsc +++ b/maps/mp/bots/_bot_internal.gsc @@ -8,9 +8,9 @@ added() { self endon( "disconnect" ); - + self.pers[ "bots" ] = []; - + self.pers[ "bots" ][ "skill" ] = []; self.pers[ "bots" ][ "skill" ][ "base" ] = 7; // a base knownledge of the bot self.pers[ "bots" ][ "skill" ][ "aim_time" ] = 0.05; // how long it takes for a bot to aim to a location @@ -32,7 +32,7 @@ added() self.pers[ "bots" ][ "skill" ][ "bones" ] = "j_head"; // a list of comma seperated bones the bot will aim at self.pers[ "bots" ][ "skill" ][ "ads_fov_multi" ] = 0.5; // a factor of how much ads to reduce when adsing self.pers[ "bots" ][ "skill" ][ "ads_aimspeed_multi" ] = 0.5; // a factor of how much more aimspeed delay to add - + self.pers[ "bots" ][ "behavior" ] = []; self.pers[ "bots" ][ "behavior" ][ "strafe" ] = 50; // percentage of how often the bot strafes a target self.pers[ "bots" ][ "behavior" ][ "nade" ] = 50; // percentage of how often the bot will grenade @@ -42,7 +42,7 @@ added() self.pers[ "bots" ][ "behavior" ][ "switch" ] = 1; // percentage of how often the bot will switch weapons self.pers[ "bots" ][ "behavior" ][ "class" ] = 1; // percentage of how often the bot will change classes self.pers[ "bots" ][ "behavior" ][ "jump" ] = 100; // percentage of how often the bot will jumpshot and dropshot - + self.pers[ "bots" ][ "behavior" ][ "quickscope" ] = false; // is a quickscoper self.pers[ "bots" ][ "behavior" ][ "initswitch" ] = 10; // percentage of how often the bot will switch weapons on spawn } @@ -54,10 +54,10 @@ added() connected() { self endon( "disconnect" ); - + self.bot = spawnstruct(); self resetBotVars(); - + self thread onPlayerSpawned(); self thread bot_skip_killcam(); self thread forceRespawn(); @@ -69,16 +69,16 @@ connected() forceRespawn() { self endon( "disconnect" ); - + for ( ;; ) { wait 0.5; - + if ( !isdefined( self.respawntext ) ) { continue; } - + self thread use( 0.1 ); } } @@ -110,12 +110,12 @@ resetBotVars() self.bot.after_target = undefined; self.bot.after_target_pos = undefined; self.bot.moveto = self.origin; - + self.bot.script_aimpos = undefined; - + self.bot.script_goal = undefined; self.bot.script_goal_dist = 0.0; - + self.bot.next_wp = -1; self.bot.second_next_wp = -1; self.bot.towards_goal = undefined; @@ -125,7 +125,7 @@ resetBotVars() self.bot.climbing = false; self.bot.last_next_wp = -1; self.bot.last_second_next_wp = -1; - + self.bot.isfrozen = false; self.bot.isreloading = false; self.bot.isfragging = false; @@ -134,19 +134,19 @@ resetBotVars() self.bot.issmokingafter = false; self.bot.isknifing = false; self.bot.isknifingafter = false; - + self.bot.semi_time = false; self.bot.jump_time = undefined; self.bot.last_fire_time = -1; - + self.bot.is_cur_full_auto = false; self.bot.cur_weap_dist_multi = 1; self.bot.is_cur_sniper = false; - + self.bot.prio_objective = false; - + self.bot.rand = randomint( 100 ); - + self BotBuiltinBotStop(); } @@ -157,11 +157,11 @@ bot_skip_killcam() { level endon( "game_ended" ); self endon( "disconnect" ); - + for ( ;; ) { wait 1; - + if ( isdefined( self.killcam ) ) { self notify( "end_killcam" ); @@ -175,16 +175,16 @@ bot_skip_killcam() onPlayerSpawned() { self endon( "disconnect" ); - + for ( ;; ) { self waittill( "spawned_player" ); - + self resetBotVars(); self thread onWeaponChange(); - + self thread reload_watch(); - + self thread spawned(); } } @@ -197,27 +197,27 @@ doBotMovement_loop( data ) move_To = self.bot.moveto; angles = self getplayerangles(); dir = ( 0, 0, 0 ); - + if ( distancesquared( self.origin, move_To ) >= 49 ) { cosa = cos( 0 - angles[ 1 ] ); sina = sin( 0 - angles[ 1 ] ); - + // get the direction dir = move_To - self.origin; - + // rotate our direction according to our angles dir = ( dir[ 0 ] * cosa - dir[ 1 ] * sina, - dir[ 0 ] * sina + dir[ 1 ] * cosa, - 0 ); - + dir[ 0 ] * sina + dir[ 1 ] * cosa, + 0 ); + // make the length 127 dir = vector_scale( vectornormalize( dir ), 127 ); - + // invert the second component as the engine requires this dir = ( dir[ 0 ], 0 - dir[ 1 ], 0 ); } - + // climb through windows if ( self isMantling() ) { @@ -229,16 +229,16 @@ doBotMovement_loop( data ) data.wasmantling = false; self stand(); } - + startPos = self.origin + ( 0, 0, 50 ); startPosForward = startPos + vector_scale( anglestoforward( ( 0, angles[ 1 ], 0 ) ), 25 ); bt = bullettrace( startPos, startPosForward, false, self ); - + if ( bt[ "fraction" ] >= 1 ) { // check if need to jump bt = bullettrace( startPosForward, startPosForward - ( 0, 0, 40 ), false, self ); - + if ( bt[ "fraction" ] < 1 && bt[ "normal" ][ 2 ] > 0.9 && data.i > 1.5 && !self isOnLadder() ) { data.i = 0; @@ -262,7 +262,7 @@ doBotMovement_loop( data ) self crouch(); } } - + // move! self BotBuiltinBotMovement( int( dir[ 0 ] ), int( dir[ 1 ] ) ); } @@ -274,14 +274,14 @@ doBotMovement() { self endon( "disconnect" ); self endon( "death" ); - + data = spawnstruct(); data.wasmantling = false; - + for ( data.i = 0; true; data.i += 0.05 ) { wait 0.05; - + waittillframeend; self doBotMovement_loop( data ); } @@ -294,9 +294,9 @@ spawned() { self endon( "disconnect" ); self endon( "death" ); - + wait self.pers[ "bots" ][ "skill" ][ "spawn_time" ]; - + self thread doBotMovement(); self thread check_reload(); self thread stance(); @@ -307,7 +307,7 @@ spawned() self thread watchHoldBreath(); self thread onNewEnemy(); self thread watchPickupGun(); - + self notify( "bot_spawned" ); } @@ -318,23 +318,23 @@ watchPickupGun() { self endon( "disconnect" ); self endon( "death" ); - + for ( ;; ) { wait 1; - + if ( self usebuttonpressed() ) { continue; } - + weap = self getcurrentweapon(); - + if ( weap != "none" && self getAmmoCount( weap ) ) { continue; } - + self thread use( 0.5 ); } } @@ -348,18 +348,18 @@ SetWeaponDistMulti( weap ) { return 1; } - + switch ( weaponClass( weap ) ) { case "rifle": return 0.9; - + case "smg": return 0.7; - + case "pistol": return 0.5; - + default: return 1; } @@ -374,12 +374,12 @@ IsWeapSniper( weap ) { return false; } - + if ( weaponClass( weap ) != "sniper" ) { return false; } - + return true; } @@ -390,16 +390,16 @@ watchHoldBreath() { self endon( "disconnect" ); self endon( "death" ); - + for ( ;; ) { wait 1; - + if ( self.bot.isfrozen ) { continue; } - + self holdbreath( self playerads() > 0 ); } } @@ -411,13 +411,13 @@ onWeaponChange() { self endon( "disconnect" ); self endon( "death" ); - + first = true; - + for ( ;; ) { newWeapon = undefined; - + if ( first ) { first = false; @@ -427,7 +427,7 @@ onWeaponChange() { self waittill( "weapon_change", newWeapon ); } - + self.bot.is_cur_full_auto = WeaponIsFullAuto( newWeapon ); self.bot.cur_weap_dist_multi = SetWeaponDistMulti( newWeapon ); self.bot.is_cur_sniper = IsWeapSniper( newWeapon ); @@ -440,29 +440,29 @@ onWeaponChange() reload_watch_loop() { self.bot.isreloading = true; - + while ( true ) { ret = self waittill_any_timeout( 7.5, "reload" ); - + if ( ret == "timeout" ) { break; } - + weap = self getcurrentweapon(); - + if ( weap == "none" ) { break; } - + if ( self getweaponslotclipammo( self getWeaponSlot( weap ) ) >= WeaponClipSize( weap ) ) { break; } } - + self.bot.isreloading = false; } @@ -473,11 +473,11 @@ reload_watch() { self endon( "disconnect" ); self endon( "death" ); - + for ( ;; ) { self waittill( "reload_start" ); - + self reload_watch_loop(); } } @@ -488,40 +488,40 @@ reload_watch() stance_loop() { self.bot.climbing = false; - + if ( self.bot.isfrozen ) { return; } - + toStance = "stand"; - + if ( self.bot.next_wp != -1 ) { toStance = level.waypoints[ self.bot.next_wp ].type; } - + if ( !isdefined( toStance ) ) { toStance = "crouch"; } - + if ( toStance == "stand" && randomint( 100 ) <= self.pers[ "bots" ][ "behavior" ][ "crouch" ] ) { toStance = "crouch"; } - + if ( toStance == "climb" ) { self.bot.climbing = true; toStance = "stand"; } - + if ( toStance != "stand" && toStance != "crouch" && toStance != "prone" ) { toStance = "crouch"; } - + if ( toStance == "stand" ) { self stand(); @@ -543,11 +543,11 @@ stance() { self endon( "disconnect" ); self endon( "death" ); - + for ( ;; ) { self waittill_either( "finished_static_waypoints", "new_static_waypoint" ); - + self stance_loop(); } } @@ -559,7 +559,7 @@ check_reload() { self endon( "disconnect" ); self endon( "death" ); - + for ( ;; ) { self waittill_notify_or_timeout( "weapon_fired", 5 ); @@ -575,29 +575,29 @@ reload_thread() self endon( "disconnect" ); self endon( "death" ); self endon( "weapon_fired" ); - + wait 2.5; - + if ( isdefined( self.bot.target ) || self.bot.isreloading || self.bot.isfraggingafter || self.bot.issmokingafter || self.bot.isfrozen ) { return; } - + cur = self getcurrentweapon(); - + if ( cur == "" || cur == "none" ) { return; } - + if ( IsWeaponClipOnly( cur ) || !self getweaponslotammo( self getWeaponSlot( cur ) ) ) { return; } - + maxsize = WeaponClipSize( cur ); cursize = self getweaponslotclipammo( self getWeaponSlot( cur ) ); - + if ( cursize / maxsize < 0.5 ) { self thread reload(); @@ -611,19 +611,19 @@ updateBones() { self endon( "disconnect" ); self endon( "death" ); - + bones = strtok( self.pers[ "bots" ][ "skill" ][ "bones" ], "," ); waittime = self.pers[ "bots" ][ "skill" ][ "bone_update_interval" ]; - + for ( ;; ) { self waittill_notify_or_timeout( "new_enemy", waittime ); - + if ( !isdefined( self.bot.target ) ) { continue; } - + self.bot.target.bone = random( bones ); } } @@ -647,7 +647,7 @@ createTargetObj( ent, theTime ) obj.bone = undefined; obj.aim_offset = undefined; obj.aim_offset_base = undefined; - + return obj; } @@ -659,22 +659,22 @@ updateAimOffset( obj ) if ( !isdefined( obj.aim_offset_base ) ) { diffAimAmount = self.pers[ "bots" ][ "skill" ][ "aim_offset_amount" ]; - + if ( diffAimAmount > 0 ) { obj.aim_offset_base = ( randomfloatrange( 0 - diffAimAmount, diffAimAmount ), - randomfloatrange( 0 - diffAimAmount, diffAimAmount ), - randomfloatrange( 0 - diffAimAmount, diffAimAmount ) ); + randomfloatrange( 0 - diffAimAmount, diffAimAmount ), + randomfloatrange( 0 - diffAimAmount, diffAimAmount ) ); } else { obj.aim_offset_base = ( 0, 0, 0 ); } } - + aimDiffTime = self.pers[ "bots" ][ "skill" ][ "aim_offset_time" ] * 1000; objCreatedFor = obj.trace_time; - + if ( objCreatedFor >= aimDiffTime ) { offsetScalar = 0; @@ -683,7 +683,7 @@ updateAimOffset( obj ) { offsetScalar = 1 - objCreatedFor / aimDiffTime; } - + obj.aim_offset = vector_scale( obj.aim_offset_base, offsetScalar ); } @@ -695,13 +695,13 @@ targetObjUpdateTraced( obj, daDist, ent, theTime, isScriptObj ) distClose = self.pers[ "bots" ][ "skill" ][ "dist_start" ]; distClose *= self.bot.cur_weap_dist_multi; distClose *= distClose; - + distMax = self.pers[ "bots" ][ "skill" ][ "dist_max" ]; distMax *= self.bot.cur_weap_dist_multi; distMax *= distMax; - + timeMulti = 1; - + if ( !isScriptObj ) { if ( daDist > distMax ) @@ -713,13 +713,13 @@ targetObjUpdateTraced( obj, daDist, ent, theTime, isScriptObj ) timeMulti = 1 - ( ( daDist - distClose ) / ( distMax - distClose ) ); } } - + obj.no_trace_time = 0; obj.trace_time += int( 50 * timeMulti ); obj.dist = daDist; obj.last_seen_pos = ent.origin; obj.trace_time_time = theTime; - + self updateAimOffset( obj ); } @@ -750,54 +750,54 @@ target_loop() hasTarget = isdefined( self.bot.target ); adsAmount = self playerads(); adsFovFact = self.pers[ "bots" ][ "skill" ][ "ads_fov_multi" ]; - + if ( hasTarget && !isdefined( self.bot.target.entity ) ) { self.bot.target = undefined; hasTarget = false; } - + // reduce fov if ads'ing if ( adsAmount > 0 ) { myFov *= 1 - adsFovFact * adsAmount; } - + playercount = level.players.size; - + for ( i = -1; i < playercount; i++ ) { obj = undefined; - + if ( i == -1 ) { if ( !isdefined( self.bot.script_target ) ) { continue; } - + ent = self.bot.script_target; key = ent getentitynumber() + ""; daDist = distancesquared( self.origin, ent.origin ); obj = self.bot.targets[ key ]; isObjDef = isdefined( obj ); entOrigin = ent.origin; - + if ( isdefined( self.bot.script_target_offset ) ) { entOrigin += self.bot.script_target_offset; } - + if ( SmokeTrace( myEye, entOrigin, level.smokeradius ) && bullettracepassed( myEye, entOrigin, false, ent ) ) { if ( !isObjDef ) { obj = self createTargetObj( ent, theTime ); obj.offset = self.bot.script_target_offset; - + self.bot.targets[ key ] = obj; } - + self targetObjUpdateTraced( obj, daDist, ent, theTime, true ); } else @@ -806,9 +806,9 @@ target_loop() { continue; } - + self targetObjUpdateNoTrace( obj ); - + if ( obj.no_trace_time > rememberTime ) { self.bot.targets[ key ] = undefined; @@ -819,65 +819,65 @@ target_loop() else { player = level.players[ i ]; - + if ( player == self ) { continue; } - + key = player getentitynumber() + ""; obj = self.bot.targets[ key ]; daDist = distancesquared( self.origin, player.origin ); isObjDef = isdefined( obj ); - + if ( ( level.teambased && self.team == player.team ) || player.sessionstate != "playing" || !isalive( player ) ) { if ( isObjDef ) { self.bot.targets[ key ] = undefined; } - + continue; } - + targetHead = player getTagOrigin( "j_head" ); targetAnkleLeft = player getTagOrigin( "j_ankle_le" ); targetAnkleRight = player getTagOrigin( "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 ) || - daDist < level.bots_maxknifedistance * 4 ) - - && ( getConeDot( player.origin, self.origin, myAngles ) >= myFov || - ( isObjDef && obj.trace_time ) ) ); - + 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 ) || + daDist < level.bots_maxknifedistance * 4 ) + + && ( getConeDot( player.origin, self.origin, myAngles ) >= myFov || + ( isObjDef && obj.trace_time ) ) ); + if ( isdefined( self.bot.target_this_frame ) && self.bot.target_this_frame == player ) { self.bot.target_this_frame = undefined; - + canTargetPlayer = true; } - + if ( canTargetPlayer ) { if ( !isObjDef ) { obj = self createTargetObj( player, theTime ); - + self.bot.targets[ key ] = obj; } - + self targetObjUpdateTraced( obj, daDist, player, theTime, false ); } else @@ -886,9 +886,9 @@ target_loop() { continue; } - + self targetObjUpdateNoTrace( obj ); - + if ( obj.no_trace_time > rememberTime ) { self.bot.targets[ key ] = undefined; @@ -896,67 +896,67 @@ target_loop() } } } - + if ( !isdefined( obj ) ) { continue; } - + if ( theTime - obj.time < initReactTime ) { continue; } - + timeDiff = theTime - obj.trace_time_time; - + if ( timeDiff < bestTime ) { bestTargets = []; bestKeys = []; bestTime = timeDiff; } - + if ( timeDiff == bestTime ) { bestTargets[ key ] = obj; bestKeys[ bestKeys.size ] = key; } } - + if ( hasTarget && isdefined( bestTargets[ self.bot.target.entity getentitynumber() + "" ] ) ) { return; } - + closest = 2147483647; toBeTarget = undefined; - + for ( i = bestKeys.size - 1; i >= 0; i-- ) { theDist = bestTargets[ bestKeys[ i ] ].dist; - + if ( theDist > closest ) { continue; } - + closest = theDist; toBeTarget = bestTargets[ bestKeys[ i ] ]; } - + beforeTargetID = -1; newTargetID = -1; - + if ( hasTarget && isdefined( self.bot.target.entity ) ) { beforeTargetID = self.bot.target.entity getentitynumber(); } - + if ( isdefined( toBeTarget ) && isdefined( toBeTarget.entity ) ) { newTargetID = toBeTarget.entity getentitynumber(); } - + if ( beforeTargetID != newTargetID ) { self.bot.target = toBeTarget; @@ -971,11 +971,11 @@ target() { self endon( "disconnect" ); self endon( "death" ); - + for ( ;; ) { wait 0.05; - + self target_loop(); } } @@ -987,26 +987,26 @@ onNewEnemy() { self endon( "disconnect" ); self endon( "death" ); - + for ( ;; ) { self waittill( "new_enemy" ); - + if ( !isdefined( self.bot.target ) ) { continue; } - + if ( !isdefined( self.bot.target.entity ) || !isplayer( self.bot.target.entity ) ) { continue; } - + if ( self.bot.target.didlook ) { continue; } - + self thread watchToLook(); } } @@ -1019,78 +1019,78 @@ watchToLook() self endon( "disconnect" ); self endon( "death" ); self endon( "new_enemy" ); - + for ( ;; ) { while ( isdefined( self.bot.target ) && self.bot.target.didlook ) { wait 0.05; } - + while ( isdefined( self.bot.target ) && self.bot.target.no_trace_time ) { wait 0.05; } - + if ( !isdefined( self.bot.target ) ) { break; } - + self.bot.target.didlook = true; - + if ( self.bot.isfrozen ) { continue; } - + if ( self.bot.target.dist > level.bots_maxshotgundistance * 2 ) { continue; } - + if ( self.bot.target.dist <= level.bots_maxknifedistance ) { continue; } - + if ( !self canFire( self getcurrentweapon() ) ) { continue; } - + if ( !self isInRange( self.bot.target.dist, self getcurrentweapon() ) ) { continue; } - + if ( self.bot.is_cur_sniper ) { continue; } - + if ( randomint( 100 ) > self.pers[ "bots" ][ "behavior" ][ "jump" ] ) { continue; } - + if ( !getcvarint( "bots_play_jumpdrop" ) ) { continue; } - + if ( isdefined( self.bot.jump_time ) && gettime() - self.bot.jump_time <= 5000 ) { continue; } - + if ( self.bot.target.rand <= self.pers[ "bots" ][ "behavior" ][ "strafe" ] ) { if ( self getStance() != "stand" ) { continue; } - + self.bot.jump_time = gettime(); self jump(); } @@ -1100,7 +1100,7 @@ watchToLook() { continue; } - + self.bot.jump_time = gettime(); self prone(); self notify( "kill_goal" ); @@ -1117,15 +1117,15 @@ start_bot_after_target( who ) { self endon( "disconnect" ); self endon( "death" ); - + self.bot.after_target = who; self.bot.after_target_pos = who.origin; - + self notify( "kill_after_target" ); self endon( "kill_after_target" ); - + wait self.pers[ "bots" ][ "skill" ][ "shoot_after_time" ]; - + self.bot.after_target = undefined; } @@ -1144,24 +1144,24 @@ clear_bot_after_target() aim_loop() { aimspeed = self.pers[ "bots" ][ "skill" ][ "aim_time" ]; - + eyePos = self getEyePos(); curweap = self getcurrentweapon(); angles = self getplayerangles(); adsAmount = self playerads(); adsAimSpeedFact = self.pers[ "bots" ][ "skill" ][ "ads_aimspeed_multi" ]; - + // reduce aimspeed if ads'ing if ( adsAmount > 0 ) { aimspeed *= 1 + adsAimSpeedFact * adsAmount; } - + if ( isdefined( self.bot.target ) && isdefined( self.bot.target.entity ) && !( self.bot.prio_objective && isdefined( self.bot.script_aimpos ) ) ) { no_trace_time = self.bot.target.no_trace_time; no_trace_look_time = self.pers[ "bots" ][ "skill" ][ "no_trace_look_time" ]; - + if ( no_trace_time <= no_trace_look_time ) { trace_time = self.bot.target.trace_time; @@ -1169,39 +1169,39 @@ aim_loop() target = self.bot.target.entity; conedot = 0; isplay = isplayer( self.bot.target.entity ); - + offset = self.bot.target.offset; - + if ( !isdefined( offset ) ) { offset = ( 0, 0, 0 ); } - + aimoffset = self.bot.target.aim_offset; - + if ( !isdefined( aimoffset ) ) { aimoffset = ( 0, 0, 0 ); } - + dist = self.bot.target.dist; rand = self.bot.target.rand; no_trace_ads_time = self.pers[ "bots" ][ "skill" ][ "no_trace_ads_time" ]; reaction_time = self.pers[ "bots" ][ "skill" ][ "reaction_time" ]; nadeAimOffset = 0; - + bone = self.bot.target.bone; - + if ( !isdefined( bone ) ) { bone = "j_spineupper"; } - + if ( self.bot.isfraggingafter || self.bot.issmokingafter || issubstr( "_grenade_", curweap ) ) { nadeAimOffset = dist / 3000; } - + if ( no_trace_time && ( !isdefined( self.bot.after_target ) || self.bot.after_target != target ) ) { if ( no_trace_time > no_trace_ads_time ) @@ -1212,11 +1212,11 @@ aim_loop() if ( !self.bot.isfraggingafter && !self.bot.issmokingafter ) { nade = self getValidGrenade(); - + if ( isdefined( nade ) && rand <= self.pers[ "bots" ][ "behavior" ][ "nade" ] && bullettracepassed( eyePos, eyePos + ( 0, 0, 75 ), false, self ) && bullettracepassed( last_pos, last_pos + ( 0, 0, 100 ), false, target ) && dist > level.bots_mingrenadedistance && dist < level.bots_maxgrenadedistance && getcvarint( "bots_play_nade" ) ) { time = 0.5; - + if ( !isSecondaryGrenade( nade ) ) { self thread frag( time ); @@ -1225,7 +1225,7 @@ aim_loop() { self thread smoke( time ); } - + self notify( "kill_goal" ); } } @@ -1241,28 +1241,28 @@ aim_loop() } } } - + self thread bot_lookat( last_pos + ( 0, 0, self getEyeHeight() + nadeAimOffset ), aimspeed ); return; } - + if ( trace_time ) { if ( isplay ) { aimpos = target getTagOrigin( bone ); - + if ( !isdefined( aimpos ) ) { return; } - + aimpos += offset; aimpos += aimoffset; aimpos += ( 0, 0, nadeAimOffset ); - + conedot = getConeDot( aimpos, eyePos, angles ); - + if ( !nadeAimOffset && conedot > 0.999 && lengthsquared( aimoffset ) < 0.05 ) { self thread bot_lookat( aimpos, 0.05 ); @@ -1278,9 +1278,9 @@ aim_loop() aimpos += offset; aimpos += aimoffset; aimpos += ( 0, 0, nadeAimOffset ); - + conedot = getConeDot( aimpos, eyePos, angles ); - + if ( !nadeAimOffset && conedot > 0.999 && lengthsquared( aimoffset ) < 0.05 ) { self thread bot_lookat( aimpos, 0.05 ); @@ -1290,25 +1290,25 @@ aim_loop() self thread bot_lookat( aimpos, aimspeed ); } } - + if ( isplay && !self.bot.isknifingafter && conedot > 0.9 && dist < level.bots_maxknifedistance && trace_time > reaction_time && getcvarint( "bots_play_knife" ) ) { self clear_bot_after_target(); self thread knife(); return; } - + if ( !self canFire( curweap ) || !self isInRange( dist, curweap ) ) { return; } - + canADS = ( self canAds( dist, curweap ) && conedot > 0.75 ); - + if ( canADS ) { stopAdsOverride = false; - + if ( self.bot.is_cur_sniper ) { if ( self.pers[ "bots" ][ "behavior" ][ "quickscope" ] && self.bot.last_fire_time != -1 && gettime() - self.bot.last_fire_time < 1000 ) @@ -1320,58 +1320,58 @@ aim_loop() self notify( "kill_goal" ); } } - + if ( !stopAdsOverride ) { self thread pressADS(); } } - + if ( trace_time > reaction_time ) { if ( ( !canADS || adsAmount >= 1.0 || self GetStance() == "prone" ) && ( conedot > 0.99 || dist < level.bots_maxknifedistance ) && getcvarint( "bots_play_fire" ) ) { self botFire(); } - + if ( isplay ) { self thread start_bot_after_target( target ); } } - + return; } } } - + if ( isdefined( self.bot.after_target ) ) { nadeAimOffset = 0; last_pos = self.bot.after_target_pos; dist = distancesquared( self.origin, last_pos ); - + if ( self.bot.isfraggingafter || self.bot.issmokingafter || issubstr( "_grenade_", curweap ) ) { nadeAimOffset = dist / 3000; } - + aimpos = last_pos + ( 0, 0, self getEyeHeight() + nadeAimOffset ); conedot = getConeDot( aimpos, eyePos, angles ); - + self thread bot_lookat( aimpos, aimspeed ); - + if ( !self canFire( curweap ) || !self isInRange( dist, curweap ) ) { return; } - + canADS = ( self canAds( dist, curweap ) && conedot > 0.75 ); - + if ( canADS ) { stopAdsOverride = false; - + if ( self.bot.is_cur_sniper ) { if ( self.pers[ "bots" ][ "behavior" ][ "quickscope" ] && self.bot.last_fire_time != -1 && gettime() - self.bot.last_fire_time < 1000 ) @@ -1383,25 +1383,25 @@ aim_loop() self notify( "kill_goal" ); } } - + if ( !stopAdsOverride ) { self thread pressADS(); } } - + if ( ( !canADS || adsAmount >= 1.0 || self GetStance() == "prone" ) && ( conedot > 0.95 || dist < level.bots_maxknifedistance ) && getcvarint( "bots_play_fire" ) ) { self botFire(); } - + return; } - + if ( self.bot.next_wp != -1 && isdefined( level.waypoints[ self.bot.next_wp ].angles ) && false ) { forwardPos = anglestoforward( level.waypoints[ self.bot.next_wp ].angles ) * 1024; - + self thread bot_lookat( eyePos + forwardPos, aimspeed ); } else if ( isdefined( self.bot.script_aimpos ) ) @@ -1411,7 +1411,7 @@ aim_loop() else { lookat = undefined; - + if ( self.bot.second_next_wp != -1 && !self.bot.climbing ) { lookat = level.waypoints[ self.bot.second_next_wp ].origin; @@ -1420,7 +1420,7 @@ aim_loop() { lookat = self.bot.towards_goal; } - + if ( isdefined( lookat ) ) { self thread bot_lookat( lookat + ( 0, 0, self getEyeHeight() ), aimspeed ); @@ -1435,16 +1435,16 @@ aim() { self endon( "disconnect" ); self endon( "death" ); - + for ( ;; ) { wait 0.05; - + if ( level.gameended || self.bot.isfrozen ) { continue; } - + self aim_loop(); } } @@ -1455,18 +1455,18 @@ aim() botFire() { self.bot.last_fire_time = gettime(); - + if ( self.bot.is_cur_full_auto ) { self thread pressFire(); return; } - + if ( self.bot.semi_time ) { return; } - + self thread pressFire(); self thread doSemiTime(); } @@ -1480,7 +1480,7 @@ doSemiTime() self endon( "disconnect" ); self notify( "bot_semi_time" ); self endon( "bot_semi_time" ); - + self.bot.semi_time = true; wait self.pers[ "bots" ][ "skill" ][ "semi_time" ]; self.bot.semi_time = false; @@ -1495,7 +1495,7 @@ canFire( curweap ) { return false; } - + return self getweaponslotclipammo( self getWeaponSlot( curweap ) ); } @@ -1508,26 +1508,26 @@ canAds( dist, curweap ) { return false; } - + if ( !getcvarint( "bots_play_ads" ) ) { return false; } - + far = level.bots_noadsdistance; - + if ( dist < far ) { return false; } - + weapclass = ( weaponClass( curweap ) ); - + if ( weapclass == "spread" ) { return false; } - + return true; } @@ -1540,14 +1540,14 @@ isInRange( dist, curweap ) { return false; } - + weapclass = weaponClass( curweap ); - + if ( weapclass == "spread" && dist > level.bots_maxshotgundistance ) { return false; } - + return true; } @@ -1570,9 +1570,9 @@ killWalkCauseNoWaypoints() self endon( "disconnect" ); self endon( "death" ); self endon( "kill_goal" ); - + wait 2; - + self notify( "kill_goal" ); } @@ -1582,39 +1582,39 @@ killWalkCauseNoWaypoints() walk_loop() { hasTarget = isdefined( self.bot.target ) && isdefined( self.bot.target.entity ) && !self.bot.prio_objective; - + if ( hasTarget ) { curweap = self getcurrentweapon(); - + if ( self.bot.target.entity.classname == "script_vehicle" ) { return; } - + if ( self.bot.isfraggingafter || self.bot.issmokingafter ) { return; } - + if ( isplayer( self.bot.target.entity ) && self.bot.target.trace_time && self canFire( curweap ) && self isInRange( self.bot.target.dist, curweap ) ) { if ( self GetStance() == "prone" || ( self.bot.is_cur_sniper && self playerads() > 0 ) ) { return; } - + if ( self.bot.target.rand <= self.pers[ "bots" ][ "behavior" ][ "strafe" ] ) { self strafe( self.bot.target.entity ); } - + return; } } - + dist = 16; - + if ( level.waypointcount ) { goal = level.waypoints[ randomint( level.waypointcount ) ].origin; @@ -1626,15 +1626,15 @@ walk_loop() forward = vector_scale( anglestoforward( self getplayerangles() ), stepDist ); forward = ( forward[ 0 ], forward[ 1 ], 0 ); myOrg = self.origin + ( 0, 0, 32 ); - + goal = physicstrace( myOrg, myOrg + forward, false, self ); goal = physicstrace( goal + ( 0, 0, 50 ), goal + ( 0, 0, -40 ), false, self ); - + // too small, lets bounce off the wall if ( distancesquared( goal, myOrg ) < stepDist * stepDist - 1 || randomint( 100 ) < 5 ) { trace = bullettrace( myOrg, myOrg + forward, false, self ); - + if ( trace[ "surfacetype" ] == "none" || randomint( 100 ) < 25 ) { // didnt hit anything, just choose a random direction then @@ -1648,22 +1648,22 @@ walk_loop() // r = d - 2 (d . n) n d = vectornormalize( trace[ "position" ] - myOrg ); n = trace[ "normal" ]; - + r = d - vector_scale( vector_scale( n, vectordot( d, n ) ), 2 ); - + goal = physicstrace( myOrg, myOrg + vector_scale( ( r[ 0 ], r[ 1 ], 0 ), stepDist ), false, self ); goal = physicstrace( goal + ( 0, 0, 50 ), goal + ( 0, 0, -40 ), false, self ); } } } - + isScriptGoal = false; - + if ( isdefined( self.bot.script_goal ) && !hasTarget ) { goal = self.bot.script_goal; dist = self.bot.script_goal_dist; - + isScriptGoal = true; } else @@ -1672,10 +1672,10 @@ walk_loop() { goal = self.bot.target.last_seen_pos; } - + self notify( "new_goal_internal" ); } - + self doWalk( goal, dist, isScriptGoal ); self.bot.towards_goal = undefined; self.bot.next_wp = -1; @@ -1689,23 +1689,23 @@ walk() { self endon( "disconnect" ); self endon( "death" ); - + for ( ;; ) { wait 0.05; - + self botSetMoveTo( self.origin ); - + if ( !getcvarint( "bots_play_move" ) ) { continue; } - + if ( level.gameended || self.bot.isfrozen || self.bot.stop_move ) { continue; } - + self walk_loop(); } } @@ -1717,25 +1717,25 @@ strafe( target ) { self endon( "kill_goal" ); self thread killWalkOnEvents(); - + angles = vectortoangles( vectornormalize( target.origin - self.origin ) ); anglesLeft = ( 0, angles[ 1 ] + 90, 0 ); anglesRight = ( 0, angles[ 1 ] - 90, 0 ); - + myOrg = self.origin + ( 0, 0, 16 ); left = myOrg + vector_scale( anglestoforward( anglesLeft ), 500 ); right = myOrg + vector_scale( anglestoforward( anglesRight ), 500 ); - + traceLeft = bullettrace( myOrg, left, false, self ); traceRight = bullettrace( myOrg, right, false, self ); - + strafe = traceLeft[ "position" ]; - + if ( traceRight[ "fraction" ] > traceLeft[ "fraction" ] ) { strafe = traceRight[ "position" ]; } - + self.bot.last_next_wp = -1; self.bot.last_second_next_wp = -1; self botSetMoveTo( strafe ); @@ -1751,12 +1751,12 @@ watchOnGoal( goal, dis ) self endon( "disconnect" ); self endon( "death" ); self endon( "kill_goal" ); - + while ( distancesquared( self.origin, goal ) > dis ) { wait 0.05; } - + self notify( "goal_internal" ); } @@ -1766,7 +1766,7 @@ watchOnGoal( goal, dis ) cleanUpAStar( team ) { self waittill_any( "death", "disconnect", "kill_goal" ); - + for ( i = self.bot.astar.size - 1; i >= 0; i-- ) { RemoveWaypointUsage( self.bot.astar[ i ], team ); @@ -1779,19 +1779,19 @@ cleanUpAStar( team ) initAStar( goal ) { team = undefined; - + if ( level.teambased ) { team = self.team; } - + self.bot.astar = AStarSearch( self.origin, goal, team, self.bot.greedy_path ); - + if ( isdefined( team ) ) { self thread cleanUpAStar( team ); } - + return self.bot.astar.size - 1; } @@ -1801,14 +1801,14 @@ initAStar( goal ) removeAStar() { remove = self.bot.astar.size - 1; - + if ( level.teambased ) { RemoveWaypointUsage( self.bot.astar[ remove ], self.team ); } - + self.bot.astar[ remove ] = undefined; - + return self.bot.astar.size - 1; } @@ -1820,11 +1820,11 @@ killWalkOnEvents() self endon( "kill_goal" ); self endon( "disconnect" ); self endon( "death" ); - + self waittill_any( "flash_rumble_loop", "new_enemy", "new_goal_internal", "goal_internal", "bad_path_internal" ); - + waittillframeend; - + self notify( "kill_goal" ); } @@ -1836,7 +1836,7 @@ doWalkScriptNotify() self endon( "disconnect" ); self endon( "death" ); self endon( "kill_goal" ); - + if ( self waittill_either_return( "goal_internal", "bad_path_internal" ) == "goal_internal" ) { self notify( "goal" ); @@ -1855,25 +1855,25 @@ doWalk( goal, dist, isScriptGoal ) level endon ( "game_ended" ); self endon( "kill_goal" ); self endon( "goal_internal" ); // so that the watchOnGoal notify can happen same frame, not a frame later - + dist *= dist; - + if ( isScriptGoal ) { self thread doWalkScriptNotify(); } - + self thread killWalkOnEvents(); self thread watchOnGoal( goal, dist ); - + current = self initAStar( goal ); - + // skip waypoints we already completed to prevent rubber banding if ( current > 0 && self.bot.astar[ current ] == self.bot.last_next_wp && self.bot.astar[ current - 1 ] == self.bot.last_second_next_wp ) { current = self removeAStar(); } - + if ( current >= 0 ) { // check if a waypoint is closer than the goal @@ -1883,38 +1883,38 @@ doWalk( goal, dist, isScriptGoal ) { self.bot.next_wp = self.bot.astar[ current ]; self.bot.second_next_wp = -1; - + if ( current > 0 ) { self.bot.second_next_wp = self.bot.astar[ current - 1 ]; } - + self notify( "new_static_waypoint" ); - + self movetowards( level.waypoints[ self.bot.next_wp ].origin ); self.bot.last_next_wp = self.bot.next_wp; self.bot.last_second_next_wp = self.bot.second_next_wp; - + current = self removeAStar(); } } } - + self.bot.next_wp = -1; self.bot.second_next_wp = -1; self notify( "finished_static_waypoints" ); - + if ( distancesquared( self.origin, goal ) > dist ) { self.bot.last_next_wp = -1; self.bot.last_second_next_wp = -1; self movetowards( goal ); // any better way?? } - + self notify( "finished_goal" ); - + wait 1; - + if ( distancesquared( self.origin, goal ) > dist ) { self notify( "bad_path_internal" ); @@ -1930,41 +1930,41 @@ movetowards( goal ) { return; } - + self.bot.towards_goal = goal; - + lastOri = self.origin; stucks = 0; timeslow = 0; time = 0; - + while ( distancesquared( self.origin, goal ) > level.bots_goaldistance ) { self botSetMoveTo( goal ); - + if ( time > 3000 ) { time = 0; - + if ( distancesquared( self.origin, lastOri ) < 32 * 32 ) { self thread knife(); wait 0.5; - + stucks++; - + randomDir = self getRandomLargestStafe( stucks ); - + self BotNotifyBotEvent( "stuck" ); - + self botSetMoveTo( randomDir ); wait stucks; self stand(); - + self.bot.last_next_wp = -1; self.bot.last_second_next_wp = -1; } - + lastOri = self.origin; } else if ( timeslow > 0 && ( timeslow % 1000 ) == 0 ) @@ -1989,10 +1989,10 @@ movetowards( goal ) } } } - + wait 0.05; time += 50; - + if ( lengthsquared( self getVelocity() ) < 1000 ) { timeslow += 50; @@ -2001,13 +2001,13 @@ movetowards( goal ) { timeslow = 0; } - + if ( stucks == 2 ) { self notify( "bad_path_internal" ); } } - + self.bot.towards_goal = undefined; self notify( "completed_move_to" ); } @@ -2020,11 +2020,11 @@ doMantle() self endon( "disconnect" ); self endon( "death" ); self endon( "kill_goal" ); - + self jump(); - + wait 0.35; - + self jump(); } @@ -2036,7 +2036,7 @@ getRandomLargestStafe( dist ) // find a better algo? traces = NewHeap( ::HeapTraceFraction ); myOrg = self.origin + ( 0, 0, 16 ); - + traces HeapInsert( bullettrace( myOrg, myOrg + ( -100 * dist, 0, 0 ), false, self ) ); traces HeapInsert( bullettrace( myOrg, myOrg + ( 100 * dist, 0, 0 ), false, self ) ); traces HeapInsert( bullettrace( myOrg, myOrg + ( 0, 100 * dist, 0 ), false, self ) ); @@ -2045,19 +2045,19 @@ getRandomLargestStafe( dist ) traces HeapInsert( bullettrace( myOrg, myOrg + ( -100 * dist, 100 * dist, 0 ), false, self ) ); traces HeapInsert( bullettrace( myOrg, myOrg + ( 100 * dist, -100 * dist, 0 ), false, self ) ); traces HeapInsert( bullettrace( myOrg, myOrg + ( 100 * dist, 100 * dist, 0 ), false, self ) ); - + toptraces = []; - + top = traces.data[ 0 ]; toptraces[ toptraces.size ] = top; traces HeapRemove(); - + while ( traces.data.size && top[ "fraction" ] - traces.data[ 0 ][ "fraction" ] < 0.1 ) { toptraces[ toptraces.size ] = traces.data[ 0 ]; traces HeapRemove(); } - + return toptraces[ randomint( toptraces.size ) ][ "position" ]; } @@ -2085,18 +2085,18 @@ knife() self endon( "disconnect" ); self notify( "bot_knife" ); self endon( "bot_knife" ); - + self.bot.isknifing = true; self.bot.isknifingafter = true; - + self BotBuiltinBotAction( "+melee" ); wait 0.05; self BotBuiltinBotAction( "-melee" ); - + self.bot.isknifing = false; - + wait 1; - + self.bot.isknifingafter = false; } @@ -2109,7 +2109,7 @@ reload() self endon( "disconnect" ); self notify( "bot_reload" ); self endon( "bot_reload" ); - + self BotBuiltinBotAction( "+reload" ); wait 0.05; self BotBuiltinBotAction( "-reload" ); @@ -2124,24 +2124,24 @@ frag( time ) self endon( "disconnect" ); self notify( "bot_frag" ); self endon( "bot_frag" ); - + if ( !isdefined( time ) ) { time = 0.05; } - + self BotBuiltinBotAction( "+frag" ); self.bot.isfragging = true; self.bot.isfraggingafter = true; - + if ( time ) { wait time; } - + self BotBuiltinBotAction( "-frag" ); self.bot.isfragging = false; - + wait 1.25; self.bot.isfraggingafter = false; } @@ -2155,24 +2155,24 @@ smoke( time ) self endon( "disconnect" ); self notify( "bot_smoke" ); self endon( "bot_smoke" ); - + if ( !isdefined( time ) ) { time = 0.05; } - + self BotBuiltinBotAction( "+smoke" ); self.bot.issmoking = true; self.bot.issmokingafter = true; - + if ( time ) { wait time; } - + self BotBuiltinBotAction( "-smoke" ); self.bot.issmoking = false; - + wait 1.25; self.bot.issmokingafter = false; } @@ -2183,7 +2183,7 @@ smoke( time ) fire( what ) { self notify( "bot_fire" ); - + if ( what ) { self BotBuiltinBotAction( "+fire" ); @@ -2203,19 +2203,19 @@ pressFire( time ) self endon( "disconnect" ); self notify( "bot_fire" ); self endon( "bot_fire" ); - + if ( !isdefined( time ) ) { time = 0.05; } - + self BotBuiltinBotAction( "+fire" ); - + if ( time ) { wait time; } - + self BotBuiltinBotAction( "-fire" ); } @@ -2225,7 +2225,7 @@ pressFire( time ) ads( what ) { self notify( "bot_ads" ); - + if ( what ) { self BotBuiltinBotAction( "+ads" ); @@ -2245,19 +2245,19 @@ pressADS( time ) self endon( "disconnect" ); self notify( "bot_ads" ); self endon( "bot_ads" ); - + if ( !isdefined( time ) ) { time = 0.05; } - + self BotBuiltinBotAction( "+ads" ); - + if ( time ) { wait time; } - + self BotBuiltinBotAction( "-ads" ); } @@ -2270,19 +2270,19 @@ use( time ) self endon( "disconnect" ); self notify( "bot_use" ); self endon( "bot_use" ); - + if ( !isdefined( time ) ) { time = 0.05; } - + self BotBuiltinBotAction( "+activate" ); - + if ( time ) { wait time; } - + self BotBuiltinBotAction( "-activate" ); } @@ -2295,13 +2295,13 @@ jump() self endon( "disconnect" ); self notify( "bot_jump" ); self endon( "bot_jump" ); - + if ( self getStance() != "stand" ) { self stand(); wait 1; } - + self BotBuiltinBotAction( "+gostand" ); wait 0.05; self BotBuiltinBotAction( "-gostand" ); @@ -2353,57 +2353,57 @@ bot_lookat( pos, time, vel, doAimPredict ) self endon( "death" ); self endon( "spawned_player" ); level endon ( "game_ended" ); - + if ( level.gameended || self.bot.isfrozen || !getcvarint( "bots_play_aim" ) ) { return; } - + if ( !isdefined( pos ) ) { return; } - + if ( !isdefined( doAimPredict ) ) { doAimPredict = false; } - + if ( !isdefined( time ) ) { time = 0.05; } - + if ( !isdefined( vel ) ) { vel = ( 0, 0, 0 ); } - + steps = int( time * 20 ); - + if ( steps < 1 ) { steps = 1; } - + myEye = self getEyePos(); // get our eye pos - + if ( doAimPredict ) { myEye += vector_scale( vector_scale( self getVelocity(), 0.05 ), steps - 1 ); // account for our velocity - + pos += vector_scale( vector_scale( vel, 0.05 ), steps - 1 ); // add the velocity vector } - + myAngle = self getplayerangles(); angles = vectortoangles( ( pos - myEye ) - anglestoforward( myAngle ) ); - + X = AngleClamp180( angles[ 0 ] - myAngle[ 0 ] ); X = X / steps; - + Y = AngleClamp180( angles[ 1 ] - myAngle[ 1 ] ); Y = Y / steps; - + for ( i = 0; i < steps; i++ ) { myAngle = ( AngleClamp180( myAngle[ 0 ] + X ), AngleClamp180( myAngle[ 1 ] + Y ), 0 ); diff --git a/maps/mp/bots/_bot_script.gsc b/maps/mp/bots/_bot_script.gsc index d1376d2..a161bbf 100644 --- a/maps/mp/bots/_bot_script.gsc +++ b/maps/mp/bots/_bot_script.gsc @@ -7,7 +7,7 @@ added() { self endon( "disconnect" ); - + self set_diff(); } @@ -17,11 +17,11 @@ added() connected() { self endon( "disconnect" ); - + self.killerlocation = undefined; self.lastkiller = undefined; self.bot_change_class = true; - + self thread difficulty(); self thread teamWatch(); self thread classWatch(); @@ -36,47 +36,47 @@ onKilled( eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, { self.killerlocation = undefined; self.lastkiller = undefined; - + if ( !isdefined( self ) || !isdefined( self.team ) ) { return; } - + if ( sMeansOfDeath == "MOD_FALLING" || sMeansOfDeath == "MOD_SUICIDE" ) { return; } - + if ( iDamage <= 0 ) { return; } - + if ( !isdefined( eAttacker ) || !isdefined( eAttacker.team ) ) { return; } - + if ( eAttacker == self ) { return; } - + if ( level.teambased && eAttacker.team == self.team ) { return; } - + if ( !isdefined( eInflictor ) || eInflictor.classname != "player" ) { return; } - + if ( !isalive( eAttacker ) ) { return; } - + self.killerlocation = eAttacker.origin; self.lastkiller = eAttacker; } @@ -90,49 +90,49 @@ onDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoin { return; } - + if ( !isalive( self ) ) { return; } - + if ( sMeansOfDeath == "MOD_FALLING" || sMeansOfDeath == "MOD_SUICIDE" ) { return; } - + if ( iDamage <= 0 ) { return; } - + if ( !isdefined( eAttacker ) || !isdefined( eAttacker.team ) ) { return; } - + if ( eAttacker == self ) { return; } - + if ( level.teambased && eAttacker.team == self.team ) { return; } - + if ( !isdefined( eInflictor ) || eInflictor.classname != "player" ) { return; } - + if ( !isalive( eAttacker ) ) { return; } - + self bot_cry_for_help( eAttacker ); - + self SetAttacker( eAttacker ); } @@ -145,62 +145,62 @@ bot_cry_for_help( attacker ) { return; } - + theTime = gettime(); - + if ( isdefined( self.help_time ) && theTime - self.help_time < 1000 ) { return; } - + self.help_time = theTime; - + for ( i = level.players.size - 1; i >= 0; i-- ) { player = level.players[ i ]; - + if ( !player is_bot() ) { continue; } - + if ( !isdefined( player.team ) ) { continue; } - + if ( !player IsPlayerModelOK() ) { continue; } - + if ( !isalive( player ) ) { continue; } - + if ( player == self ) { continue; } - + if ( player.team != self.team ) { continue; } - + dist = player.pers[ "bots" ][ "skill" ][ "help_dist" ]; dist *= dist; - + if ( distancesquared( self.origin, player.origin ) > dist ) { continue; } - + if ( randomint( 100 ) < 50 ) { self SetAttacker( attacker ); - + if ( randomint( 100 ) > 70 ) { break; @@ -215,16 +215,16 @@ bot_cry_for_help( attacker ) set_diff() { rankVar = getcvarint( "bots_skill" ); - + switch ( rankVar ) { case 0: self.pers[ "bots" ][ "skill" ][ "base" ] = RoundNum( random_normal_distribution( 3.5, 1.75, 1, 7 ) ); break; - + case 8: break; - + case 9: self.pers[ "bots" ][ "skill" ][ "base" ] = randomintrange( 1, 7 ); self.pers[ "bots" ][ "skill" ][ "aim_time" ] = 0.05 * randomintrange( 1, 20 ); @@ -234,11 +234,11 @@ set_diff() self.pers[ "bots" ][ "skill" ][ "no_trace_look_time" ] = 50 * randomint( 100 ); self.pers[ "bots" ][ "skill" ][ "remember_time" ] = 50 * randomint( 100 ); self.pers[ "bots" ][ "skill" ][ "fov" ] = randomfloatrange( -1, 1 ); - + randomNum = randomintrange( 500, 25000 ); self.pers[ "bots" ][ "skill" ][ "dist_start" ] = randomNum; self.pers[ "bots" ][ "skill" ][ "dist_max" ] = randomNum * 2; - + self.pers[ "bots" ][ "skill" ][ "spawn_time" ] = 0.05 * randomint( 20 ); self.pers[ "bots" ][ "skill" ][ "help_dist" ] = randomintrange( 500, 25000 ); self.pers[ "bots" ][ "skill" ][ "semi_time" ] = randomfloatrange( 0.05, 1 ); @@ -247,7 +247,7 @@ set_diff() self.pers[ "bots" ][ "skill" ][ "aim_offset_amount" ] = randomfloatrange( 0.05, 1 ); self.pers[ "bots" ][ "skill" ][ "bone_update_interval" ] = randomfloatrange( 0.05, 1 ); self.pers[ "bots" ][ "skill" ][ "bones" ] = "j_head,j_spine4,j_ankle_ri,j_ankle_le"; - + self.pers[ "bots" ][ "behavior" ][ "strafe" ] = randomint( 100 ); self.pers[ "bots" ][ "behavior" ][ "nade" ] = randomint( 100 ); self.pers[ "bots" ][ "behavior" ][ "camp" ] = randomint( 100 ); @@ -257,7 +257,7 @@ set_diff() self.pers[ "bots" ][ "behavior" ][ "class" ] = randomint( 100 ); self.pers[ "bots" ][ "behavior" ][ "jump" ] = randomint( 100 ); break; - + default: self.pers[ "bots" ][ "skill" ][ "base" ] = rankVar; break; @@ -270,7 +270,7 @@ set_diff() difficulty() { self endon( "disconnect" ); - + for ( ;; ) { if ( getcvarint( "bots_skill" ) != 9 ) @@ -297,7 +297,7 @@ difficulty() self.pers[ "bots" ][ "skill" ][ "bones" ] = "j_spine4,j_ankle_le,j_ankle_ri"; self.pers[ "bots" ][ "skill" ][ "ads_fov_multi" ] = 0.5; self.pers[ "bots" ][ "skill" ][ "ads_aimspeed_multi" ] = 0.5; - + self.pers[ "bots" ][ "behavior" ][ "strafe" ] = 0; self.pers[ "bots" ][ "behavior" ][ "nade" ] = 10; self.pers[ "bots" ][ "behavior" ][ "camp" ] = 5; @@ -307,7 +307,7 @@ difficulty() self.pers[ "bots" ][ "behavior" ][ "class" ] = 2; self.pers[ "bots" ][ "behavior" ][ "jump" ] = 0; break; - + case 2: self.pers[ "bots" ][ "skill" ][ "aim_time" ] = 0.55; self.pers[ "bots" ][ "skill" ][ "init_react_time" ] = 1000; @@ -328,7 +328,7 @@ difficulty() self.pers[ "bots" ][ "skill" ][ "bones" ] = "j_spine4,j_ankle_le,j_ankle_ri,j_head"; self.pers[ "bots" ][ "skill" ][ "ads_fov_multi" ] = 0.5; self.pers[ "bots" ][ "skill" ][ "ads_aimspeed_multi" ] = 0.5; - + self.pers[ "bots" ][ "behavior" ][ "strafe" ] = 10; self.pers[ "bots" ][ "behavior" ][ "nade" ] = 15; self.pers[ "bots" ][ "behavior" ][ "camp" ] = 5; @@ -338,7 +338,7 @@ difficulty() self.pers[ "bots" ][ "behavior" ][ "class" ] = 2; self.pers[ "bots" ][ "behavior" ][ "jump" ] = 10; break; - + case 3: self.pers[ "bots" ][ "skill" ][ "aim_time" ] = 0.4; self.pers[ "bots" ][ "skill" ][ "init_react_time" ] = 750; @@ -359,7 +359,7 @@ difficulty() self.pers[ "bots" ][ "skill" ][ "bones" ] = "j_spine4,j_spine4,j_ankle_le,j_ankle_ri,j_head"; self.pers[ "bots" ][ "skill" ][ "ads_fov_multi" ] = 0.5; self.pers[ "bots" ][ "skill" ][ "ads_aimspeed_multi" ] = 0.5; - + self.pers[ "bots" ][ "behavior" ][ "strafe" ] = 20; self.pers[ "bots" ][ "behavior" ][ "nade" ] = 20; self.pers[ "bots" ][ "behavior" ][ "camp" ] = 5; @@ -369,7 +369,7 @@ difficulty() self.pers[ "bots" ][ "behavior" ][ "class" ] = 2; self.pers[ "bots" ][ "behavior" ][ "jump" ] = 25; break; - + case 4: self.pers[ "bots" ][ "skill" ][ "aim_time" ] = 0.3; self.pers[ "bots" ][ "skill" ][ "init_react_time" ] = 600; @@ -390,7 +390,7 @@ difficulty() self.pers[ "bots" ][ "skill" ][ "bones" ] = "j_spine4,j_spine4,j_ankle_le,j_ankle_ri,j_head,j_head"; self.pers[ "bots" ][ "skill" ][ "ads_fov_multi" ] = 0.5; self.pers[ "bots" ][ "skill" ][ "ads_aimspeed_multi" ] = 0.5; - + self.pers[ "bots" ][ "behavior" ][ "strafe" ] = 30; self.pers[ "bots" ][ "behavior" ][ "nade" ] = 25; self.pers[ "bots" ][ "behavior" ][ "camp" ] = 5; @@ -400,7 +400,7 @@ difficulty() self.pers[ "bots" ][ "behavior" ][ "class" ] = 2; self.pers[ "bots" ][ "behavior" ][ "jump" ] = 35; break; - + case 5: self.pers[ "bots" ][ "skill" ][ "aim_time" ] = 0.25; self.pers[ "bots" ][ "skill" ][ "init_react_time" ] = 500; @@ -421,7 +421,7 @@ difficulty() self.pers[ "bots" ][ "skill" ][ "bones" ] = "j_spine4,j_head"; self.pers[ "bots" ][ "skill" ][ "ads_fov_multi" ] = 0.5; self.pers[ "bots" ][ "skill" ][ "ads_aimspeed_multi" ] = 0.5; - + self.pers[ "bots" ][ "behavior" ][ "strafe" ] = 40; self.pers[ "bots" ][ "behavior" ][ "nade" ] = 35; self.pers[ "bots" ][ "behavior" ][ "camp" ] = 5; @@ -431,7 +431,7 @@ difficulty() self.pers[ "bots" ][ "behavior" ][ "class" ] = 2; self.pers[ "bots" ][ "behavior" ][ "jump" ] = 50; break; - + case 6: self.pers[ "bots" ][ "skill" ][ "aim_time" ] = 0.2; self.pers[ "bots" ][ "skill" ][ "init_react_time" ] = 250; @@ -452,7 +452,7 @@ difficulty() self.pers[ "bots" ][ "skill" ][ "bones" ] = "j_spine4,j_head,j_head"; self.pers[ "bots" ][ "skill" ][ "ads_fov_multi" ] = 0.5; self.pers[ "bots" ][ "skill" ][ "ads_aimspeed_multi" ] = 0.5; - + self.pers[ "bots" ][ "behavior" ][ "strafe" ] = 50; self.pers[ "bots" ][ "behavior" ][ "nade" ] = 45; self.pers[ "bots" ][ "behavior" ][ "camp" ] = 5; @@ -462,7 +462,7 @@ difficulty() self.pers[ "bots" ][ "behavior" ][ "class" ] = 2; self.pers[ "bots" ][ "behavior" ][ "jump" ] = 75; break; - + case 7: self.pers[ "bots" ][ "skill" ][ "aim_time" ] = 0.1; self.pers[ "bots" ][ "skill" ][ "init_react_time" ] = 100; @@ -483,7 +483,7 @@ difficulty() self.pers[ "bots" ][ "skill" ][ "bones" ] = "j_head"; self.pers[ "bots" ][ "skill" ][ "ads_fov_multi" ] = 0.5; self.pers[ "bots" ][ "skill" ][ "ads_aimspeed_multi" ] = 0.5; - + self.pers[ "bots" ][ "behavior" ][ "strafe" ] = 65; self.pers[ "bots" ][ "behavior" ][ "nade" ] = 65; self.pers[ "bots" ][ "behavior" ][ "camp" ] = 5; @@ -495,7 +495,7 @@ difficulty() break; } } - + wait 5; } } @@ -506,21 +506,21 @@ difficulty() teamWatch() { self endon( "disconnect" ); - + for ( ;; ) { - while ( !isdefined( self.pers[ "team" ] ) || !allowTeamChoice() ) + while ( !isdefined( self.pers[ "team" ] ) || !allowTeamChoice() ) { wait .05; } - + wait 0.1; - + if ( self.team != "axis" && self.team != "allies" ) { self notify( "menuresponse", game[ "menu_team" ], getcvar( "bots_team" ) ); } - + while ( isdefined( self.pers[ "team" ] ) ) { wait .05; @@ -535,7 +535,7 @@ chooseRandomClass() { weap = ""; weapons = []; - + if ( self.team == "axis" ) { weapons[ weapons.size ] = "mp40_mp"; @@ -577,9 +577,9 @@ chooseRandomClass() weapons[ weapons.size ] = "PPS42_mp"; } } - + weap = weapons[ randomint( weapons.size ) ]; - + return weap; } @@ -589,26 +589,26 @@ chooseRandomClass() classWatch() { self endon( "disconnect" ); - + // cod2 has to wait this long or else theres a crash? wait 3; - + for ( ;; ) { while ( !isdefined( self.pers[ "team" ] ) || !allowClassChoice() ) { wait .05; } - + wait 0.5; - + if ( !isdefined( self.pers[ "weapon" ] ) || self.pers[ "weapon" ] == "" || !isdefined( self.bot_change_class ) ) { self notify( "menuresponse", game[ "menu_weapon_" + self.team ], self chooseRandomClass() ); } - + self.bot_change_class = true; - + while ( isdefined( self.pers[ "team" ] ) && isdefined( self.pers[ "weapon" ] ) && self.pers[ "weapon" ] != "" && isdefined( self.bot_change_class ) ) { wait .05; @@ -622,16 +622,16 @@ classWatch() onSpawned() { self endon( "disconnect" ); - + for ( ;; ) { self waittill( "spawned_player" ); - + if ( randomint( 100 ) <= self.pers[ "bots" ][ "behavior" ][ "class" ] ) { self.bot_change_class = undefined; } - + self.bot_lock_goal = false; self.help_time = undefined; self.bot_was_follow_script_update = undefined; @@ -645,11 +645,11 @@ onBotSpawned() { self endon( "disconnect" ); level endon( "game_ended" ); - + for ( ;; ) { self waittill( "bot_spawned" ); - + self thread start_bot_threads(); } } diff --git a/maps/mp/bots/_bot_utility.gsc b/maps/mp/bots/_bot_utility.gsc index cd49d91..3a8cbd9 100644 --- a/maps/mp/bots/_bot_utility.gsc +++ b/maps/mp/bots/_bot_utility.gsc @@ -11,7 +11,7 @@ wait_for_builtins() { return true; } - + if ( i < 18 ) { waittillframeend; @@ -21,7 +21,7 @@ wait_for_builtins() wait 0.05; } } - + return false; } @@ -81,7 +81,7 @@ BotBuiltinIsBot() { return self [[ level.bot_builtins[ "isbot" ] ]](); } - + return false; } @@ -99,35 +99,35 @@ is_host() doHostCheck() { self.pers[ "bot_host" ] = false; - + if ( self is_bot() ) { return; } - + result = false; - + if ( getcvar( "bots_main_firstIsHost" ) != "0" ) { BotBuiltinPrintConsole( "WARNING: bots_main_firstIsHost is enabled" ); - + if ( getcvar( "bots_main_firstIsHost" ) == "1" ) { setcvar( "bots_main_firstIsHost", self getguid() ); } - + if ( getcvar( "bots_main_firstIsHost" ) == self getguid() + "" ) { result = true; } } - + DvarGUID = getcvar( "bots_main_GUIDs" ); - + if ( DvarGUID != "" ) { guids = strtok( DvarGUID, "," ); - + for ( i = 0; i < guids.size; i++ ) { if ( self getguid() + "" == guids[ i ] ) @@ -136,12 +136,12 @@ doHostCheck() } } } - + if ( !result ) { return; } - + self.pers[ "bot_host" ] = true; } @@ -226,7 +226,7 @@ BotGetTargetRandom() { return undefined; } - + return self.bot.target.rand; } @@ -268,7 +268,7 @@ IsBotKnifing() BotFreezeControls( what ) { self.bot.isfrozen = what; - + if ( what ) { self notify( "kill_goal" ); @@ -289,7 +289,7 @@ BotIsFrozen() BotStopMoving( what ) { self.bot.stop_move = what; - + if ( what ) { self notify( "kill_goal" ); @@ -330,7 +330,7 @@ SetScriptGoal( goal, dist ) { dist = 16; } - + self.bot.script_goal = goal; self.bot.script_goal_dist = dist; waittillframeend; @@ -412,7 +412,7 @@ GetThreat() { return undefined; } - + return self.bot.target.entity; } @@ -480,24 +480,24 @@ getValidGrenade() grenadeTypes[ 5 ] = "smoke_grenade_russian_mp"; grenadeTypes[ 6 ] = "frag_grenade_german_mp"; grenadeTypes[ 7 ] = "smoke_grenade_german_mp"; - + possibles = []; - + for ( i = 0; i < grenadeTypes.size; i++ ) { if ( !self hasweapon( grenadeTypes[ i ] ) ) { continue; } - + if ( !self getAmmoCount( grenadeTypes[ i ] ) ) { continue; } - + possibles[ possibles.size ] = grenadeTypes[ i ]; } - + return random( possibles ); } @@ -531,12 +531,12 @@ isOnLadder() weaponClass( weap ) { answer = level.bots_weapon_class_names[ weap ]; - + if ( !isdefined( answer ) ) { answer = ""; } - + return answer; } @@ -546,12 +546,12 @@ weaponClass( weap ) WeaponClipSize( weap ) { answer = level.bots_weapon_clip_sizes[ weap ]; - + if ( !isdefined( answer ) ) { answer = 1; } - + return answer; } @@ -576,7 +576,7 @@ getWeaponSlot( weap ) getAmmoCount( weap ) { slot = self getWeaponSlot( weap ); - + return self getweaponslotclipammo( slot ) + self getweaponslotammo( slot ); } @@ -594,19 +594,19 @@ IsWeaponClipOnly( weap ) getStance() { myEye = self getTagOrigin( "tag_eye" ); - + height = myEye[ 2 ] - self.origin[ 2 ]; - + if ( height > 50 ) { return "stand"; } - + if ( height < 20 ) { return "prone"; } - + return "crouch"; } @@ -619,7 +619,7 @@ getVelocity() { return ( 0, 0, 0 ); } - + return self.velocity; } @@ -637,7 +637,7 @@ IsPlayerModelOK() WeaponIsFullAuto( weap ) { weaptoks = strtok( weap, "_" ); - + return isdefined( weaptoks[ 0 ] ) && isstring( weaptoks[ 0 ] ) && isdefined( level.bots_fullautoguns[ weaptoks[ 0 ] ] ); } @@ -647,17 +647,17 @@ WeaponIsFullAuto( weap ) getEyeHeight() { stance = self GetStance(); - + if ( stance == "prone" ) { return 11; } - + if ( stance == "crouch" ) { return 40; } - + return 60; } @@ -670,29 +670,29 @@ getTagOrigin( where ) { return ( 0, 0, 0 ); } - + if ( !isdefined( self.bot_model_fix ) ) { return self.origin; } - + if ( !isdefined( self.tags ) ) { self.tags = []; self.tagmap = []; } - + if ( isdefined( self.tagmap[ where ] ) ) { return self.tagmap[ where ].origin; } - + obj = spawn( "script_origin", ( 0, 0, 0 ) ); obj linkto( self, where, ( 0, 0, 0 ), ( 0, 0, 0 ) ); - + self.tags[ self.tags.size ] = obj; self.tagmap[ where ] = obj; - + return self.origin; } @@ -723,7 +723,7 @@ waittill_either_return( str1, str2 ) { return str1; } - + return str2; } @@ -745,7 +745,7 @@ waittill_string( msg, ent ) { self endon( "death" ); } - + ent endon( "die" ); self waittill( msg ); ent notify( "returned", msg ); @@ -760,36 +760,36 @@ waittill_any_timeout( timeOut, string1, string2, string3, string4, string5 ) { self endon( "death" ); } - + ent = spawnstruct(); - + if ( isdefined( string1 ) ) { self thread waittill_string( string1, ent ); } - + if ( isdefined( string2 ) ) { self thread waittill_string( string2, ent ); } - + if ( isdefined( string3 ) ) { self thread waittill_string( string3, ent ); } - + if ( isdefined( string4 ) ) { self thread waittill_string( string4, ent ); } - + if ( isdefined( string5 ) ) { self thread waittill_string( string5, ent ); } - + ent thread _timeout( timeOut ); - + ent waittill( "returned", msg ); ent notify( "die" ); return msg; @@ -801,7 +801,7 @@ waittill_any_timeout( timeOut, string1, string2, string3, string4, string5 ) _timeout( delay ) { self endon( "die" ); - + wait( delay ); self notify( "returned", "timeout" ); } @@ -820,12 +820,12 @@ isWeaponDroppable( weap ) random( arr ) { size = arr.size; - + if ( !size ) { return undefined; } - + return arr[ randomint( size ) ]; } @@ -835,17 +835,17 @@ random( arr ) array_remove( ents, remover ) { newents = []; - + for ( i = 0; i < ents.size; i++ ) { index = ents[ i ]; - + if ( index != remover ) { newents[ newents.size ] = index; } } - + return newents; } @@ -866,15 +866,15 @@ GetHostPlayer() for ( i = 0; i < level.players.size; i++ ) { player = level.players[ i ]; - + if ( !player is_host() ) { continue; } - + return player; } - + return undefined; } @@ -884,51 +884,51 @@ GetHostPlayer() bot_wait_for_host() { host = undefined; - + while ( !isdefined( level ) || !isdefined( level.players ) ) { wait 0.05; } - + for ( i = getcvarfloat( "bots_main_waitForHostTime" ); i > 0; i -= 0.05 ) { host = GetHostPlayer(); - + if ( isdefined( host ) ) { break; } - + wait 0.05; } - + if ( !isdefined( host ) ) { return; } - + for ( i = getcvarfloat( "bots_main_waitForHostTime" ); i > 0; i -= 0.05 ) { if ( isdefined( host.pers[ "team" ] ) ) { break; } - + wait 0.05; } - + if ( !isdefined( host.pers[ "team" ] ) ) { return; } - + for ( i = getcvarfloat( "bots_main_waitForHostTime" ); i > 0; i -= 0.05 ) { if ( host.pers[ "team" ] == "allies" || host.pers[ "team" ] == "axis" ) { break; } - + wait 0.05; } } @@ -941,13 +941,13 @@ sqrt( num ) res = 0; bit = 1 << 30; // The second-to-top bit is set. // Same as ((unsigned) INT32_MAX + 1) / 2. - + // "bit" starts at the highest power of four <= the argument. while ( bit > num ) { bit >>= 2; } - + while ( bit != 0 ) { if ( num >= res + bit ) @@ -959,10 +959,10 @@ sqrt( num ) { res >>= 1; } - + bit >>= 2; } - + return res; } @@ -974,17 +974,17 @@ RaySphereIntersect( start, end, spherePos, radius ) { // check if the start or end points are in the sphere r2 = radius * radius; - + if ( distancesquared( start, spherePos ) < r2 ) { return true; } - + if ( distancesquared( end, spherePos ) < r2 ) { return true; } - + // check if the line made by start and end intersect the sphere dp = end - start; a = dp[ 0 ] * dp[ 0 ] + dp[ 1 ] * dp[ 1 ] + dp[ 2 ] * dp[ 2 ]; @@ -994,35 +994,35 @@ RaySphereIntersect( start, end, spherePos, radius ) c -= 2.0 * ( spherePos[ 0 ] * start[ 0 ] + spherePos[ 1 ] * start[ 1 ] + spherePos[ 2 ] * start[ 2 ] ); c -= radius * radius; bb4ac = b * b - 4.0 * a * c; - + if ( abs( a ) < 0.0001 || bb4ac < 0 ) { return false; } - + mu1 = ( 0 - b + sqrt( bb4ac ) ) / ( 2 * a ); // mu2 = (0-b - sqrt(bb4ac)) / (2 * a); - + // intersection points of the sphere ip1 = start + vector_scale( dp, mu1 ); // ip2 = start + mu2 * dp; - + myDist = distancesquared( start, end ); - + // check if both intersection points far if ( distancesquared( start, ip1 ) > myDist/* && distancesquared(start, ip2) > myDist*/ ) { return false; } - + dpAngles = vectortoangles( dp ); - + // check if the point is behind us if ( getConeDot( ip1, start, dpAngles ) < 0/* || getConeDot(ip2, start, dpAngles) < 0*/ ) { return false; } - + return true; } @@ -1043,15 +1043,15 @@ SmokeTrace( start, end, rad ) for ( i = level.bots_smokelist.count - 1; i >= 0; i-- ) { nade = level.bots_smokelist.data[ i ]; - + if ( !RaySphereIntersect( start, end, nade.origin, rad ) ) { continue; } - + return false; } - + return true; } @@ -1072,7 +1072,7 @@ DistanceSquared2D( to, from ) { to = ( to[ 0 ], to[ 1 ], 0 ); from = ( from[ 0 ], from[ 1 ], 0 ); - + return distancesquared( to, from ); } @@ -1082,7 +1082,7 @@ DistanceSquared2D( to, from ) RoundNum( x ) { y = int( x ); - + if ( abs( x ) - abs( y ) > 0.5 ) { if ( x < 0 ) @@ -1106,7 +1106,7 @@ RoundNum( x ) RoundUp( floatVal ) { i = int( floatVal ); - + if ( i != floatVal ) { return i + 1; @@ -1124,12 +1124,12 @@ AngleClamp180( angle ) { angleFrac = angle / 360.0; angle = ( angleFrac - int( angleFrac ) ) * 360.0; - + if ( angle > 180.0 ) { return angle - 360.0; } - + return angle; } @@ -1142,7 +1142,7 @@ max( a, b ) { return a; } - + return b; } @@ -1155,7 +1155,7 @@ min( a, b ) { return b; } - + return a; } @@ -1173,122 +1173,122 @@ clamp( a, minv, maxv ) keyCodeToString( a ) { b = ""; - + switch ( a ) { case 0: b = "a"; break; - + case 1: b = "b"; break; - + case 2: b = "c"; break; - + case 3: b = "d"; break; - + case 4: b = "e"; break; - + case 5: b = "f"; break; - + case 6: b = "g"; break; - + case 7: b = "h"; break; - + case 8: b = "i"; break; - + case 9: b = "j"; break; - + case 10: b = "k"; break; - + case 11: b = "l"; break; - + case 12: b = "m"; break; - + case 13: b = "n"; break; - + case 14: b = "o"; break; - + case 15: b = "p"; break; - + case 16: b = "q"; break; - + case 17: b = "r"; break; - + case 18: b = "s"; break; - + case 19: b = "t"; break; - + case 20: b = "u"; break; - + case 21: b = "v"; break; - + case 22: b = "w"; break; - + case 23: b = "x"; break; - + case 24: b = "y"; break; - + case 25: b = "z"; break; - + case 26: b = "."; break; - + case 27: b = " "; break; } - + return b; } @@ -1298,35 +1298,35 @@ keyCodeToString( a ) parseTokensIntoWaypoint( tokens ) { waypoint = spawnstruct(); - + orgStr = tokens[ 0 ]; orgToks = strtok( orgStr, " " ); waypoint.origin = ( float_old( orgToks[ 0 ] ), float_old( orgToks[ 1 ] ), float_old( orgToks[ 2 ] ) ); - + childStr = tokens[ 1 ]; childToks = strtok( childStr, " " ); waypoint.children = []; - + for ( j = 0; j < childToks.size; j++ ) { waypoint.children[ j ] = int( childToks[ j ] ); } - + type = tokens[ 2 ]; waypoint.type = type; - + anglesStr = tokens[ 3 ]; - + if ( isdefined( anglesStr ) && anglesStr != "" ) { anglesToks = strtok( anglesStr, " " ); - + if ( anglesToks.size >= 3 ) { waypoint.angles = ( float_old( anglesToks[ 0 ] ), float_old( anglesToks[ 1 ] ), float_old( anglesToks[ 2 ] ) ); } } - + return waypoint; } @@ -1338,60 +1338,60 @@ readWpsFromFile( mapname ) waypoints = []; filename = mapname + "_wp.csv"; f = openfile( filename, "read" ); - + if ( f < 0 ) { return waypoints; } - + BotBuiltinPrintConsole( "Attempting to read waypoints from " + filename ); - + for ( ;; ) { argc = freadln( f ); - + if ( argc <= 0 ) { break; } - + waypointCount = int( fgetarg( f, 0 ) ); - + if ( waypointCount <= 0 ) { break; } - + for ( i = 1; i <= waypointCount; i++ ) { argc = freadln( f ); line = ""; - + for ( h = 0; h < argc; h++ ) { line += fgetarg( f, h ); - + if ( h < argc - 1 ) { line += ","; } } - + if ( !isdefined( line ) || line == "" ) { continue; } - + tokens = strtok( line, "," ); - + waypoint = parseTokensIntoWaypoint( tokens ); - + waypoints[ i - 1 ] = waypoint; } - + break; } - + closefile( f ); return waypoints; } @@ -1402,7 +1402,7 @@ readWpsFromFile( mapname ) float_old( num ) { setcvar( "temp_dvar_bot_util", num ); - + return getcvarfloat( "temp_dvar_bot_util" ); } @@ -1413,50 +1413,50 @@ loadmbotWps( mapname, gametype ) { f = openfile( mapname + "_" + gametype + ".wp", "read" ); wps = []; - + if ( f < 0 ) { f = openfile( mapname + "_" + gametype + ".tmp", "read" ); } - + if ( f < 0 ) { return wps; } - + argc = freadln( f ); - + if ( argc <= 0 ) { closefile( f ); return wps; } - + arg = fgetarg( f, 0 ); - + if ( !isdefined( arg ) || arg != "mbotwp" ) { closefile( f ); return wps; } - + i = 0; - + while ( freadln( f ) != -1 ) { s = fgetarg( f, 0 ); t = strtok( s, " ," ); - + if ( !isdefined( t ) || t.size < 6 ) { break; } - + wp = spawnstruct(); wp.origin = ( float_old( t[ 0 ] ), float_old( t[ 1 ] ), float_old( t[ 2 ] ) ); - + stance = "stand"; - + if ( t[ 4 ] == "1" ) { stance = "crouch"; @@ -1465,15 +1465,15 @@ loadmbotWps( mapname, gametype ) { stance = "prone"; } - + wp.children = []; k = 0; - + for ( k = 0; k < int( t[ 5 ] ); k++ ) { wp.children[ k ] = int( t[ 6 + k ] ); } - + if ( t[ 3 ] == "l" || t[ 3 ] == "m" || t[ 3 ] == "f" || t[ 3 ] == "j" ) { wp.type = "climb"; @@ -1485,7 +1485,7 @@ loadmbotWps( mapname, gametype ) else if ( t[ 3 ] == "c" ) { wp.type = "crouch"; - + wpc = wp.children[ 0 ]; wp.children = []; wp.children[ 0 ] = wpc; @@ -1494,17 +1494,17 @@ loadmbotWps( mapname, gametype ) { wp.type = stance; } - + if ( ( t.size == 9 && t[ 3 ] == "w" && t[ 5 ] == "1" ) || t[ 3 ] == "g" || t[ 3 ] == "c" ) { k += 6; wp.angles = ( float_old( t[ k ] ), float_old( t[ k + 1 ] ), 0.0 ); } - + wps[ i ] = wp; i++; } - + closefile( f ); return wps; } @@ -1515,20 +1515,20 @@ loadmbotWps( mapname, gametype ) load_waypoints() { mapname = getcvar( "mapname" ); - + level.waypointcount = 0; level.waypointusage = []; level.waypointusage[ "allies" ] = []; level.waypointusage[ "axis" ] = []; - - + + if ( !isdefined( level.waypoints ) ) { level.waypoints = []; } - + wps = readWpsFromFile( mapname ); - + if ( wps.size ) { level.waypoints = wps; @@ -1542,49 +1542,49 @@ load_waypoints() maps\mp\bots\waypoints\_custom_map::main( mapname ); break; } - + if ( level.waypoints.size ) { BotBuiltinPrintConsole( "Loaded " + level.waypoints.size + " waypoints from script." ); } } - + if ( !level.waypoints.size ) { wps = loadmbotWps( mapname, "tdm" ); - + level.waypoints = wps; - + if ( level.waypoints.size ) { BotBuiltinPrintConsole( "Loaded mbot " + level.waypoints.size + " wps" ); } } - + if ( !level.waypoints.size ) { BotBuiltinPrintConsole( "No waypoints loaded!" ); } - + level.waypointcount = level.waypoints.size; - + for ( i = 0; i < level.waypointcount; i++ ) { if ( !isdefined( level.waypoints[ i ].children ) || !isdefined( level.waypoints[ i ].children.size ) ) { level.waypoints[ i ].children = []; } - + if ( !isdefined( level.waypoints[ i ].origin ) ) { level.waypoints[ i ].origin = ( 0, 0, 0 ); } - + if ( !isdefined( level.waypoints[ i ].type ) ) { level.waypoints[ i ].type = "crouch"; } - + level.waypoints[ i ].childcount = undefined; } } @@ -1595,19 +1595,19 @@ load_waypoints() nearAnyOfWaypoints( dist, waypoints ) { dist *= dist; - + for ( i = 0; i < waypoints.size; i++ ) { waypoint = level.waypoints[ waypoints[ i ] ]; - + if ( distancesquared( waypoint.origin, self.origin ) > dist ) { continue; } - + return true; } - + return false; } @@ -1617,21 +1617,21 @@ nearAnyOfWaypoints( dist, waypoints ) waypointsNear( waypoints, dist ) { dist *= dist; - + answer = []; - + for ( i = 0; i < waypoints.size; i++ ) { wp = level.waypoints[ waypoints[ i ] ]; - + if ( distancesquared( wp.origin, self.origin ) > dist ) { continue; } - + answer[ answer.size ] = waypoints[ i ]; } - + return answer; } @@ -1642,21 +1642,21 @@ getNearestWaypointOfWaypoints( waypoints ) { answer = undefined; closestDist = 2147483647; - + for ( i = 0; i < waypoints.size; i++ ) { waypoint = level.waypoints[ waypoints[ i ] ]; thisDist = distancesquared( self.origin, waypoint.origin ); - + if ( isdefined( answer ) && thisDist > closestDist ) { continue; } - + answer = waypoints[ i ]; closestDist = thisDist; } - + return answer; } @@ -1666,18 +1666,18 @@ getNearestWaypointOfWaypoints( waypoints ) getWaypointsOfType( type ) { answer = []; - + for ( i = 0; i < level.waypointcount; i++ ) { wp = level.waypoints[ i ]; - + if ( type == "camp" ) { if ( wp.type != "crouch" ) { continue; } - + if ( wp.children.size != 1 ) { continue; @@ -1687,10 +1687,10 @@ getWaypointsOfType( type ) { continue; } - + answer[ answer.size ] = i; } - + return answer; } @@ -1703,7 +1703,7 @@ getWaypointForIndex( i ) { return undefined; } - + return level.waypoints[ i ]; } @@ -1715,7 +1715,7 @@ getGoodMapAmount() switch ( getcvar( "mapname" ) ) { } - + return 2; } @@ -1727,7 +1727,7 @@ getMapName( map ) switch ( map ) { } - + return map; } @@ -1737,27 +1737,27 @@ getMapName( map ) waittill_any( string1, string2, string3, string4, string5 ) { assert( isdefined( string1 ) ); - + if ( isdefined( string2 ) ) { self endon( string2 ); } - + if ( isdefined( string3 ) ) { self endon( string3 ); } - + if ( isdefined( string4 ) ) { self endon( string4 ); } - + if ( isdefined( string5 ) ) { self endon( string5 ); } - + self waittill( string1 ); } @@ -1775,27 +1775,27 @@ doExtraCheck() getBotToKick() { bots = getBotArray(); - + if ( !isdefined( bots ) || !isdefined( bots.size ) || bots.size <= 0 || !isdefined( bots[ 0 ] ) ) { return undefined; } - + tokick = undefined; axis = 0; allies = 0; team = getcvar( "bots_team" ); - + // count teams for ( i = 0; i < bots.size; i++ ) { bot = bots[ i ]; - + if ( !isdefined( bot ) || !isdefined( bot.team ) ) { continue; } - + if ( bot.team == "allies" ) { allies++; @@ -1809,7 +1809,7 @@ getBotToKick() return bot; } } - + // search for a bot on the other team if ( team == "custom" || team == "axis" ) { @@ -1819,7 +1819,7 @@ getBotToKick() { // get the team with the most bots team = "allies"; - + if ( axis > allies ) { team = "axis"; @@ -1829,63 +1829,63 @@ getBotToKick() { team = "axis"; } - + // get the bot on this team with lowest skill for ( i = 0; i < bots.size; i++ ) { bot = bots[ i ]; - + if ( !isdefined( bot ) || !isdefined( bot.team ) ) { continue; } - + if ( bot.team != team ) { continue; } - + if ( !isdefined( bot.pers ) || !isdefined( bot.pers[ "bots" ] ) || !isdefined( bot.pers[ "bots" ][ "skill" ] ) || !isdefined( bot.pers[ "bots" ][ "skill" ][ "base" ] ) ) { continue; } - + if ( isdefined( tokick ) && bot.pers[ "bots" ][ "skill" ][ "base" ] > tokick.pers[ "bots" ][ "skill" ][ "base" ] ) { continue; } - + tokick = bot; } - + if ( isdefined( tokick ) ) { return tokick; } - + // just kick lowest skill for ( i = 0; i < bots.size; i++ ) { bot = bots[ i ]; - + if ( !isdefined( bot ) || !isdefined( bot.team ) ) { continue; } - + if ( !isdefined( bot.pers ) || !isdefined( bot.pers[ "bots" ] ) || !isdefined( bot.pers[ "bots" ][ "skill" ] ) || !isdefined( bot.pers[ "bots" ][ "skill" ][ "base" ] ) ) { continue; } - + if ( isdefined( tokick ) && bot.pers[ "bots" ][ "skill" ][ "base" ] > tokick.pers[ "bots" ][ "skill" ][ "base" ] ) { continue; } - + tokick = bot; } - + return tokick; } @@ -1896,19 +1896,19 @@ getBotArray() { result = []; playercount = level.players.size; - + for ( i = 0; i < playercount; i++ ) { player = level.players[ i ]; - + if ( !player is_bot() ) { continue; } - + result[ result.size ] = player; } - + return result; } @@ -1918,9 +1918,9 @@ getBotArray() WaypointsToKDTree() { kdTree = KDTree(); - + kdTree _WaypointsToKDTree( level.waypoints, 0 ); - + return kdTree; } @@ -1933,44 +1933,44 @@ _WaypointsToKDTree( waypoints, dem ) { return; } - + callbacksort = undefined; - + switch ( dem ) { case 0: callbacksort = ::HeapSortCoordX; break; - + case 1: callbacksort = ::HeapSortCoordY; break; - + case 2: callbacksort = ::HeapSortCoordZ; break; } - + heap = NewHeap( callbacksort ); - + for ( i = 0; i < waypoints.size; i++ ) { heap HeapInsert( waypoints[ i ] ); } - + sorted = []; - + while ( heap.data.size ) { sorted[ sorted.size ] = heap.data[ 0 ]; heap HeapRemove(); } - + median = int( sorted.size / 2 ); // use divide and conq - + left = []; right = []; - + for ( i = 0; i < sorted.size; i++ ) { if ( i < median ) @@ -1982,11 +1982,11 @@ _WaypointsToKDTree( waypoints, dem ) left[ left.size ] = sorted[ i ]; } } - + self KDTreeInsert( sorted[ median ] ); - + _WaypointsToKDTree( left, ( dem + 1 ) % 3 ); - + _WaypointsToKDTree( right, ( dem + 1 ) % 3 ); } @@ -1998,7 +1998,7 @@ List() list = spawnstruct(); list.count = 0; list.data = []; - + return list; } @@ -2008,7 +2008,7 @@ List() ListAdd( thing ) { self.data[ self.count ] = thing; - + self.count++; } @@ -2021,7 +2021,7 @@ ListAddFirst( thing ) { self.data[ i + 1 ] = self.data[ i ]; } - + self.data[ 0 ] = thing; self.count++; } @@ -2040,7 +2040,7 @@ ListRemove( thing ) self.data[ i ] = self.data[ i + 1 ]; i++; } - + self.data[ i ] = undefined; self.count--; break; @@ -2056,7 +2056,7 @@ KDTree() kdTree = spawnstruct(); kdTree.root = undefined; kdTree.count = 0; - + return kdTree; } @@ -2085,12 +2085,12 @@ _KDTreeInsert( node, data, dem, x0, y0, z0, x1, y1, z1 ) r.y1 = y1; r.z0 = z0; r.z1 = z1; - + self.count++; - + return r; } - + switch ( dem ) { case 0: @@ -2102,9 +2102,9 @@ _KDTreeInsert( node, data, dem, x0, y0, z0, x1, y1, z1 ) { node.right = self _KDTreeInsert( node.right, data, 1, node.data.origin[ 0 ], y0, z0, x1, y1, z1 ); } - + break; - + case 1: if ( data.origin[ 1 ] < node.data.origin[ 1 ] ) { @@ -2114,9 +2114,9 @@ _KDTreeInsert( node, data, dem, x0, y0, z0, x1, y1, z1 ) { node.right = self _KDTreeInsert( node.right, data, 2, x0, node.data.origin[ 1 ], z0, x1, y1, z1 ); } - + break; - + case 2: if ( data.origin[ 2 ] < node.data.origin[ 2 ] ) { @@ -2126,10 +2126,10 @@ _KDTreeInsert( node, data, dem, x0, y0, z0, x1, y1, z1 ) { node.right = self _KDTreeInsert( node.right, data, 0, x0, y0, node.data.origin[ 2 ], x1, y1, z1 ); } - + break; } - + return node; } @@ -2142,7 +2142,7 @@ KDTreeNearest( origin ) { return undefined; } - + return self _KDTreeNearest( self.root, origin, self.root.data, distancesquared( self.root.data.origin, origin ), 0 ); } @@ -2155,31 +2155,31 @@ _KDTreeNearest( node, point, closest, closestdist, dem ) { return closest; } - + thisDis = distancesquared( node.data.origin, point ); - + if ( thisDis < closestdist ) { closestdist = thisDis; closest = node.data; } - + if ( node RectDistanceSquared( point ) < closestdist ) { near = node.left; far = node.right; - + if ( point[ dem ] > node.data.origin[ dem ] ) { near = node.right; far = node.left; } - + closest = self _KDTreeNearest( near, point, closest, closestdist, ( dem + 1 ) % 3 ); - + closest = self _KDTreeNearest( far, point, closest, distancesquared( closest.origin, point ), ( dem + 1 ) % 3 ); } - + return closest; } @@ -2191,7 +2191,7 @@ RectDistanceSquared( origin ) dx = 0; dy = 0; dz = 0; - + if ( origin[ 0 ] < self.x0 ) { dx = origin[ 0 ] - self.x0; @@ -2200,7 +2200,7 @@ RectDistanceSquared( origin ) { dx = origin[ 0 ] - self.x1; } - + if ( origin[ 1 ] < self.y0 ) { dy = origin[ 1 ] - self.y0; @@ -2209,8 +2209,8 @@ RectDistanceSquared( origin ) { dy = origin[ 1 ] - self.y1; } - - + + if ( origin[ 2 ] < self.z0 ) { dz = origin[ 2 ] - self.z0; @@ -2219,7 +2219,7 @@ RectDistanceSquared( origin ) { dz = origin[ 2 ] - self.z1; } - + return dx * dx + dy * dy + dz * dz; } @@ -2279,7 +2279,7 @@ NewHeap( compare ) heap_node = spawnstruct(); heap_node.data = []; heap_node.compare = compare; - + return heap_node; } @@ -2290,19 +2290,19 @@ HeapInsert( item ) { insert = self.data.size; self.data[ insert ] = item; - + current = insert + 1; - + while ( current > 1 ) { last = current; current = int( current / 2 ); - + if ( ![[ self.compare ]]( item, self.data[ current - 1 ] ) ) { break; } - + self.data[ last - 1 ] = self.data[ current - 1 ]; self.data[ current - 1 ] = item; } @@ -2315,17 +2315,17 @@ _HeapNextChild( node, hsize ) { left = node * 2; right = left + 1; - + if ( left > hsize ) { return -1; } - + if ( right > hsize ) { return left; } - + if ( [[ self.compare ]]( self.data[ left - 1 ], self.data[ right - 1 ] ) ) { return left; @@ -2342,39 +2342,39 @@ _HeapNextChild( node, hsize ) HeapRemove() { remove = self.data.size; - + if ( !remove ) { return remove; } - + move = self.data[ remove - 1 ]; self.data[ 0 ] = move; self.data[ remove - 1 ] = undefined; remove--; - + if ( !remove ) { return remove; } - + last = 1; next = self _HeapNextChild( 1, remove ); - + while ( next != -1 ) { if ( [[ self.compare ]]( move, self.data[ next - 1 ] ) ) { break; } - + self.data[ last - 1 ] = self.data[ next - 1 ]; self.data[ next - 1 ] = move; - + last = next; next = self _HeapNextChild( next, remove ); } - + return remove; } @@ -2395,14 +2395,14 @@ RemoveWaypointUsage( wp, team ) { return; } - + if ( !isdefined( level.waypointusage[ team ][ wp + "" ] ) ) { return; } - + level.waypointusage[ team ][ wp + "" ]--; - + if ( level.waypointusage[ team ][ wp + "" ] <= 0 ) { level.waypointusage[ team ][ wp + "" ] = undefined; @@ -2416,25 +2416,25 @@ GetNearestWaypointWithSight( pos ) { candidate = undefined; dist = 2147483647; - + for ( i = 0; i < level.waypointcount; i++ ) { if ( !bullettracepassed( pos + ( 0, 0, 15 ), level.waypoints[ i ].origin + ( 0, 0, 15 ), false, undefined ) ) { continue; } - + curdis = distancesquared( level.waypoints[ i ].origin, pos ); - + if ( curdis > dist ) { continue; } - + dist = curdis; candidate = i; } - + return candidate; } @@ -2445,20 +2445,20 @@ getNearestWaypoint( pos ) { candidate = undefined; dist = 2147483647; - + for ( i = 0; i < level.waypointcount; i++ ) { curdis = distancesquared( level.waypoints[ i ].origin, pos ); - + if ( curdis > dist ) { continue; } - + dist = curdis; candidate = i; } - + return candidate; } @@ -2472,59 +2472,59 @@ AStarSearch( start, goal, team, greedy_path ) open = NewHeap( ::ReverseHeapAStar ); // heap openset = []; // set for quick lookup closed = []; // set for quick lookup - - + + startWp = getNearestWaypoint( start ); - + if ( !isdefined( startWp ) ) { return []; } - + _startwp = undefined; - + if ( !bullettracepassed( start + ( 0, 0, 15 ), level.waypoints[ startWp ].origin + ( 0, 0, 15 ), false, undefined ) ) { _startwp = GetNearestWaypointWithSight( start ); } - + if ( isdefined( _startwp ) ) { startWp = _startwp; } - - + + goalWp = getNearestWaypoint( goal ); - + if ( !isdefined( goalWp ) ) { return []; } - + _goalWp = undefined; - + if ( !bullettracepassed( goal + ( 0, 0, 15 ), level.waypoints[ goalWp ].origin + ( 0, 0, 15 ), false, undefined ) ) { _goalWp = GetNearestWaypointWithSight( goal ); } - + if ( isdefined( _goalWp ) ) { goalWp = _goalWp; } - - + + node = spawnstruct(); node.g = 0; // path dist so far node.h = distancesquared( level.waypoints[ startWp ].origin, level.waypoints[ goalWp ].origin ); // herustic, distance to goal for path finding node.f = node.h + node.g; // combine path dist and heru, use reverse heap to sort the priority queue by this attru node.index = startWp; node.parent = undefined; // we are start, so we have no parent - + // push node onto queue openset[ node.index + "" ] = node; open HeapInsert( node ); - + // while the queue is not empty while ( open.data.size ) { @@ -2533,12 +2533,12 @@ AStarSearch( start, goal, team, greedy_path ) open HeapRemove(); openset[ bestNode.index + "" ] = undefined; wp = level.waypoints[ bestNode.index ]; - + // check if we made it to the goal if ( bestNode.index == goalWp ) { path = []; - + while ( isdefined( bestNode ) ) { if ( isdefined( team ) && isdefined( level.waypointusage ) ) @@ -2547,68 +2547,68 @@ AStarSearch( start, goal, team, greedy_path ) { level.waypointusage[ team ][ bestNode.index + "" ] = 0; } - + level.waypointusage[ team ][ bestNode.index + "" ]++; } - + // construct path path[ path.size ] = bestNode.index; - + bestNode = bestNode.parent; } - + return path; } - + // for each child of bestnode for ( i = wp.children.size - 1; i >= 0; i-- ) { child = wp.children[ i ]; childWp = level.waypoints[ child ]; - + penalty = 1; - + if ( !greedy_path && isdefined( team ) && isdefined( level.waypointusage ) ) { temppen = 1; - + if ( isdefined( level.waypointusage[ team ][ child + "" ] ) ) { - temppen = level.waypointusage[ team ][ child + "" ]; // consider how many bots are taking this path + temppen = level.waypointusage[ team ][ child + "" ]; // consider how many bots are taking this path } - + if ( temppen > 1 ) { penalty = temppen; } } - + // have certain types of nodes more expensive if ( childWp.type == "climb" || childWp.type == "prone" ) { penalty += 4; } - + // calc the total path we have took 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 inopen = isdefined( openset[ child + "" ] ); - + if ( inopen && openset[ child + "" ].g <= newg ) { continue; } - + inclosed = isdefined( closed[ child + "" ] ); - + if ( inclosed && closed[ child + "" ].g <= newg ) { continue; } - + node = undefined; - + if ( inopen ) { node = openset[ child + "" ]; @@ -2621,19 +2621,19 @@ AStarSearch( start, goal, team, greedy_path ) { node = spawnstruct(); } - + node.parent = bestNode; node.g = newg; node.h = distancesquared( childWp.origin, level.waypoints[ goalWp ].origin ); node.f = node.g + node.h; node.index = child; - + // check if in closed, remove it if ( inclosed ) { closed[ child + "" ] = undefined; } - + // check if not in open, add it if ( !inopen ) { @@ -2641,11 +2641,11 @@ AStarSearch( start, goal, team, greedy_path ) openset[ child + "" ] = node; } } - + // done with children, push onto closed closed[ bestNode.index + "" ] = bestNode; } - + return []; } @@ -2657,12 +2657,12 @@ array_average( array ) { assert( array.size > 0 ); total = 0; - + for ( i = 0; i < array.size; i++ ) { total += array[ i ]; } - + return ( total / array.size ); } @@ -2674,19 +2674,19 @@ array_std_deviation( array, mean ) { assert( array.size > 0 ); tmp = []; - + for ( i = 0; i < array.size; i++ ) { tmp[ i ] = ( array[ i ] - mean ) * ( array[ i ] - mean ); } - + total = 0; - + for ( i = 0; i < tmp.size; i++ ) { total = total + tmp[ i ]; } - + return sqrt( total / array.size ); } @@ -2700,28 +2700,28 @@ random_normal_distribution( mean, std_deviation, lower_bound, upper_bound ) x2 = 0; w = 1; y1 = 0; - + while ( w >= 1 ) { x1 = 2 * randomfloatrange( 0, 1 ) - 1; x2 = 2 * randomfloatrange( 0, 1 ) - 1; w = x1 * x1 + x2 * x2; } - + w = sqrt( ( -2.0 * Log( w ) ) / w ); y1 = x1 * w; number = mean + y1 * std_deviation; - + if ( isdefined( lower_bound ) && number < lower_bound ) { number = lower_bound; } - + if ( isdefined( upper_bound ) && number > upper_bound ) { number = upper_bound; } - + return ( number ); } @@ -2737,7 +2737,7 @@ Log( x ) denom = 1.0; frac = xmlxpl; sum = frac; - + while ( sum != old_sum ) { old_sum = sum; @@ -2745,7 +2745,7 @@ Log( x ) frac *= xmlxpl_2; sum += frac / denom; } - + answer = 2.0 * sum; return answer; } diff --git a/maps/mp/bots/waypoints/_custom_map.gsc b/maps/mp/bots/waypoints/_custom_map.gsc index ee0a2e8..5825b72 100644 --- a/maps/mp/bots/waypoints/_custom_map.gsc +++ b/maps/mp/bots/waypoints/_custom_map.gsc @@ -1,4 +1,4 @@ -main(mapname) +main( mapname ) { } diff --git a/maps/mp/gametypes/_clientids.gsc b/maps/mp/gametypes/_clientids.gsc index f81004a..49e3cf8 100644 --- a/maps/mp/gametypes/_clientids.gsc +++ b/maps/mp/gametypes/_clientids.gsc @@ -1,9 +1,9 @@ init() { level.clientid = 0; - + level thread onPlayerConnect(); - + // bootstrap level thread scripts\bots_adapter_libcod::init(); level thread scripts\bots::init(); @@ -11,10 +11,10 @@ init() onPlayerConnect() { - for(;;) + for ( ;; ) { - level waittill("connecting", player); - + level waittill( "connecting", player ); + player.clientid = level.clientid; level.clientid++; // Is this safe? What if a server runs for a long time and many people join/leave } diff --git a/scripts/bots_adapter_libcod.gsc b/scripts/bots_adapter_libcod.gsc index c529ebf..9b185e5 100644 --- a/scripts/bots_adapter_libcod.gsc +++ b/scripts/bots_adapter_libcod.gsc @@ -19,67 +19,67 @@ do_botaction( action ) case "+fire": self fireweapon( true ); break; - + case "-fire": self fireweapon( false ); break; - + case "+ads": self adsaim( true ); break; - + case "-ads": self adsaim( false ); break; - + case "-reload": self reloadweapon( false ); break; - + case "+reload": self reloadweapon( true ); break; - + case "-melee": self meleeweapon( false ); break; - + case "+melee": self meleeweapon( true ); break; - + case "+frag": self thrownade( true ); break; - + case "-frag": self thrownade( false ); break; - + case "-gocrouch": case "-goprone": case "-gostand": self setbotstance( "stand" ); break; - + case "+gocrouch": self setbotstance( "crouch" ); break; - + case "+goprone": self setbotstance( "prone" ); break; - + case "+gostand": self setbotstance( "jump" ); break; - + case "-smoke": // no equal in libcod case "-activate": case "-holdbreath": break; } - + // self botaction( action ); } @@ -94,7 +94,7 @@ do_botstop() self setlean( "none" ); self setwalkdir( "none" ); self switchtoweaponid( 1 ); // libcod needs weapon name to id - + // self botstop(); } @@ -106,27 +106,27 @@ do_botmovement( forward, right ) self setwalkdir( "forward" ); return; } - + if ( right > 63 ) { self setwalkdir( "right" ); return; } - + if ( forward < -63 ) { self setwalkdir( "back" ); return; } - + if ( right < -63 ) { self setwalkdir( "left" ); return; } - + self setwalkdir( "none" ); - + // self botmovement( forward, right ); }