From b424838158ba83dc6b5fa5623d4e0a7eef8f471c Mon Sep 17 00:00:00 2001 From: Sven Eberhardt Date: Tue, 28 Apr 2015 18:59:50 +0200 Subject: [PATCH] Add Find_InArray (#1073). --- docs/sdk/script/fn/Find_InArray.xml | 44 +++++++++++++++++++++++++++++ planet/System.ocg/FindObject.c | 5 ++++ src/gamescript/C4FindObject.cpp | 21 ++++++++++++++ src/gamescript/C4FindObject.h | 15 +++++++++- src/gamescript/C4GameScript.cpp | 1 + src/script/C4ValueArray.h | 5 ++++ 6 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 docs/sdk/script/fn/Find_InArray.xml diff --git a/docs/sdk/script/fn/Find_InArray.xml b/docs/sdk/script/fn/Find_InArray.xml new file mode 100644 index 000000000..b362e21b3 --- /dev/null +++ b/docs/sdk/script/fn/Find_InArray.xml @@ -0,0 +1,44 @@ + + + + + + Find_InArray + Objects + Search + 6.1 OC + + array + + + array + search_array + Array in which the object must be. + + + + Search criterion: Finds only objects in the array. + The implementation just checks for every object whether it is contained in the array. The object search is not reduced by checking only objects in the given array, so the criterion should not be used as an optimization to speed up object search. To perform such an optimization, a simple loop over the array should be used. + + + // A kind of healing spell for which people have to stay within a distance and cannot gain the healing effect if they are not present in Fx*Start + +func FxHealingStart(object target, proplist effect, bool temp) +{ + if (!temp) effect.targets = FindObjects(Find_OCF(OCF_Alive), Find_Distance(200)); +} + +func FxHealingTimer(object target, proplist effect) +{ + for (var target in Find_Objects(Find_Distance(200), Find_InArray(effect.targets))); + target->DoEnergy(+1); +} + + Objects are healed by the effect and need to stay within 200 range to keep being healed. The Find_InArray criterion ensures that only objects that were initially in the range retrieve healing. + + + FindObjects + + Sven22015-04 + diff --git a/planet/System.ocg/FindObject.c b/planet/System.ocg/FindObject.c index 2293ee4ee..260530f62 100644 --- a/planet/System.ocg/FindObject.c +++ b/planet/System.ocg/FindObject.c @@ -156,6 +156,11 @@ global func Find_Layer(object layer) return [C4FO_Layer, layer]; } +global func Find_InArray(array a) +{ + return [C4FO_InArray, a]; +} + global func Find_PathFree(object to_obj) { if (!to_obj) diff --git a/src/gamescript/C4FindObject.cpp b/src/gamescript/C4FindObject.cpp index ec433f7d6..383ea7cab 100644 --- a/src/gamescript/C4FindObject.cpp +++ b/src/gamescript/C4FindObject.cpp @@ -213,6 +213,9 @@ C4FindObject *C4FindObject::CreateByValue(const C4Value &DataVal, C4SortObject * case C4FO_Layer: return new C4FindObjectLayer(Data[1].getObj()); + case C4FO_InArray: + return new C4FindObjectInArray(Data[1].getArray()); + } return NULL; } @@ -766,6 +769,24 @@ bool C4FindObjectLayer::IsImpossible() return false; } +// *** C4FindObjectInArray + +bool C4FindObjectInArray::Check(C4Object *pObj) +{ + // O(n) array look-up + if (!pArray) return false; + int32_t sz = pArray->GetSize(); + for (int i=0; i_GetItem(i).getObj() == pObj) + return true; + return false; +} + +bool C4FindObjectInArray::IsImpossible() +{ + return !pArray || !pArray->GetSize(); +} + // *** C4SortObject C4SortObject *C4SortObject::CreateByValue(const C4Value &DataVal, const C4Object *context) diff --git a/src/gamescript/C4FindObject.h b/src/gamescript/C4FindObject.h index f4daf2927..b10f9355f 100644 --- a/src/gamescript/C4FindObject.h +++ b/src/gamescript/C4FindObject.h @@ -42,7 +42,9 @@ enum C4FindObjectCondID C4FO_Owner = 18, C4FO_Controller = 19, C4FO_Func = 20, - C4FO_Layer = 21 // last C4FO must be smaller than C4SO_First. + C4FO_Layer = 21, + C4FO_InArray = 22, + // last C4FO must be smaller than C4SO_First. }; // Sort map - using same values as C4FindObjectCondID! @@ -371,6 +373,17 @@ protected: virtual bool IsImpossible(); }; +class C4FindObjectInArray : public C4FindObject +{ +public: + C4FindObjectInArray(C4ValueArray *pArray) : pArray(pArray) {} +private: + C4ValueArray *pArray; +protected: + virtual bool Check(C4Object *pObj); + virtual bool IsImpossible(); +}; + // result sorting class C4SortObject { diff --git a/src/gamescript/C4GameScript.cpp b/src/gamescript/C4GameScript.cpp index bcdd39dc5..f30bc8dd5 100644 --- a/src/gamescript/C4GameScript.cpp +++ b/src/gamescript/C4GameScript.cpp @@ -2845,6 +2845,7 @@ C4ScriptConstDef C4ScriptGameConstMap[]= { "C4FO_Controller" ,C4V_Int, C4FO_Controller }, { "C4FO_Func" ,C4V_Int, C4FO_Func }, { "C4FO_Layer" ,C4V_Int, C4FO_Layer }, + { "C4FO_InArray" ,C4V_Int, C4FO_InArray }, { "MD_DragSource" ,C4V_Int, C4MC_MD_DragSource }, { "MD_DropTarget" ,C4V_Int, C4MC_MD_DropTarget }, diff --git a/src/script/C4ValueArray.h b/src/script/C4ValueArray.h index 180bf31d5..d1b6e3bb4 100644 --- a/src/script/C4ValueArray.h +++ b/src/script/C4ValueArray.h @@ -45,6 +45,11 @@ public: return C4VNull; } + const C4Value &_GetItem(int32_t iElem) const // unchecked access; not auto-increasing array + { + return pData[iElem]; + } + C4Value operator[](int32_t iElem) const { return GetItem(iElem); } C4Value &operator[](int32_t iElem); // interface for the engine, asserts that 0 <= index < MaxSize