Пример #1
0
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));
}
Пример #2
0
C4ValueArray * C4PropList::GetProperties() const
{
	C4ValueArray * a;
	int i;
	if (GetPrototype())
	{
		a = GetPrototype()->GetProperties();
		i = a->GetSize();
		a->SetSize(i + Properties.GetSize());
	}
	else
	{
		a = new C4ValueArray(Properties.GetSize());
		i = 0;
	}
	const C4Property * p = Properties.First();
	while (p)
	{
		assert(p->Key != nullptr && "Proplist key is nullpointer");
		(*a)[i++] = C4VString(p->Key);
		assert(((*a)[i - 1].GetType() == C4V_String) && "Proplist key is non-string");
		p = Properties.Next(p);
	}
	return a;
}
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;
}
Пример #4
0
// return is to be freed by the caller
C4ValueArray *C4FindObject::FindMany(const C4ObjectList &Objs)
{
	// Trivial case
	if (IsImpossible())
		return new C4ValueArray();
	// Set up array
	C4ValueArray *pArray = new C4ValueArray(32);
	int32_t iSize = 0;
	// Search
	for (C4Object *obj : Objs)
		if (obj->Status)
			if (Check(obj))
			{
				// Grow the array, if neccessary
				if (iSize >= pArray->GetSize())
					pArray->SetSize(iSize * 2);
				// Add object
				(*pArray)[iSize++] = C4VObj(obj);
			}
	// Shrink array
	pArray->SetSize(iSize);
	// Recheck object status (may shrink array again)
	CheckObjectStatus(pArray);
	// Apply sorting
	if (pSort) pSort->SortObjects(pArray);
	return pArray;
}
Пример #5
0
void C4ParticleProperties::SetCollisionFunc(const C4Value &source)
{
	C4ValueArray *valueArray;
	if (!(valueArray = source.getArray())) return;

	int arraySize = valueArray->GetSize();
	if (arraySize < 1) return;

	int type = (*valueArray)[0].getInt();

	switch (type)
	{
	case C4PC_Die:
		collisionCallback = &C4ParticleProperties::CollisionDie;
		break;
	case C4PC_Bounce:
		collisionCallback = &C4ParticleProperties::CollisionBounce;
		bouncyness = 1.f;
		if (arraySize >= 2)
			bouncyness = ((float)(*valueArray)[1].getInt());
		break;
	case C4PC_Stop:
		collisionCallback = &C4ParticleProperties::CollisionStop;
		break;
	default:
		assert(false);
		break;
	}
}
Пример #6
0
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;
}
Пример #7
0
static C4ValueArray *FnLayerCreateMatTexMask(C4PropList * _this, const C4Value &mask_spec)
{
	// layer script function: Generate an array 256 bools representing the given mask_spec
	C4MapScriptMatTexMask mat_mask(mask_spec);
	C4ValueArray *result = new C4ValueArray(C4M_MaxTexIndex + 1);
	for (int32_t i=0; i < C4M_MaxTexIndex + 1; ++i)
	{
		result->SetItem(i, C4VBool(mat_mask(uint8_t(i), C4M_MaxTexIndex)));
	}
	return result;
}
Пример #8
0
C4ValueArray * C4Effect::GetProperties() const
{
	C4ValueArray * a = C4PropList::GetProperties();
	int i;
	i = a->GetSize();
	a->SetSize(i + 5);
	(*a)[i++] = C4VString(&::Strings.P[P_Name]);
	(*a)[i++] = C4VString(&::Strings.P[P_Priority]);
	(*a)[i++] = C4VString(&::Strings.P[P_Interval]);
	(*a)[i++] = C4VString(&::Strings.P[P_CommandTarget]);
	(*a)[i++] = C4VString(&::Strings.P[P_Time]);
	return a;
}
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;
	}
}
Пример #11
0
C4ValueArray *C4FindObject::FindMany(const C4ObjectList &Objs,
                                     const C4LSectors &Sct) {
  // Trivial case
  if (IsImpossible()) return new C4ValueArray();
  C4Rect *pBounds = GetBounds();
  if (!pBounds) return FindMany(Objs);
  // Prepare for array that may be generated
  C4ValueArray *pArray;
  int32_t iSize;
  // Check shape lists?
  if (UseShapes()) {
    // Get area
    C4LArea Area(&Game.Objects.Sectors, *pBounds);
    C4LSector *pSct;
    C4ObjectList *pLst = Area.FirstObjectShapes(&pSct);
    // Check if a single-sector check is enough
    if (!Area.Next(pSct)) return FindMany(pSct->ObjectShapes);
    // Set up array
    pArray = new C4ValueArray(32);
    iSize = 0;
    // Create marker, search all areas
    uint32_t iMarker = ::Game.Objects.GetNextMarker();
    for (; pLst; pLst = Area.NextObjectShapes(pLst, &pSct))
      for (C4ObjectLink *pLnk = pLst->First; pLnk; pLnk = pLnk->Next)
        if (pLnk->Obj->Status)
          if (pLnk->Obj->Marker != iMarker) {
            pLnk->Obj->Marker = iMarker;
            if (Check(pLnk->Obj)) {
              // Grow the array, if neccessary
              if (iSize >= pArray->GetSize()) pArray->SetSize(iSize * 2);
              // Add object
              (*pArray)[iSize++] = C4VObj(pLnk->Obj);
            }
          }
  } else {
    // Set up array
    pArray = new C4ValueArray(32);
    iSize = 0;
    // Search
    C4LArea Area(&Game.Objects.Sectors, *pBounds);
    C4LSector *pSct;
    for (C4ObjectList *pLst = Area.FirstObjects(&pSct); pLst;
         pLst = Area.NextObjects(pLst, &pSct))
      for (C4ObjectLink *pLnk = pLst->First; pLnk; pLnk = pLnk->Next)
        if (pLnk->Obj->Status)
          if (Check(pLnk->Obj)) {
            // Grow the array, if neccessary
            if (iSize >= pArray->GetSize()) pArray->SetSize(iSize * 2);
            // Add object
            (*pArray)[iSize++] = C4VObj(pLnk->Obj);
          }
  }
  // Shrink array
  pArray->SetSize(iSize);
  // Recheck object status (may shrink array again)
  CheckObjectStatus(pArray);
  // Apply sorting
  if (pSort) pSort->SortObjects(pArray);
  return pArray;
}
bool C4EditCursor::DoContextMenu(DWORD dwKeyState)
{
	bool fObjectSelected = !!Selection.ObjectCount();
#ifdef USE_WIN32_WINDOWS
	POINT point; GetCursorPos(&point);
	HMENU hContext = GetSubMenu(hMenu,0);
	SetMenuItemEnable( hContext, IDM_VIEWPORT_DELETE, fObjectSelected && Console.Editing);
	SetMenuItemEnable( hContext, IDM_VIEWPORT_DUPLICATE, fObjectSelected && Console.Editing);
	SetMenuItemEnable( hContext, IDM_VIEWPORT_CONTENTS, fObjectSelected && Selection.GetObject()->Contents.ObjectCount() && Console.Editing);
	SetMenuItemText(hContext,IDM_VIEWPORT_DELETE,LoadResStr("IDS_MNU_DELETE"));
	SetMenuItemText(hContext,IDM_VIEWPORT_DUPLICATE,LoadResStr("IDS_MNU_DUPLICATE"));
	SetMenuItemText(hContext,IDM_VIEWPORT_CONTENTS,LoadResStr("IDS_MNU_CONTENTS"));

	ObjselectDelItems();
	C4FindObjectAtPoint pFO(X,Y);
	C4ValueArray * atcursor; atcursor = pFO.FindMany(::Objects, ::Objects.Sectors); // needs freeing (single object ptr)
	int itemcount = atcursor->GetSize();
	if(itemcount > 0)
	{
		const int maxitems = 25; // Maximum displayed objects. if you raise it, also change note with IDM_VPORTDYN_FIRST in resource.h
		if(itemcount > maxitems) itemcount = maxitems+1;
		itemsObjselect.resize(itemcount+1); // +1 for a separator
		itemsObjselect[0].ItemId = IDM_VPORTDYN_FIRST;
		itemsObjselect[0].Object = NULL;
		AppendMenu(hContext, MF_SEPARATOR, IDM_VPORTDYN_FIRST, NULL);
		int i = 1;
		for(std::vector<ObjselItemDt>::iterator it = itemsObjselect.begin() + 1; it != itemsObjselect.end(); ++it, ++i)
		{
			C4Object * obj = (*atcursor)[i-1].getObj();
			assert(obj);
			it->ItemId = IDM_VPORTDYN_FIRST+i;
			it->Object = obj;
			AppendMenu(hContext, MF_STRING, it->ItemId, FormatString("%s #%i (%i/%i)", obj->GetName(), obj->Number, obj->GetX(), obj->GetY()).GetWideChar());
		}
		if(atcursor->GetSize() > maxitems)
		{
			AppendMenu(hContext, MF_GRAYED, IDM_VPORTDYN_FIRST+maxitems+1, L"...");
			itemsObjselect[maxitems+1].ItemId = IDM_VPORTDYN_FIRST+maxitems+1;
			itemsObjselect[maxitems+1].Object = NULL;
		}
	}
	delete atcursor;

	int32_t iItem = TrackPopupMenu(
	                  hContext,
	                  TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD | TPM_LEFTBUTTON | TPM_NONOTIFY,
	                  point.x,point.y, 0,
	                  Console.hWindow,
	                  NULL);
	switch (iItem)
	{
	case IDM_VIEWPORT_DELETE: Delete(); break;
	case IDM_VIEWPORT_DUPLICATE: Duplicate(); break;
	case IDM_VIEWPORT_CONTENTS: GrabContents(); break;
	case 0: break;
	default:
		for(std::vector<ObjselItemDt>::iterator it = itemsObjselect.begin() + 1; it != itemsObjselect.end(); ++it)
			if(it->ItemId == iItem)
			{
				DoContextObjsel(it->Object, (dwKeyState & MK_SHIFT) == 0);
				break;
			}
		break;
	}
	ObjselectDelItems();
#else
#ifdef WITH_DEVELOPER_MODE
	gtk_widget_set_sensitive(itemDelete, fObjectSelected && Console.Editing);
	gtk_widget_set_sensitive(itemDuplicate, fObjectSelected && Console.Editing);
	gtk_widget_set_sensitive(itemGrabContents, fObjectSelected && Selection.GetObject()->Contents.ObjectCount() && Console.Editing);

	ObjselectDelItems();
	C4FindObjectAtPoint pFO(X,Y);
	C4ValueArray * atcursor; atcursor = pFO.FindMany(::Objects, ::Objects.Sectors); // needs freeing
	int itemcount = atcursor->GetSize();
	if(itemcount > 0)
	{
		itemsObjselect.resize(itemcount+1); // +1 for a separator
		itemsObjselect[0].MenuItem = gtk_separator_menu_item_new();
		itemsObjselect[0].EditCursor = this;
		gtk_menu_shell_append(GTK_MENU_SHELL(menuContext), itemsObjselect[0].MenuItem);
		int i = 0;
		for(std::vector<ObjselItemDt>::iterator it = itemsObjselect.begin() + 1; it != itemsObjselect.end(); ++it, ++i)
		{
			it->EditCursor = this;
			C4Object * obj = (*atcursor)[i].getObj();
			assert(obj);
			it->Object = obj;
			GtkWidget * wdg = gtk_menu_item_new_with_label(FormatString("%s #%i (%i/%i)", obj->GetName(), obj->Number, obj->GetX(), obj->GetY()).getData());
			it->MenuItem = wdg;
			gtk_menu_shell_append(GTK_MENU_SHELL(menuContext), wdg);
			g_signal_connect(G_OBJECT(wdg), "activate", G_CALLBACK(OnObjselect), &*it);
		}
	}
	delete atcursor;
	gtk_widget_show_all(menuContext);

	gtk_menu_popup(GTK_MENU(menuContext), NULL, NULL, NULL, NULL, 3, 0);
#endif
#endif
	return true;
}
Пример #13
0
void C4ParticleValueProvider::Set(const C4ValueArray &fromArray)
{
	startValue = endValue = 1.0f;
	valueFunction = &C4ParticleValueProvider::Const;

	size_t arraySize = (size_t) fromArray.GetSize();
	if (arraySize < 2) return;

	int type = fromArray[0].getInt();

	switch (type)
	{
	case C4PV_Const:
		if (arraySize >= 2)
		{
			SetType(C4PV_Const);
			SetParameterValue(VAL_TYPE_FLOAT, fromArray[1], &C4ParticleValueProvider::startValue);
		}
		break;

	case C4PV_Linear:
		if (arraySize >= 3)
		{
			SetType(C4PV_Linear);
			SetParameterValue(VAL_TYPE_FLOAT, fromArray[1], &C4ParticleValueProvider::startValue);
			SetParameterValue(VAL_TYPE_FLOAT, fromArray[2], &C4ParticleValueProvider::endValue);
		}
		break;
	case C4PV_Random:
		if (arraySize >= 3)
		{
			SetType(C4PV_Random);
			SetParameterValue(VAL_TYPE_FLOAT, fromArray[1], &C4ParticleValueProvider::startValue);
			SetParameterValue(VAL_TYPE_FLOAT, fromArray[2], &C4ParticleValueProvider::endValue);
			if (arraySize >= 4)
				SetParameterValue(VAL_TYPE_INT, fromArray[3], 0, &C4ParticleValueProvider::rerollInterval);
			alreadyRolled = 0;
		}
		break;
	case C4PV_Direction:
		if (arraySize >= 2)
		{
			SetType(C4PV_Direction);
			SetParameterValue(VAL_TYPE_FLOAT, fromArray[1], &C4ParticleValueProvider::startValue);
		}
		break;
	case C4PV_Step:
		if (arraySize >= 4)
		{
			SetType(C4PV_Step);
			SetParameterValue(VAL_TYPE_FLOAT, fromArray[1], &C4ParticleValueProvider::startValue);
			SetParameterValue(VAL_TYPE_FLOAT, fromArray[2], &C4ParticleValueProvider::currentValue);
			SetParameterValue(VAL_TYPE_FLOAT, fromArray[3], &C4ParticleValueProvider::delay);
			SetParameterValue(VAL_TYPE_FLOAT, fromArray[4], &C4ParticleValueProvider::maxValue);
			if (delay == 0.f) delay = 1.f;
		}
		break;
	case C4PV_KeyFrames:
		if (arraySize >= 5)
		{
			SetType(C4PV_KeyFrames);
			SetParameterValue(VAL_TYPE_INT, fromArray[1], 0,  &C4ParticleValueProvider::smoothing);
			keyFrames.resize(arraySize + 4 - 1); // 2*2 additional information floats at the beginning and ending, offset the first array item, though

			keyFrameCount = 0;
			const size_t startingOffset = 2;
			size_t i = startingOffset;
			for (; i < arraySize; ++i)
			{
				SetParameterValue(VAL_TYPE_KEYFRAMES, fromArray[(int32_t)i], 0, 0, 2 + i - startingOffset);
			}
			keyFrameCount = (i - startingOffset) / 2 + 2;

			startValue = keyFrames[2 + 1];
			endValue = keyFrames[2 * keyFrameCount - 1];

			// add two points for easier interpolation at beginning and ending
			keyFrames[0] = -500.f;
			keyFrames[1] = keyFrames[2 + 1];
			keyFrames[2 * keyFrameCount - 2] = 1500.f;
			keyFrames[2 * keyFrameCount - 1] = keyFrames[keyFrameCount - 1 - 2];

		}
		break;
	case C4PV_Sin:
		if (arraySize >= 3)
		{
			SetType(C4PV_Sin); // Sin(parameterValue) * maxValue + startValue
			SetParameterValue(VAL_TYPE_FLOAT, fromArray[1], &C4ParticleValueProvider::parameterValue);
			SetParameterValue(VAL_TYPE_FLOAT, fromArray[2], &C4ParticleValueProvider::maxValue);
			SetParameterValue(VAL_TYPE_FLOAT, fromArray[3], &C4ParticleValueProvider::startValue);
		}
		break;
	case C4PV_Speed:
		if (arraySize >= 3)
		{
			SetType(C4PV_Speed);
			SetParameterValue(VAL_TYPE_FLOAT, fromArray[1], &C4ParticleValueProvider::speedFactor);
			SetParameterValue(VAL_TYPE_FLOAT, fromArray[2], &C4ParticleValueProvider::startValue);
		}
		break;
	case C4PV_Wind:
		if (arraySize >= 3)
		{
			SetType(C4PV_Wind);
			SetParameterValue(VAL_TYPE_FLOAT, fromArray[1], &C4ParticleValueProvider::speedFactor);
			SetParameterValue(VAL_TYPE_FLOAT, fromArray[2], &C4ParticleValueProvider::startValue);
		}
		break;
	case C4PV_Gravity:
		if (arraySize >= 3)
		{
			SetType(C4PV_Gravity);
			SetParameterValue(VAL_TYPE_FLOAT, fromArray[1], &C4ParticleValueProvider::speedFactor);
			SetParameterValue(VAL_TYPE_FLOAT, fromArray[2], &C4ParticleValueProvider::startValue);
		}
		break;
	default:
		throw C4AulExecError("invalid particle value provider supplied");
		break;
	}
}