273 lines
7.4 KiB
C++
273 lines
7.4 KiB
C++
#pragma once
|
|
#ifndef GAMESERVER_TARGET_SEARCHER_H
|
|
#define GAMESERVER_TARGET_SEARCHER_H
|
|
|
|
//==================================================================================================
|
|
|
|
class Skill;
|
|
|
|
namespace ns_object {
|
|
;
|
|
|
|
struct RelationHint
|
|
{
|
|
bool checked;
|
|
eUSER_RELATION_TYPE relation;
|
|
};
|
|
|
|
//-------------------------------------
|
|
// A : Actor
|
|
// T : main Target
|
|
// X : apply target or range (targets)
|
|
// R : Range (A<->T)
|
|
// r : radius in of range
|
|
// * : boundary
|
|
//-------------------------------------
|
|
// ##1:
|
|
// * * * * *
|
|
// * * * * *
|
|
// * * T * *
|
|
// * * * * *
|
|
// * * * * *
|
|
//-------------------------------------
|
|
// ##2:
|
|
// * * * * *
|
|
// * X X X *
|
|
// * X T X *
|
|
// * X X X *
|
|
// * * *<-r->*
|
|
//-------------------------------------
|
|
// * * * * *
|
|
// * X X X *
|
|
// * X X X *
|
|
// * X X X *
|
|
// * * *<-r->*
|
|
//-------------------------------------
|
|
|
|
struct SearchOption
|
|
{
|
|
// ##1: default range select based on center position like a NpcAI
|
|
enum eOptions
|
|
{
|
|
eOption_None,
|
|
eOption_LookAround,
|
|
eOption_NpcAI,
|
|
eOption_SingleSearch,
|
|
eOption_SkillBase,
|
|
eOption_SelectBestFit,
|
|
};
|
|
enum eFilter
|
|
{
|
|
eFilter_None = 0,
|
|
//
|
|
eFilter_SkipCantBeAttacked = 1 << 0, //
|
|
eFilter_SkipObserver = 1 << 1, //
|
|
eFilter_SkipTransparent = 1 << 2, //
|
|
eFilter_SkipDead = 1 << 4, //
|
|
eFilter_SkipTileCheck = 1 << 5, // SkillBase
|
|
eFilter_SkipRangeCheck = 1 << 7, // SkillBase
|
|
//
|
|
eFilter_CheckNonPreemptive = 1 << 10, // NpcAI
|
|
//
|
|
};
|
|
enum eContinueResult {
|
|
eStop,
|
|
eContinue,
|
|
};
|
|
|
|
struct LookAround;
|
|
struct NpcAI;
|
|
struct SelectBestFit;
|
|
struct SingleSearch;
|
|
struct SkillBase;
|
|
|
|
SearchOption(const eOptions& search_option, const ulong& search_filter);
|
|
// NOTE: f110521.3L, changed the damage box ranges according to the attack range formation
|
|
bool GetApplicationRangeBox(\
|
|
nsGrid::ViewBoxCubic* const damage_box, const float z_axis_tolerant_value) const;
|
|
// NOTE: this method find accetable objects fit in conditions.
|
|
bool IsSatisfiedObjectFindingConditions(
|
|
const nsGrid::ViewBoxCubic* apply_box,
|
|
Character* const actor, Character* const target) const;
|
|
// NOTE: f110309.1L, this method is generally used by using embedded IFF_Filter rule
|
|
// this method check whether a target is friend or enemy.
|
|
bool IsSatisfiedObjectIFFRelations(
|
|
Character* const actor, Character* const target,
|
|
const RelationHint* cached_relation, RelationHint* result_relation) const;
|
|
// NOTE: f110309.1L, apply IFF_Filter rule. this method is used by Skill abilities
|
|
bool IsSatisfiedObjectAbilityConditions(
|
|
Character* const actor, Character* const target,
|
|
const BASE_ABILITYINFO* base_ability_info) const;
|
|
//
|
|
// Fields...
|
|
const eOptions option;
|
|
mutable ulong filter;
|
|
mutable IFF_Filter iff_filter;
|
|
mutable int max_number_of_selected_chars;
|
|
mutable bool validated;
|
|
struct Arguments {
|
|
//
|
|
eSKILL_TARGET_TYPE search_target_type;
|
|
const WzVector* start_pos;
|
|
const WzVector* application_center_pos;
|
|
float attack_ranges;
|
|
float ranges_of_application;
|
|
eSKILL_AREA_TYPE forms_of_application;
|
|
//
|
|
Character* except_object_if_exist;
|
|
//
|
|
} arguments;
|
|
//
|
|
__DISABLE_COPY(SearchOption);
|
|
};
|
|
|
|
inline SearchOption::SearchOption(
|
|
const eOptions& search_option, const ulong& search_filter)
|
|
: option(search_option)
|
|
, filter(search_filter)
|
|
, max_number_of_selected_chars(0)
|
|
, validated(false)
|
|
{
|
|
ZeroMemory(&arguments, sizeof(arguments));
|
|
}
|
|
|
|
struct SearchResult
|
|
{
|
|
struct LookAround;
|
|
struct NpcAI;
|
|
struct SelectBestFit;
|
|
struct SingleSearch;
|
|
struct SkillBase;
|
|
};
|
|
|
|
struct SearchOption::LookAround : public SearchOption
|
|
{
|
|
typedef SearchResult::LookAround result_type;
|
|
static const ulong kFilterValue;
|
|
//
|
|
explicit LookAround(eSKILL_TARGET_TYPE target_type)
|
|
: SearchOption(eOption_LookAround, kFilterValue) { __TOUCHED(target_type); }
|
|
//
|
|
__DISABLE_COPY(LookAround);
|
|
};
|
|
|
|
struct SearchOption::NpcAI : public SearchOption
|
|
{
|
|
typedef SearchResult::NpcAI result_type;
|
|
static const ulong kFilterValue;
|
|
//
|
|
NpcAI(NPC* npc);
|
|
|
|
eContinueResult AppendToResultIfIsSatisfiedObject(
|
|
NPC* const actor, Character* const target, result_type* result) const;
|
|
//
|
|
NPC* const actor;
|
|
struct Working {
|
|
DWORD exist_record[MAX_TARGET_NUM];
|
|
} working;
|
|
//
|
|
__DISABLE_COPY(NpcAI);
|
|
};
|
|
|
|
struct SearchOption::SelectBestFit : public SearchOption
|
|
{
|
|
typedef SearchResult::SelectBestFit result_type;
|
|
static const ulong kFilterValue;
|
|
//
|
|
SelectBestFit() : SearchOption(eOption_SelectBestFit, kFilterValue) {}
|
|
|
|
eContinueResult AppendToResultIfIsSatisfiedObject(
|
|
Character* const actor, Character* const target, result_type* result) const;
|
|
//
|
|
__DISABLE_COPY(SelectBestFit);
|
|
};
|
|
|
|
// NOTE: simple enemies search
|
|
struct SearchOption::SingleSearch : public SearchOption
|
|
{
|
|
typedef SearchResult::SingleSearch result_type;
|
|
static const ulong kFilterValue;
|
|
//
|
|
SingleSearch(
|
|
int max_number_of_selected_characters,
|
|
Character* input_actor,
|
|
Character* input_main_target_if_exist_it,
|
|
const WzVector* input_specific_application_center_pos_if_main_target_is_not_used_to_pos,
|
|
//
|
|
float attack_ranges,
|
|
float ranges_of_application,
|
|
eSKILL_AREA_TYPE forms_of_application);
|
|
//
|
|
bool PrefetchResult(result_type* const result) const;
|
|
eContinueResult AppendToResultIfIsSatisfiedObject(
|
|
Character* const actor, Character* const target, result_type* result) const;
|
|
//
|
|
Character* const actor;
|
|
struct Working {
|
|
Character* main_target;
|
|
} working;
|
|
//
|
|
__DISABLE_COPY(SingleSearch);
|
|
};
|
|
|
|
// this search option accept only skill not style.
|
|
// if you want search targets by style, use SingleSearch
|
|
struct SearchOption::SkillBase : public SearchOption
|
|
{
|
|
typedef SearchResult::SkillBase result_type;
|
|
static const ulong kFilterValue;
|
|
//
|
|
static SearchOption::SkillBase* CreateInstance(Skill* input_skill);
|
|
static void DestroyInstance();
|
|
//
|
|
//bool PrefetchResult(result_type* const result);
|
|
//eContinueResult AppendToResultIfIsSatisfiedObject(
|
|
// Character* const actor, Character* const target, result_type* result) const;
|
|
//
|
|
Skill* const skill;
|
|
Character* const actor;
|
|
bool instanced;
|
|
struct Working {
|
|
Character* main_target;
|
|
//bool include_actor;
|
|
bool need_process_abilities[MAX_ABILITY_NUM];
|
|
const BASE_ABILITYINFO* ability_infos[MAX_ABILITY_NUM];
|
|
RelationHint hint[MAX_TARGET_NUM];
|
|
} working;
|
|
|
|
private:
|
|
SearchOption::SkillBase(Skill* input_skill);
|
|
//
|
|
__DISABLE_COPY(SkillBase);
|
|
};
|
|
|
|
//==================================================================================================
|
|
|
|
struct SearchResult::LookAround
|
|
{
|
|
};
|
|
|
|
struct SearchResult::NpcAI
|
|
{
|
|
int number_of_selected_chars;
|
|
Character* targets[MAX_TARGET_NUM];
|
|
};
|
|
|
|
struct SearchResult::SelectBestFit
|
|
{
|
|
};
|
|
|
|
struct SearchResult::SingleSearch
|
|
{
|
|
int number_of_selected_chars;
|
|
Character* targets[MAX_TARGET_NUM];
|
|
};
|
|
|
|
struct SearchResult::SkillBase
|
|
{
|
|
bool multi_select;
|
|
};
|
|
|
|
}; //end of namespace
|
|
|
|
#endif //GAMESERVER_TARGET_SEARCHER_H
|