diff --git a/README.md b/README.md index efa1025..20762ef 100644 --- a/README.md +++ b/README.md @@ -114,6 +114,13 @@ This mod extends the functionality and features of Combat Training in Black Ops - bots_main_waitForHostTime - a float value, how long in seconds to wait for the host player to connect before adding in bots ## Changelog +- v1.1.1 + - Fixed some script runtime errors + - Improved domination + - Bots use altmode weapons + - Improved revenge + - Bots can swap weapons on spawn more likely + - v1.1.0 - Rewrote using CoD4x as a base - Fixed bots not knifing diff --git a/main_shared/maps/mp/gametypes/_bot.gsc b/main_shared/maps/mp/gametypes/_bot.gsc index 232e25e..8c2ff7e 100644 --- a/main_shared/maps/mp/gametypes/_bot.gsc +++ b/main_shared/maps/mp/gametypes/_bot.gsc @@ -15,7 +15,7 @@ */ init() { - level.bw_VERSION = "1.1.0"; + level.bw_VERSION = "1.1.1"; level.bot_offline = false; diff --git a/mods/mp_bots/maps/mp/bots/_bot_script.gsc b/mods/mp_bots/maps/mp/bots/_bot_script.gsc index 4b5c827..8e82340 100644 --- a/mods/mp_bots/maps/mp/bots/_bot_script.gsc +++ b/mods/mp_bots/maps/mp/bots/_bot_script.gsc @@ -173,6 +173,7 @@ bot_damage_callback( eAttacker, iDamage, sMeansOfDeath, sWeapon, eInflictor, sHi return; self.killerLocation = undefined; + self.lastKiller = undefined; if(!IsDefined( self ) || !isDefined(self.team)) return; @@ -201,6 +202,7 @@ bot_damage_callback( eAttacker, iDamage, sMeansOfDeath, sWeapon, eInflictor, sHi return; self.killerLocation = eAttacker.origin; + self.lastKiller = eAttacker; if (!isSubStr(sWeapon, "_silencer_")) self bot_cry_for_help( eAttacker ); @@ -332,7 +334,10 @@ bot_spawn() self thread bot_radiation_think(); if (getDvarInt("bots_play_nade")) + { self thread bot_use_equipment_think(); + self thread bot_watch_think_mw2(); + } if (getDvarInt("bots_play_target_other")) { @@ -686,6 +691,9 @@ changeToWeapon(weap) self SwitchToWeapon(weap); + if (isWeaponAltmode(weap)) + self setSpawnWeapon(weap); + self waittill_any_timeout(5, "weapon_change"); return (self GetCurrentWeapon() == weap); @@ -2457,7 +2465,7 @@ bot_dogs_think() } } - if ( dog.script_owner == self ) + if ( isDefined(dog.script_owner) && dog.script_owner == self ) { continue; } @@ -2527,6 +2535,53 @@ follow_target() } /* + Bots play mw2 +*/ +bot_watch_think_mw2() +{ + self endon("disconnect"); + self endon("death"); + level endon("game_ended"); + + for (;;) + { + wait randomIntRange(1, 4); + + if(self isDefusing() || self isPlanting()) + continue; + + if (self IsRemoteControlling()) + continue; + + if (self InLastStand()) + continue; + + if (isDefined(self GetThreat())) + continue; + + tube = self getValidTube(); + if (!isDefined(tube)) + { + if (self GetAmmoCount("m72_law_mp")) + tube = "m72_law_mp"; + else if (self GetAmmoCount("rpg_mp")) + tube = "rpg_mp"; + else + continue; + } + + if (self GetCurrentWeapon() == tube) + continue; + + if (randomInt(100) > 35) + continue; + + self ChangeToWeapon(tube); + } +} + +/* + Fast swaps or reload cancels don't work cause t5 bots wait for the anim to complete Bots will think to switch weapons */ bot_weapon_think() @@ -2534,6 +2589,8 @@ bot_weapon_think() self endon("death"); self endon("disconnect"); level endon("game_ended"); + + first = true; for(;;) { @@ -2554,13 +2611,23 @@ bot_weapon_think() if (isDefined(threat) && !isPlayer(threat)) continue; - if(curWeap != "none" && self getAmmoCount(curWeap) && curWeap != "strela_mp") + if (first) { - if(randomInt(100) > 2) + first = false; + + if (randomInt(100) > 10) continue; + } + else + { + if(curWeap != "none" && self getAmmoCount(curWeap) && curWeap != "strela_mp") + { + if(randomInt(100) > 2) + continue; - if(isDefined(threat)) - continue; + if(isDefined(threat)) + continue; + } } weaponslist = self getweaponslist(); @@ -2573,7 +2640,7 @@ bot_weapon_think() if(!self getAmmoCount(weapon)) continue; - if (!maps\mp\gametypes\_weapons::isPrimaryWeapon( weapon ) && !maps\mp\gametypes\_weapons::isSideArm( weapon )) + if (!maps\mp\gametypes\_weapons::isPrimaryWeapon( weapon ) && !maps\mp\gametypes\_weapons::isSideArm( weapon ) && !isWeaponAltmode(weapon)) continue; if(curWeap == weapon || weapon == "none" || weapon == "" || weapon == "strela_mp") @@ -2760,6 +2827,14 @@ bot_revenge_think() { self endon( "death" ); self endon( "disconnect" ); + + if (isDefined(self.lastKiller) && isAlive(self.lastKiller)) + { + if(bulletTracePassed(self getEye(), self.lastKiller getTagOrigin( "j_spineupper" ), false, self.lastKiller)) + { + self setAttacker(self.lastKiller); + } + } if(!isDefined(self.killerLocation)) return; @@ -3094,20 +3169,23 @@ bot_dom_cap_think() otherFlagCount = maps\mp\gametypes\dom::getTeamFlagCount( otherTeam ); - if ( myFlagCount < otherFlagCount ) + if (game["teamScores"][myteam] >= game["teamScores"][otherTeam]) { - if ( randomint( 100 ) < 15 ) - continue; - } - else if ( myFlagCount == otherFlagCount ) - { - if ( randomint( 100 ) < 35 ) - continue; - } - else if ( myFlagCount > otherFlagCount ) - { - if ( randomint( 100 ) < 95 ) - continue; + if ( myFlagCount < otherFlagCount ) + { + if ( randomint( 100 ) < 15 ) + continue; + } + else if ( myFlagCount == otherFlagCount ) + { + if ( randomint( 100 ) < 35 ) + continue; + } + else if ( myFlagCount > otherFlagCount ) + { + if ( randomint( 100 ) < 95 ) + continue; + } } flag = undefined; diff --git a/mods/mp_bots/maps/mp/bots/_bot_utility.gsc b/mods/mp_bots/maps/mp/bots/_bot_utility.gsc index a1e42d4..be32501 100644 --- a/mods/mp_bots/maps/mp/bots/_bot_utility.gsc +++ b/mods/mp_bots/maps/mp/bots/_bot_utility.gsc @@ -145,6 +145,38 @@ GetBotDiffNum() return num; } +/* + is the weapon alt mode? +*/ +isWeaponAltmode(weap) +{ + if (isStrStart(weap, "gl_") || isStrStart(weap, "ft_") || isStrStart(weap, "mk_")) + return true; + + return false; +} + +/* + Returns a valid grenade launcher weapon +*/ +getValidTube() +{ + weaps = self getweaponslist(); + + for (i = 0; i < weaps.size; i++) + { + weap = weaps[i]; + + if(!self getAmmoCount(weap)) + continue; + + if ((isSubStr(weap, "gl_") && !isSubStr(weap, "_gl_")) || weap == "china_lake_mp") + return weap; + } + + return undefined; +} + /* Taken from iw4 script */ @@ -332,9 +364,9 @@ doExtraCheck() */ getConeDot(to, from, dir) { - dirToTarget = VectorNormalize(to-from); - forward = AnglesToForward(dir); - return vectordot(dirToTarget, forward); + dirToTarget = VectorNormalize(to-from); + forward = AnglesToForward(dir); + return vectordot(dirToTarget, forward); } /* diff --git a/mods/mp_bots/maps/mp/gametypes/_bot.gsc b/mods/mp_bots/maps/mp/gametypes/_bot.gsc index 232e25e..8c2ff7e 100644 --- a/mods/mp_bots/maps/mp/gametypes/_bot.gsc +++ b/mods/mp_bots/maps/mp/gametypes/_bot.gsc @@ -15,7 +15,7 @@ */ init() { - level.bw_VERSION = "1.1.0"; + level.bw_VERSION = "1.1.1"; level.bot_offline = false; diff --git a/mods/patch_mp/maps/mp/bots/_bot_script.gsc b/mods/patch_mp/maps/mp/bots/_bot_script.gsc index 4b5c827..8e82340 100644 --- a/mods/patch_mp/maps/mp/bots/_bot_script.gsc +++ b/mods/patch_mp/maps/mp/bots/_bot_script.gsc @@ -173,6 +173,7 @@ bot_damage_callback( eAttacker, iDamage, sMeansOfDeath, sWeapon, eInflictor, sHi return; self.killerLocation = undefined; + self.lastKiller = undefined; if(!IsDefined( self ) || !isDefined(self.team)) return; @@ -201,6 +202,7 @@ bot_damage_callback( eAttacker, iDamage, sMeansOfDeath, sWeapon, eInflictor, sHi return; self.killerLocation = eAttacker.origin; + self.lastKiller = eAttacker; if (!isSubStr(sWeapon, "_silencer_")) self bot_cry_for_help( eAttacker ); @@ -332,7 +334,10 @@ bot_spawn() self thread bot_radiation_think(); if (getDvarInt("bots_play_nade")) + { self thread bot_use_equipment_think(); + self thread bot_watch_think_mw2(); + } if (getDvarInt("bots_play_target_other")) { @@ -686,6 +691,9 @@ changeToWeapon(weap) self SwitchToWeapon(weap); + if (isWeaponAltmode(weap)) + self setSpawnWeapon(weap); + self waittill_any_timeout(5, "weapon_change"); return (self GetCurrentWeapon() == weap); @@ -2457,7 +2465,7 @@ bot_dogs_think() } } - if ( dog.script_owner == self ) + if ( isDefined(dog.script_owner) && dog.script_owner == self ) { continue; } @@ -2527,6 +2535,53 @@ follow_target() } /* + Bots play mw2 +*/ +bot_watch_think_mw2() +{ + self endon("disconnect"); + self endon("death"); + level endon("game_ended"); + + for (;;) + { + wait randomIntRange(1, 4); + + if(self isDefusing() || self isPlanting()) + continue; + + if (self IsRemoteControlling()) + continue; + + if (self InLastStand()) + continue; + + if (isDefined(self GetThreat())) + continue; + + tube = self getValidTube(); + if (!isDefined(tube)) + { + if (self GetAmmoCount("m72_law_mp")) + tube = "m72_law_mp"; + else if (self GetAmmoCount("rpg_mp")) + tube = "rpg_mp"; + else + continue; + } + + if (self GetCurrentWeapon() == tube) + continue; + + if (randomInt(100) > 35) + continue; + + self ChangeToWeapon(tube); + } +} + +/* + Fast swaps or reload cancels don't work cause t5 bots wait for the anim to complete Bots will think to switch weapons */ bot_weapon_think() @@ -2534,6 +2589,8 @@ bot_weapon_think() self endon("death"); self endon("disconnect"); level endon("game_ended"); + + first = true; for(;;) { @@ -2554,13 +2611,23 @@ bot_weapon_think() if (isDefined(threat) && !isPlayer(threat)) continue; - if(curWeap != "none" && self getAmmoCount(curWeap) && curWeap != "strela_mp") + if (first) { - if(randomInt(100) > 2) + first = false; + + if (randomInt(100) > 10) continue; + } + else + { + if(curWeap != "none" && self getAmmoCount(curWeap) && curWeap != "strela_mp") + { + if(randomInt(100) > 2) + continue; - if(isDefined(threat)) - continue; + if(isDefined(threat)) + continue; + } } weaponslist = self getweaponslist(); @@ -2573,7 +2640,7 @@ bot_weapon_think() if(!self getAmmoCount(weapon)) continue; - if (!maps\mp\gametypes\_weapons::isPrimaryWeapon( weapon ) && !maps\mp\gametypes\_weapons::isSideArm( weapon )) + if (!maps\mp\gametypes\_weapons::isPrimaryWeapon( weapon ) && !maps\mp\gametypes\_weapons::isSideArm( weapon ) && !isWeaponAltmode(weapon)) continue; if(curWeap == weapon || weapon == "none" || weapon == "" || weapon == "strela_mp") @@ -2760,6 +2827,14 @@ bot_revenge_think() { self endon( "death" ); self endon( "disconnect" ); + + if (isDefined(self.lastKiller) && isAlive(self.lastKiller)) + { + if(bulletTracePassed(self getEye(), self.lastKiller getTagOrigin( "j_spineupper" ), false, self.lastKiller)) + { + self setAttacker(self.lastKiller); + } + } if(!isDefined(self.killerLocation)) return; @@ -3094,20 +3169,23 @@ bot_dom_cap_think() otherFlagCount = maps\mp\gametypes\dom::getTeamFlagCount( otherTeam ); - if ( myFlagCount < otherFlagCount ) + if (game["teamScores"][myteam] >= game["teamScores"][otherTeam]) { - if ( randomint( 100 ) < 15 ) - continue; - } - else if ( myFlagCount == otherFlagCount ) - { - if ( randomint( 100 ) < 35 ) - continue; - } - else if ( myFlagCount > otherFlagCount ) - { - if ( randomint( 100 ) < 95 ) - continue; + if ( myFlagCount < otherFlagCount ) + { + if ( randomint( 100 ) < 15 ) + continue; + } + else if ( myFlagCount == otherFlagCount ) + { + if ( randomint( 100 ) < 35 ) + continue; + } + else if ( myFlagCount > otherFlagCount ) + { + if ( randomint( 100 ) < 95 ) + continue; + } } flag = undefined; diff --git a/mods/patch_mp/maps/mp/bots/_bot_utility.gsc b/mods/patch_mp/maps/mp/bots/_bot_utility.gsc index a1e42d4..be32501 100644 --- a/mods/patch_mp/maps/mp/bots/_bot_utility.gsc +++ b/mods/patch_mp/maps/mp/bots/_bot_utility.gsc @@ -145,6 +145,38 @@ GetBotDiffNum() return num; } +/* + is the weapon alt mode? +*/ +isWeaponAltmode(weap) +{ + if (isStrStart(weap, "gl_") || isStrStart(weap, "ft_") || isStrStart(weap, "mk_")) + return true; + + return false; +} + +/* + Returns a valid grenade launcher weapon +*/ +getValidTube() +{ + weaps = self getweaponslist(); + + for (i = 0; i < weaps.size; i++) + { + weap = weaps[i]; + + if(!self getAmmoCount(weap)) + continue; + + if ((isSubStr(weap, "gl_") && !isSubStr(weap, "_gl_")) || weap == "china_lake_mp") + return weap; + } + + return undefined; +} + /* Taken from iw4 script */ @@ -332,9 +364,9 @@ doExtraCheck() */ getConeDot(to, from, dir) { - dirToTarget = VectorNormalize(to-from); - forward = AnglesToForward(dir); - return vectordot(dirToTarget, forward); + dirToTarget = VectorNormalize(to-from); + forward = AnglesToForward(dir); + return vectordot(dirToTarget, forward); } /* diff --git a/mods/patch_mp/maps/mp/gametypes/_bot.gsc b/mods/patch_mp/maps/mp/gametypes/_bot.gsc index 232e25e..8c2ff7e 100644 --- a/mods/patch_mp/maps/mp/gametypes/_bot.gsc +++ b/mods/patch_mp/maps/mp/gametypes/_bot.gsc @@ -15,7 +15,7 @@ */ init() { - level.bw_VERSION = "1.1.0"; + level.bw_VERSION = "1.1.1"; level.bot_offline = false; diff --git a/out/Move to root of Black Ops folder/mods/mp_bots/mod.ff b/out/Move to root of Black Ops folder/mods/mp_bots/mod.ff index a688786..ba5d576 100644 Binary files a/out/Move to root of Black Ops folder/mods/mp_bots/mod.ff and b/out/Move to root of Black Ops folder/mods/mp_bots/mod.ff differ diff --git a/out/Move to root of Black Ops folder/mods/mp_bots/mp_bots.iwd b/out/Move to root of Black Ops folder/mods/mp_bots/mp_bots.iwd index bb3f8c4..1ef994c 100644 Binary files a/out/Move to root of Black Ops folder/mods/mp_bots/mp_bots.iwd and b/out/Move to root of Black Ops folder/mods/mp_bots/mp_bots.iwd differ diff --git a/out/Others/patch_mp.ff b/out/Others/patch_mp.ff index 7e515b3..5020cd1 100644 Binary files a/out/Others/patch_mp.ff and b/out/Others/patch_mp.ff differ diff --git a/out/readme.txt b/out/readme.txt index c858f72..a2f56fb 100644 --- a/out/readme.txt +++ b/out/readme.txt @@ -13,6 +13,13 @@ You can find the more information at the Git Repo: https://github.com/ineedbots/ 4. The mod is now loaded! Go play Combat Training and enjoy the new additions. ## Changelog +- v1.1.1 + - Fixed some script runtime errors + - Improved domination + - Bots use altmode weapons + - Improved revenge + - Bots can swap weapons on spawn more likely + - v1.1.0 - Rewrote using CoD4x as a base - Fixed bots not knifing diff --git a/out/ss.png b/out/ss.png index cdb4135..30bce1f 100644 Binary files a/out/ss.png and b/out/ss.png differ