Files
ZombieGame-Rawr/project/BigThink.cpp
Bram verhulst f9a11385fe Fianlly
2025-06-02 21:29:29 +02:00

251 lines
9.0 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{ 2.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 };
constexpr float gridCellSize{ 50.f };
const std::string BeforeLeavingTimer{ "BeforeLeaving" };
constexpr bool BeforeLeavingDoOnce{ false };
const std::string NoHouseTimer{ "NoHouse" };
constexpr float noHouseTimeout = 5.0f;
constexpr bool NoHouseDoOnce{ false };
const std::string HouseExploreTimer{ "HouseExplore" };
constexpr float houseExploreTimeout = 2.0f;
constexpr bool HouseExploreDoOnce{ false };
return new BT::Selector({
// [1] House visibility update
new BT::Sequence({
new BT::Conditional(BT_Condition::SeeHouse),
new BT::Action(BT_Action::CheckHouses),
//new BT::Action(BT_Grid::UpdateExplorationGrid),
new BT::Action(std::bind(BT_Action::SetTimer, _1, NoHouseTimer, NoHouseDoOnce))
}),
// [2] Inside house logic
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::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)
}),
})
}),
// [3] Outside house behavior
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(BT_Grid::FindUnexploredCell),
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)),
new BT::Action(std::bind(BT_Action::SetTimer, _1, NoHouseTimer, NoHouseDoOnce)),
new BT::Selector({
new BT::PartialSequence({
new BT::Action(BT_Grid::FindUnexploredCell),
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 * 2)),
new BT::Action(BT_Action::EnableSpin),
new BT::Action(BT_Action::GoToTarget)
})
})
}),
}),
});
}
BT::Selector* HandleBug() {
const std::string StuckTimer{ "StuckTimer" };
constexpr float stuckTimeout = 3.0f; // Time in seconds before considering stuck
constexpr bool StuckDoOnce{ false };
constexpr float unstuckRange = 10.0f; // Range to pick a random target when stuck
return
new BT::Selector({
new BT::Sequence({
new BT::Conditional(std::bind(BT_Condition::CheckMovement, _1, stuckTimeout)),
new BT::Conditional(std::bind(BT_Condition::CheckTimer, _1, StuckTimer, StuckDoOnce)),
new BT::Action(std::bind(BT_Action::SetTimer, _1, StuckTimer, StuckDoOnce)),
new BT::Action(std::bind(BT_Action::FindRandomLocation, _1, unstuckRange)),
new BT::Action(BT_Action::EnableSpin),
new BT::Action(BT_Action::GoToTarget)
})
});
}
}