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); }