#pragma once #include #include #include #include #define TOPICS(X) \ X(NEW(IntroductionSource), _("Introduction"), "gametype_tdm") \ X(NEW(MovementSource), _("Movement"), "gametype_inv") \ X(NEW(GametypeSource), _("Gametypes"), "gametype_dm") \ X(NEW(WeaponSource), _("Weapons"), "gametype_duel") \ X(NEW(ItemSource), _("Items"), "gametype_kh") \ X(NEW(PowerupSource), _("Powerups"), "gametype_dom") \ X(NEW(BuffSource), _("Buffs"), "gametype_ka") \ X(NEW(NadeSource), _("Nades"), "gametype_ft") \ X(NEW(MonsterSource), _("Monsters"), "gametype_lms") \ X(NEW(VehicleSource), _("Vehicles"), "gametype_rc") \ X(NEW(TurretSource), _("Turrets"), "gametype_as") \ X(NEW(MutatorSource), _("Mutators"), "gametype_nb") \ X(NEW(ModSource), _("Mods"), "gametype_ons") \ /**/ // XONRELEASE TODO: improve icons, consider just creating new ones from scratch just for the guide CLASS(TopicSource, DataSource) METHOD(TopicSource, getEntry, entity(TopicSource this, int i, void(string, string) returns)); METHOD(TopicSource, reload, int(TopicSource this, string filter)); ENDCLASS(TopicSource) .bool m_hidden; .bool instanceOfAmmo; .bool instanceOfHealth; .bool instanceOfArmor; .bool instanceOfPowerup; #define _REGISTRY_SOURCE_FILL(arr_name, register_arr, cond1, cond2, cond3, num_conds, filter_cond) \ if (num_conds >= 1) \ FOREACH(register_arr, !it.m_hidden && (cond1) && (filter_cond), { \ AL_sete(arr_name##_MENU, arr_name##_MENU_COUNT, it); \ ++arr_name##_MENU_COUNT; \ }); \ if (num_conds >= 2) \ FOREACH(register_arr, !it.m_hidden && (cond2) && (filter_cond), { \ AL_sete(arr_name##_MENU, arr_name##_MENU_COUNT, it); \ ++arr_name##_MENU_COUNT; \ }); \ if (num_conds >= 3) \ FOREACH(register_arr, !it.m_hidden && (cond3) && (filter_cond), { \ AL_sete(arr_name##_MENU, arr_name##_MENU_COUNT, it); \ ++arr_name##_MENU_COUNT; \ }); #define _REGISTRY_SOURCE(id, arr_name, register_arr, cond1, cond2, cond3, num_conds) \ ArrayList arr_name##_MENU; \ int arr_name##_MENU_COUNT; \ STATIC_INIT_LATE(arr_name##_MENU) \ { \ AL_NEW(arr_name##_MENU, REGISTRY_MAX(register_arr), NULL, e); \ _REGISTRY_SOURCE_FILL(arr_name, register_arr, cond1, cond2, cond3, num_conds, true); \ } \ CLASS(id, DataSource) \ METHOD(id, getEntry, entity(id this, int i, void(string, string) returns)) \ { \ entity e = AL_gete(arr_name##_MENU, i); \ if (returns) \ e.display(e, returns); \ return e; \ } \ METHOD(id, reload, int(id this, string filter)) \ { \ arr_name##_MENU_COUNT = 0; \ _REGISTRY_SOURCE_FILL(arr_name, register_arr, cond1, cond2, cond3, num_conds, \ (filter == "" ? true : (strstrofs(strtolower(it.message ? it.message : it.m_name), strtolower(filter), 0) >= 0))); \ return arr_name##_MENU_COUNT; \ } \ ENDCLASS(id) #define REGISTRY_SOURCE(...) EVAL(OVERLOAD(REGISTRY_SOURCE, __VA_ARGS__)) #define REGISTRY_SOURCE_3(id, arr_name, register_arr) _REGISTRY_SOURCE(id, arr_name, register_arr, true, false, false, 1) #define REGISTRY_SOURCE_4(id, arr_name, register_arr, cond1) _REGISTRY_SOURCE(id, arr_name, register_arr, cond1, false, false, 1) #define REGISTRY_SOURCE_5(id, arr_name, register_arr, cond1, cond2) _REGISTRY_SOURCE(id, arr_name, register_arr, cond1, cond2, false, 2) #define REGISTRY_SOURCE_6(id, arr_name, register_arr, cond1, cond2, cond3) _REGISTRY_SOURCE(id, arr_name, register_arr, cond1, cond2, cond3, 3) // The descriptions for these are in menu/xonotic/guide/pages.qc REGISTRY_SOURCE(IntroductionSource, Introduction, IntroductionGuidePages) REGISTRY_SOURCE(MovementSource, Movement, MovementGuidePages) REGISTRY_SOURCE(ModSource, Mods, ModsGuidePages) #include // The descriptions for these are in common/gametypes/gametype/*/*.qc REGISTRY_SOURCE(GametypeSource, Gametypes, Gametypes) #include // The descriptions for these are in common/mutators/mutator/buffs/buff/*.qc REGISTRY_SOURCE(BuffSource, Buffs, StatusEffects, it.instanceOfBuff) #include // The descriptions for these are in common/mutators/mutator/powerups/powerup/*.qc REGISTRY_SOURCE(PowerupSource, Powerups, Items, it.instanceOfPowerup) #include // The descriptions for these are in common/items/item/*.qc and common/mutators/mutator/instagib/items.qc REGISTRY_SOURCE(ItemSource, Items, Items, !it.instanceOfPowerup && it.instanceOfAmmo, !it.instanceOfPowerup && it.instanceOfHealth, !it.instanceOfPowerup && it.instanceOfArmor) #include // The descriptions for these are in common/mutators/mutator/nades/nade/*.qc REGISTRY_SOURCE(NadeSource, Nades, Nades) #include // The descriptions for these are in common/weapons/weapon/*.qc and common/mutators/mutator/overkill/ok*.qc (weapon files) REGISTRY_SOURCE(WeaponSource, Weapons, Weapons, !startsWith(it.registered_id, "WEP_OVERKILL_"), startsWith(it.registered_id, "WEP_OVERKILL_") && !(it.spawnflags & WEP_FLAG_SUPERWEAPON), startsWith(it.registered_id, "WEP_OVERKILL_") && (it.spawnflags & WEP_FLAG_SUPERWEAPON)) #include // The descriptions for these are in common/monsters/monster/*.qc REGISTRY_SOURCE(MonsterSource, Monsters, Monsters) #include // The descriptions for these are in common/vehicles/vehicle/*.qc // XONRELEASE TODO: improve icons to make the styling consistent, may need to create new ones from scratch just for the guide REGISTRY_SOURCE(VehicleSource, Vehicles, Vehicles) #include // The descriptions for these are in common/turrets/turret/*.qc REGISTRY_SOURCE(TurretSource, Turrets, Turrets) #include // The descriptions for these are in common/mutators/mutator/*.qc (not the cl_* or sv_* files) REGISTRY_SOURCE(MutatorSource, Mutators, Mutators)