diff --git a/maps/bots/objectives/_manager.gsc b/maps/bots/objectives/_manager.gsc index 71b7d49..4c6e83f 100644 --- a/maps/bots/objectives/_manager.gsc +++ b/maps/bots/objectives/_manager.gsc @@ -9,6 +9,7 @@ init() level.bot_objectives[level.bot_objectives.size] = CreateObjectiveForManger( "revive", maps\bots\objectives\_revive::Finder, maps\bots\objectives\_revive::Priority, maps\bots\objectives\_revive::Executer, 1000 ); level.bot_objectives[level.bot_objectives.size] = CreateObjectiveForManger( "powerup", maps\bots\objectives\_powerup::Finder, maps\bots\objectives\_powerup::Priority, maps\bots\objectives\_powerup::Executer, 2500 ); level.bot_objectives[level.bot_objectives.size] = CreateObjectiveForManger( "wallweapon", maps\bots\objectives\_wallweapon::Finder, maps\bots\objectives\_wallweapon::Priority, maps\bots\objectives\_wallweapon::Executer, 7500 ); + level.bot_objectives[level.bot_objectives.size] = CreateObjectiveForManger( "treasurechest", maps\bots\objectives\_treasurechest::Finder, maps\bots\objectives\_treasurechest::Priority, maps\bots\objectives\_treasurechest::Executer, 7000 ); } connected() diff --git a/maps/bots/objectives/_treasurechest.gsc b/maps/bots/objectives/_treasurechest.gsc new file mode 100644 index 0000000..5edf415 --- /dev/null +++ b/maps/bots/objectives/_treasurechest.gsc @@ -0,0 +1,271 @@ +#include common_scripts\utility; +#include maps\_utility; +#include maps\bots\_bot_utility; +#include maps\bots\objectives\_utility; + +Finder( eObj ) +{ + answer = []; + + if ( self inLastStand() ) + { + return answer; + } + + weapons = self GetWeaponsList(); + + // TODO check if need a new weapon, rate weapons too is better then current etc + chests = level.chests; + + if ( !isDefined( chests ) ) + { + chests = GetEntArray( "treasure_chest_use", "targetname" ); + } + + if ( !isDefined( chests ) || chests.size <= 0 ) + { + return answer; + } + + for ( i = 0; i < chests.size; i ++ ) + { + chest = chests[i]; + + // not active chest + if ( isDefined( chest.disabled ) && chest.disabled ) + { + continue; + } + + // box is waiting for someone to grab weapon + if ( isDefined( chest.grab_weapon_hint ) && chest.grab_weapon_hint ) + { + continue; + } + + cost = 950; + + if ( IsDefined( level.zombie_treasure_chest_cost ) ) + { + cost = level.zombie_treasure_chest_cost; + } + else if ( isDefined( chest.zombie_cost ) ) + { + cost = chest.zombie_cost; + } + + // check cost + if ( self.score < cost ) + { + continue; + } + + lid = getent( chest.target, "targetname" ); + + if ( !isDefined( lid ) ) + { + continue; + } + + weapon_spawn_org = getent( lid.target, "targetname" ); + + if ( !isdefined( weapon_spawn_org ) ) + { + continue; + } + + org = self getOffset( lid ); + + if ( GetPathIsInaccessible( self.origin, org ) ) + { + continue; + } + + answer[answer.size] = self CreateFinderObjective( eObj, eObj.sName + "_" + chest GetEntityNumber(), chest, self [[eObj.fpPriorty]]( eObj, chest ) ); + } + + return answer; +} + +getOffset( model ) +{ + org = model get_angle_offset_node( 40, ( 0, 90, 0 ), ( 0, 0, 1 ) ); + + return org; +} + +Priority( eObj, eEnt ) +{ + base_priority = 1; + base_priority += ClampLerp( get_path_dist( self.origin, eEnt.origin ), 0, 800, 2, -2 ); + + if ( self HasBotObjective() && self.bot_current_objective.eEnt != eEnt ) + { + base_priority -= 1; + } + + return base_priority; +} + +Executer( eObj ) +{ + self endon( "disconnect" ); + self endon( "zombified" ); + + chest = eObj.eEnt; + + self thread WatchForCancel( chest ); + + self GoDoTreasureChest( eObj ); + + self WatchForCancelCleanup(); + self ClearScriptAimPos(); + self ClearScriptGoal(); + self ClearPriorityObjective(); + + self CompletedObjective( eObj.bWasSuccessful, eObj.sReason ); +} + +WatchForCancelCleanup() +{ + self notify( "WatchForCancelTreasurechest" ); +} + +WatchForCancel( chest ) +{ + self endon( "disconnect" ); + self endon( "zombified" ); + self endon( "WatchForCancelTreasurechest" ); + + for ( ;; ) + { + wait 0.05; + + if ( self inLastStand() ) + { + self CancelObjective( "self inLastStand()" ); + break; + } + } +} + +WatchToGoToChest( chest ) +{ + self endon( "cancel_bot_objective" ); + self endon( "disconnect" ); + self endon( "zombified" ); + self endon( "goal" ); + self endon( "bad_path" ); + self endon( "new_goal" ); + + for ( ;; ) + { + wait 0.05; + + if ( self IsTouching( chest ) || chest PointInsideUseTrigger( self.origin ) ) + { + self notify( "goal" ); + break; // is this needed? + } + + if ( isDefined( chest.disabled ) && chest.disabled ) + { + self notify( "bad_path" ); + break; // is this needed? + } + } +} + +GoDoTreasureChest( eObj ) +{ + self endon( "cancel_bot_objective" ); + + chest = eObj.eEnt; + lid = getent( chest.target, "targetname" ); + weapon_spawn_org = getent( lid.target, "targetname" ); + org = self getOffset( lid ); + + weap = self GetCurrentWeapon(); + + if ( weap == "none" || !self getAmmoCount( weap ) ) + { + self SetPriorityObjective(); + } + + // go to box + self thread WatchToGoToChest( chest ); + self SetScriptGoal( org, 32 ); + + result = self waittill_any_return( "goal", "bad_path", "new_goal" ); + + if ( result != "goal" ) + { + eObj.sReason = "didn't go to chest"; + return; + } + + if ( !self IsTouching( chest ) && !chest PointInsideUseTrigger( self.origin ) ) + { + eObj.sReason = "not touching chest"; + return; + } + + // ok we are touching weapon, lets look at it + self SetScriptAimPos( chest.origin ); + + // wait to look at it + wait 1; + + // press use + self thread BotPressUse( 0.15 ); + wait 0.1; + + // ok we pressed use, wait for randomization to complete + self ClearScriptAimPos(); + self ClearScriptGoal(); + self ClearPriorityObjective(); + weapon_spawn_org waittill( "randomization_done" ); + + if ( isDefined( level.flag[ "moving_chest_now" ] ) && flag( "moving_chest_now" ) ) + { + eObj.sReason = "chest is moving!"; + return; + } + + waittillframeend; + weap = weapon_spawn_org.weapon_string; + // weapon is done cooking, grabit! + self SetPriorityObjective(); + + // go to box + self thread WatchToGoToChest( chest ); + self SetScriptGoal( org, 32 ); + + result = self waittill_any_return( "goal", "bad_path", "new_goal" ); + + if ( result != "goal" ) + { + eObj.sReason = "didn't go to chest"; + return; + } + + if ( !self IsTouching( chest ) && !chest PointInsideUseTrigger( self.origin ) ) + { + eObj.sReason = "not touching chest"; + return; + } + + // ok we are touching weapon, lets look at it + self SetScriptAimPos( chest.origin ); + + // wait to look at it + wait 1; + + // press use + self thread BotPressUse( 0.15 ); + wait 0.1; + + // complete! + eObj.sReason = "completed " + weap; + eObj.bWasSuccessful = true; +} diff --git a/maps/bots/objectives/_utility.gsc b/maps/bots/objectives/_utility.gsc index d8e8040..a7a229b 100644 --- a/maps/bots/objectives/_utility.gsc +++ b/maps/bots/objectives/_utility.gsc @@ -184,10 +184,11 @@ get_angle_offset_node( forward_size, angle_offset, offset ) debug_offset_line( node ) { + self endon( "death" ); self notify( "debug_offset_line" ); self endon( "debug_offset_line" ); - for ( ;; ) + while ( isDefined( self ) ) { line( self.origin, node ); wait 0.05; @@ -217,7 +218,7 @@ PointInsideUseTrigger( point ) return false; } - if ( !bulletTracePassed( point, self.origin, false, undefined ) ) + if ( !sightTracePassed( point, self.origin, false, undefined ) ) { return false; } diff --git a/maps/bots/objectives/_wallweapon.gsc b/maps/bots/objectives/_wallweapon.gsc index cebd8ba..f05c267 100644 --- a/maps/bots/objectives/_wallweapon.gsc +++ b/maps/bots/objectives/_wallweapon.gsc @@ -107,7 +107,7 @@ Priority( eObj, eEnt ) base_priority -= 1; } - if ( eEnt.zombie_weapon_upgrade == "zombie_kar98k" ) + if ( isSubStr( eEnt.zombie_weapon_upgrade, "kar98k" ) || isSubStr( eEnt.zombie_weapon_upgrade, "type99" ) ) { base_priority -= 999; } @@ -130,6 +130,7 @@ Executer( eObj ) self ClearScriptAimPos(); self ClearScriptGoal(); self ClearPriorityObjective(); + self CompletedObjective( eObj.bWasSuccessful, eObj.sReason ); }