Exemple #1
0
static void CreateAddMapItemSubObjs(UIObject *c, void *vData)
{
	const CreateAddMapItemObjsImplData *data = vData;
	const int pageSize = data->GridSize.x * data->GridSize.y;
	// Check if we need to recreate the objs
	// TODO: this is a very heavyweight way to do it
	int count = 0;
	bool allChildrenSame = true;
	for (int i = 0; i < MapObjectsCount(&gMapObjects); i++)
	{
		MapObject *mo = IndexMapObject(i);
		UIObject *o2 =
			UIObjectCreate(UITYPE_CUSTOM, 0, svec2i_zero(), data->GridItemSize);
		o2->IsDynamicData = true;
		CCALLOC(o2->Data, data->DataSize);
		if (!data->ObjFunc(o2, mo, data->Data))
		{
			UIObjectDestroy(o2);
			continue;
		}
		const int pageIdx = count / pageSize;
		if (pageIdx >= (int)c->Children.size)
		{
			allChildrenSame = false;
			break;
		}
		const UIObject **op = CArrayGet(&c->Children, pageIdx);
		const UIObject **octx = CArrayGet(&(*op)->Children, 0);
		const int idx = count % pageSize;
		if (idx >= (int)(*octx)->Children.size)
		{
			allChildrenSame = false;
			break;
		}
		const UIObject **oc = CArrayGet(&(*octx)->Children, idx);
		if (memcmp(o2->Data, (*oc)->Data, data->DataSize) != 0)
		{
			allChildrenSame = false;
			UIObjectDestroy(o2);
			break;
		}
		count++;
		UIObjectDestroy(o2);
	}
	int cCount = CountAddMapItemSubObjs(c);
	if (cCount == count && allChildrenSame)
	{
		return;
	}

	// Recreate the child UI objects
	c->Highlighted = NULL;
	UIObject **objs = c->Children.data;
	for (int i = 0; i < (int)c->Children.size; i++, objs++)
	{
		UIObjectDestroy(*objs);
	}
	CArrayClear(&c->Children);

	// Create pagination
	int pageNum = 1;
	UIObject *pageLabel = NULL;
	UIObject *page = NULL;
	UIObject *o =
		UIObjectCreate(UITYPE_CUSTOM, 0, svec2i_zero(), data->GridItemSize);
	o->ChangesData = true;
	const struct vec2i gridStart = svec2i_zero();
	struct vec2i pos = svec2i_zero();
	count = 0;
	for (int i = 0; i < MapObjectsCount(&gMapObjects); i++)
	{
		// Only add normal map objects
		MapObject *mo = IndexMapObject(i);
		UIObject *o2 = UIObjectCopy(o);
		o2->IsDynamicData = true;
		CCALLOC(o2->Data, data->DataSize);
		if (!data->ObjFunc(o2, mo, data->Data))
		{
			UIObjectDestroy(o2);
			continue;
		}
		o2->Pos = pos;
		if (count == 0)
		{
			pageLabel = UIObjectCreate(
				UITYPE_LABEL, 0,
				svec2i((pageNum - 1) * 10, 0), svec2i(10, FontH()));
			char buf[32];
			sprintf(buf, "%d", pageNum);
			UIObjectSetDynamicLabel(pageLabel, buf);
			page = UIObjectCreate(
				UITYPE_CONTEXT_MENU, 0,
				svec2i_add(data->PageOffset, pageLabel->Size), svec2i_zero());
			UIObjectAddChild(pageLabel, page);
			pageNum++;
		}
		UIObjectAddChild(page, o2);
		pos.x += o->Size.x;
		if (((count + 1) % data->GridSize.x) == 0)
		{
			pos.x = gridStart.x;
			pos.y += o->Size.y;
		}
		count++;
		if (count == pageSize)
		{
			count = 0;
			pos = gridStart;
			UIObjectAddChild(c, pageLabel);
		}
	}
	if (pageLabel != NULL)
	{
		UIObjectAddChild(c, pageLabel);
	}

	UIObjectDestroy(o);
}
void SetupQuickPlayCampaign(CampaignSetting *setting)
{
	Mission *m;
	CMALLOC(m, sizeof *m);
	MissionInit(m);
	m->WallStyle = rand() % WALL_STYLE_COUNT;
	m->FloorStyle = rand() % FLOOR_STYLE_COUNT;
	m->RoomStyle = rand() % FLOOR_STYLE_COUNT;
	m->ExitStyle = rand() % GetExitCount();
	m->KeyStyle = rand() % KEYSTYLE_COUNT;
	strcpy(
		m->DoorStyle, DoorStyleStr(rand() % gPicManager.doorStyleNames.size));
	m->Size = GenerateQuickPlayMapSize(
		ConfigGetEnum(&gConfig, "QuickPlay.MapSize"));
	m->Type = MAPTYPE_CLASSIC;	// TODO: generate different map types
	switch (m->Type)
	{
	case MAPTYPE_CLASSIC:
		m->u.Classic.Walls = GenerateQuickPlayParam(
			ConfigGetEnum(&gConfig, "QuickPlay.WallCount"), 0, 5, 15, 30);
		m->u.Classic.WallLength = GenerateQuickPlayParam(
			ConfigGetEnum(&gConfig, "QuickPlay.WallLength"), 1, 3, 6, 12);
		m->u.Classic.CorridorWidth = rand() % 3 + 1;
		m->u.Classic.Rooms.Count = GenerateQuickPlayParam(
			ConfigGetEnum(&gConfig, "QuickPlay.RoomCount"), 0, 2, 5, 12);
		m->u.Classic.Rooms.Min = rand() % 10 + 5;
		m->u.Classic.Rooms.Max = rand() % 10 + m->u.Classic.Rooms.Min;
		m->u.Classic.Rooms.Edge = 1;
		m->u.Classic.Rooms.Overlap = 1;
		m->u.Classic.Rooms.Walls = rand() % 5;
		m->u.Classic.Rooms.WallLength = rand() % 6 + 1;
		m->u.Classic.Rooms.WallPad = rand() % 4 + 1;
		m->u.Classic.Squares = GenerateQuickPlayParam(
			ConfigGetEnum(&gConfig, "QuickPlay.SquareCount"), 0, 1, 3, 6);
		m->u.Classic.Doors.Enabled = rand() % 2;
		m->u.Classic.Doors.Min = 1;
		m->u.Classic.Doors.Max = 6;
		m->u.Classic.Pillars.Count = rand() % 5;
		m->u.Classic.Pillars.Min = rand() % 3 + 1;
		m->u.Classic.Pillars.Max = rand() % 3 + m->u.Classic.Pillars.Min;
		break;
	default:
		assert(0 && "unknown map type");
		break;
	}
	CharacterStoreTerminate(&setting->characters);
	CharacterStoreInit(&setting->characters);
	int c = GenerateQuickPlayParam(
		ConfigGetEnum(&gConfig, "QuickPlay.EnemyCount"), 3, 5, 8, 12);
	SetupQuickPlayEnemies(m, c, &setting->characters);

	c = GenerateQuickPlayParam(
		ConfigGetEnum(&gConfig, "QuickPlay.ItemCount"), 0, 2, 5, 10);
	for (int i = 0; i < c; i++)
	{
		MapObjectDensity mop;
		mop.M = IndexMapObject(rand() % MapObjectsCount(&gMapObjects));
		mop.Density = GenerateQuickPlayParam(
			ConfigGetEnum(&gConfig, "QuickPlay.ItemCount"), 0, 5, 10, 20);
		CArrayPushBack(&m->MapObjectDensities, &mop);
	}
	m->EnemyDensity = (40 + (rand() % 20)) / m->Enemies.size;
	CA_FOREACH(const GunDescription, g, gGunDescriptions.Guns)
		if (g->IsRealGun)
		{
			CArrayPushBack(&m->Weapons, &g);
		}
	CA_FOREACH_END()
	m->WallMask = RandomBGColor();
	m->FloorMask = RandomBGColor();
	m->RoomMask = RandomBGColor();
	m->AltMask = RandomBGColor();

	CFREE(setting->Title);
	CSTRDUP(setting->Title, "Quick play");
	CFREE(setting->Author);
	CSTRDUP(setting->Author, "");
	CFREE(setting->Description);
	CSTRDUP(setting->Description, "");
	CArrayPushBack(&setting->Missions, m);
	CFREE(m);
}