feat: improved take cover action node selection
This commit is contained in:
		
							parent
							
								
									2c21845991
								
							
						
					
					
						commit
						dc60937660
					
				|  | @ -17,7 +17,7 @@ MoveToTarget::MoveToTarget() | |||
| goap::State *MoveToTarget::get_apply_state(goap::ActorWorldState *context) const { | ||||
|     gd::Node3D *target{gd::Object::cast_to<gd::Node3D>(context->get_world_property("target_node"))}; | ||||
|     if(target == nullptr) { | ||||
|         gd::UtilityFunctions::push_warning("Failed to get target node of action ", get_static_class()); | ||||
|         gd::UtilityFunctions::push_warning("Failed to get target node of ", context->get_path()); | ||||
|         return nullptr; | ||||
|     } else { | ||||
|         MoveTo *state{this->create_state<MoveTo>()}; | ||||
|  | @ -97,34 +97,32 @@ TakeCover::TakeCover() | |||
| 
 | ||||
| bool TakeCover::procedural_is_possible(goap::ActorWorldState *context) const { | ||||
|     // positions of the context and the target 
 | ||||
|     gd::Vector3 const global_position{context->get_world_property("parent_global_position")}; | ||||
|     gd::Vector3 const context_position{context->get_world_property("parent_global_position")}; | ||||
|     gd::Vector3 const target_position{context->get_world_property("target_global_position")}; | ||||
|     // if there is no available navigation room, it is not possible to find a cover marker
 | ||||
|     NavRoom *room{NavRoom::get_closest_room(global_position)}; | ||||
|     NavRoom *room{NavRoom::get_closest_room(context_position)}; | ||||
|     if(room == nullptr) | ||||
|         return false; | ||||
|     // immediately return true if there is at least one marker that counts as cover from the target
 | ||||
|     for(NavMarker *marker : room->get_markers()) | ||||
|         if(TakeCover::is_marker_cover_from(marker, target_position)) | ||||
|         if(TakeCover::is_marker_cover_from(marker, target_position, context_position)) | ||||
|             return true; | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| goap::State *TakeCover::get_apply_state(goap::ActorWorldState *context) const { | ||||
|     // positions of the context and the target to hide from
 | ||||
|     gd::Vector3 const global_position{context->get_world_property("parent_global_position")}; | ||||
|     gd::Vector3 const context_position{context->get_world_property("parent_global_position")}; | ||||
|     gd::Vector3 const target_position{context->get_world_property("target_global_position")}; | ||||
|     // find the room this entity is located in
 | ||||
|     NavRoom *room{NavRoom::get_closest_room(global_position)}; | ||||
|     NavRoom *room{NavRoom::get_closest_room(context_position)}; | ||||
|     if(room == nullptr) | ||||
|         return nullptr; | ||||
|     NavMarker *best_marker{nullptr}; // marker with the best score found so far
 | ||||
|     float best_score{0.f}; // best score found so far
 | ||||
|     float best_score{0.f}; // best score found so far, starts at zero because negative values should not be considered
 | ||||
|     for(NavMarker *marker : room->get_markers()) { | ||||
|         gd::Vector3 const marker_position{marker->get_global_position()}; // position of the marker being considered
 | ||||
|         float const score{(marker_position.distance_squared_to(target_position) * 1.2f) // score is a comparison between distances to the target and context
 | ||||
|                         - (marker_position.distance_squared_to(global_position) * 0.8f)}; | ||||
|         if(score > best_score && TakeCover::is_marker_cover_from(marker, target_position)) { | ||||
|         float const score{this->score_cover_marker(marker, target_position, context_position)}; | ||||
|         if(score > best_score) { | ||||
|             best_score = score; | ||||
|             best_marker = marker; | ||||
|         } | ||||
|  | @ -138,9 +136,22 @@ goap::State *TakeCover::get_apply_state(goap::ActorWorldState *context) const { | |||
|     return state; | ||||
| } | ||||
| 
 | ||||
| bool TakeCover::is_marker_cover_from(NavMarker *marker, gd::Vector3 const &target) { | ||||
| bool TakeCover::is_marker_cover_from(NavMarker *marker, gd::Vector3 const &target_position, gd::Vector3 const &context_position) { | ||||
|     gd::Vector3 const marker_position{marker->get_global_position()}; | ||||
|     float const distance_to_target{target_position.distance_to(context_position)}; | ||||
|     return marker->get_marker_type() == MarkerType::Cover | ||||
|         && marker->get_global_basis() | ||||
|                 .get_column(2) | ||||
|                 .dot(marker->get_global_position() - target) < -2.f; | ||||
|         && marker->get_global_basis().get_column(2).dot(marker_position - target_position) < -2.f | ||||
|         && context_position.distance_to(marker_position) < (distance_to_target * 2.f); | ||||
| } | ||||
| 
 | ||||
| float TakeCover::score_cover_marker(class NavMarker* marker, const gd::Vector3& target_position, const gd::Vector3& context_position) const { | ||||
|     if(!TakeCover::is_marker_cover_from(marker, target_position, context_position)) | ||||
|         return 0.f; | ||||
|     gd::Vector3 const marker_position{marker->get_global_position()}; // position of the marker being considered
 | ||||
|     float const target_distance{marker_position.distance_to(target_position)}; | ||||
|     float const context_distance{marker_position.distance_to(context_position)}; | ||||
|     // score is a weighted comparison between distances to the target and context
 | ||||
|     // marker distance from context grows faster than marker distance from target
 | ||||
|     return (target_distance) - (context_distance); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -53,7 +53,8 @@ public: | |||
|     virtual bool procedural_is_possible(goap::ActorWorldState *context) const override; | ||||
|     virtual goap::State *get_apply_state(goap::ActorWorldState *context) const override; | ||||
| private: | ||||
|     static bool is_marker_cover_from(class NavMarker *marker, gd::Vector3 const &target); | ||||
|     static bool is_marker_cover_from(class NavMarker *marker, gd::Vector3 const &target_position, gd::Vector3 const &context_position); | ||||
|     float score_cover_marker(class NavMarker *marker, gd::Vector3 const &target_position, gd::Vector3 const &context_position) const; | ||||
| }; | ||||
| 
 | ||||
| #endif // !RTS_ACTIONS_HPP
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Sara
						Sara