Files
ZombieGame-Rawr/project/BigThink.cpp
2025-06-01 23:04:37 +02:00

222 lines
8.4 KiB
C++

#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),
})
}),
});
}
}