C4ValueArray::C4ValueArray(const C4ValueArray &ValueArray2) : iSize(0), iCapacity(0), pData(NULL) { SetSize(ValueArray2.GetSize()); for (int32_t i = 0; i < iSize; i++) pData[i].Set(ValueArray2.GetItem(i)); }
bool C4MapScriptAlgo::GetXYProps(const C4PropList *props, C4PropertyName k, int32_t *out_xy, bool zero_defaults) { // Evaluate property named "k" in proplist props to store two numbers in out_xy: // If props->k is a single integer, fill both numbers in out_xy with it // If props->k is an array, check that it contains two numbers and store them in out_xy if (!props->HasProperty(&Strings.P[k])) { if (zero_defaults) out_xy[0] = out_xy[1] = 0; return false; } C4Value val; C4ValueArray *arr; props->GetProperty(k, &val); if ((arr = val.getArray())) { if (arr->GetSize() != 2) throw C4AulExecError(FormatString("C4MapScriptAlgo: Expected either integer or array with two integer elements in property \"%s\".", Strings.P[k].GetCStr()).getData()); out_xy[0] = arr->GetItem(0).getInt(); out_xy[1] = arr->GetItem(1).getInt(); } else { out_xy[0] = out_xy[1] = val.getInt(); } return true; }
bool C4ValueArray::operator==(const C4ValueArray& IntList2) const { for (int32_t i=0; i<std::max(iSize, IntList2.GetSize()); i++) if (GetItem(i) != IntList2.GetItem(i)) return false; return true; }
C4MapScriptAlgoPolygon::C4MapScriptAlgoPolygon(const C4PropList *props) { // Get MAPALGO_Polygon properties C4Value vptx, vpty; props->GetProperty(P_X, &vptx); props->GetProperty(P_Y, &vpty); C4ValueArray *ptx = vptx.getArray(), *pty = vpty.getArray(); if (!ptx || !pty || ptx->GetSize() != pty->GetSize()) throw C4AulExecError("C4MapScriptAlgoPolygon: Expected two equally sized int arrays in properties \"X\" and \"Y\"."); poly.resize(ptx->GetSize()); for (int32_t i=0; i<ptx->GetSize(); ++i) { poly[i].x = ptx->GetItem(i).getInt(); poly[i].y = pty->GetItem(i).getInt(); } wdt = props->GetPropertyInt(P_Wdt); if (!wdt) wdt = 1; empty = !!props->GetPropertyInt(P_Empty); open = !!props->GetPropertyInt(P_Open); if (open && !empty) throw C4AulExecError("C4MapScriptAlgoPolygon: Only empty polygons may be open."); }
C4MapScriptAlgoModifier::C4MapScriptAlgoModifier(const C4PropList *props, int32_t min_ops, int32_t max_ops) { // Evaluate "Op" property of all algos that take another algo or layer as an operand // Op may be a proplist or an array of proplists C4Value vops; int32_t n; C4ValueArray temp_ops; props->GetProperty(P_Op, &vops); C4ValueArray *ops = vops.getArray(); if (!ops) { C4PropList *op = vops.getPropList(); if (op) { temp_ops.SetItem(0, vops); ops = &temp_ops; n = 1; } } else { n = ops->GetSize(); } if (!ops || n<min_ops || (max_ops && n>max_ops)) throw C4AulExecError(FormatString("C4MapScriptAlgo: Expected between %d and %d operands in property \"Op\".", (int)min_ops, (int)max_ops).getData()); operands.resize(n); try { // can easily crash this by building a recursive prop list // unfortunately, protecting against that is not trivial for (int32_t i=0; i<n; ++i) { C4MapScriptAlgo *new_algo = FnParAlgo(ops->GetItem(i).getPropList()); if (!new_algo) throw C4AulExecError(FormatString("C4MapScriptAlgo: Operand %d in property \"Op\" not valid.", (int)i).getData()); operands[i] = new_algo; } } catch (...) { Clear(); throw; } }