#include "stdafx.h" #include "BigThink.h" #include "Behaviour.h" #include "BehaviourTree.h" using namespace std::placeholders; namespace BigThink { BT::Selector* ItemHandling() { constexpr float HpThreshold{ 0.f }; return new BT::Selector({ new BT::Sequence({ new BT::Conditional(std::bind(BT_Condition::ItemInInv, _1, eItemType::MEDKIT)), new BT::Conditional(std::bind(BT_Condition::HpUnderThreshold, _1, HpThreshold)), new BT::Action(std::bind(BT_Action::UseItem, _1, eItemType::MEDKIT)) }), new BT::Sequence({ new BT::Conditional(std::bind(BT_Condition::ItemInInv, _1, eItemType::FOOD)), new BT::Conditional(BT_Condition::CheckMinNeededEnergy), new BT::Action(std::bind(BT_Action::UseItem, _1, eItemType::FOOD)) }) }); } BT::Sequence* ZombieHandling() { constexpr float minShotgunAngleDiff{ .2f }; constexpr float minPistolAngleDiff{ .1f }; constexpr float maxShotgunShootRange{ 8.f }; constexpr float maxPistolShootRange{ 15.f }; const std::string ShotgunTimer{ "Shotgun" }; constexpr bool ShotgunDoOnce{ true }; const std::string PistolTimer{ "Pistol" }; constexpr bool PistolDoOnce{ true }; return new BT::Sequence({ new BT::Conditional(BT_Condition::SeeZombie), new BT::Sequence({ new BT::Action(BT_Action::AvoidingZombie), new BT::Conditional(BT_Condition::HasWeapon), new BT::Action(BT_Action::SetZombieTarget), new BT::Sequence({ new BT::Action(BT_Action::RotateToZombie), new BT::Selector({ new BT::Sequence({ new BT::Conditional(std::bind(BT_Condition::ItemInInv, _1, eItemType::SHOTGUN)), new BT::Conditional(std::bind(BT_Condition::InRange, _1, maxShotgunShootRange)), new BT::Action(std::bind(BT_Action::ReadyToShoot, _1, minShotgunAngleDiff)), new BT::Conditional(std::bind(BT_Condition::CheckTimer, _1, ShotgunTimer, ShotgunDoOnce)), new BT::Action(std::bind(BT_Action::Shoot, _1, eItemType::SHOTGUN)), new BT::Action(std::bind(BT_Action::SetTimer, _1, ShotgunTimer, ShotgunDoOnce)) }), new BT::Sequence({ new BT::Conditional(std::bind(BT_Condition::ItemInInv, _1, eItemType::PISTOL)), new BT::Conditional(std::bind(BT_Condition::InRange, _1, maxPistolShootRange)), new BT::Action(std::bind(BT_Action::ReadyToShoot, _1, minPistolAngleDiff)), new BT::Conditional(std::bind(BT_Condition::CheckTimer, _1, PistolTimer, PistolDoOnce)), new BT::Action(std::bind(BT_Action::Shoot, _1, eItemType::PISTOL)), new BT::Action(std::bind(BT_Action::SetTimer, _1, PistolTimer, PistolDoOnce)) }) }) }) }) }); } BT::Sequence* PurgeZoneHandling() { constexpr int searchDegree{ 5 }; return new BT::Sequence({ new BT::Conditional(BT_Condition::InPurgeZone), new BT::Action(std::bind(BT_Action::FindClosestEdge, _1, searchDegree)), new BT::Action(BT_Action::GoToTarget) }); } BT::PartialSequence* PickUpHandling() { return new BT::PartialSequence({ new BT::Conditional(BT_Condition::SeeItem), new BT::Action(BT_Action::DisableSpin), new BT::Action(BT_Action::SetItemAsTarget), new BT::Action(BT_Action::GoToTarget), new BT::Selector({ new BT::Sequence({ new BT::Conditional(std::bind(BT_Condition::IsTypeOfItem, _1, eItemType::GARBAGE)), new BT::Action(BT_Action::DestroyItemOnFloor) }), new BT::Sequence({ new BT::Conditional(BT_Condition::EmptyValue), new BT::Action(BT_Action::SwapItem) }), new BT::Sequence({ new BT::Conditional(BT_Condition::InvIsNotFull), new BT::Action(BT_Action::PickUpItem) }), new BT::Sequence({ new BT::Conditional(BT_Condition::InvIsFull), new BT::Selector({ new BT::Sequence({ new BT::Conditional(std::bind(BT_Condition::IsTypeOfItem,_1, eItemType::FOOD)), new BT::Action(BT_Action::CheckItem) }), new BT::Sequence({ new BT::Conditional(std::bind(BT_Condition::IsTypeOfItem, _1, eItemType::MEDKIT)), new BT::Action(BT_Action::CheckItem) }), new BT::Sequence({ new BT::Conditional(std::bind(BT_Condition::IsTypeOfItem, _1, eItemType::SHOTGUN)), new BT::Action(BT_Action::CheckItem) }), new BT::Sequence({ new BT::Conditional(std::bind(BT_Condition::IsTypeOfItem, _1, eItemType::PISTOL)), new BT::Action(BT_Action::CheckItem) }) }) }) }) }); } BT::Selector* HouseHandling() { constexpr float maxTravelDistance{ 400.f }; constexpr int searchRadius{ 500 }; constexpr int randomRadius{ 50 }; constexpr int searchDegree{ 5 }; constexpr float InsideOffset{ 5.f }; const std::string BeforeLeavingTimer{ "BeforeLeaving" }; constexpr bool BeforeLeavingDoOnce{ false }; const std::string NoHouseTimer{ "NoHouse" }; constexpr float noHouseTimeout = 5.0f; // Time in seconds before giving up and going random constexpr bool NoHouseDoOnce{ false }; return new BT::Selector({ new BT::Sequence({ new BT::Conditional(BT_Condition::SeeHouse), new BT::Action(BT_Action::CheckHouses), new BT::Action(std::bind(BT_Action::SetTimer, _1, NoHouseTimer, NoHouseDoOnce)) // Reset timer when we see a house }), new BT::PartialSequence({ new BT::Conditional(BT_Condition::InsideTargetHouse), new BT::Action(BT_Action::SetExpireDate), new BT::Action(std::bind(BT_Action::SetTimer, _1, BeforeLeavingTimer, BeforeLeavingDoOnce)), new BT::Selector({ new BT::PartialSequence({ new BT::Conditional(std::bind(BT_Condition::CheckTimer, _1, BeforeLeavingTimer, BeforeLeavingDoOnce)), new BT::Selector({ new BT::PartialSequence({ new BT::Conditional(BT_Condition::NewHouse), new BT::Action(std::bind(BT_Action::GetHouseAsTarget, _1, maxTravelDistance)), new BT::Action(BT_Action::EnableSpin), new BT::Action(BT_Action::GoToTarget), }), new BT::PartialSequence({ new BT::Action(std::bind(BT_Action::FindRandomLocation, _1, randomRadius)), new BT::Action(BT_Action::EnableSpin), new BT::Action(BT_Action::GoToTarget) }), /*new BT::PartialSequence({ new BT::Action(std::bind(BT_Action::TryFindHouse, _1, searchRadius, searchDegree)), new BT::Action(BT_Action::EnableSpin), new BT::Action(BT_Action::GoToTarget) }),*/ /*new BT::PartialSequence({ new BT::Conditional(BT_Condition::ReExploreHouse), new BT::Action(std::bind(BT_Action::GetHouseAsTarget, _1, maxTravelDistance)), new BT::Action(BT_Action::EnableSpin), new BT::Action(BT_Action::GoToTarget), }),*/ new BT::PartialSequence({ new BT::Action(std::bind(BT_Action::FindRandomLocation, _1, randomRadius)), new BT::Action(BT_Action::EnableSpin), new BT::Action(BT_Action::GoToTarget) }) }), }), new BT::PartialSequence({ new BT::Action(std::bind(BT_Action::GetInsideTarget, _1, InsideOffset)), new BT::Action(BT_Action::EnableSpin), new BT::Action(BT_Action::GoToTarget) }), }) }), new BT::Selector({ new BT::PartialSequence({ new BT::Conditional(BT_Condition::NewHouse), new BT::Action(std::bind(BT_Action::GetHouseAsTarget, _1, maxTravelDistance)), new BT::Action(BT_Action::EnableSpin), new BT::Action(BT_Action::GoToTarget), }), new BT::PartialSequence({ new BT::Action(std::bind(BT_Action::TryFindHouse, _1, searchRadius, searchDegree)), new BT::Action(BT_Action::EnableSpin), new BT::Action(BT_Action::GoToTarget) }), new BT::PartialSequence({ new BT::Conditional(std::bind(BT_Condition::CheckTimer, _1, NoHouseTimer, NoHouseDoOnce)), // Check if we haven't seen a house in a while new BT::Action(std::bind(BT_Action::SetTimer, _1, NoHouseTimer, NoHouseDoOnce)), // Reset the timer new BT::Action(std::bind(BT_Action::FindRandomLocation, _1, randomRadius * 2)), // Go further when random walking new BT::Action(BT_Action::EnableSpin), new BT::Action(BT_Action::GoToTarget) }), new BT::PartialSequence({ new BT::Conditional(BT_Condition::ReExploreHouse), new BT::Action(std::bind(BT_Action::GetHouseAsTarget, _1, maxTravelDistance)), new BT::Action(BT_Action::EnableSpin), new BT::Action(BT_Action::GoToTarget), }) }), }); } }