void LoadMissions(CArray *missions, json_t *missionsNode, int version) { json_t *child; for (child = missionsNode->child; child; child = child->next) { Mission m; MissionInit(&m); m.Title = GetString(child, "Title"); m.Description = GetString(child, "Description"); JSON_UTILS_LOAD_ENUM(m.Type, child, "Type", StrMapType); LoadInt(&m.Size.x, child, "Width"); LoadInt(&m.Size.y, child, "Height"); LoadInt(&m.WallStyle, child, "WallStyle"); LoadInt(&m.FloorStyle, child, "FloorStyle"); LoadInt(&m.RoomStyle, child, "RoomStyle"); LoadInt(&m.ExitStyle, child, "ExitStyle"); LoadInt(&m.KeyStyle, child, "KeyStyle"); if (version <= 5) { int doorStyle; LoadInt(&doorStyle, child, "DoorStyle"); strcpy(m.DoorStyle, DoorStyleStr(doorStyle)); } else { char *tmp = GetString(child, "DoorStyle"); strcpy(m.DoorStyle, tmp); CFREE(tmp); } LoadMissionObjectives( &m.Objectives, json_find_first_label(child, "Objectives")->child, version); LoadIntArray(&m.Enemies, child, "Enemies"); LoadIntArray(&m.SpecialChars, child, "SpecialChars"); if (version <= 3) { CArray items; CArrayInit(&items, sizeof(int)); LoadIntArray(&items, child, "Items"); CArray densities; CArrayInit(&densities, sizeof(int)); LoadIntArray(&densities, child, "ItemDensities"); for (int i = 0; i < (int)items.size; i++) { MapObjectDensity mod; mod.M = IntMapObject(*(int *)CArrayGet(&items, i)); mod.Density = *(int *)CArrayGet(&densities, i); CArrayPushBack(&m.MapObjectDensities, &mod); } } else { json_t *modsNode = json_find_first_label(child, "MapObjectDensities"); if (modsNode && modsNode->child) { modsNode = modsNode->child; for (json_t *modNode = modsNode->child; modNode; modNode = modNode->next) { MapObjectDensity mod; mod.M = StrMapObject( json_find_first_label(modNode, "MapObject")->child->text); LoadInt(&mod.Density, modNode, "Density"); CArrayPushBack(&m.MapObjectDensities, &mod); } } } LoadInt(&m.EnemyDensity, child, "EnemyDensity"); LoadWeapons( &m.Weapons, json_find_first_label(child, "Weapons")->child); strcpy(m.Song, json_find_first_label(child, "Song")->child->text); if (version <= 4) { // Load colour indices int wc, fc, rc, ac; LoadInt(&wc, child, "WallColor"); LoadInt(&fc, child, "FloorColor"); LoadInt(&rc, child, "RoomColor"); LoadInt(&ac, child, "AltColor"); m.WallMask = RangeToColor(wc); m.FloorMask = RangeToColor(fc); m.RoomMask = RangeToColor(rc); m.AltMask = RangeToColor(ac); } else { LoadColor(&m.WallMask, child, "WallMask"); LoadColor(&m.FloorMask, child, "FloorMask"); LoadColor(&m.RoomMask, child, "RoomMask"); LoadColor(&m.AltMask, child, "AltMask"); } switch (m.Type) { case MAPTYPE_CLASSIC: LoadInt(&m.u.Classic.Walls, child, "Walls"); LoadInt(&m.u.Classic.WallLength, child, "WallLength"); LoadInt(&m.u.Classic.CorridorWidth, child, "CorridorWidth"); LoadClassicRooms( &m, json_find_first_label(child, "Rooms")->child); LoadInt(&m.u.Classic.Squares, child, "Squares"); LoadClassicDoors(&m, child, "Doors"); LoadClassicPillars(&m, child, "Pillars"); break; case MAPTYPE_STATIC: if (!TryLoadStaticMap(&m, child, version)) { continue; } break; case MAPTYPE_CAVE: LoadInt(&m.u.Cave.FillPercent, child, "FillPercent"); LoadInt(&m.u.Cave.Repeat, child, "Repeat"); LoadInt(&m.u.Cave.R1, child, "R1"); LoadInt(&m.u.Cave.R2, child, "R2"); break; default: assert(0 && "unknown map type"); continue; } CArrayPushBack(missions, &m); } }
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); }
static void ConvertMission( Mission *dest, struct MissionOld *src, const int charCount) { int i; CFREE(dest->Title); CSTRDUP(dest->Title, src->title); CFREE(dest->Description); CSTRDUP(dest->Description, src->description); dest->Type = MAPTYPE_CLASSIC; dest->Size = Vec2iNew(src->mapWidth, src->mapHeight); dest->WallStyle = src->wallStyle; dest->FloorStyle = src->floorStyle; dest->RoomStyle = src->roomStyle; dest->ExitStyle = src->exitStyle; dest->KeyStyle = src->keyStyle; strcpy(dest->DoorStyle, DoorStyleStr(src->doorStyle)); for (i = 0; i < src->objectiveCount; i++) { MissionObjective mo; memset(&mo, 0, sizeof mo); ConvertMissionObjective(&mo, &src->objectives[i]); CArrayPushBack(&dest->Objectives, &mo); } // Note: modulo for compatibility with older, buggy missions for (i = 0; i < src->baddieCount; i++) { int n = src->baddies[i] % charCount; CArrayPushBack(&dest->Enemies, &n); } for (i = 0; i < src->specialCount; i++) { int n = src->specials[i] % charCount; CArrayPushBack(&dest->SpecialChars, &n); } for (i = 0; i < src->itemCount; i++) { MapObjectDensity mod; mod.M = IntMapObject(src->items[i]); mod.Density = src->itemDensity[i]; CArrayPushBack(&dest->MapObjectDensities, &mod); } dest->EnemyDensity = src->baddieDensity; CArrayClear(&dest->Weapons); for (i = 0; i < WEAPON_MAX; i++) { if ((src->weaponSelection & (1 << i)) || !src->weaponSelection) { GunDescription *g = CArrayGet(&gGunDescriptions.Guns, i); CArrayPushBack(&dest->Weapons, &g); } } strcpy(dest->Song, src->song); dest->WallMask = RangeToColor(abs(src->wallRange) % COLORRANGE_COUNT); dest->FloorMask = RangeToColor(abs(src->floorRange) % COLORRANGE_COUNT); dest->RoomMask = RangeToColor(abs(src->roomRange) % COLORRANGE_COUNT); dest->AltMask = RangeToColor(abs(src->altRange) % COLORRANGE_COUNT); dest->u.Classic.Walls = src->wallCount; dest->u.Classic.WallLength = src->wallLength; dest->u.Classic.CorridorWidth = 1; dest->u.Classic.Rooms.Count = src->roomCount; dest->u.Classic.Rooms.Min = 6; dest->u.Classic.Rooms.Max = 10; dest->u.Classic.Rooms.Edge = 0; dest->u.Classic.Rooms.Walls = 0; dest->u.Classic.Squares = src->squareCount; dest->u.Classic.Doors.Enabled = 1; dest->u.Classic.Doors.Min = dest->u.Classic.Doors.Max = 1; dest->u.Classic.Pillars.Count = 0; }