From 472716ff59f3a9e996d33a7894c61115f16bd9a4 Mon Sep 17 00:00:00 2001 From: geNia Date: Mon, 9 Nov 2020 16:38:25 -0500 Subject: [PATCH] Add Q-Zandronum plugin --- src/plugins/CMakeLists.txt | 1 + src/plugins/zandronumq/CMakeLists.txt | 123 + .../createserverdialogpages/flagsid.cpp | 214 + .../createserverdialogpages/flagsid.h | 45 + .../createserverdialogpages/flagspage.cpp | 404 ++ .../createserverdialogpages/flagspage.h | 137 + .../createserverdialogpages/flagspage.ui | 4492 +++++++++++++++++ .../flagspagevaluecontroller.h | 47 + .../flagspagevaluecontroller2.cpp | 659 +++ .../flagspagevaluecontroller2.h | 87 + .../flagspagevaluecontroller3.cpp | 693 +++ .../flagspagevaluecontroller3.h | 90 + .../votingsetupwidget.cpp | 145 + .../votingsetupwidget.h | 60 + .../votingsetupwidget.ui | 263 + .../zandronumq/enginezandronumqconfigbox.cpp | 88 + .../zandronumq/enginezandronumqconfigbox.h | 55 + src/plugins/zandronumq/huffman/bitreader.cpp | 144 + src/plugins/zandronumq/huffman/bitreader.h | 85 + src/plugins/zandronumq/huffman/bitwriter.cpp | 271 + src/plugins/zandronumq/huffman/bitwriter.h | 109 + src/plugins/zandronumq/huffman/codec.h | 71 + src/plugins/zandronumq/huffman/huffcodec.cpp | 330 ++ src/plugins/zandronumq/huffman/huffcodec.h | 179 + src/plugins/zandronumq/huffman/huffman.cpp | 155 + src/plugins/zandronumq/huffman/huffman.h | 55 + src/plugins/zandronumq/huffmanqt.cpp | 61 + src/plugins/zandronumq/huffmanqt.h | 37 + src/plugins/zandronumq/huffmanudpsocket.cpp | 86 + src/plugins/zandronumq/huffmanudpsocket.h | 48 + .../translations/zandronumq_ca_ES.ts | 2969 +++++++++++ .../translations/zandronumq_es_ES.ts | 2973 +++++++++++ .../translations/zandronumq_pl_PL.ts | 3609 +++++++++++++ src/plugins/zandronumq/zandronumq.xpm | 149 + src/plugins/zandronumq/zandronumq2dmflags.cpp | 341 ++ src/plugins/zandronumq/zandronumq2dmflags.h | 284 ++ src/plugins/zandronumq/zandronumq3dmflags.cpp | 362 ++ src/plugins/zandronumq/zandronumq3dmflags.h | 304 ++ src/plugins/zandronumq/zandronumqbinaries.cpp | 524 ++ src/plugins/zandronumq/zandronumqbinaries.h | 112 + .../zandronumq/zandronumqbroadcast.cpp | 182 + src/plugins/zandronumq/zandronumqbroadcast.h | 51 + .../zandronumq/zandronumqengineplugin.cpp | 190 + .../zandronumq/zandronumqengineplugin.h | 55 + .../zandronumq/zandronumqgameexefactory.cpp | 109 + .../zandronumq/zandronumqgameexefactory.h | 49 + src/plugins/zandronumq/zandronumqgamehost.cpp | 173 + src/plugins/zandronumq/zandronumqgamehost.h | 49 + src/plugins/zandronumq/zandronumqgameinfo.cpp | 63 + src/plugins/zandronumq/zandronumqgameinfo.h | 101 + .../zandronumq/zandronumqgamerunner.cpp | 37 + src/plugins/zandronumq/zandronumqgamerunner.h | 43 + .../zandronumq/zandronumqgamesettings.cpp | 171 + .../zandronumq/zandronumqgamesettings.h | 175 + .../zandronumq/zandronumqmasterclient.cpp | 187 + .../zandronumq/zandronumqmasterclient.h | 56 + .../zandronumq/zandronumqrconprotocol.cpp | 352 ++ .../zandronumq/zandronumqrconprotocol.h | 109 + src/plugins/zandronumq/zandronumqserver.cpp | 762 +++ src/plugins/zandronumq/zandronumqserver.h | 196 + .../zandronumqserverdmflagsparser.cpp | 105 + .../zandronumqserverdmflagsparser.h | 83 + 62 files changed, 24159 insertions(+) create mode 100644 src/plugins/zandronumq/CMakeLists.txt create mode 100644 src/plugins/zandronumq/createserverdialogpages/flagsid.cpp create mode 100644 src/plugins/zandronumq/createserverdialogpages/flagsid.h create mode 100644 src/plugins/zandronumq/createserverdialogpages/flagspage.cpp create mode 100644 src/plugins/zandronumq/createserverdialogpages/flagspage.h create mode 100644 src/plugins/zandronumq/createserverdialogpages/flagspage.ui create mode 100644 src/plugins/zandronumq/createserverdialogpages/flagspagevaluecontroller.h create mode 100644 src/plugins/zandronumq/createserverdialogpages/flagspagevaluecontroller2.cpp create mode 100644 src/plugins/zandronumq/createserverdialogpages/flagspagevaluecontroller2.h create mode 100644 src/plugins/zandronumq/createserverdialogpages/flagspagevaluecontroller3.cpp create mode 100644 src/plugins/zandronumq/createserverdialogpages/flagspagevaluecontroller3.h create mode 100644 src/plugins/zandronumq/createserverdialogpages/votingsetupwidget.cpp create mode 100644 src/plugins/zandronumq/createserverdialogpages/votingsetupwidget.h create mode 100644 src/plugins/zandronumq/createserverdialogpages/votingsetupwidget.ui create mode 100644 src/plugins/zandronumq/enginezandronumqconfigbox.cpp create mode 100644 src/plugins/zandronumq/enginezandronumqconfigbox.h create mode 100644 src/plugins/zandronumq/huffman/bitreader.cpp create mode 100644 src/plugins/zandronumq/huffman/bitreader.h create mode 100644 src/plugins/zandronumq/huffman/bitwriter.cpp create mode 100644 src/plugins/zandronumq/huffman/bitwriter.h create mode 100644 src/plugins/zandronumq/huffman/codec.h create mode 100644 src/plugins/zandronumq/huffman/huffcodec.cpp create mode 100644 src/plugins/zandronumq/huffman/huffcodec.h create mode 100644 src/plugins/zandronumq/huffman/huffman.cpp create mode 100644 src/plugins/zandronumq/huffman/huffman.h create mode 100644 src/plugins/zandronumq/huffmanqt.cpp create mode 100644 src/plugins/zandronumq/huffmanqt.h create mode 100644 src/plugins/zandronumq/huffmanudpsocket.cpp create mode 100644 src/plugins/zandronumq/huffmanudpsocket.h create mode 100644 src/plugins/zandronumq/translations/zandronumq_ca_ES.ts create mode 100644 src/plugins/zandronumq/translations/zandronumq_es_ES.ts create mode 100644 src/plugins/zandronumq/translations/zandronumq_pl_PL.ts create mode 100644 src/plugins/zandronumq/zandronumq.xpm create mode 100644 src/plugins/zandronumq/zandronumq2dmflags.cpp create mode 100644 src/plugins/zandronumq/zandronumq2dmflags.h create mode 100644 src/plugins/zandronumq/zandronumq3dmflags.cpp create mode 100644 src/plugins/zandronumq/zandronumq3dmflags.h create mode 100644 src/plugins/zandronumq/zandronumqbinaries.cpp create mode 100644 src/plugins/zandronumq/zandronumqbinaries.h create mode 100644 src/plugins/zandronumq/zandronumqbroadcast.cpp create mode 100644 src/plugins/zandronumq/zandronumqbroadcast.h create mode 100644 src/plugins/zandronumq/zandronumqengineplugin.cpp create mode 100644 src/plugins/zandronumq/zandronumqengineplugin.h create mode 100644 src/plugins/zandronumq/zandronumqgameexefactory.cpp create mode 100644 src/plugins/zandronumq/zandronumqgameexefactory.h create mode 100644 src/plugins/zandronumq/zandronumqgamehost.cpp create mode 100644 src/plugins/zandronumq/zandronumqgamehost.h create mode 100644 src/plugins/zandronumq/zandronumqgameinfo.cpp create mode 100644 src/plugins/zandronumq/zandronumqgameinfo.h create mode 100644 src/plugins/zandronumq/zandronumqgamerunner.cpp create mode 100644 src/plugins/zandronumq/zandronumqgamerunner.h create mode 100644 src/plugins/zandronumq/zandronumqgamesettings.cpp create mode 100644 src/plugins/zandronumq/zandronumqgamesettings.h create mode 100644 src/plugins/zandronumq/zandronumqmasterclient.cpp create mode 100644 src/plugins/zandronumq/zandronumqmasterclient.h create mode 100644 src/plugins/zandronumq/zandronumqrconprotocol.cpp create mode 100644 src/plugins/zandronumq/zandronumqrconprotocol.h create mode 100644 src/plugins/zandronumq/zandronumqserver.cpp create mode 100644 src/plugins/zandronumq/zandronumqserver.h create mode 100644 src/plugins/zandronumq/zandronumqserverdmflagsparser.cpp create mode 100644 src/plugins/zandronumq/zandronumqserverdmflagsparser.h diff --git a/src/plugins/CMakeLists.txt b/src/plugins/CMakeLists.txt index dbcfa46b..36702df2 100644 --- a/src/plugins/CMakeLists.txt +++ b/src/plugins/CMakeLists.txt @@ -36,6 +36,7 @@ add_opt_subdirectory(chocolate-doom) add_opt_subdirectory(odamex) add_opt_subdirectory(srb2) add_opt_subdirectory(zandronum) +add_opt_subdirectory(zandronumq) add_opt_subdirectory(turok2ex) # For unmaintained source ports diff --git a/src/plugins/zandronumq/CMakeLists.txt b/src/plugins/zandronumq/CMakeLists.txt new file mode 100644 index 00000000..ece6492a --- /dev/null +++ b/src/plugins/zandronumq/CMakeLists.txt @@ -0,0 +1,123 @@ +#------------------------------------------------------------------------------ +# CMakeLists.txt +#------------------------------------------------------------------------------ +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA +#------------------------------------------------------------------------------ +# Copyright (C) 2012 "Zalewa" +#------------------------------------------------------------------------------ +cmake_minimum_required(VERSION 2.8.12) + +if(POLICY CMP0071) + cmake_policy(SET CMP0071 NEW) +endif() + +set(PLUGIN_NAME zandronumq) +set(PLUGIN_VERSION 42) +include(../PluginHeader.cmake) + +qt5_wrap_ui(ZANDRONUMQ_UI_FILES + createserverdialogpages/flagspage.ui + createserverdialogpages/votingsetupwidget.ui +) + +set(ZANDRONUMQ_FILES + createserverdialogpages/flagsid.cpp + createserverdialogpages/flagspagevaluecontroller2.cpp + createserverdialogpages/flagspagevaluecontroller3.cpp + createserverdialogpages/flagspage.cpp + createserverdialogpages/votingsetupwidget.cpp + huffman/bitreader.cpp + huffman/bitwriter.cpp + huffman/huffcodec.cpp + huffman/huffman.cpp + enginezandronumqconfigbox.cpp + huffmanqt.cpp + huffmanudpsocket.cpp + zandronumqbinaries.cpp + zandronumqbroadcast.cpp + zandronumq2dmflags.cpp + zandronumq3dmflags.cpp + zandronumqengineplugin.cpp + zandronumqgameexefactory.cpp + zandronumqgamehost.cpp + zandronumqgameinfo.cpp + zandronumqgamerunner.cpp + zandronumqgamesettings.cpp + zandronumqmasterclient.cpp + zandronumqrconprotocol.cpp + zandronumqserver.cpp + zandronumqserverdmflagsparser.cpp +) + +set(HEADER_FILES + createserverdialogpages/flagspage.h + createserverdialogpages/votingsetupwidget.h + createserverdialogpages/flagsid.h + createserverdialogpages/flagspagevaluecontroller2.h + createserverdialogpages/flagspagevaluecontroller3.h + huffman/bitreader.h + huffman/bitwriter.h + huffman/codec.h + huffman/huffcodec.h + huffman/huffman.h + enginezandronumqconfigbox.h + huffmanqt.h + huffmanudpsocket.h + zandronumqbinaries.h + zandronumqbroadcast.h + zandronumq2dmflags.h + zandronumq3dmflags.h + zandronumqengineplugin.h + zandronumqgameexefactory.h + zandronumqgamehost.h + zandronumqgameinfo.h + zandronumqgamerunner.h + zandronumqgamesettings.h + zandronumqmasterclient.h + zandronumqrconprotocol.h + zandronumqserver.h + zandronumqserverdmflagsparser.h +) + +set(TRANSLATIONS_FILES + translations/zandronumq_ca_ES.ts + translations/zandronumq_es_ES.ts + translations/zandronumq_pl_PL.ts +) +set(FILES_TO_TRANSLATE + ${HEADER_FILES} + ${ZANDRONUMQ_UI_FILES} + ${ZANDRONUMQ_FILES} +) + +include(../Translation.cmake) + +add_library(${PLUGIN_NAME} + MODULE + ${ZANDRONUMQ_FILES} + ${HEADER_FILES} + ${ZANDRONUMQ_UI_FILES} + ${QM_FILES} +) + +if (NOT UNIX OR APPLE) + # Linking Wadseeker is not needed on Linux and only causes + # the resulting .so to get an RPATH. Windows still needs + # to link it, though, or otherwise the compilation will fail. + target_link_libraries(${PLUGIN_NAME} LINK_PRIVATE Wadseeker::wadseeker) +endif() + +include(../PluginFooter.cmake) diff --git a/src/plugins/zandronumq/createserverdialogpages/flagsid.cpp b/src/plugins/zandronumq/createserverdialogpages/flagsid.cpp new file mode 100644 index 00000000..9604147c --- /dev/null +++ b/src/plugins/zandronumq/createserverdialogpages/flagsid.cpp @@ -0,0 +1,214 @@ +//------------------------------------------------------------------------------ +// flagsid.cpp +//------------------------------------------------------------------------------ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301 USA +// +//------------------------------------------------------------------------------ +// Copyright (C) 2016 "Zalewa" +//------------------------------------------------------------------------------ +#include "flagsid.h" + +#include "createserverdialogpages/flagspage.h" +#include "zandronumqgamesettings.h" +#include +#include + +#include + +/////////////////////////////////////////////////////////////////////////// + +DClass +{ +public: + FlagsPage *page; +}; +DPointered(FlagsId) + +FlagsId::FlagsId(FlagsPage *page) +{ + d->page = page; + + assign(); +} + +FlagsId::~FlagsId() +{ +} + +void FlagsId::save(IniSection &cfg) +{ + for (const QCheckBox *checkbox : d->page->findChildren()) + { + QVariant flagName = checkbox->property("flagname"); + if (flagName.isValid()) + { + cfg[flagName.toString()] = checkbox->isChecked(); + } + } +} + +void FlagsId::load(const IniSection &cfg) +{ + for (QCheckBox *checkbox : d->page->findChildren()) + { + QVariant flagName = checkbox->property("flagname"); + if (flagName.isValid() && cfg.hasSetting(flagName.toString())) + { + checkbox->setChecked(static_cast(cfg[flagName.toString()])); + } + } +} + +// Let's always keep this horror below at the bottom of this file, +// where it is out of sight. +void FlagsId::assign() +{ + using namespace ZandronumqGameSettingsNames; + + FlagsPage *f = d->page; + + f->cbCompatAllowSilentBFGTrick->setProperty("flagname", COMPAT_ALLOW_SILENT_BFGTRICK); + f->cbCompatEnableWallRunning->setProperty("flagname", COMPAT_ENABLE_WALL_RUNNING); + f->cbCompatDontLetOthersHearPickups->setProperty("flagname", COMPAT_DONT_LET_OTHERS_HEAR_PICKUPS); + f->cbCompatMonstersSeeSemiInvisiblePlayers->setProperty("flagname", COMPAT_MONSTERS_SEE_SEMI_INVISIBLE_PLAYERS); + f->cbCompatNoMonstersDropoffMove->setProperty("flagname", COMPAT_NO_MONSTERS_DROPOFF_MOVE); + f->cbCompatScrollingSectorsAreAdditive->setProperty("flagname", COMPAT_SCROLLING_SECTORS_ARE_ADDITIVE); + f->cbCompatInstantlyMovingFloorsArentSilent->setProperty("flagname", COMPAT_INSTANTLY_MOVING_FLOORS_ARENT_SILENT); + f->cbCompatSectorSoundsUseOriginalMethod->setProperty("flagname", COMPAT_SECTOR_SOUNDS_USE_ORIGINAL_METHOD); + f->cbCompatAnyBossDeathActivatesMapSpecials->setProperty("flagname", COMPAT_ANY_BOSS_DEATH_ACTIVATES_MAP_SPECIALS); + f->cbCompatFrictionPushersPullersAffectMonsters->setProperty("flagname", COMPAT_FRICTION_PUSHERS_PULLERS_AFFECT_MONSTERS); + f->cbCompatCrusherGibsByMorphingNotReplacement->setProperty("flagname", COMPAT_CRUSHER_GIBS_BY_MORPHING_NOT_REPLACEMENT); + f->cbCompatBlockMonsterLinesIgnoreFriendlyMonsters->setProperty("flagname", COMPAT_BLOCK_MONSTER_LINES_IGNORE_FRIENDLY_MONSTERS); + f->cbCompatFindNeighboringLightLevelLikeDoom->setProperty("flagname", COMPAT_FIND_NEIGHBORING_LIGHT_LEVEL_LIKE_DOOM); + f->cbCompatFindShortestTexturesLikeDoom->setProperty("flagname", COMPAT_FIND_SHORTEST_TEXTURES_LIKE_DOOM); + f->cbCompatUseBuggierStairBuilding->setProperty("flagname", COMPAT_USE_BUGGIER_STAIR_BUILDING); + f->cbCompatLimitPainElementals->setProperty("flagname", COMPAT_LIMIT_PAIN_ELEMENTALS); + f->cbCompatActorsAreInfinitelyTall->setProperty("flagname", COMPAT_ACTORS_ARE_INFINITELY_TALL); + f->cbCompatSpawnItemDropsOnTheFloor->setProperty("flagname", COMPAT_SPAWN_ITEM_DROPS_ON_THE_FLOOR); + f->cbCompatAllSpecialLinesCanDropUseLines->setProperty("flagname", COMPAT_ALL_SPECIAL_LINES_CAN_DROP_USE_LINES); + f->cbCompatDisableBoomDoorLightEffect->setProperty("flagname", COMPAT_DISABLE_BOOM_DOOR_LIGHT_EFFECT); + f->cbCompatRavensScrollersUseOriginalSpeed->setProperty("flagname", COMPAT_RAVENS_SCROLLERS_USE_ORIGINAL_SPEED); + f->cbCompatUseSectorBasedSoundTargetCode->setProperty("flagname", COMPAT_USE_SECTOR_BASED_SOUND_TARGET_CODE); + f->cbCompatLimitDehMaxHealthToHealthBonus->setProperty("flagname", COMPAT_LIMIT_DEH_MAX_HEALTH_TO_HEALTH_BONUS); + f->cbCompatTraceIgnoreLinesWithoutSameSectorOnBothSides->setProperty("flagname", COMPAT_TRACE_IGNORE_LINES_WITHOUT_SAME_SECTOR_ON_BOTH_SIDES); + f->cbCompatMonstersCantBePushedOffCliffs->setProperty("flagname", COMPAT_MONSTERS_CANT_BE_PUSHED_OFF_CLIFFS); + f->cbCompatUseOriginalMissileClippingHeight->setProperty("flagname", COMPAT_USE_ORIGINAL_MISSILE_CLIPPING_HEIGHT); + f->cbCompatMinotaur->setProperty("flagname", COMPAT_MINOTAUR); + f->cbCompatOriginalVelocityCalcForMushroomInDehacked->setProperty("flagname", COMPAT_ORIGINAL_VELOCITY_CALC_FOR_MUSHROOM_IN_DEHACKED); + f->cbCompatSpriteSortOrderInverted->setProperty("flagname", COMPAT_SPRITE_SORT_ORDER_INVERTED); + f->cbCompatHitscansOriginalBlockmap->setProperty("flagname", COMPAT_HITSCANS_ORIGINAL_BLOCKMAP); + f->cbCompatDrawPolyobjectsOld->setProperty("flagname", COMPAT_DRAW_POLYOBJECTS_OLD); + f->cbNoTaunt->setProperty("flagname", NO_TAUNT); + f->cbNoUseCrosshairs->setProperty("flagname", NO_USE_CROSSHAIRS); + f->cbNoUseLandConsoleCommand->setProperty("flagname", NO_USE_LAND_CONSOLE_COMMAND); + f->cbCompatPlasmaBumpBug->setProperty("flagname", COMPAT_PLASMA_BUMP_BUG); + f->cbCompatOriginalWeaponSwitch->setProperty("flagname", COMPAT_ORIGINAL_WEAPON_SWITCH); + f->cbCompatLimitedMovementInTheAir->setProperty("flagname", COMPAT_LIMITED_MOVEMENT_IN_THE_AIR); + f->cbCompatAllowInstantRespawn->setProperty("flagname", COMPAT_ALLOW_INSTANT_RESPAWN); + f->cbCompatUseOldIntermissionScreensMusic->setProperty("flagname", COMPAT_USE_OLD_INTERMISSION_SCREENS_MUSIC); + f->cbCompatDisableStealthMonsters->setProperty("flagname", COMPAT_DISABLE_STEALTH_MONSTERS); + f->cbCompatOldDamageRadiusInfiniteHeight->setProperty("flagname", COMPAT_OLD_DAMAGE_RADIUS_INFINITE_HEIGHT); + f->cbCompatClientsSendFullButtonInfo->setProperty("flagname", COMPAT_CLIENTS_SEND_FULL_BUTTON_INFO); + f->cbCompatOldRandomNumberGenerator->setProperty("flagname", COMPAT_OLD_RANDOM_NUMBER_GENERATOR); + f->cbCompatNETScriptsAreClientside->setProperty("flagname", COMPAT_NETSCRIPTS_ARE_CLIENTSIDE); + f->cbCompatAddNOGRAVITYFlagToSpheres->setProperty("flagname", COMPAT_ADD_NOGRAVITYFLAG_TO_SPHERES); + f->cbDontStopPlayerScriptsOnDisconnect->setProperty("flagname", DONT_STOP_PLAYER_SCRIPTS_ON_DISCONNECT); + f->cbOldZDoomHorizontalThrust->setProperty("flagname", OLD_ZDOOM_HORIZONTAL_THRUST); + f->cbOldZDoomBridgeDrops->setProperty("flagname", OLD_ZDOOM_BRIDGE_DROPS); + f->cbOldZDoomJumpPhysics->setProperty("flagname", OLD_ZDOOM_JUMP_PHYSICS); + f->cbCompatFullWeaponLower->setProperty("flagname", COMPAT_FULL_WEAPON_LOWER); + f->cbCompatOriginalSoundCurve->setProperty("flagname", COMPAT_ORIGINAL_SOUND_CURVE); + f->cbCompatUseVanillaAutoaimTracerBehavior->setProperty("flagname", COMPAT_USE_VANILLA_AUTOAIM_TRACER_BEHAVIOR); + f->cbCompatWestSpawnsAreSilent->setProperty("flagname", COMPAT_WEST_SPAWNS_ARE_SILENT); + f->cbCompatMaskedMidtex->setProperty("flagname", COMPAT_MASKED_MIDTEX); + f->cbCompatBadAngles->setProperty("flagname", COMPAT_BAD_ANGLES); + f->cbCompatFloorMove->setProperty("flagname", COMPAT_FLOOR_MOVE); + f->cbNoMonsters->setProperty("flagname", NO_MONSTERS); + f->cbItemsRespawn->setProperty("flagname", ITEMS_RESPAWN); + f->cbMegaPowerupsRespawn->setProperty("flagname", MEGA_POWERUPS_RESPAWN); + f->cbNoUseFOV->setProperty("flagname", NO_USE_FOV); + f->cbNoUseFreelook->setProperty("flagname", NO_USE_FREELOOK); + f->cbInfiniteAmmo->setProperty("flagname", INFINITE_AMMO); + f->cbDontSpawnDeathmatchWeapons->setProperty("flagname", DONT_SPAWN_DEATHMATCH_WEAPONS); + f->cbMonstersAreFast->setProperty("flagname", MONSTERS_ARE_FAST); + f->cbMonstersRespawn->setProperty("flagname", MONSTERS_RESPAWN); + f->cbLoseAllInventory->setProperty("flagname", LOSE_ALL_INVENTORY); + f->cbLoseArmor->setProperty("flagname", LOSE_ARMOR); + f->cbLoseKeys->setProperty("flagname", LOSE_KEYS); + f->cbLosePowerups->setProperty("flagname", LOSE_POWERUPS); + f->cbLoseWeapons->setProperty("flagname", LOSE_WEAPONS); + f->cbLoseAllAmmo->setProperty("flagname", LOSE_ALL_AMMO); + f->cbLoseHalfAmmo->setProperty("flagname", LOSE_HALF_AMMO); + f->cbRespawnAutomatically->setProperty("flagname", RESPAWN_AUTOMATICALLY); + f->cbRespawnFarthestAwayFromOthers->setProperty("flagname", RESPAWN_FARTHEST_AWAY_FROM_OTHERS); + f->cbWeaponsStayAfterPickup->setProperty("flagname", WEAPONS_STAY_AFTER_PICKUP); + f->cbDontSpawnHealth->setProperty("flagname", DONT_SPAWN_HEALTH); + f->cbDontSpawnArmor->setProperty("flagname", DONT_SPAWN_ARMOR); + f->cbBarrelsRespawn->setProperty("flagname", BARRELS_RESPAWN); + f->cbServerPicksTeams->setProperty("flagname", SERVER_PICKS_TEAMS); + f->cbPlayersCantSwitchTeams->setProperty("flagname", PLAYERS_CANT_SWITCH_TEAMS); + f->cbKeepTeamsAfterAMapChange->setProperty("flagname", KEEP_TEAMS_AFTER_AMAP_CHANGE); + f->cbHideAlliesOnTheAutomap->setProperty("flagname", HIDE_ALLIES_ON_THE_AUTOMAP); + f->cbDontLetPlayersSpyOnAllies->setProperty("flagname", DONT_LET_PLAYERS_SPY_ON_ALLIES); + f->cbInstantFlagSkullReturn->setProperty("flagname", INSTANT_FLAG_SKULL_RETURN); + f->cbNoSuicide->setProperty("flagname", NO_SUICIDE); + f->cbNoRespawn->setProperty("flagname", NO_RESPAWN); + f->cbNoUseAutomap->setProperty("flagname", NO_USE_AUTOMAP); + f->cbNoUseAutoaim->setProperty("flagname", NO_USE_AUTOAIM); + f->cbInfiniteInventory->setProperty("flagname", INFINITE_INVENTORY); + f->cbSlowlyLoseHealthWhenOver100->setProperty("flagname", SLOWLY_LOSE_HEALTH_WHEN_OVER100); + f->cbCanUseChasecam->setProperty("flagname", CAN_USE_CHASECAM); + f->cbAllowBFGFreeaiming->setProperty("flagname", ALLOW_BFGFREEAIMING); + f->cbDontCheckAmmoWhenSwitchingWeapons->setProperty("flagname", DONT_CHECK_AMMO_WHEN_SWITCHING_WEAPONS); + f->cbMonstersMustBeKilledToExit->setProperty("flagname", MONSTERS_MUST_BE_KILLED_TO_EXIT); + f->cbKillBossMonsters->setProperty("flagname", KILL_BOSS_MONSTERS); + f->cbRespawnWhereDied->setProperty("flagname", RESPAWN_WHERE_DIED); + f->cbRespawnWithAShotgun->setProperty("flagname", RESPAWN_WITH_ASHOTGUN); + f->cbDropWeaponOnDeath->setProperty("flagname", DROP_WEAPON_ON_DEATH); + f->cbLoseAFragOnDeath->setProperty("flagname", LOSE_AFRAG_ON_DEATH); + f->cbNoRespawnProtection->setProperty("flagname", NO_RESPAWN_PROTECTION); + f->cbKeepFragsAfterMapChange->setProperty("flagname", KEEP_FRAGS_AFTER_MAP_CHANGE); + f->cbDoubleAmmo->setProperty("flagname", DOUBLE_AMMO); + f->cbDontSpawnRunes->setProperty("flagname", DONT_SPAWN_RUNES); + f->cbNoUnlagged->setProperty("flagname", NO_UNLAGGED); + f->cbAlwaysApplyLMSSpectatorSettings->setProperty("flagname", ALWAYS_APPLY_LMSSPECTATOR_SETTINGS); + f->cbNoMedals->setProperty("flagname", NO_MEDALS); + f->cbScoreDamageNotKills->setProperty("flagname", SCORE_DAMAGE_NOT_KILLS); + f->cbDontSpawnAnyMultiplayerItem->setProperty("flagname", DONT_SPAWN_ANY_MULTIPLAYER_ITEM); + f->cbNoTargetIdentify->setProperty("flagname", NO_TARGET_IDENTIFY); + f->cbNoDisplayCoopInfo->setProperty("flagname", NO_DISPLAY_COOP_INFO); + f->cbNoMaxBloodScalar->setProperty("flagname", NO_MAX_BLOOD_SCALAR); + f->cbNoItemDrop->setProperty("flagname", NO_ITEM_DROP); + f->cbNoRocketJump->setProperty("flagname", NO_ROCKET_JUMP); + f->cbNoUseCustomGLLightingSettings->setProperty("flagname", NO_USE_CUSTOM_GLLIGHTING_SETTINGS); + f->cbNoTurnOffTranslucency->setProperty("flagname", NO_TURN_OFF_TRANSLUCENCY); + f->cbShareKeys->setProperty("flagname", SHARE_KEYS); + f->cbSurvivalNoMapResetOnDeath->setProperty("flagname", SURVIVAL_NO_MAP_RESET_ON_DEATH); + f->cbDeadPlayersCanKeepInventory->setProperty("flagname", DEAD_PLAYERS_CAN_KEEP_INVENTORY); + f->cbLMSChainsaw->setProperty("flagname", LMSCHAINSAW); + f->cbLMSPistol->setProperty("flagname", LMSPISTOL); + f->cbLMSShotgun->setProperty("flagname", LMSSHOTGUN); + f->cbLMSSuperShotgun->setProperty("flagname", LMSSUPER_SHOTGUN); + f->cbLMSChaingun->setProperty("flagname", LMSCHAINGUN); + f->cbLMSMinigun->setProperty("flagname", LMSMINIGUN); + f->cbLMSRocketLauncher->setProperty("flagname", LMSROCKET_LAUNCHER); + f->cbLMSGrenadeLauncher->setProperty("flagname", LMSGRENADE_LAUNCHER); + f->cbLMSPlasmaRifle->setProperty("flagname", LMSPLASMA_RIFLE); + f->cbLMSRailgun->setProperty("flagname", LMSRAILGUN); + f->cbLMSSpectatorsCanTalkToActivePlayers->setProperty("flagname", LMSSPECTATORS_CAN_TALK_TO_ACTIVE_PLAYERS); + f->cbLMSSpectatorsCanViewTheGame->setProperty("flagname", LMSSPECTATORS_CAN_VIEW_THE_GAME); +} diff --git a/src/plugins/zandronumq/createserverdialogpages/flagsid.h b/src/plugins/zandronumq/createserverdialogpages/flagsid.h new file mode 100644 index 00000000..b3895923 --- /dev/null +++ b/src/plugins/zandronumq/createserverdialogpages/flagsid.h @@ -0,0 +1,45 @@ +//------------------------------------------------------------------------------ +// flagsid.h +//------------------------------------------------------------------------------ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301 USA +// +//------------------------------------------------------------------------------ +// Copyright (C) 2016 "Zalewa" +//------------------------------------------------------------------------------ +#ifndef id0bc86735_418c_47d6_a765_374dfc391a5e +#define id0bc86735_418c_47d6_a765_374dfc391a5e + +#include + +class FlagsPage; +class IniSection; + +class FlagsId +{ +public: + FlagsId(FlagsPage *flagsPage); + ~FlagsId(); + + void assign(); + void save(IniSection &cfg); + void load(const IniSection &cfg); + +private: + DPtr d; +}; + +#endif diff --git a/src/plugins/zandronumq/createserverdialogpages/flagspage.cpp b/src/plugins/zandronumq/createserverdialogpages/flagspage.cpp new file mode 100644 index 00000000..40a4eef4 --- /dev/null +++ b/src/plugins/zandronumq/createserverdialogpages/flagspage.cpp @@ -0,0 +1,404 @@ +//------------------------------------------------------------------------------ +// flagspage.cpp +//------------------------------------------------------------------------------ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301 USA +// +//------------------------------------------------------------------------------ +// Copyright (C) 2012 "Zalewa" +//------------------------------------------------------------------------------ +#include "flagspage.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "createserverdialogpages/flagsid.h" +#include "createserverdialogpages/flagspagevaluecontroller2.h" +#include "createserverdialogpages/flagspagevaluecontroller3.h" +#include "createserverdialogpages/votingsetupwidget.h" +#include "zandronumqgameinfo.h" + +const unsigned DEFAULT_LMSALLOWEDWEAPONS = 1023; +const unsigned DEFAULT_LMSSPECTATORSETTINGS = 3; + +class DmflagsValidator : public QValidator +{ +public: + void fixup(QString &input) const override + { + if (input.trimmed().isEmpty()) + { + input = "0"; + } + } + + State validate(QString &input, int &pos) const override + { + Q_UNUSED(pos); + if (input.trimmed().isEmpty()) + { + return QValidator::Intermediate; + } + + bool bOk; + input.toUInt(&bOk); + return bOk ? QValidator::Acceptable : QValidator::Invalid; + } +}; +//////////////////////////////////////////////////////////////////////////////// +class FlagsPage::PrivData +{ +public: + DmflagsValidator validator; + QSharedPointer flagsController; +}; + +//////////////////////////////////////////////////////////////////////////////// +FlagsPage::FlagsPage(CreateServerDialog *pParentDialog) + : CreateServerDialogPage(pParentDialog, tr("Zandronumq")) +{ + setupUi(this); + + d = new PrivData(); + + setTabOrder(tabWidget, votingPage); + setTabOrder(votingPage, leDmflags); + + FlagsId flagsId(this); + flagsId.assign(); + + // The validator makes sure that the line edit will accept only + // 32-bit unsigned values. + leDmflags->setValidator(&d->validator); + leDmflags2->setValidator(&d->validator); + leZandronumqDmflags->setValidator(&d->validator); + leCompatflags->setValidator(&d->validator); + leCompatflags2->setValidator(&d->validator); + leZandronumqCompatflags->setValidator(&d->validator); + leLMSAllowedWeapons->setValidator(&d->validator); + leLMSSpectatorSettings->setValidator(&d->validator); + + // Version-specific widgets should all be invisible at this stage. + Zandronumq2::FlagsPageValueController(this).setVisible(false); + Zandronumq3::FlagsPageValueController(this).setVisible(false); + + // Init values for widgets. + cboGameVersion->addItem(tr("Zandronumq 3"), ZandronumqGameInfo::GV_Zandronumq3); + cboGameVersion->addItem(tr("Zandronumq 2 (old)"), ZandronumqGameInfo::GV_Zandronumq2); + + cboFallingDamage->insertItem(FDT_None, tr("None")); + cboFallingDamage->insertItem(FDT_Old, tr("Old (ZDoom)")); + cboFallingDamage->insertItem(FDT_Hexen, tr("Hexen")); + cboFallingDamage->insertItem(FDT_Strife, tr("Strife")); + cboFallingDamage->setCurrentIndex(FDT_None); + + initJumpCrouchComboBoxes(cboJumping); + initJumpCrouchComboBoxes(cboCrouching); + + setGameVersion(ZandronumqGameInfo::GV_Zandronumq3); + + // Widget states + spinMonsterKillPercentage->setEnabled(false); +} + +FlagsPage::~FlagsPage() +{ + delete d; +} + +void FlagsPage::applyWidgetsChange() +{ + if (d->flagsController != nullptr) + d->flagsController->convertWidgetsToNumerical(); +} + +void FlagsPage::fillInGameCreateParams(GameCreateParams &gameCreateParams) +{ + QStringList params; + + params << "+dmflags" << leDmflags->text(); + params << "+dmflags2" << leDmflags2->text(); + params << "+zadmflags" << leZandronumqDmflags->text(); + params << "+compatflags" << leCompatflags->text(); + if (leCompatflags2->isEnabled() && leCompatflags2->isVisible()) + params << "+compatflags2" << leCompatflags2->text(); + params << "+zacompatflags" << leZandronumqCompatflags->text(); + params << "+lmsallowedweapons" << leLMSAllowedWeapons->text(); + params << "+lmsspectatorsettings" << leLMSSpectatorSettings->text(); + + if (cbMonstersMustBeKilledToExit->isChecked()) + { + params << "+sv_killallmonsters_percentage" + << QString::number(spinMonsterKillPercentage->value()); + } + params << "+sv_afk2spec" << + QString::number(spinForceInactivePlayersSpectatingMins->value()); + params << "+sv_coop_damagefactor" << + QString::number(spinMonstersDamageFactor->value()); + + params << "+sv_defaultdmflags" << (cbDefaultDmflags->isChecked() ? "1" : "0"); + + params << votingPage->generateGameRunParameters(); + + gameCreateParams.setOption("GameVersion", gameVersion()); + gameCreateParams.customParameters() << params; +} + +void FlagsPage::initJumpCrouchComboBoxes(QComboBox *pComboBox) +{ + pComboBox->insertItem(JCA_Default, tr("Default")); + pComboBox->insertItem(JCA_No, tr("No")); + pComboBox->insertItem(JCA_Yes, tr("Yes")); +} + +void FlagsPage::insertFlagsIfValid(QLineEdit *dst, QString flags, unsigned valIfInvalid) +{ + int dummy; + if (d->validator.validate(flags, dummy) == QValidator::Acceptable) + { + dst->setText(flags); + } + else + { + dst->setText(QString::number(valIfInvalid)); + } +} + +bool FlagsPage::loadConfig(Ini &ini) +{ + IniSection section = ini.section("dmflags"); + loadGameVersion(static_cast((int)section["gameversion"])); + + // The below numerical flag inserts are here to support old configs. + insertFlagsIfValid(leDmflags, section["dmflags"]); + insertFlagsIfValid(leDmflags2, section["dmflags2"]); + insertFlagsIfValid(leZandronumqDmflags, section["zandronumqDmflags"]); + insertFlagsIfValid(leCompatflags, section["compatflags"]); + insertFlagsIfValid(leZandronumqCompatflags, section["zandronumqCompatflags"]); + insertFlagsIfValid(leLMSAllowedWeapons, section["lmsallowedweapons"], DEFAULT_LMSALLOWEDWEAPONS); + insertFlagsIfValid(leLMSSpectatorSettings, section["lmsspectatorsettings"], DEFAULT_LMSSPECTATORSETTINGS); + propagateFlagsInputsChanges(); + // End of old config support. + + FlagsId flagsId(this); + flagsId.load(section); + + IniVariable varKillMonstersPercentage = section["killmonsters_percentage"]; + if (!varKillMonstersPercentage.value().isNull()) + { + spinMonsterKillPercentage->setValue(varKillMonstersPercentage); + } + IniVariable varForceInactivePlayersSpectatingMins = section["force_inactive_players_spectating_mins"]; + if (!varForceInactivePlayersSpectatingMins.value().isNull()) + { + spinForceInactivePlayersSpectatingMins->setValue(varForceInactivePlayersSpectatingMins); + } + IniVariable varMonstersDamageFactor = section["monsters_damage_factor"]; + if (!varMonstersDamageFactor.value().isNull()) + { + spinMonstersDamageFactor->setValue(varMonstersDamageFactor); + } + + if (section.hasSetting("falling_damage_type")) + cboFallingDamage->setCurrentIndex(section["falling_damage_type"]); + if (section.hasSetting("jump_ability")) + cboJumping->setCurrentIndex(section["jump_ability"]); + if (section.hasSetting("crouch_ability")) + cboCrouching->setCurrentIndex(section["crouch_ability"]); + setPlayerBlock(static_cast(section.value("player_block", PB_NotSet).toInt())); + setLevelExit(static_cast(section.value("level_exit", EXIT_NotSet).toInt())); + + cbDefaultDmflags->setChecked((bool)section["defaultdmflags"]); + + bool loaded = votingPage->loadConfig(ini); + applyWidgetsChange(); + return loaded; +} + +void FlagsPage::propagateFlagsInputsChanges() +{ + if (d->flagsController != nullptr) + d->flagsController->convertNumericalToWidgets(); +} + +bool FlagsPage::saveConfig(Ini &ini) +{ + IniSection section = ini.section("dmflags"); + + // Remove obsolete settings that were created by old method of saving + // dmflags. That way the subsequent loads of this file will not trigger + // the backward-compatibility fallbacks. + QStringList oldSettings; + oldSettings << "dmflags" << "dmflags2" << "zandronumqDmflags" << "compatflags" + << "zandronumqCompatflags" << "lmsallowedweapons" << "lmsspectatorsettings"; + for (const QString &oldSetting : oldSettings) + { + section.deleteSetting(oldSetting); + } + + FlagsId flagsId(this); + flagsId.save(section); + + section["gameversion"] = cboGameVersion->itemData(cboGameVersion->currentIndex()).toInt(); + section["defaultdmflags"] = cbDefaultDmflags->isChecked(); + section["falling_damage_type"] = cboFallingDamage->currentIndex(); + section["jump_ability"] = cboJumping->currentIndex(); + section["crouch_ability"] = cboCrouching->currentIndex(); + if (playerBlock() != PB_NotSet) + section["player_block"] = playerBlock(); + if (levelExit() != EXIT_NotSet) + section["level_exit"] = levelExit(); + + section["killmonsters_percentage"] = spinMonsterKillPercentage->value(); + section["force_inactive_players_spectating_mins"] = + spinForceInactivePlayersSpectatingMins->value(); + section["monsters_damage_factor"] = + static_cast(spinMonstersDamageFactor->value()); + + return votingPage->saveConfig(ini); +} + +void FlagsPage::applyGameVersion() +{ + setGameVersion(static_cast( + cboGameVersion->itemData(cboGameVersion->currentIndex()).toInt())); +} + +void FlagsPage::loadGameVersion(ZandronumqGameInfo::GameVersion version) +{ + int index = cboGameVersion->findData(version); + if (index < 0) + { + gLog << tr("Unknown Zandronumq version in the config. Reverting to default."); + version = DEFAULT_GAME_VERSION; + index = cboGameVersion->findData(version); + if (index < 0) + { + gLog << QString("Zandronumq: FlagsPage::loadGameVersion() - oops, " + "a bug!, GameVersion = %1").arg(version); + return; + } + } + setGameVersion(version); +} + +void FlagsPage::setGameVersion(ZandronumqGameInfo::GameVersion version) +{ + cboGameVersion->blockSignals(true); + int index = cboGameVersion->findData(version); + if (index >= 0) + cboGameVersion->setCurrentIndex(index); + cboGameVersion->blockSignals(false); + if (d->flagsController != nullptr) + { + d->flagsController->setVisible(false); + } + switch (version) + { + default: + gLog << tr("Tried to set unknown Zandronumq version. Reverting to default."); // intentional fall-through + case ZandronumqGameInfo::GV_Zandronumq2: + d->flagsController = QSharedPointer( + new Zandronumq2::FlagsPageValueController(this)); + break; + case ZandronumqGameInfo::GV_Zandronumq3: + d->flagsController = QSharedPointer( + new Zandronumq3::FlagsPageValueController(this)); + break; + } + d->flagsController->setVisible(true); + d->flagsController->convertWidgetsToNumerical(); +} + +ZandronumqGameInfo::GameVersion FlagsPage::gameVersion() const +{ + #if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0) + return static_cast(cboGameVersion->currentData().toInt()); + #else + return static_cast(cboGameVersion->itemData(cboGameVersion->currentIndex()).toInt()); + #endif +} + +FlagsPage::PlayerBlock FlagsPage::playerBlock() const +{ + if (rbPlayersCanWalkThroughEachOther->isChecked()) + return PB_Noclip; + if (rbAlliesCanWalkThroughEachOther->isChecked()) + return PB_AllyNoclip; + if (rbPlayersBlockEachOtherNormally->isChecked()) + return PB_Block; + return PB_NotSet; +} + +void FlagsPage::setPlayerBlock(PlayerBlock playerBlock) +{ + switch (playerBlock) + { + case PB_NotSet: + // do nothing + break; + case PB_Noclip: + rbPlayersCanWalkThroughEachOther->setChecked(true); + break; + case PB_AllyNoclip: + rbAlliesCanWalkThroughEachOther->setChecked(true); + break; + case PB_Block: + rbPlayersBlockEachOtherNormally->setChecked(true); + break; + default: + qDebug() << "FlagsPage::setPlayerBlock - unhandled PlayerBlock " << playerBlock; + break; + } +} + +FlagsPage::LevelExit FlagsPage::levelExit() const +{ + if (rbContinueToTheNextMap->isChecked()) + return EXIT_NextMap; + if (rbRestartTheCurrentLevel->isChecked()) + return EXIT_RestartMap; + if (rbKillThePlayer->isChecked()) + return EXIT_KillPlayer; + return EXIT_NotSet; +} + +void FlagsPage::setLevelExit(LevelExit levelExit) +{ + switch (levelExit) + { + case EXIT_NotSet: + // do nothing + break; + case EXIT_NextMap: + rbContinueToTheNextMap->setChecked(true); + break; + case EXIT_RestartMap: + rbRestartTheCurrentLevel->setChecked(true); + break; + case EXIT_KillPlayer: + rbKillThePlayer->setChecked(true); + break; + default: + qDebug() << "FlagsPage::setLevelExit - unhandled LevelExit " << levelExit; + break; + } +} diff --git a/src/plugins/zandronumq/createserverdialogpages/flagspage.h b/src/plugins/zandronumq/createserverdialogpages/flagspage.h new file mode 100644 index 00000000..7c44e84e --- /dev/null +++ b/src/plugins/zandronumq/createserverdialogpages/flagspage.h @@ -0,0 +1,137 @@ +//------------------------------------------------------------------------------ +// flagspage.h +//------------------------------------------------------------------------------ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301 USA +// +//------------------------------------------------------------------------------ +// Copyright (C) 2012 "Zalewa" +//------------------------------------------------------------------------------ +#ifndef DOOMSEEKER_PLUGIN_ZANDRONUMQ_CREATESERVERDIALOGPAGES_FLAGSPAGE_H +#define DOOMSEEKER_PLUGIN_ZANDRONUMQ_CREATESERVERDIALOGPAGES_FLAGSPAGE_H + +#include "ui_flagspage.h" +#include "zandronumqgameinfo.h" +#include + +namespace Zandronumq2 +{ +class FlagsPageValueController; +} + +namespace Zandronumq3 +{ +class FlagsPageValueController; +} + +class GameCreateParams; + +class FlagsPage : public CreateServerDialogPage, private Ui::FlagsPage +{ + friend class FlagsId; + friend class Zandronumq2::FlagsPageValueController; + friend class Zandronumq3::FlagsPageValueController; + + Q_OBJECT + +public: + /** + * This is stored in config and indexing cannot change between versions. + */ + enum FallingDamageType + { + FDT_None = 0, + FDT_Old = 1, + FDT_Hexen = 2, + FDT_Strife = 3 + }; + + /** + * This is stored in config and indexing cannot change between versions. + */ + enum JumpCrouchAbility + { + JCA_Default = 0, + JCA_No = 1, + JCA_Yes = 2 + }; + + /** + * This is stored in config and indexing cannot change between versions. + */ + enum PlayerBlock + { + PB_NotSet = 0, + PB_Noclip = 1, + PB_AllyNoclip = 2, + PB_Block = 3 + }; + + /** + * This is stored in config and indexing cannot change between versions. + */ + enum LevelExit + { + EXIT_NotSet = 0, + EXIT_NextMap = 1, + EXIT_RestartMap = 2, + EXIT_KillPlayer = 3 + }; + + static const ZandronumqGameInfo::GameVersion DEFAULT_GAME_VERSION = ZandronumqGameInfo::GV_Zandronumq2; + + FlagsPage(CreateServerDialog *pParentDialog); + ~FlagsPage() override; + + void fillInGameCreateParams(GameCreateParams ¶ms) override; + bool loadConfig(Ini &ini) override; + bool saveConfig(Ini &ini) override; + +private: + class PrivData; + + PrivData *d; + + void initJumpCrouchComboBoxes(QComboBox *pComboBox); + void insertFlagsIfValid(QLineEdit *dst, QString flags, unsigned valIfInvalid = 0); + + ZandronumqGameInfo::GameVersion gameVersion() const; + void loadGameVersion(ZandronumqGameInfo::GameVersion version); + void setGameVersion(ZandronumqGameInfo::GameVersion version); + + PlayerBlock playerBlock() const; + void setPlayerBlock(PlayerBlock playerBlock); + + LevelExit levelExit() const; + void setLevelExit(LevelExit levelExit); + +private slots: + void applyGameVersion(); + + /** + * @brief Extracts dmflags values from widgets and inserts their + * numerical values into the text input widgets. + */ + void applyWidgetsChange(); + + /** + * @brief Takes the numerical values of flags and applies them to + * widgets. + */ + void propagateFlagsInputsChanges(); +}; + +#endif diff --git a/src/plugins/zandronumq/createserverdialogpages/flagspage.ui b/src/plugins/zandronumq/createserverdialogpages/flagspage.ui new file mode 100644 index 00000000..48369602 --- /dev/null +++ b/src/plugins/zandronumq/createserverdialogpages/flagspage.ui @@ -0,0 +1,4492 @@ + + + FlagsPage + + + + 0 + 0 + 853 + 476 + + + + Form + + + + + + 0 + + + + General + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Game version: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">If this is checked then Zandronumq may override some of the settings selected here.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">(+sv_defaultdmflags)</span></p></body></html> + + + Default DMFlags + + + + + + + + + + + + Environment + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + Falling damage: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + 0 + 8 + + + + + 16777215 + 8 + + + + + + + + No monsters + + + + + + + + 0 + 8 + + + + + 16777215 + 8 + + + + + + + + Items respawn + + + + + + + Barrels respawn + + + + + + + Respawn invulnerability and invisibility spheres. + + + Mega powerups respawn + + + + + + + + + + Teams + + + + + + Server picks teams + + + + + + + Players can't switch teams + + + + + + + Keep teams after a map change + + + + + + + + 0 + 8 + + + + + 16777215 + 8 + + + + + + + + Hide allies on the automap + + + + + + + Don't let players spy on allies + + + + + + + + 0 + 8 + + + + + 16777215 + 8 + + + + + + + + Instant flag/skull return + + + + + + + + + + + + + + Don't use ping-based backwards reconciliation for player-fired hitscans and rails. + + + No unlagged + + + + + + + Apply lmsspectatorsettings in all game modes. + + + Always apply LMS spectator settings + + + + + + + Enforces clients not to show medals, i.e. behave as if cl_medals == 0. + + + No medals + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + Players + + + + + + + + Disallow + + + + + + + + Suicide + + + + + + + Respawn + + + + + + + <html><head/><body><p align="justify">P_RadiusAttack doesn't give players any z-momentum if the attack was made by a player. This essentially disables rocket jumping.</p></body></html> + + + Rocket jump + + + + + + + Taunt + + + + + + + Item drop + + + + + + + + + + 0 + 8 + + + + + 16777215 + 8 + + + + + + + + + + Use automap + + + + + + + Turn off translucency + + + + + + + Use crosshairs + + + + + + + Use custom GL lighting settings + + + + + + + Enforces clients not to identify players, i.e. behave as if cl_identifytarget == 0. + + + Target identify + + + + + + + Enforces clients not to draw coop info, i.e. behave as if cl_drawcoopinfo == 0. + + + Display coop info + + + + + + + + + + 0 + 8 + + + + + 16777215 + 8 + + + + + + + + Use autoaim + + + + + + + Only let the arbitrator set FOV (for all players) + + + Use FOV + + + + + + + Use freelook + + + + + + + <html><head/><body><p>Players are not allowed to use the land CCMD. Because of Zandronumq's default amount of air control, flying players can get a huge speed boast with the land CCMD. Disallowing players to land, allows to keep the default air control most people are used to while not giving flying players too much of an advantage.</p></body></html> + + + Use 'land' console command + + + + + + + <html><head/><body><p>Don't allow players to change how strongly will their screen flash when they get hit.</p></body></html> + + + Change bloodied screen brightness + + + + + + + + + + + + Abilities + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + Jumping: + + + + + + + + + + Crouching: + + + + + + + + + + + + Infinite inventory + + + + + + + Infinite ammo + + + + + + + Like Quake 3 + + + Slowly lose health when over 100% + + + + + + + Can use chasecam + + + + + + + Allow BFG freeaiming + + + + + + + + + + Behavior + + + + + + Players can walk through each other + + + + + + + Allies can walk through each other + + + + + + + Players block each other normally + + + true + + + + + + + Don't check ammo when switching weapons + + + + + + + + + + + + Force inactive players to spectate after: + + + + + + + + 60 + 0 + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 9999 + + + + + + + min. + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + Cooperative + + + + + + 0 + + + + + + + Score damage, not kills + + + + + + + Environment + + + + + + Don't spawn Deathmatch weapons + + + + + + + Spawn map actors in coop as if the game was single player. + + + Don't spawn any multiplayer actor in coop + + + + + + + Monsters... + + + + + + are fast (like Nightmare) + + + + + + + respawn (like Nightmare) + + + + + + + must be killed to enable exit + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + Kill percentage: + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 100 + + + 100 + + + + + + + Multiplier of damage dealt by monsters. + + + Damage factor: + + + + + + + <html><body><p>Multiplier of damage dealt by monsters.</p></body></html> + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 999999.000000000000000 + + + 0.100000000000000 + + + 1.000000000000000 + + + + + + + + + Kill all monsters spawned by a boss cube when the boss dies + + + + + + + + + + + + + + + On player death... + + + + + + Respawn where died + + + + + + + Lose all inventory + + + + + + + Lose armor + + + + + + + Lose keys + + + + + + + Lose powerups + + + + + + + Lose weapons + + + + + + + Lose all ammo + + + + + + + Lose half ammo + + + + + + + <html><head/><body><p>Affects game modes where &quot;max. lives&quot; can be used. If set, players who become dead spectators (run out of lives) will still keep inventory in accordance to the &quot;Lose *&quot; flags above. If unset, players who lose all lives will always lose entire inventory.</p></body></html> + + + Players who lose all lives can keep inventory + + + + + + + + + + + + Share keys between players + + + + + + + <html><head/><body><p>Players will be respawned with full lives but the map will not be reset. Inventory will be preserved in accordance to &quot;Lose inventory&quot; flags. Players will be able to continue from the point where they died.</p></body></html> + + + Survival only: no map reset when all players die + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + Deathmatch + + + + + + When players die, they... + + + + + + Respawn automatically + + + + + + + Drop their weapon + + + + + + + Respawn farthest away from others + + + + + + + Lose a frag + + + + + + + Respawn with a shotgun + + + + + + + Don't get respawn protection + + + + + + + + + + + + When someone exits the level... + + + + + + Continue to the next map + + + true + + + + + + + Restart the current level + + + + + + + Kill the player + + + + + + + + 0 + 8 + + + + + 16777215 + 8 + + + + + + + + Keep frags after map change + + + + + + + + + + + + Weapons && Ammo + + + + + + Weapons stay after pickup + + + + + + + Double ammo + + + + + + + + + + Don't spawn... + + + + + + Health + + + + + + + Armor + + + + + + + Runes + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + LMS + + + + + + + + Weapons + + + + + + Chainsaw + + + + + + + Pistol + + + + + + + Shotgun + + + + + + + Super shotgun + + + + + + + Chaingun + + + + + + + Minigun + + + + + + + Rocket launcher + + + + + + + Grenade launcher + + + + + + + Plasma rifle + + + + + + + Railgun + + + + + + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + lmsallowedweapons: + + + + + + + + 100 + 16777215 + + + + 0 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + lmsspectatorsettings: + + + + + + + + 100 + 16777215 + + + + 0 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + Spectators can... + + + + + + Talk to active players + + + + + + + View the game + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + Compatibility + + + + + + + + + + Enable buggier wall clipping so players can wallrun. + + + Enable wall running + + + + + + + Pickups are only heard locally. + + + Don't let others hear pickups + + + + + + + Allow instant respawn + + + + + + + <html><head/><body><p>Disable stealth monsters, since doom2.exe didn't have them.</p><p><span style=" font-weight:600;">Note: this handles ZDoom's invisible monsters.</span></p><p><span style=" font-weight:600;">THIS DOESN'T AFFECT THE PARTIAL INVISIBILITY SPHERE IN ANY WAY. See &quot;Monsters see semi-invisible players&quot; for that.</span></p></body></html> + + + Disable stealth monsters + + + + + + + Limit actors to one sound at a time. + + + Allow silent BFG trick + + + + + + + Clients use the vanilla Doom weapon on pickup behavior. + + + Original weapon switch + + + + + + + Limited movement in the air + + + + + + + This affects the partial invisibility sphere. + + + Monsters see semi-invisible players + + + + + + + Allow the map01 "plasma bump" bug. + + + Plasma bump bug + + + + + + + Any boss death activates map specials + + + + + + + Friction/pushers/pullers affect Monsters + + + + + + + <html><head/><body><p>Crushed monsters are turned into gibs, rather than replaced by gibs.</p></body></html> + + + Crusher gibs by morphing, not replacement + + + + + + + Block monster lines ignore friendly monsters + + + + + + + Find neighboring light level like Doom + + + + + + + + + + + Use doom2.exe's original intermission screens/music. + + + Use old intermission screens/music + + + + + + + Scrolling sectors are additive like in Boom. + + + Scrolling sectors are additive + + + + + + + Sector sounds use original method for sound origin. + + + Sector sounds use original method + + + + + + + Monsters cannot move when hanging over a dropoff. + + + No monsters dropoff move + + + + + + + Instantly moving floors are not silent. + + + Instantly moving floors aren't silent + + + + + + + <html><head/><body><p>Clients send ucmd.buttons as &quot;long&quot; instead of as &quot;byte&quot; in CLIENTCOMMANDS_ClientMove. So far this is only necessary if the ACS function GetPlayerInput is used in a server side script to check for buttons bigger than BT_ZOOM. Otherwise this information is completely useless for the server and the additional net traffic to send it should be avoided.</p></body></html> + + + Clients send full button info + + + + + + + <html><head/><body><p>Use Doom's random table instead of ZDoom's random number generator. Affects weapon damage among other things.</p></body></html> + + + Old random number generator + + + + + + + Monsters can't be pushed off cliffs + + + + + + + Old damage radius (infinite height) + + + + + + + Minotaur's floor flame explodes immediately when feet are clipped + + + + + + + Original velocity calc. for A_Mushroom in Dehacked + + + + + + + Sprite sort order inverted for sprites of equal distance + + + + + + + Hitscans use original blockmap and hit check code + + + + + + + Draw polyobjects the old fashioned way + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + Compatibility 2 + + + + + + + + + + Use original missile clipping height + + + + + + + Use sector based sound target code + + + + + + + <html><head/><body><p>Doom's hitscan tracing code ignores all lines with both sides in the same sector. ZDoom's does not. This option reverts to the original but less precise behavior. </p></body></html> + + + Trace ignore lines w/ same sector on both sides + + + + + + + Limit deh.MaxHealth to health bonus + + + + + + + <html><head/><body><p>The scrolling floor specials in Heretic and Hexen move the player much faster than the actual texture scrolling speed. Enable this option to restore this effect. </p></body></html> + + + Raven's scrollers use original speed + + + + + + + <html><head/><body><p>Add NOGRAVITY to actors named InvulnerabilitySphere, Soulsphere, Megasphere and BlurSphere when spawned by the map.</p></body></html> + + + Add NOGRAVITY flag to spheres + + + + + + + <html><head/><body><p>When a player leaves the game, don't stop any scripts of that player that are still running.</p></body></html> + + + Don't stop player scripts on disconnect + + + + + + + <html><head/><body><p>If this is enabled, explosions cause a strong horizontal thrust like in old ZDoom versions.</p></body></html> + + + Old ZDoom horizontal thrust + + + + + + + <html><head/><body><p>If this is enabled, non-SOLID things like flags fall through bridges (as they used to do in old ZDoom versions).</p></body></html> + + + + Old ZDoom bridge drops + + + + + + + <html><head/><body><p>Uses old ZDoom jump physics, it's a minor bug in the gravity code that causes gravity application in the wrong place.</p></body></html> + + + ZDoom 1.23B33 jump physics + + + + + + + <html><head/><p>Zandronumq uses more tracers to fill in the gaps, this reverts it to vanilla's 3 tracer behavior</p></body></html> + + + Use vanilla autoaim tracer behavior + + + + + + + Ignore compositing when drawing masked midtextures + + + + + + + It is impossible to face directly NSEW + + + + + + + + + + + <html><head/><body><p>Use Doom's shortest texture find behavior. This is requied by some WADs in MAP07.</p></body></html> + + + Find shortest textures like Doom + + + + + + + Limit pain elementals to 20 lost souls + + + + + + + Spawned item drops on the floor + + + + + + + <html><head/><body><p>Treat ACS scripts with the SCRIPTF_Net flag to be client side, i.e. executed on the clients, but not on the server.</p></body></html> + + + NET scripts are clientside + + + + + + + Actors are infinitely tall + + + + + + + Don't fix loop index for stair building. + + + Use buggier stair building + + + + + + + Disable Boom door light effect + + + + + + + All special lines can drop use lines + + + + + + + Original sound curve + + + + + + + Disallow weapon change until fully drawn or hidden + + + + + + + West spawns are silent + + + + + + + Use the same floor motion behavior as Doom + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + Voting + + + + + + + + + + + + + + + zandronumq dmflags + + + + + + + 0 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + dmflags + + + + + + + dmflags2 + + + + + + + 0 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + zandronumq compatflags + + + + + + + 0 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + compatflags + + + + + + + 0 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + 0 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + compatflags2 + + + + + + + 0 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + VotingSetupWidget + QWidget +
createserverdialogpages/votingsetupwidget.h
+ 1 +
+
+ + tabWidget + cboGameVersion + cbDefaultDmflags + cboFallingDamage + cbNoMonsters + cbItemsRespawn + cbBarrelsRespawn + cbMegaPowerupsRespawn + cbServerPicksTeams + cbPlayersCantSwitchTeams + cbKeepTeamsAfterAMapChange + cbHideAlliesOnTheAutomap + cbDontLetPlayersSpyOnAllies + cbInstantFlagSkullReturn + cbNoUnlagged + cbNoMedals + cbAlwaysApplyLMSSpectatorSettings + cbNoSuicide + cbNoRespawn + cbNoItemDrop + cbNoRocketJump + cbNoTaunt + cbNoUseAutomap + cbNoUseCustomGLLightingSettings + cbNoUseCrosshairs + cbNoTurnOffTranslucency + cbNoTargetIdentify + cbNoDisplayCoopInfo + cbNoUseAutoaim + cbNoUseFOV + cbNoUseFreelook + cbNoUseLandConsoleCommand + cbNoMaxBloodScalar + cboJumping + cboCrouching + cbInfiniteInventory + cbInfiniteAmmo + cbSlowlyLoseHealthWhenOver100 + cbCanUseChasecam + cbAllowBFGFreeaiming + rbPlayersCanWalkThroughEachOther + rbAlliesCanWalkThroughEachOther + rbPlayersBlockEachOtherNormally + cbDontCheckAmmoWhenSwitchingWeapons + spinForceInactivePlayersSpectatingMins + cbScoreDamageNotKills + cbDontSpawnDeathmatchWeapons + cbDontSpawnAnyMultiplayerItem + cbMonstersAreFast + cbMonstersRespawn + cbMonstersMustBeKilledToExit + spinMonsterKillPercentage + spinMonstersDamageFactor + cbKillBossMonsters + cbRespawnWhereDied + cbLoseAllInventory + cbLoseArmor + cbLoseKeys + cbLosePowerups + cbLoseWeapons + cbLoseAllAmmo + cbLoseHalfAmmo + cbDeadPlayersCanKeepInventory + cbShareKeys + cbSurvivalNoMapResetOnDeath + cbRespawnAutomatically + cbRespawnFarthestAwayFromOthers + cbRespawnWithAShotgun + cbDropWeaponOnDeath + cbLoseAFragOnDeath + cbNoRespawnProtection + rbContinueToTheNextMap + rbRestartTheCurrentLevel + rbKillThePlayer + cbKeepFragsAfterMapChange + cbWeaponsStayAfterPickup + cbDoubleAmmo + cbDontSpawnHealth + cbDontSpawnArmor + cbDontSpawnRunes + cbLMSChainsaw + cbLMSPistol + cbLMSShotgun + cbLMSSuperShotgun + cbLMSChaingun + cbLMSMinigun + cbLMSRocketLauncher + cbLMSGrenadeLauncher + cbLMSPlasmaRifle + cbLMSRailgun + leLMSAllowedWeapons + leLMSSpectatorSettings + cbLMSSpectatorsCanTalkToActivePlayers + cbLMSSpectatorsCanViewTheGame + cbCompatEnableWallRunning + cbCompatDontLetOthersHearPickups + cbCompatAllowInstantRespawn + cbCompatDisableStealthMonsters + cbCompatAllowSilentBFGTrick + cbCompatOriginalWeaponSwitch + cbCompatLimitedMovementInTheAir + cbCompatMonstersSeeSemiInvisiblePlayers + cbCompatPlasmaBumpBug + cbCompatAnyBossDeathActivatesMapSpecials + cbCompatFrictionPushersPullersAffectMonsters + cbCompatCrusherGibsByMorphingNotReplacement + cbCompatBlockMonsterLinesIgnoreFriendlyMonsters + cbCompatFindNeighboringLightLevelLikeDoom + cbCompatUseOldIntermissionScreensMusic + cbCompatScrollingSectorsAreAdditive + cbCompatSectorSoundsUseOriginalMethod + cbCompatNoMonstersDropoffMove + cbCompatInstantlyMovingFloorsArentSilent + cbCompatClientsSendFullButtonInfo + cbCompatOldRandomNumberGenerator + cbCompatMonstersCantBePushedOffCliffs + cbCompatOldDamageRadiusInfiniteHeight + cbCompatMinotaur + cbCompatOriginalVelocityCalcForMushroomInDehacked + cbCompatSpriteSortOrderInverted + cbCompatHitscansOriginalBlockmap + cbCompatDrawPolyobjectsOld + cbCompatUseOriginalMissileClippingHeight + cbCompatUseSectorBasedSoundTargetCode + cbCompatTraceIgnoreLinesWithoutSameSectorOnBothSides + cbCompatLimitDehMaxHealthToHealthBonus + cbCompatRavensScrollersUseOriginalSpeed + cbCompatAddNOGRAVITYFlagToSpheres + cbDontStopPlayerScriptsOnDisconnect + cbOldZDoomHorizontalThrust + cbOldZDoomBridgeDrops + cbOldZDoomJumpPhysics + cbCompatUseVanillaAutoaimTracerBehavior + cbCompatMaskedMidtex + cbCompatBadAngles + cbCompatFindShortestTexturesLikeDoom + cbCompatLimitPainElementals + cbCompatSpawnItemDropsOnTheFloor + cbCompatNETScriptsAreClientside + cbCompatActorsAreInfinitelyTall + cbCompatUseBuggierStairBuilding + cbCompatDisableBoomDoorLightEffect + cbCompatAllSpecialLinesCanDropUseLines + cbCompatOriginalSoundCurve + cbCompatFullWeaponLower + cbCompatWestSpawnsAreSilent + cbCompatFloorMove + votingPage + leDmflags + leDmflags2 + leCompatflags + leCompatflags2 + leZandronumqDmflags + leZandronumqCompatflags + + + + + leDmflags + textEdited(QString) + FlagsPage + propagateFlagsInputsChanges() + + + 239 + 439 + + + 2 + 386 + + + + + leZandronumqDmflags + textEdited(QString) + FlagsPage + propagateFlagsInputsChanges() + + + 809 + 439 + + + 349 + 406 + + + + + leDmflags2 + textEdited(QString) + FlagsPage + propagateFlagsInputsChanges() + + + 239 + 465 + + + 124 + 406 + + + + + leCompatflags + textEdited(QString) + FlagsPage + propagateFlagsInputsChanges() + + + 500 + 439 + + + 572 + 394 + + + + + leZandronumqCompatflags + textEdited(QString) + FlagsPage + propagateFlagsInputsChanges() + + + 809 + 465 + + + 567 + 406 + + + + + cbNoMonsters + clicked() + FlagsPage + applyWidgetsChange() + + + 144 + 165 + + + 2 + 135 + + + + + cbItemsRespawn + clicked() + FlagsPage + applyWidgetsChange() + + + 159 + 204 + + + 0 + 178 + + + + + cbBarrelsRespawn + clicked() + FlagsPage + applyWidgetsChange() + + + 176 + 227 + + + 2 + 212 + + + + + cbMegaPowerupsRespawn + clicked() + FlagsPage + applyWidgetsChange() + + + 185 + 250 + + + 1 + 244 + + + + + cbServerPicksTeams + clicked() + FlagsPage + applyWidgetsChange() + + + 598 + 103 + + + 570 + 87 + + + + + cbPlayersCantSwitchTeams + clicked() + FlagsPage + applyWidgetsChange() + + + 598 + 126 + + + 572 + 114 + + + + + cbKeepTeamsAfterAMapChange + clicked() + FlagsPage + applyWidgetsChange() + + + 598 + 149 + + + 570 + 140 + + + + + cbHideAlliesOnTheAutomap + clicked() + FlagsPage + applyWidgetsChange() + + + 598 + 188 + + + 575 + 179 + + + + + cbDontLetPlayersSpyOnAllies + clicked() + FlagsPage + applyWidgetsChange() + + + 598 + 211 + + + 575 + 207 + + + + + cbInstantFlagSkullReturn + clicked() + FlagsPage + applyWidgetsChange() + + + 598 + 250 + + + 575 + 247 + + + + + cboFallingDamage + activated(int) + FlagsPage + applyWidgetsChange() + + + 300 + 107 + + + 2 + 79 + + + + + cbNoSuicide + clicked() + FlagsPage + applyWidgetsChange() + + + 154 + 85 + + + 1 + 79 + + + + + cbNoRespawn + clicked() + FlagsPage + applyWidgetsChange() + + + 237 + 85 + + + 0 + 106 + + + + + cbNoRocketJump + clicked() + FlagsPage + applyWidgetsChange() + + + 154 + 130 + + + 5 + 129 + + + + + cbNoTaunt + clicked() + FlagsPage + applyWidgetsChange() + + + 237 + 130 + + + 3 + 171 + + + + + cbNoUseAutomap + clicked() + FlagsPage + applyWidgetsChange() + + + 124 + 190 + + + 0 + 208 + + + + + cbNoUseCrosshairs + clicked() + FlagsPage + applyWidgetsChange() + + + 124 + 217 + + + 4 + 233 + + + + + cbNoUseCustomGLLightingSettings + clicked() + FlagsPage + applyWidgetsChange() + + + 301 + 190 + + + 4 + 261 + + + + + cbNoTurnOffTranslucency + clicked() + FlagsPage + applyWidgetsChange() + + + 301 + 217 + + + 0 + 291 + + + + + cbNoUseAutoaim + clicked() + FlagsPage + applyWidgetsChange() + + + 185 + 289 + + + 3 + 324 + + + + + cbNoUseFOV + clicked() + FlagsPage + applyWidgetsChange() + + + 214 + 312 + + + 1 + 355 + + + + + cbInfiniteInventory + clicked() + FlagsPage + applyWidgetsChange() + + + 597 + 135 + + + 586 + 151 + + + + + cbInfiniteAmmo + clicked() + FlagsPage + applyWidgetsChange() + + + 597 + 158 + + + 586 + 181 + + + + + cbSlowlyLoseHealthWhenOver100 + clicked() + FlagsPage + applyWidgetsChange() + + + 597 + 181 + + + 586 + 211 + + + + + cbCanUseChasecam + clicked() + FlagsPage + applyWidgetsChange() + + + 597 + 204 + + + 586 + 234 + + + + + cbAllowBFGFreeaiming + clicked() + FlagsPage + applyWidgetsChange() + + + 597 + 227 + + + 586 + 260 + + + + + cbNoTargetIdentify + clicked() + FlagsPage + applyWidgetsChange() + + + 124 + 244 + + + 586 + 368 + + + + + cbNoDisplayCoopInfo + clicked() + FlagsPage + applyWidgetsChange() + + + 301 + 244 + + + 586 + 406 + + + + + cboJumping + activated(int) + FlagsPage + applyWidgetsChange() + + + 596 + 85 + + + 586 + 75 + + + + + cboCrouching + activated(int) + FlagsPage + applyWidgetsChange() + + + 596 + 111 + + + 586 + 128 + + + + + cbNoUseFreelook + clicked() + FlagsPage + applyWidgetsChange() + + + 196 + 335 + + + 5 + 406 + + + + + cbNoUnlagged + clicked() + FlagsPage + applyWidgetsChange() + + + 126 + 284 + + + 0 + 290 + + + + + cbAlwaysApplyLMSSpectatorSettings + clicked() + FlagsPage + applyWidgetsChange() + + + 116 + 307 + + + 2 + 324 + + + + + cbScoreDamageNotKills + clicked() + FlagsPage + applyWidgetsChange() + + + 135 + 58 + + + 2 + 60 + + + + + cbDontSpawnDeathmatchWeapons + clicked() + FlagsPage + applyWidgetsChange() + + + 176 + 104 + + + 1 + 109 + + + + + cbMonstersAreFast + clicked() + FlagsPage + applyWidgetsChange() + + + 244 + 173 + + + 1 + 157 + + + + + cbMonstersRespawn + clicked() + FlagsPage + applyWidgetsChange() + + + 248 + 196 + + + 6 + 193 + + + + + cbMonstersMustBeKilledToExit + clicked() + FlagsPage + applyWidgetsChange() + + + 241 + 219 + + + 2 + 225 + + + + + cbMonstersMustBeKilledToExit + toggled(bool) + spinMonsterKillPercentage + setEnabled(bool) + + + 301 + 219 + + + 351 + 246 + + + + + cbRespawnWhereDied + clicked() + FlagsPage + applyWidgetsChange() + + + 819 + 84 + + + 586 + 65 + + + + + cbLoseAllInventory + clicked() + FlagsPage + applyWidgetsChange() + + + 819 + 111 + + + 586 + 100 + + + + + cbLoseArmor + clicked() + FlagsPage + applyWidgetsChange() + + + 819 + 138 + + + 586 + 137 + + + + + cbLoseKeys + clicked() + FlagsPage + applyWidgetsChange() + + + 819 + 165 + + + 586 + 163 + + + + + cbLosePowerups + clicked() + FlagsPage + applyWidgetsChange() + + + 819 + 192 + + + 586 + 195 + + + + + cbLoseWeapons + clicked() + FlagsPage + applyWidgetsChange() + + + 819 + 219 + + + 586 + 222 + + + + + cbLoseAllAmmo + clicked() + FlagsPage + applyWidgetsChange() + + + 819 + 246 + + + 586 + 250 + + + + + cbLoseHalfAmmo + clicked() + FlagsPage + applyWidgetsChange() + + + 819 + 273 + + + 586 + 275 + + + + + cbRespawnAutomatically + clicked() + FlagsPage + applyWidgetsChange() + + + 175 + 79 + + + 0 + 86 + + + + + cbRespawnFarthestAwayFromOthers + clicked() + FlagsPage + applyWidgetsChange() + + + 167 + 102 + + + 2 + 104 + + + + + cbRespawnWithAShotgun + clicked() + FlagsPage + applyWidgetsChange() + + + 173 + 125 + + + 3 + 127 + + + + + cbDropWeaponOnDeath + clicked() + FlagsPage + applyWidgetsChange() + + + 599 + 79 + + + 586 + 85 + + + + + cbLoseAFragOnDeath + clicked() + FlagsPage + applyWidgetsChange() + + + 599 + 102 + + + 586 + 110 + + + + + cbNoRespawnProtection + clicked() + FlagsPage + applyWidgetsChange() + + + 599 + 125 + + + 586 + 139 + + + + + cbWeaponsStayAfterPickup + clicked() + FlagsPage + applyWidgetsChange() + + + 597 + 183 + + + 586 + 202 + + + + + cbDoubleAmmo + clicked() + FlagsPage + applyWidgetsChange() + + + 597 + 206 + + + 586 + 232 + + + + + cbDontSpawnHealth + clicked() + FlagsPage + applyWidgetsChange() + + + 597 + 262 + + + 586 + 295 + + + + + cbDontSpawnArmor + clicked() + FlagsPage + applyWidgetsChange() + + + 597 + 285 + + + 586 + 337 + + + + + cbDontSpawnRunes + clicked() + FlagsPage + applyWidgetsChange() + + + 597 + 308 + + + 586 + 359 + + + + + rbContinueToTheNextMap + clicked() + FlagsPage + applyWidgetsChange() + + + 222 + 189 + + + 3 + 206 + + + + + rbRestartTheCurrentLevel + clicked() + FlagsPage + applyWidgetsChange() + + + 181 + 219 + + + 2 + 244 + + + + + rbKillThePlayer + clicked() + FlagsPage + applyWidgetsChange() + + + 202 + 249 + + + 2 + 287 + + + + + cbKeepFragsAfterMapChange + clicked() + FlagsPage + applyWidgetsChange() + + + 181 + 302 + + + 7 + 335 + + + + + cbLMSChainsaw + clicked() + FlagsPage + applyWidgetsChange() + + + 138 + 80 + + + 6 + 94 + + + + + cbLMSPistol + clicked() + FlagsPage + applyWidgetsChange() + + + 138 + 103 + + + 1 + 126 + + + + + cbLMSShotgun + clicked() + FlagsPage + applyWidgetsChange() + + + 138 + 126 + + + 4 + 156 + + + + + cbLMSSuperShotgun + clicked() + FlagsPage + applyWidgetsChange() + + + 138 + 149 + + + 3 + 192 + + + + + cbLMSChaingun + clicked() + FlagsPage + applyWidgetsChange() + + + 138 + 172 + + + 6 + 228 + + + + + cbLMSMinigun + clicked() + FlagsPage + applyWidgetsChange() + + + 138 + 195 + + + 3 + 262 + + + + + cbLMSRocketLauncher + clicked() + FlagsPage + applyWidgetsChange() + + + 138 + 218 + + + 6 + 294 + + + + + cbLMSGrenadeLauncher + clicked() + FlagsPage + applyWidgetsChange() + + + 138 + 241 + + + 0 + 334 + + + + + cbLMSPlasmaRifle + clicked() + FlagsPage + applyWidgetsChange() + + + 138 + 264 + + + 2 + 365 + + + + + cbLMSRailgun + clicked() + FlagsPage + applyWidgetsChange() + + + 138 + 287 + + + 6 + 406 + + + + + cbLMSSpectatorsCanTalkToActivePlayers + clicked() + FlagsPage + applyWidgetsChange() + + + 597 + 135 + + + 586 + 136 + + + + + cbLMSSpectatorsCanViewTheGame + clicked() + FlagsPage + applyWidgetsChange() + + + 597 + 158 + + + 586 + 172 + + + + + leLMSAllowedWeapons + textEdited(QString) + FlagsPage + propagateFlagsInputsChanges() + + + 365 + 62 + + + 586 + 58 + + + + + leLMSSpectatorSettings + textEdited(QString) + FlagsPage + propagateFlagsInputsChanges() + + + 365 + 88 + + + 586 + 86 + + + + + cbNoUseLandConsoleCommand + clicked() + FlagsPage + applyWidgetsChange() + + + 202 + 358 + + + 0 + 406 + + + + + cbCompatPlasmaBumpBug + clicked() + FlagsPage + applyWidgetsChange() + + + 147 + 242 + + + 3 + 76 + + + + + cbCompatAllowSilentBFGTrick + clicked() + FlagsPage + applyWidgetsChange() + + + 76 + 150 + + + 0 + 102 + + + + + cbCompatEnableWallRunning + clicked() + FlagsPage + applyWidgetsChange() + + + 79 + 58 + + + 1 + 133 + + + + + cbCompatOriginalWeaponSwitch + clicked() + FlagsPage + applyWidgetsChange() + + + 158 + 173 + + + 0 + 160 + + + + + cbCompatDontLetOthersHearPickups + clicked() + FlagsPage + applyWidgetsChange() + + + 120 + 81 + + + 2 + 191 + + + + + cbCompatLimitedMovementInTheAir + clicked() + FlagsPage + applyWidgetsChange() + + + 124 + 196 + + + 0 + 224 + + + + + cbCompatAllowInstantRespawn + clicked() + FlagsPage + applyWidgetsChange() + + + 125 + 104 + + + 2 + 250 + + + + + cbCompatUseOldIntermissionScreensMusic + clicked() + FlagsPage + applyWidgetsChange() + + + 607 + 58 + + + 3 + 279 + + + + + cbCompatDisableStealthMonsters + clicked() + FlagsPage + applyWidgetsChange() + + + 121 + 127 + + + 4 + 309 + + + + + cbCompatMonstersSeeSemiInvisiblePlayers + clicked() + FlagsPage + applyWidgetsChange() + + + 143 + 219 + + + 3 + 336 + + + + + cbCompatNoMonstersDropoffMove + clicked() + FlagsPage + applyWidgetsChange() + + + 607 + 127 + + + 6 + 402 + + + + + cbCompatScrollingSectorsAreAdditive + clicked() + FlagsPage + applyWidgetsChange() + + + 607 + 81 + + + 1 + 406 + + + + + cbCompatInstantlyMovingFloorsArentSilent + clicked() + FlagsPage + applyWidgetsChange() + + + 607 + 150 + + + 5 + 406 + + + + + cbCompatSectorSoundsUseOriginalMethod + clicked() + FlagsPage + applyWidgetsChange() + + + 607 + 104 + + + 3 + 406 + + + + + cbCompatClientsSendFullButtonInfo + clicked() + FlagsPage + applyWidgetsChange() + + + 607 + 173 + + + 1 + 406 + + + + + cbCompatOldRandomNumberGenerator + clicked() + FlagsPage + applyWidgetsChange() + + + 607 + 196 + + + 0 + 406 + + + + + cbDontSpawnAnyMultiplayerItem + clicked() + FlagsPage + applyWidgetsChange() + + + 178 + 127 + + + 293 + 290 + + + + + cbCompatMonstersCantBePushedOffCliffs + clicked() + FlagsPage + applyWidgetsChange() + + + 607 + 219 + + + 627 + 13 + + + + + cbCompatOldDamageRadiusInfiniteHeight + clicked() + FlagsPage + applyWidgetsChange() + + + 558 + 242 + + + 628 + 46 + + + + + cbCompatUseOriginalMissileClippingHeight + clicked() + FlagsPage + applyWidgetsChange() + + + 83 + 58 + + + 624 + 349 + + + + + cbCompatUseSectorBasedSoundTargetCode + clicked() + FlagsPage + applyWidgetsChange() + + + 187 + 81 + + + 631 + 91 + + + + + cbCompatTraceIgnoreLinesWithoutSameSectorOnBothSides + clicked() + FlagsPage + applyWidgetsChange() + + + 133 + 104 + + + 631 + 145 + + + + + cbCompatLimitDehMaxHealthToHealthBonus + clicked() + FlagsPage + applyWidgetsChange() + + + 265 + 127 + + + 631 + 121 + + + + + cbCompatRavensScrollersUseOriginalSpeed + clicked() + FlagsPage + applyWidgetsChange() + + + 241 + 150 + + + 631 + 179 + + + + + cbCompatAddNOGRAVITYFlagToSpheres + clicked() + FlagsPage + applyWidgetsChange() + + + 289 + 173 + + + 631 + 208 + + + + + cbDontStopPlayerScriptsOnDisconnect + clicked() + FlagsPage + applyWidgetsChange() + + + 284 + 196 + + + 631 + 257 + + + + + cbOldZDoomHorizontalThrust + clicked() + FlagsPage + applyWidgetsChange() + + + 244 + 219 + + + 631 + 289 + + + + + cbOldZDoomBridgeDrops + clicked() + FlagsPage + applyWidgetsChange() + + + 239 + 242 + + + 631 + 35 + + + + + cbCompatFindShortestTexturesLikeDoom + clicked() + FlagsPage + applyWidgetsChange() + + + 607 + 58 + + + 631 + 406 + + + + + cbCompatLimitPainElementals + clicked() + FlagsPage + applyWidgetsChange() + + + 607 + 81 + + + 631 + 406 + + + + + cbCompatSpawnItemDropsOnTheFloor + clicked() + FlagsPage + applyWidgetsChange() + + + 607 + 104 + + + 631 + 406 + + + + + cbCompatNETScriptsAreClientside + clicked() + FlagsPage + applyWidgetsChange() + + + 607 + 127 + + + 631 + 406 + + + + + cbCompatActorsAreInfinitelyTall + clicked() + FlagsPage + applyWidgetsChange() + + + 607 + 150 + + + 631 + 369 + + + + + cbCompatUseBuggierStairBuilding + clicked() + FlagsPage + applyWidgetsChange() + + + 607 + 173 + + + 631 + 390 + + + + + cbCompatDisableBoomDoorLightEffect + clicked() + FlagsPage + applyWidgetsChange() + + + 607 + 196 + + + 631 + 406 + + + + + cbCompatAllSpecialLinesCanDropUseLines + clicked() + FlagsPage + applyWidgetsChange() + + + 607 + 219 + + + 631 + 406 + + + + + cbCompatOriginalSoundCurve + clicked() + FlagsPage + applyWidgetsChange() + + + 607 + 242 + + + 631 + 406 + + + + + cbOldZDoomJumpPhysics + clicked() + FlagsPage + applyWidgetsChange() + + + 164 + 265 + + + 631 + 316 + + + + + cbCompatFullWeaponLower + clicked() + FlagsPage + applyWidgetsChange() + + + 607 + 265 + + + 607 + 307 + + + + + cbNoMedals + clicked() + FlagsPage + applyWidgetsChange() + + + 608 + 285 + + + 604 + 29 + + + + + cbDontCheckAmmoWhenSwitchingWeapons + clicked() + FlagsPage + applyWidgetsChange() + + + 597 + 352 + + + 631 + 301 + + + + + cbKillBossMonsters + clicked() + FlagsPage + applyWidgetsChange() + + + 240 + 294 + + + 315 + 254 + + + + + cbShareKeys + clicked() + FlagsPage + applyWidgetsChange() + + + 45 + 335 + + + 3 + 338 + + + + + cbNoMaxBloodScalar + clicked() + FlagsPage + applyWidgetsChange() + + + 76 + 381 + + + 4 + 322 + + + + + rbPlayersCanWalkThroughEachOther + clicked() + FlagsPage + applyWidgetsChange() + + + 553 + 280 + + + 628 + 270 + + + + + rbAlliesCanWalkThroughEachOther + clicked() + FlagsPage + applyWidgetsChange() + + + 479 + 303 + + + 631 + 291 + + + + + rbPlayersBlockEachOtherNormally + clicked() + FlagsPage + applyWidgetsChange() + + + 494 + 322 + + + 631 + 319 + + + + + cbCompatAnyBossDeathActivatesMapSpecials + clicked() + FlagsPage + applyWidgetsChange() + + + 45 + 249 + + + 3 + 268 + + + + + cbCompatMinotaur + clicked() + FlagsPage + applyWidgetsChange() + + + 588 + 256 + + + 623 + 2 + + + + + cbCompatFrictionPushersPullersAffectMonsters + clicked() + FlagsPage + applyWidgetsChange() + + + 39 + 281 + + + 0 + 280 + + + + + cbCompatCrusherGibsByMorphingNotReplacement + clicked() + FlagsPage + applyWidgetsChange() + + + 41 + 297 + + + 0 + 307 + + + + + cbCompatOriginalVelocityCalcForMushroomInDehacked + clicked() + FlagsPage + applyWidgetsChange() + + + 795 + 288 + + + 595 + 0 + + + + + cbCompatSpriteSortOrderInverted + clicked() + FlagsPage + applyWidgetsChange() + + + 448 + 302 + + + 556 + 7 + + + + + cbCompatBlockMonsterLinesIgnoreFriendlyMonsters + clicked() + FlagsPage + applyWidgetsChange() + + + 79 + 324 + + + 0 + 324 + + + + + cbCompatHitscansOriginalBlockmap + clicked() + FlagsPage + applyWidgetsChange() + + + 756 + 334 + + + 629 + 324 + + + + + cbCompatDrawPolyobjectsOld + clicked() + FlagsPage + applyWidgetsChange() + + + 707 + 357 + + + 631 + 352 + + + + + cbCompatFindNeighboringLightLevelLikeDoom + clicked() + FlagsPage + applyWidgetsChange() + + + 80 + 350 + + + 3 + 345 + + + + + cbCompatUseVanillaAutoaimTracerBehavior + clicked() + FlagsPage + applyWidgetsChange() + + + 51 + 278 + + + 3 + 279 + + + + + cbCompatWestSpawnsAreSilent + clicked() + FlagsPage + applyWidgetsChange() + + + 795 + 299 + + + 630 + 278 + + + + + cbCompatMaskedMidtex + clicked() + FlagsPage + applyWidgetsChange() + + + 131 + 295 + + + 0 + 311 + + + + + cbCompatBadAngles + clicked() + FlagsPage + applyWidgetsChange() + + + 89 + 323 + + + 1 + 338 + + + + + cbCompatFloorMove + clicked() + FlagsPage + applyWidgetsChange() + + + 440 + 314 + + + 847 + 320 + + + + + leCompatflags2 + textEdited(QString) + FlagsPage + propagateFlagsInputsChanges() + + + 393 + 454 + + + 384 + 479 + + + + + cboGameVersion + currentIndexChanged(int) + FlagsPage + applyGameVersion() + + + 136 + 48 + + + 1 + 47 + + + + + cbNoItemDrop + clicked() + FlagsPage + applyWidgetsChange() + + + 323 + 82 + + + 369 + 2 + + + + + cbSurvivalNoMapResetOnDeath + clicked() + FlagsPage + applyWidgetsChange() + + + 42 + 351 + + + 0 + 360 + + + + + cbDeadPlayersCanKeepInventory + clicked() + FlagsPage + applyWidgetsChange() + + + 664 + 290 + + + 845 + 291 + + + + + + propagateFlagsInputsChanges() + applyWidgetsChange() + applyGameVersion() + +
diff --git a/src/plugins/zandronumq/createserverdialogpages/flagspagevaluecontroller.h b/src/plugins/zandronumq/createserverdialogpages/flagspagevaluecontroller.h new file mode 100644 index 00000000..0c87cd7d --- /dev/null +++ b/src/plugins/zandronumq/createserverdialogpages/flagspagevaluecontroller.h @@ -0,0 +1,47 @@ +//------------------------------------------------------------------------------ +// flagspagevaluecontroller.h +//------------------------------------------------------------------------------ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301 USA +// +//------------------------------------------------------------------------------ +// Copyright (C) 2016 "Zalewa" +//------------------------------------------------------------------------------ +#ifndef DOOMSEEKER_PLUGIN_ZANDRONUMQ_CREATESERVERDIALOGPAGES_FLAGSPAGEVALUECONTROLLER_H +#define DOOMSEEKER_PLUGIN_ZANDRONUMQ_CREATESERVERDIALOGPAGES_FLAGSPAGEVALUECONTROLLER_H + +/** + * @brief Converts numerical flags values to widget representation + * and vice-versa. + */ +class FlagsPageValueController +{ +public: + FlagsPageValueController() {} + virtual ~FlagsPageValueController() {} + + virtual void convertNumericalToWidgets() = 0; + virtual void convertWidgetsToNumerical() = 0; + virtual void setVisible(bool visible) + { + Q_UNUSED(visible); + } + +private: + FlagsPageValueController(const FlagsPageValueController &other) = delete; +}; + +#endif diff --git a/src/plugins/zandronumq/createserverdialogpages/flagspagevaluecontroller2.cpp b/src/plugins/zandronumq/createserverdialogpages/flagspagevaluecontroller2.cpp new file mode 100644 index 00000000..35621a15 --- /dev/null +++ b/src/plugins/zandronumq/createserverdialogpages/flagspagevaluecontroller2.cpp @@ -0,0 +1,659 @@ +//------------------------------------------------------------------------------ +// flagspagevaluecontroller2.cpp +//------------------------------------------------------------------------------ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301 USA +// +//------------------------------------------------------------------------------ +// Copyright (C) 2012 "Zalewa" +//------------------------------------------------------------------------------ +#include "flagspagevaluecontroller2.h" + +#include "createserverdialogpages/flagspage.h" +#include "zandronumq2dmflags.h" +#include "zandronumqgameinfo.h" + +namespace Zandronumq2 +{ +FlagsPageValueController::FlagsPageValueController(FlagsPage *flagsPage) +{ + this->flagsPage = flagsPage; + this->compatflags = 0; + this->zandronumqCompatflags = 0; + this->dmflags = 0; + this->dmflags2 = 0; + this->zandronumqDmflags = 0; + this->lmsAllowedWeapons = 0; + this->lmsSpectatorSettings = 0; + + FlagsPage *f = flagsPage; + + // Compat flags + { + QMap &m = compatflagsCheckboxes; + + // Compatibility + // - Oldschool + m.insert(Dmflags::COMPATF_MAGICSILENCE, + f->cbCompatAllowSilentBFGTrick); + m.insert(Dmflags::COMPATF_WALLRUN, + f->cbCompatEnableWallRunning); + m.insert(Dmflags::COMPATF_SILENTPICKUP, + f->cbCompatDontLetOthersHearPickups); + m.insert(Dmflags::COMPATF_INVISIBILITY, + f->cbCompatMonstersSeeSemiInvisiblePlayers); + // - General, left panel + m.insert(Dmflags::COMPATF_DROPOFF, + f->cbCompatNoMonstersDropoffMove); + m.insert(Dmflags::COMPATF_BOOMSCROLL, + f->cbCompatScrollingSectorsAreAdditive); + m.insert(Dmflags::COMPATF_SILENT_INSTANT_FLOORS, + f->cbCompatInstantlyMovingFloorsArentSilent); + m.insert(Dmflags::COMPATF_SECTORSOUNDS, + f->cbCompatSectorSoundsUseOriginalMethod); + m.insert(Dmflags::COMPATF_ANYBOSSDEATH, + f->cbCompatAnyBossDeathActivatesMapSpecials); + m.insert(Dmflags::COMPATF_MBFMONSTERMOVE, + f->cbCompatFrictionPushersPullersAffectMonsters); + m.insert(Dmflags::COMPATF_CORPSEGIBS, + f->cbCompatCrusherGibsByMorphingNotReplacement); + m.insert(Dmflags::COMPATF_NOBLOCKFRIENDS, + f->cbCompatBlockMonsterLinesIgnoreFriendlyMonsters); + m.insert(Dmflags::COMPATF_LIGHT, + f->cbCompatFindNeighboringLightLevelLikeDoom); + + // - General, right panel + m.insert(Dmflags::COMPATF_SHORTTEX, + f->cbCompatFindShortestTexturesLikeDoom); + m.insert(Dmflags::COMPATF_STAIRINDEX, + f->cbCompatUseBuggierStairBuilding); + m.insert(Dmflags::COMPATF_LIMITPAIN, + f->cbCompatLimitPainElementals); + m.insert(Dmflags::COMPATF_NO_PASSMOBJ, + f->cbCompatActorsAreInfinitelyTall); + m.insert(Dmflags::COMPATF_NOTOSSDROPS, + f->cbCompatSpawnItemDropsOnTheFloor); + m.insert(Dmflags::COMPATF_USEBLOCKING, + f->cbCompatAllSpecialLinesCanDropUseLines); + m.insert(Dmflags::COMPATF_NODOORLIGHT, + f->cbCompatDisableBoomDoorLightEffect); + m.insert(Dmflags::COMPATF_RAVENSCROLL, + f->cbCompatRavensScrollersUseOriginalSpeed); + m.insert(Dmflags::COMPATF_SOUNDTARGET, + f->cbCompatUseSectorBasedSoundTargetCode); + m.insert(Dmflags::COMPATF_DEHHEALTH, + f->cbCompatLimitDehMaxHealthToHealthBonus); + m.insert(Dmflags::COMPATF_TRACE, + f->cbCompatTraceIgnoreLinesWithoutSameSectorOnBothSides); + m.insert(Dmflags::COMPATF_CROSSDROPOFF, + f->cbCompatMonstersCantBePushedOffCliffs); + m.insert(Dmflags::COMPATF_MISSILECLIP, + f->cbCompatUseOriginalMissileClippingHeight); + m.insert(Dmflags::COMPATF_MINOTAUR, + f->cbCompatMinotaur); + m.insert(Dmflags::COMPATF_MUSHROOM, + f->cbCompatOriginalVelocityCalcForMushroomInDehacked); + m.insert(Dmflags::COMPATF_SPRITESORT, + f->cbCompatSpriteSortOrderInverted); + m.insert(Dmflags::COMPATF_HITSCAN, + f->cbCompatHitscansOriginalBlockmap); + m.insert(Dmflags::COMPATF_POLYOBJ, + f->cbCompatDrawPolyobjectsOld); + } + + // Zandronumq compatflags + { + QMap &m = zandronumqCompatflagsCheckboxes; + + // Players + m.insert(Dmflags::ZACOMPATF_DISABLETAUNTS, + f->cbNoTaunt); + m.insert(Dmflags::ZACOMPATF_NO_CROSSHAIR, + f->cbNoUseCrosshairs); + // - Disallow + m.insert(Dmflags::ZACOMPATF_NO_LAND, + f->cbNoUseLandConsoleCommand); + // Compatibility + m.insert(Dmflags::ZACOMPATF_PLASMA_BUMP_BUG, + f->cbCompatPlasmaBumpBug); + m.insert(Dmflags::ZACOMPATF_OLD_WEAPON_SWITCH, + f->cbCompatOriginalWeaponSwitch); + m.insert(Dmflags::ZACOMPATF_LIMITED_AIRMOVEMENT, + f->cbCompatLimitedMovementInTheAir); + m.insert(Dmflags::ZACOMPATF_INSTANTRESPAWN, + f->cbCompatAllowInstantRespawn); + m.insert(Dmflags::ZACOMPATF_OLDINTERMISSION, + f->cbCompatUseOldIntermissionScreensMusic); + m.insert(Dmflags::ZACOMPATF_DISABLESTEALTHMONSTERS, + f->cbCompatDisableStealthMonsters); + m.insert(Dmflags::ZACOMPATF_OLDRADIUSDMG, + f->cbCompatOldDamageRadiusInfiniteHeight); + m.insert(Dmflags::ZACOMPATF_CLIENTS_SEND_FULL_BUTTON_INFO, + f->cbCompatClientsSendFullButtonInfo); + m.insert(Dmflags::ZACOMPATF_OLD_RANDOM_GENERATOR, + f->cbCompatOldRandomNumberGenerator); + m.insert(Dmflags::ZACOMPATF_NETSCRIPTS_ARE_CLIENTSIDE, + f->cbCompatNETScriptsAreClientside); + m.insert(Dmflags::ZACOMPATF_NOGRAVITY_SPHERES, + f->cbCompatAddNOGRAVITYFlagToSpheres); + m.insert(Dmflags::ZACOMPATF_DONT_STOP_PLAYER_SCRIPTS_ON_DISCONNECT, + f->cbDontStopPlayerScriptsOnDisconnect); + m.insert(Dmflags::ZACOMPATF_OLD_EXPLOSION_THRUST, + f->cbOldZDoomHorizontalThrust); + m.insert(Dmflags::ZACOMPATF_OLD_BRIDGE_DROPS, + f->cbOldZDoomBridgeDrops); + m.insert(Dmflags::ZACOMPATF_OLD_ZDOOM_ZMOVEMENT, + f->cbOldZDoomJumpPhysics); + m.insert(Dmflags::ZACOMPATF_FULL_WEAPON_LOWER, + f->cbCompatFullWeaponLower); + m.insert(Dmflags::ZACOMPATF_ORIGINALSOUNDCURVE, + f->cbCompatOriginalSoundCurve); + m.insert(Dmflags::ZACOMPATF_AUTOAIM, + f->cbCompatUseVanillaAutoaimTracerBehavior); + m.insert(Dmflags::ZACOMPATF_SILENT_WEST_SPAWNS, + f->cbCompatWestSpawnsAreSilent); + } + + // DMFlags + { + QMap &m = dmflagsCheckboxes; + + // General + m.insert(Dmflags::DF_NO_MONSTERS, + f->cbNoMonsters); + m.insert(Dmflags::DF_ITEMS_RESPAWN, + f->cbItemsRespawn); + m.insert(Dmflags::DF_RESPAWN_SUPER, + f->cbMegaPowerupsRespawn); + + // Players + m.insert(Dmflags::DF_NO_FOV, + f->cbNoUseFOV); + m.insert(Dmflags::DF_NO_FREELOOK, + f->cbNoUseFreelook); + m.insert(Dmflags::DF_INFINITE_AMMO, + f->cbInfiniteAmmo); + + // Cooperative + // - Environment + m.insert(Dmflags::DF_NO_COOP_WEAPON_SPAWN, + f->cbDontSpawnDeathmatchWeapons); + // - Monsters + m.insert(Dmflags::DF_FAST_MONSTERS, + f->cbMonstersAreFast); + m.insert(Dmflags::DF_MONSTERS_RESPAWN, + f->cbMonstersRespawn); + // - Player death + m.insert(Dmflags::DF_COOP_LOSE_INVENTORY, + f->cbLoseAllInventory); + m.insert(Dmflags::DF_COOP_LOSE_ARMOR, + f->cbLoseArmor); + m.insert(Dmflags::DF_COOP_LOSE_KEYS, + f->cbLoseKeys); + m.insert(Dmflags::DF_COOP_LOSE_POWERUPS, + f->cbLosePowerups); + m.insert(Dmflags::DF_COOP_LOSE_WEAPONS, + f->cbLoseWeapons); + m.insert(Dmflags::DF_COOP_LOSE_AMMO, + f->cbLoseAllAmmo); + m.insert(Dmflags::DF_COOP_HALVE_AMMO, + f->cbLoseHalfAmmo); + + // Deathmatch + // - When players die + m.insert(Dmflags::DF_FORCE_RESPAWN, + f->cbRespawnAutomatically); + m.insert(Dmflags::DF_SPAWN_FARTHEST, + f->cbRespawnFarthestAwayFromOthers); + // - Weapons&ammo + m.insert(Dmflags::DF_WEAPONS_STAY, + f->cbWeaponsStayAfterPickup); + // - Don't spawn + m.insert(Dmflags::DF_NO_HEALTH, + f->cbDontSpawnHealth); + m.insert(Dmflags::DF_NO_ARMOR, + f->cbDontSpawnArmor); + } + + // DMFlags 2 + { + QMap &m = dmflags2Checkboxes; + + // General + m.insert(Dmflags::DF2_BARRELS_RESPAWN, + f->cbBarrelsRespawn); + m.insert(Dmflags::DF2_NO_TEAM_SELECT, + f->cbServerPicksTeams); + m.insert(Dmflags::DF2_NO_TEAM_SWITCH, + f->cbPlayersCantSwitchTeams); + m.insert(Dmflags::ZADF_YES_KEEP_TEAMS, + f->cbKeepTeamsAfterAMapChange); + m.insert(Dmflags::DF2_NO_AUTOMAP_ALLIES, + f->cbHideAlliesOnTheAutomap); + m.insert(Dmflags::DF2_DISALLOW_SPYING, + f->cbDontLetPlayersSpyOnAllies); + m.insert(Dmflags::DF2_INSTANT_RETURN, + f->cbInstantFlagSkullReturn); + + // Players + // - Disallow + m.insert(Dmflags::DF2_NOSUICIDE, + f->cbNoSuicide); + m.insert(Dmflags::DF2_NO_RESPAWN, + f->cbNoRespawn); + m.insert(Dmflags::DF2_NO_AUTOMAP, + f->cbNoUseAutomap); + m.insert(Dmflags::DF2_NOAUTOAIM, + f->cbNoUseAutoaim); + // - Abilities + m.insert(Dmflags::DF2_INFINITE_INVENTORY, + f->cbInfiniteInventory); + m.insert(Dmflags::DF2_YES_DEGENERATION, + f->cbSlowlyLoseHealthWhenOver100); + m.insert(Dmflags::DF2_CHASECAM, + f->cbCanUseChasecam); + m.insert(Dmflags::DF2_YES_FREEAIMBFG, + f->cbAllowBFGFreeaiming); + m.insert(Dmflags::DF2_DONTCHECKAMMO, + f->cbDontCheckAmmoWhenSwitchingWeapons); + + // Cooperative + // - Monsters + m.insert(Dmflags::DF2_KILL_MONSTERS, + f->cbMonstersMustBeKilledToExit); + m.insert(Dmflags::DF2_KILLBOSSMONST, + f->cbKillBossMonsters); + // - Player death + m.insert(Dmflags::DF2_SAME_SPAWN_SPOT, + f->cbRespawnWhereDied); + + // Deathmatch + // - When players die + m.insert(Dmflags::DF2_COOP_SHOTGUNSTART, + f->cbRespawnWithAShotgun); + m.insert(Dmflags::DF2_YES_WEAPONDROP, + f->cbDropWeaponOnDeath); + m.insert(Dmflags::DF2_YES_LOSEFRAG, + f->cbLoseAFragOnDeath); + m.insert(Dmflags::DF2_NO_RESPAWN_INVUL, + f->cbNoRespawnProtection); + // - When someone exits + m.insert(Dmflags::DF2_YES_KEEPFRAGS, + f->cbKeepFragsAfterMapChange); + // - Weapons&ammo + m.insert(Dmflags::DF2_YES_DOUBLEAMMO, + f->cbDoubleAmmo); + // - Don't spawn + m.insert(Dmflags::DF2_NO_RUNES, + f->cbDontSpawnRunes); + } + + // Zandronumq DMFlags + { + QMap &m = zandronumqDmflagsCheckboxes; + + // General + m.insert(Dmflags::ZADF_NOUNLAGGED, + f->cbNoUnlagged); + m.insert(Dmflags::ZADF_ALWAYS_APPLY_LMS_SPECTATORSETTINGS, + f->cbAlwaysApplyLMSSpectatorSettings); + m.insert(Dmflags::ZADF_NO_MEDALS, + f->cbNoMedals); + m.insert(Dmflags::ZADF_AWARD_DAMAGE_INSTEAD_KILLS, + f->cbScoreDamageNotKills); + // - Environment + m.insert(Dmflags::ZADF_COOP_SP_ACTOR_SPAWN, + f->cbDontSpawnAnyMultiplayerItem); + + // Players + // - Disallow 2 + m.insert(Dmflags::ZADF_NO_IDENTIFY_TARGET, + f->cbNoTargetIdentify); + m.insert(Dmflags::ZADF_NO_COOP_INFO, + f->cbNoDisplayCoopInfo); + m.insert(Dmflags::ZADF_MAX_BLOOD_SCALAR, + f->cbNoMaxBloodScalar); + // - Behavior + m.insert(Dmflags::ZADF_UNBLOCK_PLAYERS, + f->rbPlayersCanWalkThroughEachOther); + m.insert(Dmflags::ZADF_UNBLOCK_ALLIES, + f->rbAlliesCanWalkThroughEachOther); + + m.insert(Dmflags::ZADF_NO_ROCKET_JUMPING, + f->cbNoRocketJump); + m.insert(Dmflags::ZADF_FORCE_GL_DEFAULTS, + f->cbNoUseCustomGLLightingSettings); + m.insert(Dmflags::ZADF_FORCE_ALPHA, + f->cbNoTurnOffTranslucency); + + // Cooperative + m.insert(Dmflags::ZADF_SHARE_KEYS, + f->cbShareKeys); + } + + // LMSAllowedWeapons + { + QMap &m = lmsAllowedWeaponsCheckboxes; + + m.insert(ZandronumqGameInfo::LMSAW_Chainsaw, + f->cbLMSChainsaw); + m.insert(ZandronumqGameInfo::LMSAW_Pistol, + f->cbLMSPistol); + m.insert(ZandronumqGameInfo::LMSAW_Shotgun, + f->cbLMSShotgun); + m.insert(ZandronumqGameInfo::LMSAW_SuperShotgun, + f->cbLMSSuperShotgun); + m.insert(ZandronumqGameInfo::LMSAW_Chaingun, + f->cbLMSChaingun); + m.insert(ZandronumqGameInfo::LMSAW_Minigun, + f->cbLMSMinigun); + m.insert(ZandronumqGameInfo::LMSAW_RocketLauncher, + f->cbLMSRocketLauncher); + m.insert(ZandronumqGameInfo::LMSAW_GrenadeLauncher, + f->cbLMSGrenadeLauncher); + m.insert(ZandronumqGameInfo::LMSAW_PlasmaRifle, + f->cbLMSPlasmaRifle); + m.insert(ZandronumqGameInfo::LMSAW_Railgun, + f->cbLMSRailgun); + } + + // LMSSpectatorSettings + { + QMap &m = lmsSpectatorSettingsCheckboxes; + + m.insert(ZandronumqGameInfo::LMSSS_TalkToActivePlayers, + f->cbLMSSpectatorsCanTalkToActivePlayers); + m.insert(ZandronumqGameInfo::LMSSS_ViewTheGame, + f->cbLMSSpectatorsCanViewTheGame); + } +} + +void FlagsPageValueController::convertNumericalToWidgets() +{ + // Get values from widgets. + readFlagsFromTextInputs(); + + convertNumericalToCheckboxes(compatflagsCheckboxes, compatflags); + convertNumericalToCheckboxes(zandronumqCompatflagsCheckboxes, zandronumqCompatflags); + convertNumericalToCheckboxes(dmflagsCheckboxes, dmflags); + convertNumericalToCheckboxes(dmflags2Checkboxes, dmflags2); + convertNumericalToCheckboxes(zandronumqDmflagsCheckboxes, zandronumqDmflags); + convertNumericalToCheckboxes(lmsAllowedWeaponsCheckboxes, lmsAllowedWeapons); + convertNumericalToCheckboxes(lmsSpectatorSettingsCheckboxes, lmsSpectatorSettings); + + convertToWidgetGeneral(); + convertToWidgetPlayers(); + convertToWidgetCooperative(); + convertToWidgetDeathmatch(); +} + +void FlagsPageValueController::convertWidgetsToNumerical() +{ + // Reset internal values. + readFlagsFromTextInputs(); + + convertCheckboxesToNumerical(compatflagsCheckboxes, compatflags); + convertCheckboxesToNumerical(zandronumqCompatflagsCheckboxes, zandronumqCompatflags); + convertCheckboxesToNumerical(dmflagsCheckboxes, dmflags); + convertCheckboxesToNumerical(dmflags2Checkboxes, dmflags2); + convertCheckboxesToNumerical(zandronumqDmflagsCheckboxes, zandronumqDmflags); + convertCheckboxesToNumerical(lmsAllowedWeaponsCheckboxes, lmsAllowedWeapons); + convertCheckboxesToNumerical(lmsSpectatorSettingsCheckboxes, lmsSpectatorSettings); + + convertToNumericalGeneral(); + convertToNumericalPlayers(); + convertToNumericalCooperative(); + convertToNumericalDeathmatch(); + + // Apply values to widgets. + flagsPage->leDmflags->setText(QString::number(dmflags)); + flagsPage->leDmflags2->setText(QString::number(dmflags2)); + flagsPage->leZandronumqDmflags->setText(QString::number(zandronumqDmflags)); + flagsPage->leCompatflags->setText(QString::number(compatflags)); + flagsPage->leZandronumqCompatflags->setText(QString::number(zandronumqCompatflags)); + flagsPage->leLMSAllowedWeapons->setText(QString::number(lmsAllowedWeapons)); + flagsPage->leLMSSpectatorSettings->setText(QString::number(lmsSpectatorSettings)); +} + +void FlagsPageValueController::convertCheckboxesToNumerical( + const QMap &checkboxMap, + unsigned &flagsValue) +{ + for (unsigned flag : checkboxMap.keys()) + { + if (checkboxMap[flag]->isChecked()) + { + flagsValue |= flag; + } + else + { + // We are subtracting the disabled flags from the current value, + // because the flagsValue variable preserves user input flags which + // are not supported by the GUI. + flagsValue &= ~flag; + } + } +} + +void FlagsPageValueController::convertNumericalToCheckboxes( + QMap &checkboxMap, + unsigned flagsValue) +{ + for (unsigned flag : checkboxMap.keys()) + { + checkboxMap[flag]->setChecked(flagsValue & flag); + } +} +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +void FlagsPageValueController::convertToNumericalGeneral() +{ + FlagsPage *f = flagsPage; + + // Environment + + // Reset the value. + dmflags &= ~(Dmflags::DF_FORCE_FALLINGZD + | Dmflags::DF_FORCE_FALLINGHX + | Dmflags::DF_FORCE_FALLINGST); + switch (f->cboFallingDamage->currentIndex()) + { + case FlagsPage::FDT_None: + // pass + break; + + case FlagsPage::FDT_Old: + dmflags |= Dmflags::DF_FORCE_FALLINGZD; + break; + + case FlagsPage::FDT_Hexen: + dmflags |= Dmflags::DF_FORCE_FALLINGHX; + break; + + case FlagsPage::FDT_Strife: + dmflags |= Dmflags::DF_FORCE_FALLINGST; + break; + } +} +//////////////////////////////////////////////////////////////////////////////// +void FlagsPageValueController::convertToNumericalPlayers() +{ + FlagsPage *f = flagsPage; + + // Abilities + + // Reset the value. + dmflags &= ~(Dmflags::DF_YES_JUMP + | Dmflags::DF_NO_JUMP); + switch (f->cboJumping->currentIndex()) + { + case FlagsPage::JCA_Default: + // pass + break; + case FlagsPage::JCA_Yes: + dmflags |= Dmflags::DF_YES_JUMP; + break; + case FlagsPage::JCA_No: + dmflags |= Dmflags::DF_NO_JUMP; + break; + } + + // Reset the value. + dmflags &= ~(Dmflags::DF_YES_CROUCH + | Dmflags::DF_NO_CROUCH); + switch (f->cboCrouching->currentIndex()) + { + case FlagsPage::JCA_Default: + // pass + break; + case FlagsPage::JCA_Yes: + dmflags |= Dmflags::DF_YES_CROUCH; + break; + case FlagsPage::JCA_No: + dmflags |= Dmflags::DF_NO_CROUCH; + break; + } +} +//////////////////////////////////////////////////////////////////////////////// +void FlagsPageValueController::convertToNumericalCooperative() +{ + // Placeholder method for future use. +} + +//////////////////////////////////////////////////////////////////////////////// +void FlagsPageValueController::convertToNumericalDeathmatch() +{ + FlagsPage *f = flagsPage; + + // Reset the value. + dmflags &= ~(Dmflags::DF_NO_EXIT + | Dmflags::DF_SAME_LEVEL); + if (f->rbKillThePlayer->isChecked()) + { + dmflags |= Dmflags::DF_NO_EXIT; + } + else if (f->rbRestartTheCurrentLevel->isChecked()) + { + dmflags |= Dmflags::DF_SAME_LEVEL; + } +} +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +void FlagsPageValueController::convertToWidgetGeneral() +{ + FlagsPage *f = flagsPage; + + // Environment + + // This one is tricky because FALLINGST flag is actually defined + // as a combination of two other flags. We need to check for it first and + // we also need to check if the result of 'AND' operation is equal to the + // value of the flag. + if ((dmflags & Dmflags::DF_FORCE_FALLINGST) + == Dmflags::DF_FORCE_FALLINGST) + { + f->cboFallingDamage->setCurrentIndex(FlagsPage::FDT_Strife); + } + else if (dmflags & Dmflags::DF_FORCE_FALLINGZD) + { + f->cboFallingDamage->setCurrentIndex(FlagsPage::FDT_Old); + } + else if (dmflags & Dmflags::DF_FORCE_FALLINGHX) + { + f->cboFallingDamage->setCurrentIndex(FlagsPage::FDT_Hexen); + } + else + { + f->cboFallingDamage->setCurrentIndex(FlagsPage::FDT_None); + } +} +//////////////////////////////////////////////////////////////////////////////// +void FlagsPageValueController::convertToWidgetPlayers() +{ + FlagsPage *f = flagsPage; + + // Abilities + if (dmflags & Dmflags::DF_YES_JUMP) + { + f->cboJumping->setCurrentIndex(FlagsPage::JCA_Yes); + } + else if (dmflags & Dmflags::DF_NO_JUMP) + { + f->cboJumping->setCurrentIndex(FlagsPage::JCA_No); + } + else + { + f->cboJumping->setCurrentIndex(FlagsPage::JCA_Default); + } + + if (dmflags & Dmflags::DF_YES_CROUCH) + { + f->cboCrouching->setCurrentIndex(FlagsPage::JCA_Yes); + } + else if (dmflags & Dmflags::DF_NO_CROUCH) + { + f->cboCrouching->setCurrentIndex(FlagsPage::JCA_No); + } + else + { + f->cboCrouching->setCurrentIndex(FlagsPage::JCA_Default); + } + + if ((zandronumqDmflags & Dmflags::ZADF_UNBLOCK_PLAYERS) == 0 && + (zandronumqDmflags & Dmflags::ZADF_UNBLOCK_ALLIES) == 0) + { + f->rbPlayersBlockEachOtherNormally->setChecked(true); + } +} +//////////////////////////////////////////////////////////////////////////////// +void FlagsPageValueController::convertToWidgetCooperative() +{ + // Placeholder method for future use. +} +//////////////////////////////////////////////////////////////////////////////// +void FlagsPageValueController::convertToWidgetDeathmatch() +{ + FlagsPage *f = flagsPage; + + if (dmflags & Dmflags::DF_NO_EXIT) + { + f->rbKillThePlayer->setChecked(true); + } + else if (dmflags & Dmflags::DF_SAME_LEVEL) + { + f->rbRestartTheCurrentLevel->setChecked(true); + } + else + { + f->rbContinueToTheNextMap->setChecked(true); + } +} +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +void FlagsPageValueController::readFlagsFromTextInputs() +{ + dmflags = flagsPage->leDmflags->text().toUInt(); + dmflags2 = flagsPage->leDmflags2->text().toUInt(); + zandronumqDmflags = flagsPage->leZandronumqDmflags->text().toUInt(); + compatflags = flagsPage->leCompatflags->text().toUInt(); + zandronumqCompatflags = flagsPage->leZandronumqCompatflags->text().toUInt(); + lmsAllowedWeapons = flagsPage->leLMSAllowedWeapons->text().toUInt(); + lmsSpectatorSettings = flagsPage->leLMSSpectatorSettings->text().toUInt(); +} +} diff --git a/src/plugins/zandronumq/createserverdialogpages/flagspagevaluecontroller2.h b/src/plugins/zandronumq/createserverdialogpages/flagspagevaluecontroller2.h new file mode 100644 index 00000000..17794626 --- /dev/null +++ b/src/plugins/zandronumq/createserverdialogpages/flagspagevaluecontroller2.h @@ -0,0 +1,87 @@ +//------------------------------------------------------------------------------ +// flagspagevaluecontroller2.h +//------------------------------------------------------------------------------ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301 USA +// +//------------------------------------------------------------------------------ +// Copyright (C) 2012 "Zalewa" +//------------------------------------------------------------------------------ +#ifndef DOOMSEEKER_PLUGIN_ZANDRONUMQ_CREATESERVERDIALOGPAGES_FLAGSPAGEVALUECONTROLLER2_H +#define DOOMSEEKER_PLUGIN_ZANDRONUMQ_CREATESERVERDIALOGPAGES_FLAGSPAGEVALUECONTROLLER2_H + +#include +#include + +#include "createserverdialogpages/flagspagevaluecontroller.h" + +class FlagsPage; + +namespace Zandronumq2 +{ +/** + * @brief Converts numerical flags values to widget representation + * and vice-versa. + */ +class FlagsPageValueController : public ::FlagsPageValueController +{ +public: + FlagsPageValueController(FlagsPage *flagsPage); + + void convertNumericalToWidgets() override; + void convertWidgetsToNumerical() override; + +private: + unsigned compatflags; + unsigned zandronumqCompatflags; + + unsigned dmflags; + unsigned dmflags2; + unsigned zandronumqDmflags; + + unsigned lmsAllowedWeapons; + unsigned lmsSpectatorSettings; + + QMap compatflagsCheckboxes; + QMap dmflagsCheckboxes; + QMap dmflags2Checkboxes; + QMap lmsAllowedWeaponsCheckboxes; + QMap lmsSpectatorSettingsCheckboxes; + QMap zandronumqCompatflagsCheckboxes; + QMap zandronumqDmflagsCheckboxes; + + FlagsPage *flagsPage; + + void convertToNumericalGeneral(); + void convertToNumericalPlayers(); + void convertToNumericalCooperative(); + void convertToNumericalDeathmatch(); + + void convertCheckboxesToNumerical(const QMap &checkboxMap, + unsigned &flagsValue); + void convertNumericalToCheckboxes(QMap &checkboxMap, + unsigned flagsValue); + + void convertToWidgetGeneral(); + void convertToWidgetPlayers(); + void convertToWidgetCooperative(); + void convertToWidgetDeathmatch(); + + void readFlagsFromTextInputs(); +}; +} + +#endif diff --git a/src/plugins/zandronumq/createserverdialogpages/flagspagevaluecontroller3.cpp b/src/plugins/zandronumq/createserverdialogpages/flagspagevaluecontroller3.cpp new file mode 100644 index 00000000..ff0cdfcf --- /dev/null +++ b/src/plugins/zandronumq/createserverdialogpages/flagspagevaluecontroller3.cpp @@ -0,0 +1,693 @@ +//------------------------------------------------------------------------------ +// flagspagevaluecontroller3.cpp +//------------------------------------------------------------------------------ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301 USA +// +//------------------------------------------------------------------------------ +// Copyright (C) 2016 "Zalewa" +//------------------------------------------------------------------------------ +#include "flagspagevaluecontroller3.h" + +#include "createserverdialogpages/flagspage.h" +#include "zandronumq3dmflags.h" +#include "zandronumqgameinfo.h" + +namespace Zandronumq3 +{ +FlagsPageValueController::FlagsPageValueController(FlagsPage *flagsPage) +{ + this->flagsPage = flagsPage; + this->compatflags = 0; + this->compatflags2 = 0; + this->zandronumqCompatflags = 0; + this->dmflags = 0; + this->dmflags2 = 0; + this->zandronumqDmflags = 0; + this->lmsAllowedWeapons = 0; + this->lmsSpectatorSettings = 0; + + FlagsPage *f = flagsPage; + + // Compat flags + { + QMap &m = compatflagsCheckboxes; + + // Compatibility + // - Oldschool + m.insert(Dmflags::COMPATF_MAGICSILENCE, + f->cbCompatAllowSilentBFGTrick); + m.insert(Dmflags::COMPATF_WALLRUN, + f->cbCompatEnableWallRunning); + m.insert(Dmflags::COMPATF_SILENTPICKUP, + f->cbCompatDontLetOthersHearPickups); + m.insert(Dmflags::COMPATF_INVISIBILITY, + f->cbCompatMonstersSeeSemiInvisiblePlayers); + // - General, left panel + m.insert(Dmflags::COMPATF_DROPOFF, + f->cbCompatNoMonstersDropoffMove); + m.insert(Dmflags::COMPATF_BOOMSCROLL, + f->cbCompatScrollingSectorsAreAdditive); + m.insert(Dmflags::COMPATF_SILENT_INSTANT_FLOORS, + f->cbCompatInstantlyMovingFloorsArentSilent); + m.insert(Dmflags::COMPATF_SECTORSOUNDS, + f->cbCompatSectorSoundsUseOriginalMethod); + m.insert(Dmflags::COMPATF_ANYBOSSDEATH, + f->cbCompatAnyBossDeathActivatesMapSpecials); + m.insert(Dmflags::COMPATF_MBFMONSTERMOVE, + f->cbCompatFrictionPushersPullersAffectMonsters); + m.insert(Dmflags::COMPATF_CORPSEGIBS, + f->cbCompatCrusherGibsByMorphingNotReplacement); + m.insert(Dmflags::COMPATF_NOBLOCKFRIENDS, + f->cbCompatBlockMonsterLinesIgnoreFriendlyMonsters); + m.insert(Dmflags::COMPATF_LIGHT, + f->cbCompatFindNeighboringLightLevelLikeDoom); + + // - General, right panel + m.insert(Dmflags::COMPATF_SHORTTEX, + f->cbCompatFindShortestTexturesLikeDoom); + m.insert(Dmflags::COMPATF_STAIRINDEX, + f->cbCompatUseBuggierStairBuilding); + m.insert(Dmflags::COMPATF_LIMITPAIN, + f->cbCompatLimitPainElementals); + m.insert(Dmflags::COMPATF_NO_PASSMOBJ, + f->cbCompatActorsAreInfinitelyTall); + m.insert(Dmflags::COMPATF_NOTOSSDROPS, + f->cbCompatSpawnItemDropsOnTheFloor); + m.insert(Dmflags::COMPATF_USEBLOCKING, + f->cbCompatAllSpecialLinesCanDropUseLines); + m.insert(Dmflags::COMPATF_NODOORLIGHT, + f->cbCompatDisableBoomDoorLightEffect); + m.insert(Dmflags::COMPATF_RAVENSCROLL, + f->cbCompatRavensScrollersUseOriginalSpeed); + m.insert(Dmflags::COMPATF_SOUNDTARGET, + f->cbCompatUseSectorBasedSoundTargetCode); + m.insert(Dmflags::COMPATF_DEHHEALTH, + f->cbCompatLimitDehMaxHealthToHealthBonus); + m.insert(Dmflags::COMPATF_TRACE, + f->cbCompatTraceIgnoreLinesWithoutSameSectorOnBothSides); + m.insert(Dmflags::COMPATF_CROSSDROPOFF, + f->cbCompatMonstersCantBePushedOffCliffs); + m.insert(Dmflags::COMPATF_MISSILECLIP, + f->cbCompatUseOriginalMissileClippingHeight); + m.insert(Dmflags::COMPATF_MINOTAUR, + f->cbCompatMinotaur); + m.insert(Dmflags::COMPATF_MUSHROOM, + f->cbCompatOriginalVelocityCalcForMushroomInDehacked); + m.insert(Dmflags::COMPATF_SPRITESORT, + f->cbCompatSpriteSortOrderInverted); + m.insert(Dmflags::COMPATF_HITSCAN, + f->cbCompatHitscansOriginalBlockmap); + m.insert(Dmflags::COMPATF_POLYOBJ, + f->cbCompatDrawPolyobjectsOld); + m.insert(Dmflags::COMPATF_MASKEDMIDTEX, + f->cbCompatMaskedMidtex); + } + + // Compatflags2 + { + QMap &m = compatflags2Checkboxes; + + m.insert(Dmflags::COMPATF2_BADANGLES, f->cbCompatBadAngles); + m.insert(Dmflags::COMPATF2_FLOORMOVE, f->cbCompatFloorMove); + } + + // Zandronumq compatflags + { + QMap &m = zandronumqCompatflagsCheckboxes; + + // Players + m.insert(Dmflags::ZACOMPATF_DISABLETAUNTS, + f->cbNoTaunt); + m.insert(Dmflags::ZACOMPATF_NO_CROSSHAIR, + f->cbNoUseCrosshairs); + // - Disallow + m.insert(Dmflags::ZACOMPATF_NO_LAND, + f->cbNoUseLandConsoleCommand); + // Compatibility + m.insert(Dmflags::ZACOMPATF_PLASMA_BUMP_BUG, + f->cbCompatPlasmaBumpBug); + m.insert(Dmflags::ZACOMPATF_OLD_WEAPON_SWITCH, + f->cbCompatOriginalWeaponSwitch); + m.insert(Dmflags::ZACOMPATF_LIMITED_AIRMOVEMENT, + f->cbCompatLimitedMovementInTheAir); + m.insert(Dmflags::ZACOMPATF_INSTANTRESPAWN, + f->cbCompatAllowInstantRespawn); + m.insert(Dmflags::ZACOMPATF_OLDINTERMISSION, + f->cbCompatUseOldIntermissionScreensMusic); + m.insert(Dmflags::ZACOMPATF_DISABLESTEALTHMONSTERS, + f->cbCompatDisableStealthMonsters); + m.insert(Dmflags::ZACOMPATF_OLDRADIUSDMG, + f->cbCompatOldDamageRadiusInfiniteHeight); + m.insert(Dmflags::ZACOMPATF_CLIENTS_SEND_FULL_BUTTON_INFO, + f->cbCompatClientsSendFullButtonInfo); + m.insert(Dmflags::ZACOMPATF_OLD_RANDOM_GENERATOR, + f->cbCompatOldRandomNumberGenerator); + m.insert(Dmflags::ZACOMPATF_NETSCRIPTS_ARE_CLIENTSIDE, + f->cbCompatNETScriptsAreClientside); + m.insert(Dmflags::ZACOMPATF_NOGRAVITY_SPHERES, + f->cbCompatAddNOGRAVITYFlagToSpheres); + m.insert(Dmflags::ZACOMPATF_DONT_STOP_PLAYER_SCRIPTS_ON_DISCONNECT, + f->cbDontStopPlayerScriptsOnDisconnect); + m.insert(Dmflags::ZACOMPATF_OLD_EXPLOSION_THRUST, + f->cbOldZDoomHorizontalThrust); + m.insert(Dmflags::ZACOMPATF_OLD_BRIDGE_DROPS, + f->cbOldZDoomBridgeDrops); + m.insert(Dmflags::ZACOMPATF_OLD_ZDOOM_ZMOVEMENT, + f->cbOldZDoomJumpPhysics); + m.insert(Dmflags::ZACOMPATF_FULL_WEAPON_LOWER, + f->cbCompatFullWeaponLower); + m.insert(Dmflags::ZACOMPATF_ORIGINALSOUNDCURVE, + f->cbCompatOriginalSoundCurve); + m.insert(Dmflags::ZACOMPATF_AUTOAIM, + f->cbCompatUseVanillaAutoaimTracerBehavior); + m.insert(Dmflags::ZACOMPATF_SILENT_WEST_SPAWNS, + f->cbCompatWestSpawnsAreSilent); + } + + // DMFlags + { + QMap &m = dmflagsCheckboxes; + + // General + m.insert(Dmflags::DF_NO_MONSTERS, + f->cbNoMonsters); + m.insert(Dmflags::DF_ITEMS_RESPAWN, + f->cbItemsRespawn); + m.insert(Dmflags::DF_RESPAWN_SUPER, + f->cbMegaPowerupsRespawn); + + // Players + m.insert(Dmflags::DF_NO_FOV, + f->cbNoUseFOV); + m.insert(Dmflags::DF_NO_FREELOOK, + f->cbNoUseFreelook); + m.insert(Dmflags::DF_INFINITE_AMMO, + f->cbInfiniteAmmo); + + // Cooperative + // - Environment + m.insert(Dmflags::DF_NO_COOP_WEAPON_SPAWN, + f->cbDontSpawnDeathmatchWeapons); + // - Monsters + m.insert(Dmflags::DF_FAST_MONSTERS, + f->cbMonstersAreFast); + m.insert(Dmflags::DF_MONSTERS_RESPAWN, + f->cbMonstersRespawn); + // - Player death + m.insert(Dmflags::DF_COOP_LOSE_INVENTORY, + f->cbLoseAllInventory); + m.insert(Dmflags::DF_COOP_LOSE_ARMOR, + f->cbLoseArmor); + m.insert(Dmflags::DF_COOP_LOSE_KEYS, + f->cbLoseKeys); + m.insert(Dmflags::DF_COOP_LOSE_POWERUPS, + f->cbLosePowerups); + m.insert(Dmflags::DF_COOP_LOSE_WEAPONS, + f->cbLoseWeapons); + m.insert(Dmflags::DF_COOP_LOSE_AMMO, + f->cbLoseAllAmmo); + m.insert(Dmflags::DF_COOP_HALVE_AMMO, + f->cbLoseHalfAmmo); + + // Deathmatch + // - When players die + m.insert(Dmflags::DF_FORCE_RESPAWN, + f->cbRespawnAutomatically); + m.insert(Dmflags::DF_SPAWN_FARTHEST, + f->cbRespawnFarthestAwayFromOthers); + // - Weapons&ammo + m.insert(Dmflags::DF_WEAPONS_STAY, + f->cbWeaponsStayAfterPickup); + // - Don't spawn + m.insert(Dmflags::DF_NO_HEALTH, + f->cbDontSpawnHealth); + m.insert(Dmflags::DF_NO_ARMOR, + f->cbDontSpawnArmor); + } + + // DMFlags 2 + { + QMap &m = dmflags2Checkboxes; + + // General + m.insert(Dmflags::DF2_BARRELS_RESPAWN, + f->cbBarrelsRespawn); + m.insert(Dmflags::DF2_NO_TEAM_SELECT, + f->cbServerPicksTeams); + m.insert(Dmflags::DF2_NO_TEAM_SWITCH, + f->cbPlayersCantSwitchTeams); + m.insert(Dmflags::ZADF_YES_KEEP_TEAMS, + f->cbKeepTeamsAfterAMapChange); + m.insert(Dmflags::DF2_NO_AUTOMAP_ALLIES, + f->cbHideAlliesOnTheAutomap); + m.insert(Dmflags::DF2_DISALLOW_SPYING, + f->cbDontLetPlayersSpyOnAllies); + m.insert(Dmflags::DF2_INSTANT_RETURN, + f->cbInstantFlagSkullReturn); + + // Players + // - Disallow + m.insert(Dmflags::DF2_NOSUICIDE, + f->cbNoSuicide); + m.insert(Dmflags::DF2_NO_RESPAWN, + f->cbNoRespawn); + m.insert(Dmflags::DF2_NO_AUTOMAP, + f->cbNoUseAutomap); + m.insert(Dmflags::DF2_NOAUTOAIM, + f->cbNoUseAutoaim); + // - Abilities + m.insert(Dmflags::DF2_INFINITE_INVENTORY, + f->cbInfiniteInventory); + m.insert(Dmflags::DF2_YES_DEGENERATION, + f->cbSlowlyLoseHealthWhenOver100); + m.insert(Dmflags::DF2_CHASECAM, + f->cbCanUseChasecam); + m.insert(Dmflags::DF2_YES_FREEAIMBFG, + f->cbAllowBFGFreeaiming); + m.insert(Dmflags::DF2_DONTCHECKAMMO, + f->cbDontCheckAmmoWhenSwitchingWeapons); + + // Cooperative + // - Monsters + m.insert(Dmflags::DF2_KILL_MONSTERS, + f->cbMonstersMustBeKilledToExit); + m.insert(Dmflags::DF2_KILLBOSSMONST, + f->cbKillBossMonsters); + // - Player death + m.insert(Dmflags::DF2_SAME_SPAWN_SPOT, + f->cbRespawnWhereDied); + + // Deathmatch + // - When players die + m.insert(Dmflags::DF2_COOP_SHOTGUNSTART, + f->cbRespawnWithAShotgun); + m.insert(Dmflags::DF2_YES_WEAPONDROP, + f->cbDropWeaponOnDeath); + m.insert(Dmflags::DF2_YES_LOSEFRAG, + f->cbLoseAFragOnDeath); + m.insert(Dmflags::DF2_NO_RESPAWN_INVUL, + f->cbNoRespawnProtection); + // - When someone exits + m.insert(Dmflags::DF2_YES_KEEPFRAGS, + f->cbKeepFragsAfterMapChange); + // - Weapons&ammo + m.insert(Dmflags::DF2_YES_DOUBLEAMMO, + f->cbDoubleAmmo); + // - Don't spawn + m.insert(Dmflags::DF2_NO_RUNES, + f->cbDontSpawnRunes); + } + + // Zandronumq DMFlags + { + QMap &m = zandronumqDmflagsCheckboxes; + + // General + m.insert(Dmflags::ZADF_NOUNLAGGED, + f->cbNoUnlagged); + m.insert(Dmflags::ZADF_ALWAYS_APPLY_LMS_SPECTATORSETTINGS, + f->cbAlwaysApplyLMSSpectatorSettings); + m.insert(Dmflags::ZADF_NO_MEDALS, + f->cbNoMedals); + m.insert(Dmflags::ZADF_AWARD_DAMAGE_INSTEAD_KILLS, + f->cbScoreDamageNotKills); + // - Environment + m.insert(Dmflags::ZADF_COOP_SP_ACTOR_SPAWN, + f->cbDontSpawnAnyMultiplayerItem); + + // Players + // - Disallow 2 + m.insert(Dmflags::ZADF_NO_IDENTIFY_TARGET, + f->cbNoTargetIdentify); + m.insert(Dmflags::ZADF_NO_COOP_INFO, + f->cbNoDisplayCoopInfo); + m.insert(Dmflags::ZADF_MAX_BLOOD_SCALAR, + f->cbNoMaxBloodScalar); + m.insert(Dmflags::ZADF_NODROP, f->cbNoItemDrop); + // - Behavior + m.insert(Dmflags::ZADF_UNBLOCK_PLAYERS, + f->rbPlayersCanWalkThroughEachOther); + m.insert(Dmflags::ZADF_UNBLOCK_ALLIES, + f->rbAlliesCanWalkThroughEachOther); + + m.insert(Dmflags::ZADF_NO_ROCKET_JUMPING, + f->cbNoRocketJump); + m.insert(Dmflags::ZADF_FORCE_GL_DEFAULTS, + f->cbNoUseCustomGLLightingSettings); + m.insert(Dmflags::ZADF_FORCE_ALPHA, + f->cbNoTurnOffTranslucency); + + // Cooperative + m.insert(Dmflags::ZADF_SHARE_KEYS, + f->cbShareKeys); + m.insert(Dmflags::ZADF_SURVIVAL_NO_MAP_RESET_ON_DEATH, + f->cbSurvivalNoMapResetOnDeath); + m.insert(Dmflags::ZADF_DEAD_PLAYERS_CAN_KEEP_INVENTORY, + f->cbDeadPlayersCanKeepInventory); + } + + // LMSAllowedWeapons + { + QMap &m = lmsAllowedWeaponsCheckboxes; + + m.insert(ZandronumqGameInfo::LMSAW_Chainsaw, + f->cbLMSChainsaw); + m.insert(ZandronumqGameInfo::LMSAW_Pistol, + f->cbLMSPistol); + m.insert(ZandronumqGameInfo::LMSAW_Shotgun, + f->cbLMSShotgun); + m.insert(ZandronumqGameInfo::LMSAW_SuperShotgun, + f->cbLMSSuperShotgun); + m.insert(ZandronumqGameInfo::LMSAW_Chaingun, + f->cbLMSChaingun); + m.insert(ZandronumqGameInfo::LMSAW_Minigun, + f->cbLMSMinigun); + m.insert(ZandronumqGameInfo::LMSAW_RocketLauncher, + f->cbLMSRocketLauncher); + m.insert(ZandronumqGameInfo::LMSAW_GrenadeLauncher, + f->cbLMSGrenadeLauncher); + m.insert(ZandronumqGameInfo::LMSAW_PlasmaRifle, + f->cbLMSPlasmaRifle); + m.insert(ZandronumqGameInfo::LMSAW_Railgun, + f->cbLMSRailgun); + } + + // LMSSpectatorSettings + { + QMap &m = lmsSpectatorSettingsCheckboxes; + + m.insert(ZandronumqGameInfo::LMSSS_TalkToActivePlayers, + f->cbLMSSpectatorsCanTalkToActivePlayers); + m.insert(ZandronumqGameInfo::LMSSS_ViewTheGame, + f->cbLMSSpectatorsCanViewTheGame); + } +} + +void FlagsPageValueController::convertNumericalToWidgets() +{ + // Get values from widgets. + readFlagsFromTextInputs(); + + convertNumericalToCheckboxes(compatflagsCheckboxes, compatflags); + convertNumericalToCheckboxes(compatflags2Checkboxes, compatflags2); + convertNumericalToCheckboxes(zandronumqCompatflagsCheckboxes, zandronumqCompatflags); + convertNumericalToCheckboxes(dmflagsCheckboxes, dmflags); + convertNumericalToCheckboxes(dmflags2Checkboxes, dmflags2); + convertNumericalToCheckboxes(zandronumqDmflagsCheckboxes, zandronumqDmflags); + convertNumericalToCheckboxes(lmsAllowedWeaponsCheckboxes, lmsAllowedWeapons); + convertNumericalToCheckboxes(lmsSpectatorSettingsCheckboxes, lmsSpectatorSettings); + + convertToWidgetGeneral(); + convertToWidgetPlayers(); + convertToWidgetCooperative(); + convertToWidgetDeathmatch(); +} + +void FlagsPageValueController::convertWidgetsToNumerical() +{ + // Reset internal values. + readFlagsFromTextInputs(); + + convertCheckboxesToNumerical(compatflagsCheckboxes, compatflags); + convertCheckboxesToNumerical(compatflags2Checkboxes, compatflags2); + convertCheckboxesToNumerical(zandronumqCompatflagsCheckboxes, zandronumqCompatflags); + convertCheckboxesToNumerical(dmflagsCheckboxes, dmflags); + convertCheckboxesToNumerical(dmflags2Checkboxes, dmflags2); + convertCheckboxesToNumerical(zandronumqDmflagsCheckboxes, zandronumqDmflags); + convertCheckboxesToNumerical(lmsAllowedWeaponsCheckboxes, lmsAllowedWeapons); + convertCheckboxesToNumerical(lmsSpectatorSettingsCheckboxes, lmsSpectatorSettings); + + convertToNumericalGeneral(); + convertToNumericalPlayers(); + convertToNumericalCooperative(); + convertToNumericalDeathmatch(); + + // Apply values to widgets. + flagsPage->leDmflags->setText(QString::number(dmflags)); + flagsPage->leDmflags2->setText(QString::number(dmflags2)); + flagsPage->leZandronumqDmflags->setText(QString::number(zandronumqDmflags)); + flagsPage->leCompatflags->setText(QString::number(compatflags)); + flagsPage->leCompatflags2->setText(QString::number(compatflags2)); + flagsPage->leZandronumqCompatflags->setText(QString::number(zandronumqCompatflags)); + flagsPage->leLMSAllowedWeapons->setText(QString::number(lmsAllowedWeapons)); + flagsPage->leLMSSpectatorSettings->setText(QString::number(lmsSpectatorSettings)); +} + +void FlagsPageValueController::convertCheckboxesToNumerical( + const QMap &checkboxMap, + unsigned &flagsValue) +{ + for (unsigned flag : checkboxMap.keys()) + { + if (checkboxMap[flag]->isChecked()) + { + flagsValue |= flag; + } + else + { + // We are subtracting the disabled flags from the current value, + // because the flagsValue variable preserves user input flags which + // are not supported by the GUI. + flagsValue &= ~flag; + } + } +} + +void FlagsPageValueController::convertNumericalToCheckboxes( + QMap &checkboxMap, + unsigned flagsValue) +{ + for (unsigned flag : checkboxMap.keys()) + { + checkboxMap[flag]->setChecked(flagsValue & flag); + } +} +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +void FlagsPageValueController::convertToNumericalGeneral() +{ + FlagsPage *f = flagsPage; + + // Environment + + // Reset the value. + dmflags &= ~(Dmflags::DF_FORCE_FALLINGZD + | Dmflags::DF_FORCE_FALLINGHX + | Dmflags::DF_FORCE_FALLINGST); + switch (f->cboFallingDamage->currentIndex()) + { + case FlagsPage::FDT_None: + // pass + break; + + case FlagsPage::FDT_Old: + dmflags |= Dmflags::DF_FORCE_FALLINGZD; + break; + + case FlagsPage::FDT_Hexen: + dmflags |= Dmflags::DF_FORCE_FALLINGHX; + break; + + case FlagsPage::FDT_Strife: + dmflags |= Dmflags::DF_FORCE_FALLINGST; + break; + } +} +//////////////////////////////////////////////////////////////////////////////// +void FlagsPageValueController::convertToNumericalPlayers() +{ + FlagsPage *f = flagsPage; + + // Abilities + + // Reset the value. + dmflags &= ~(Dmflags::DF_YES_JUMP + | Dmflags::DF_NO_JUMP); + switch (f->cboJumping->currentIndex()) + { + case FlagsPage::JCA_Default: + // pass + break; + case FlagsPage::JCA_Yes: + dmflags |= Dmflags::DF_YES_JUMP; + break; + case FlagsPage::JCA_No: + dmflags |= Dmflags::DF_NO_JUMP; + break; + } + + // Reset the value. + dmflags &= ~(Dmflags::DF_YES_CROUCH + | Dmflags::DF_NO_CROUCH); + switch (f->cboCrouching->currentIndex()) + { + case FlagsPage::JCA_Default: + // pass + break; + case FlagsPage::JCA_Yes: + dmflags |= Dmflags::DF_YES_CROUCH; + break; + case FlagsPage::JCA_No: + dmflags |= Dmflags::DF_NO_CROUCH; + break; + } +} +//////////////////////////////////////////////////////////////////////////////// +void FlagsPageValueController::convertToNumericalCooperative() +{ + // Placeholder method for future use. +} + +//////////////////////////////////////////////////////////////////////////////// +void FlagsPageValueController::convertToNumericalDeathmatch() +{ + FlagsPage *f = flagsPage; + + // Reset the value. + dmflags &= ~(Dmflags::DF_NO_EXIT + | Dmflags::DF_SAME_LEVEL); + if (f->rbKillThePlayer->isChecked()) + { + dmflags |= Dmflags::DF_NO_EXIT; + } + else if (f->rbRestartTheCurrentLevel->isChecked()) + { + dmflags |= Dmflags::DF_SAME_LEVEL; + } +} +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +void FlagsPageValueController::convertToWidgetGeneral() +{ + FlagsPage *f = flagsPage; + + // Environment + + // This one is tricky because FALLINGST flag is actually defined + // as a combination of two other flags. We need to check for it first and + // we also need to check if the result of 'AND' operation is equal to the + // value of the flag. + if ((dmflags & Dmflags::DF_FORCE_FALLINGST) + == Dmflags::DF_FORCE_FALLINGST) + { + f->cboFallingDamage->setCurrentIndex(FlagsPage::FDT_Strife); + } + else if (dmflags & Dmflags::DF_FORCE_FALLINGZD) + { + f->cboFallingDamage->setCurrentIndex(FlagsPage::FDT_Old); + } + else if (dmflags & Dmflags::DF_FORCE_FALLINGHX) + { + f->cboFallingDamage->setCurrentIndex(FlagsPage::FDT_Hexen); + } + else + { + f->cboFallingDamage->setCurrentIndex(FlagsPage::FDT_None); + } +} +//////////////////////////////////////////////////////////////////////////////// +void FlagsPageValueController::convertToWidgetPlayers() +{ + FlagsPage *f = flagsPage; + + // Abilities + if (dmflags & Dmflags::DF_YES_JUMP) + { + f->cboJumping->setCurrentIndex(FlagsPage::JCA_Yes); + } + else if (dmflags & Dmflags::DF_NO_JUMP) + { + f->cboJumping->setCurrentIndex(FlagsPage::JCA_No); + } + else + { + f->cboJumping->setCurrentIndex(FlagsPage::JCA_Default); + } + + if (dmflags & Dmflags::DF_YES_CROUCH) + { + f->cboCrouching->setCurrentIndex(FlagsPage::JCA_Yes); + } + else if (dmflags & Dmflags::DF_NO_CROUCH) + { + f->cboCrouching->setCurrentIndex(FlagsPage::JCA_No); + } + else + { + f->cboCrouching->setCurrentIndex(FlagsPage::JCA_Default); + } + + if ((zandronumqDmflags & Dmflags::ZADF_UNBLOCK_PLAYERS) == 0 && + (zandronumqDmflags & Dmflags::ZADF_UNBLOCK_ALLIES) == 0) + { + f->rbPlayersBlockEachOtherNormally->setChecked(true); + } +} +//////////////////////////////////////////////////////////////////////////////// +void FlagsPageValueController::convertToWidgetCooperative() +{ + // Placeholder method for future use. +} +//////////////////////////////////////////////////////////////////////////////// +void FlagsPageValueController::convertToWidgetDeathmatch() +{ + FlagsPage *f = flagsPage; + + if (dmflags & Dmflags::DF_NO_EXIT) + { + f->rbKillThePlayer->setChecked(true); + } + else if (dmflags & Dmflags::DF_SAME_LEVEL) + { + f->rbRestartTheCurrentLevel->setChecked(true); + } + else + { + f->rbContinueToTheNextMap->setChecked(true); + } +} +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +void FlagsPageValueController::readFlagsFromTextInputs() +{ + dmflags = flagsPage->leDmflags->text().toUInt(); + dmflags2 = flagsPage->leDmflags2->text().toUInt(); + zandronumqDmflags = flagsPage->leZandronumqDmflags->text().toUInt(); + compatflags = flagsPage->leCompatflags->text().toUInt(); + compatflags2 = flagsPage->leCompatflags2->text().toUInt(); + zandronumqCompatflags = flagsPage->leZandronumqCompatflags->text().toUInt(); + lmsAllowedWeapons = flagsPage->leLMSAllowedWeapons->text().toUInt(); + lmsSpectatorSettings = flagsPage->leLMSSpectatorSettings->text().toUInt(); +} + +void FlagsPageValueController::setVisible(bool visible) +{ + flagsPage->leCompatflags2->setVisible(visible); + flagsPage->lblCompatflags2->setVisible(visible); + flagsPage->cbCompatMaskedMidtex->setVisible(visible); + flagsPage->cbNoItemDrop->setVisible(visible); + flagsPage->cbSurvivalNoMapResetOnDeath->setVisible(visible); + flagsPage->cbDeadPlayersCanKeepInventory->setVisible(visible); + for (QWidget *checkbox : compatflags2Checkboxes.values()) + { + checkbox->setVisible(visible); + } +} +} diff --git a/src/plugins/zandronumq/createserverdialogpages/flagspagevaluecontroller3.h b/src/plugins/zandronumq/createserverdialogpages/flagspagevaluecontroller3.h new file mode 100644 index 00000000..9be801eb --- /dev/null +++ b/src/plugins/zandronumq/createserverdialogpages/flagspagevaluecontroller3.h @@ -0,0 +1,90 @@ +//------------------------------------------------------------------------------ +// flagspagevaluecontroller3.h +//------------------------------------------------------------------------------ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301 USA +// +//------------------------------------------------------------------------------ +// Copyright (C) 2016 "Zalewa" +//------------------------------------------------------------------------------ +#ifndef DOOMSEEKER_PLUGIN_ZANDRONUMQ_CREATESERVERDIALOGPAGES_FLAGSPAGEVALUECONTROLLER3_H +#define DOOMSEEKER_PLUGIN_ZANDRONUMQ_CREATESERVERDIALOGPAGES_FLAGSPAGEVALUECONTROLLER3_H + +#include +#include + +#include "createserverdialogpages/flagspagevaluecontroller.h" + +class FlagsPage; + +namespace Zandronumq3 +{ +/** + * @brief Converts numerical flags values to widget representation + * and vice-versa. + */ +class FlagsPageValueController : public ::FlagsPageValueController +{ +public: + FlagsPageValueController(FlagsPage *flagsPage); + + void convertNumericalToWidgets() override; + void convertWidgetsToNumerical() override; + void setVisible(bool visible) override; + +private: + unsigned compatflags; + unsigned compatflags2; + unsigned zandronumqCompatflags; + + unsigned dmflags; + unsigned dmflags2; + unsigned zandronumqDmflags; + + unsigned lmsAllowedWeapons; + unsigned lmsSpectatorSettings; + + QMap compatflagsCheckboxes; + QMap compatflags2Checkboxes; + QMap dmflagsCheckboxes; + QMap dmflags2Checkboxes; + QMap lmsAllowedWeaponsCheckboxes; + QMap lmsSpectatorSettingsCheckboxes; + QMap zandronumqCompatflagsCheckboxes; + QMap zandronumqDmflagsCheckboxes; + + FlagsPage *flagsPage; + + void convertToNumericalGeneral(); + void convertToNumericalPlayers(); + void convertToNumericalCooperative(); + void convertToNumericalDeathmatch(); + + void convertCheckboxesToNumerical(const QMap &checkboxMap, + unsigned &flagsValue); + void convertNumericalToCheckboxes(QMap &checkboxMap, + unsigned flagsValue); + + void convertToWidgetGeneral(); + void convertToWidgetPlayers(); + void convertToWidgetCooperative(); + void convertToWidgetDeathmatch(); + + void readFlagsFromTextInputs(); +}; +} + +#endif diff --git a/src/plugins/zandronumq/createserverdialogpages/votingsetupwidget.cpp b/src/plugins/zandronumq/createserverdialogpages/votingsetupwidget.cpp new file mode 100644 index 00000000..9845f518 --- /dev/null +++ b/src/plugins/zandronumq/createserverdialogpages/votingsetupwidget.cpp @@ -0,0 +1,145 @@ +//------------------------------------------------------------------------------ +// votingsetupwidget.cpp +//------------------------------------------------------------------------------ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301 USA +// +//------------------------------------------------------------------------------ +// Copyright (C) 2014 "Zalewa" +//------------------------------------------------------------------------------ +#include "votingsetupwidget.h" + +#include +#include + +VotingSetupWidget::VotingSetupWidget(QWidget *parent) + : QWidget(parent) +{ + setupUi(this); + mainPanel->setEnabled(false); +} + +QStringList VotingSetupWidget::generateGameRunParameters() +{ + if (cbUseThisPage->isChecked()) + { + return gameParametersList(); + } + else + { + return QStringList(); + } +} + +QStringList VotingSetupWidget::gameParametersList() const +{ + QStringList params; + + params << "+sv_limitnumvotes" << (cbVoteFloodingProtectionEnabled->isChecked() ? "1" : "0"); + params << "+sv_minvoters" << QString::number(spinMinimumNumberOfPlayersRequiredToCallAVote->value()); + params << "+sv_nocallvote" << QString::number(static_cast(whoCanVote())); + + params << "+sv_nochangemapvote" << (!cbChangeMapVote->isChecked() ? "1" : "0"); + params << "+sv_noduellimitvote" << (!cbDuelLimitVote->isChecked() ? "1" : "0"); + params << "+sv_nofraglimitvote" << (!cbFragLimitVote->isChecked() ? "1" : "0"); + params << "+sv_nokickvote" << (!cbKickVote->isChecked() ? "1" : "0"); + params << "+sv_nomapvote" << (!cbMapVote->isChecked() ? "1" : "0"); + params << "+sv_nopointlimitvote" << (!cbPointLimitVote->isChecked() ? "1" : "0"); + params << "+sv_notimelimitvote" << (!cbTimeLimitVote->isChecked() ? "1" : "0"); + params << "+sv_nowinlimitvote" << (!cbWinLimitVote->isChecked() ? "1" : "0"); + params << "+sv_noforcespecvote" << (!cbForceSpectatorVote->isChecked() ? "1" : "0"); + + return params; +} + +bool VotingSetupWidget::loadConfig(Ini &ini) +{ + IniSection section = ini.section("voting"); + + cbUseThisPage->setChecked(section.value("UseThisPage").toBool()); + + setWhoCanVote(static_cast(section.value("WhoCanVote").toInt())); + spinMinimumNumberOfPlayersRequiredToCallAVote->setValue(section.value("MinimumPlayersRequiredToVote", 1).toInt()); + cbVoteFloodingProtectionEnabled->setChecked(section.value("VoteFloodingProtection", true).toBool()); + + cbKickVote->setChecked(section.value("KickVote", true).toBool()); + cbChangeMapVote->setChecked(section.value("ChangeMapVote", true).toBool()); + cbMapVote->setChecked(section.value("MapVote", true).toBool()); + cbTimeLimitVote->setChecked(section.value("TimeLimitVote", true).toBool()); + cbFragLimitVote->setChecked(section.value("FragLimitVote", true).toBool()); + cbDuelLimitVote->setChecked(section.value("DuelLimitVote", true).toBool()); + cbPointLimitVote->setChecked(section.value("PointLimitVote", true).toBool()); + cbWinLimitVote->setChecked(section.value("WinLimitVote", true).toBool()); + cbForceSpectatorVote->setChecked(section.value("ForceSpectatorVote", true).toBool()); + + return true; +} + +bool VotingSetupWidget::saveConfig(Ini &ini) +{ + IniSection section = ini.section("voting"); + + section["UseThisPage"] = cbUseThisPage->isChecked(); + + section["WhoCanVote"] = whoCanVote(); + section["MinimumPlayersRequiredToVote"] = spinMinimumNumberOfPlayersRequiredToCallAVote->value(); + section["VoteFloodingProtection"] = cbVoteFloodingProtectionEnabled->isChecked(); + + section["KickVote"] = cbKickVote->isChecked(); + section["ChangeMapVote"] = cbChangeMapVote->isChecked(); + section["MapVote"] = cbMapVote->isChecked(); + section["TimeLimitVote"] = cbTimeLimitVote->isChecked(); + section["FragLimitVote"] = cbFragLimitVote->isChecked(); + section["DuelLimitVote"] = cbDuelLimitVote->isChecked(); + section["PointLimitVote"] = cbPointLimitVote->isChecked(); + section["WinLimitVote"] = cbWinLimitVote->isChecked(); + section["ForceSpectatorVote"] = cbForceSpectatorVote->isChecked(); + + return true; +} + +void VotingSetupWidget::setWhoCanVote(WhoCanVote who) +{ + switch (who) + { + case NoneCanVote: + rbNoOneCanVote->setChecked(true); + break; + case SpectatorsCantVote: + rbSpectatorsCantVote->setChecked(true); + break; + case AllCanVote: + default: + rbAllCanVote->setChecked(true); + break; + } +} + +VotingSetupWidget::WhoCanVote VotingSetupWidget::whoCanVote() const +{ + if (rbNoOneCanVote->isChecked()) + { + return NoneCanVote; + } + else if (rbSpectatorsCantVote->isChecked()) + { + return SpectatorsCantVote; + } + else + { + return AllCanVote; + } +} diff --git a/src/plugins/zandronumq/createserverdialogpages/votingsetupwidget.h b/src/plugins/zandronumq/createserverdialogpages/votingsetupwidget.h new file mode 100644 index 00000000..97664f3f --- /dev/null +++ b/src/plugins/zandronumq/createserverdialogpages/votingsetupwidget.h @@ -0,0 +1,60 @@ +//------------------------------------------------------------------------------ +// votingsetupwidget.h +//------------------------------------------------------------------------------ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301 USA +// +//------------------------------------------------------------------------------ +// Copyright (C) 2014 "Zalewa" +//------------------------------------------------------------------------------ +#ifndef id3E880CB7_0FF0_4187_BAD90AD0EA16A263 +#define id3E880CB7_0FF0_4187_BAD90AD0EA16A263 + +#include "ui_votingsetupwidget.h" +#include +#include + +class Ini; + +class VotingSetupWidget : public QWidget, private Ui::VotingSetupWidget +{ + Q_OBJECT + +public: + VotingSetupWidget(QWidget *parent); + + QStringList generateGameRunParameters(); + bool loadConfig(Ini &ini); + bool saveConfig(Ini &ini); + +private: + /** + * @brief Internal enums cast directly to game's CCMD values. + */ + enum WhoCanVote + { + AllCanVote = 0, + NoneCanVote = 1, + SpectatorsCantVote = 2 + }; + + QStringList gameParametersList() const; + + void setWhoCanVote(WhoCanVote who); + WhoCanVote whoCanVote() const; +}; + +#endif diff --git a/src/plugins/zandronumq/createserverdialogpages/votingsetupwidget.ui b/src/plugins/zandronumq/createserverdialogpages/votingsetupwidget.ui new file mode 100644 index 00000000..05abdf41 --- /dev/null +++ b/src/plugins/zandronumq/createserverdialogpages/votingsetupwidget.ui @@ -0,0 +1,263 @@ + + + VotingSetupWidget + + + + 0 + 0 + 519 + 306 + + + + Form + + + + 0 + + + + + Use this page + + + + + + + + 0 + + + + + Who can vote + + + + + + All can vote + + + true + + + + + + + No one can vote + + + + + + + Spectators can't vote + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + Minimum number of players required to call a vote: + + + + + + + + 0 + 0 + + + + 1 + + + + + + + + + Allow specific votes + + + + + + duellimit + + + true + + + + + + + pointlimit + + + true + + + + + + + timelimit + + + true + + + + + + + winlimit + + + true + + + + + + + changemap + + + true + + + + + + + kick + + + true + + + + + + + map + + + true + + + + + + + fraglimit + + + true + + + + + + + force players to spectate + + + true + + + + + + + + + + Vote flooding protection enabled + + + true + + + + + + + + + + Qt::Vertical + + + + 20 + 59 + + + + + + + + rbAllCanVote + rbNoOneCanVote + rbSpectatorsCantVote + spinMinimumNumberOfPlayersRequiredToCallAVote + cbKickVote + cbFragLimitVote + cbChangeMapVote + cbDuelLimitVote + cbMapVote + cbPointLimitVote + cbTimeLimitVote + cbWinLimitVote + + + + + cbUseThisPage + toggled(bool) + mainPanel + setEnabled(bool) + + + 80 + 2 + + + 470 + 79 + + + + + diff --git a/src/plugins/zandronumq/enginezandronumqconfigbox.cpp b/src/plugins/zandronumq/enginezandronumqconfigbox.cpp new file mode 100644 index 00000000..41be8160 --- /dev/null +++ b/src/plugins/zandronumq/enginezandronumqconfigbox.cpp @@ -0,0 +1,88 @@ +//------------------------------------------------------------------------------ +// enginezandronumqconfigbox.cpp +//------------------------------------------------------------------------------ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301 USA +// +//------------------------------------------------------------------------------ +// Copyright (C) 2012 "Zalewa" +//------------------------------------------------------------------------------ + +#include "enginezandronumqconfigbox.h" +#include "ini/ini.h" +#include "plugins/engineplugin.h" +#include "zandronumqengineplugin.h" + +#include +#include +#include +#include +#include +#include +#include + +EngineZandronumqConfigBox::EngineZandronumqConfigBox(EnginePlugin *plugin, IniSection &cfg, QWidget *parent) + : EngineConfigPage(plugin, cfg, parent) +{ + // Create the testing box, we might as well do this in code. + groupTesting = new QGroupBox(); + groupTesting->setTitle(tr("Testing Releases")); + groupTesting->setCheckable(true); + groupTesting->setLayout(new QVBoxLayout()); + groupTesting->layout()->addWidget(new QLabel(tr("Directory for testing releases:"))); + addWidget(groupTesting); + + QWidget *releasePathLayout = new QWidget(); + releasePathLayout->setLayout(new QHBoxLayout()); + leTestingPath = new QLineEdit(); + btnBrowseTestingPath = new QPushButton("..."); + releasePathLayout->layout()->addWidget(leTestingPath); + releasePathLayout->layout()->addWidget(btnBrowseTestingPath); + groupTesting->layout()->addWidget(releasePathLayout); + + connect(btnBrowseTestingPath, SIGNAL(clicked()), this, SLOT(btnBrowseTestingPathClicked())); +} + +void EngineZandronumqConfigBox::btnBrowseTestingPathClicked() +{ + QString strDirpath = QFileDialog::getExistingDirectory(this, tr("Doomseeker - choose Zandronumq testing directory")); + if (!strDirpath.isEmpty()) + leTestingPath->setText(strDirpath); +} + +void EngineZandronumqConfigBox::readSettings() +{ + EngineConfigPage::readSettings(); + + IniSection &config = *ZandronumqEnginePlugin::staticInstance()->data()->pConfig; + + groupTesting->setChecked(config["EnableTesting"]); + leTestingPath->setText(config["TestingPath"]); +} + +void EngineZandronumqConfigBox::saveSettings() +{ + EngineConfigPage::saveSettings(); + + QString strVal; + + IniSection &config = *ZandronumqEnginePlugin::staticInstance()->data()->pConfig; + + config["EnableTesting"] = groupTesting->isChecked(); + + strVal = leTestingPath->text(); + config["TestingPath"] = strVal; +} diff --git a/src/plugins/zandronumq/enginezandronumqconfigbox.h b/src/plugins/zandronumq/enginezandronumqconfigbox.h new file mode 100644 index 00000000..d58d6e7e --- /dev/null +++ b/src/plugins/zandronumq/enginezandronumqconfigbox.h @@ -0,0 +1,55 @@ +//------------------------------------------------------------------------------ +// enginezandronumqconfigbox.h +//------------------------------------------------------------------------------ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301 USA +// +//------------------------------------------------------------------------------ +// Copyright (C) 2012 "Zalewa" +//------------------------------------------------------------------------------ +#ifndef DOOMSEEKER_PLUGIN_ZANDRONUMQ_ENGINE_ZANDRONUMQ_CONFIG_H +#define DOOMSEEKER_PLUGIN_ZANDRONUMQ_ENGINE_ZANDRONUMQ_CONFIG_H + +#include "gui/configuration/engineconfigpage.h" + +class QCheckBox; +class QGroupBox; +class QLineEdit; +class QPushButton; + +class EngineZandronumqConfigBox : public EngineConfigPage +{ + Q_OBJECT + +public: + EngineZandronumqConfigBox(EnginePlugin *plugin, IniSection &cfg, QWidget *parent = nullptr); + + void readSettings() override; + + +protected slots: + void btnBrowseTestingPathClicked(); + +protected: + + void saveSettings() override; + + QGroupBox *groupTesting; + QLineEdit *leTestingPath; + QPushButton *btnBrowseTestingPath; +}; + +#endif diff --git a/src/plugins/zandronumq/huffman/bitreader.cpp b/src/plugins/zandronumq/huffman/bitreader.cpp new file mode 100644 index 00000000..ebc9216a --- /dev/null +++ b/src/plugins/zandronumq/huffman/bitreader.cpp @@ -0,0 +1,144 @@ +/** + * skulltag::BitReader class - Allows reading arbitrary bit lengths of data. + * Version 1 - Revsion 0 + * + * Copyright 2009 Timothy Landers + * email: code.vortexcortex@gmail.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "bitreader.h" + +namespace skulltag { + // BitReader class implementation + + int BitReader::intBitSize = 0; + int BitReader::intSize = 0; + int BitReader::mask[32] = {0}; + + /** Creates a new BitReader. */ + BitReader::BitReader(){ + init(); + } + + /** Creates a new BitReader. + * @param input Source of data that bits will be read from. + * @param max Maximum number of chars to read. */ + BitReader::BitReader( unsigned char const * input, int const &max ){ + inputBuffer( input, max ); + } + + /** Sets the input buffer that bytes will be read from. + * @param input Source of data that bits will be read from. + * @param max Maximum number of chars to input. + * @return true if successful, false if an error occurs. */ + bool BitReader::inputBuffer( unsigned char const * input, int const &max ){ + init(); // zero the vars. + currentByte = input; + if ( input == 0 ) return false; + if ( max < 1 ) return false; + bytesAvailable = max; + bitsAvailable = max << 3; + maximumBytes = max; + return true; + } + + /** Initializes this BitReader */ + void BitReader::init(){ + // initialize static variables if not initialized yet. + if ( intSize == 0 ){ + intSize = sizeof maximumBytes; + mask[0] = 0; + + // fill mask such that m = { 0, 1, 3, 7, 15, etc. } + for ( int i = 1; i < 32; i++ ) mask[i] = (mask[i-1] << 1) | 1; + + intBitSize = intSize << 3; + } + + // initialize member variables. + bitsAvailable = 0; + bytesAvailable = 0; + bufferBits = 0; + currentByte = 0; + maximumBytes = 0; + bitsUsed = 0; + } + + /** Fills the internal bit buffer. + * @return true if successful, false if an error occurs. */ + bool BitReader::fill(){ + if ( (currentByte == 0) || (bytesAvailable <= 0) ) return false; + + // while there's at least one octet free in the buffer, and one byte to read. + while ( (bitsUsed < (intBitSize - 8)) && (bytesAvailable > 0) ){ + + // put a byte into the bottom end of the buffer. + bufferBits |= (*currentByte & mask[8]) << (intBitSize - bitsUsed - 8); + + // Set variables to reflect the change. + currentByte++; + bytesAvailable--; + bitsUsed += 8; + } + return true; + } + + /** Fetches a specified number of bits and stores them in an int. + * @param bits destination of the retrieved bits.
+ * The bits will be stored in the least significant portion of the int. + * @param count the number of bits to fetch. + * @return the number of bits read -- may not be equal to the amount requested. */ + int BitReader::get( int &bits, int const &count ){ + bits = 0; + // Requesting more bits than are available. + if ( count > bitsAvailable ) return 0; + if ( (count > bitsUsed) && (!fill()) ) return 0; + bits = (bufferBits >> (intBitSize - count)) & mask[count]; + // lesser of bits in buffer or requested bits. + int got = (bitsUsed < count) ? bitsUsed : count; + // get as many bits from the buffer as we can. + if ( got > 0 ){ + bufferBits <<= got; + bitsUsed -= got; + bitsAvailable -= got; + } + // if more bits are requested. + if ( count > got ){ + if (!fill()) { + bits = (bits >> (count - got)) & mask[count - got]; + return got; + } + got = count - got; + // avoid reading more bits than available. + if ( got <= bitsAvailable ){ + bits |= (bufferBits >> (intBitSize - got)) & mask[got]; + bufferBits <<= got; + bitsUsed -= got; + bitsAvailable -= got; + } + } + return count; + } + + /** @return Amount of bits that can be read from this BitReader. */ + int BitReader::availableBits(){ return bitsAvailable; } + +} // end namespace skulltag diff --git a/src/plugins/zandronumq/huffman/bitreader.h b/src/plugins/zandronumq/huffman/bitreader.h new file mode 100644 index 00000000..c6463248 --- /dev/null +++ b/src/plugins/zandronumq/huffman/bitreader.h @@ -0,0 +1,85 @@ +/** + * skulltag::BitReader class - Allows reading arbitrary bit lengths of data. + * Version 1 - Revsion 0 + * + * Copyright 2009 Timothy Landers + * email: code.vortexcortex@gmail.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef _BIT_READER_VERSION +#define _BIT_READER_VERSION 1 + +/** Prevents naming convention problems via encapsulation. */ +namespace skulltag { // scope limitation + +/** BitReader - Allows reading of varying amounts of bits from a char buffer.
+ * Very usefull for inputting variable bit length encodings such as Huffman. */ + + class BitReader { + int bufferBits; /**< intermediary buffer of bits. */ + int bitsUsed; /**< number of bits used in the buffer. */ + unsigned char const * currentByte; /**< position in memory the next char will be read. */ + int bytesAvailable; /**< amount of available space left in the input buffer in bytes. Excludes the contents of bufferBits. */ + int bitsAvailable; /**< amount of available space left in the input buffer in bits. Includes the contents of bufferBits. */ + int maximumBytes; /**< total amount of bytes that can be read from the input buffer. */ + static int mask[]; /**< maps a number of bits to a bit mask containing as many bits. */ + static int intSize; /**< number of chars in an int. */ + static int intBitSize; /**< number of bits in an ing. */ +public: + + /** Creates a new BitReader. */ + BitReader(); + + /** Creates a new BitReader. + * @param input Source of data that bits will be read from. + * @param max Maximum number of chars to read. */ + BitReader( unsigned char const * input, int const &max ); + + /** Sets the input buffer that bytes will be read from. + * @param input Source of data that bits will be read from. + * @param max Maximum number of chars to input. + * @return true if successful, false if an error occurs. */ + bool inputBuffer( unsigned char const * input, int const &max ); + + /** Fetches a specified number of bits and stores them in an int. + * @param bits destination of the retrieved bits.
+ * The bits will be stored in the least significant portion of the int. + * @param count the number of bits to fetch. + * @return the number of bits read -- may not be equal to the amount requested. */ + int get( int &bits, int const &count ); + + /** @return Amount of bits that can be read from this BitReader. */ + int availableBits(); + + private: + + /** Fills the internal bit buffer. + * @return true if successful, false if an error occurs. */ + bool fill(); + + /** Initializes this BitReader. */ + void init(); + + }; + +} +#endif + diff --git a/src/plugins/zandronumq/huffman/bitwriter.cpp b/src/plugins/zandronumq/huffman/bitwriter.cpp new file mode 100644 index 00000000..178035da --- /dev/null +++ b/src/plugins/zandronumq/huffman/bitwriter.cpp @@ -0,0 +1,271 @@ +/* + * skulltag::BitWriter class - Enables writing arbitrary bit lengths of data. + * + * Copyright 2009 Timothy Landers + * email: code.vortexcortex@gmail.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "bitwriter.h" + +/* The internal buffer of bits is an int which is initiallized to zero. + * The Bit Buffer: [00000000000000000000000000000000] - 0 bits stored. + * + * Bits stored in the bit buffer occupy the most significant bits available. + * When bits are stored their order is preserved. + * Storing the 5 bits 01011 into the bit buffer would result in: + * The Bit Buffer: [01011000000000000000000000000000] - 5 bits stored. + * + * Additionally storing 0x12f3 (13 bits) would result in: + * The Bit Buffer: [01011100101111001100000000000000] - 18 bits stored. + * + * Data is stored via any of the put(...) functions. + * + * To retrieve bytes (chars) of data from the bit buffer and empty the bit buffer: flush(); + * Flushing the bit buffer takes groups of 8 bits (octets) and stores them in the + * output buffer at the current byte position. Calling flush() would cause output + * to receive 2 bytes (0x5c, 0xbc) == (01011100, 10111100) and the remaining bits would + * be moved to the most significant bit positions. + * The Bit Buffer: [11000000000000000000000000000000] - 2 bits stored. + * Note: The empty bits of the bit buffer must be zero to avoid additional masking operations. + * flush() is called automatically if the bit buffer is too full during a call to put(...) + * + * When the bit storage operation is complete call finish(...). Finish will flush as many full + * bytes of data into the output buffer as possible, the remaining bits will be padded out + * to a full octet with zeros (on their less significant side), then written to the output + * buffer. finish( bytesStored, padding ) passes by reference the number of bytes stored + * and number of padding bits added (0 to 7) to the last stored byte. + * + * Bits are not added one at a time, they are masked, shifted and bitwise OR'ed into + * the buffer in as large a group as possible. This allows the BitWriter to add multiple bits in a single + * operation instead of calling a function for each 1 bit added. + * + * Normal usage: + * + * char * dataArray = new char[ max_output_size ]; + * BitWriter * buffer = new BitWriter( dataArray, max_output_size ); + * ... + * // various calls to put(...); + * ... + * int numBytesOutput, paddedBits; + * buffer->finish( numBytesOutput, paddedBits ); + * ... + * // do something with dataArray + * ... + * delete buffer; + * delete dataArray; + * + * */ + +/** Prevents naming convention problems via encapsulation. */ +namespace skulltag { + + // Static variable initially set to zero as a signal for init() + int BitWriter::intSize = 0; + int BitWriter::mask[32]; + + /** Initializes this BitWriter. */ + void BitWriter::init(){ + + // initialize static variables if not initialized yet. + if ( intSize == 0 ){ + intSize = sizeof maximumBytes; + mask[0] = 0; + + // fill mask such that m = { 0, 1, 3, 7, 15, etc. } + for ( int i = 1; i < 32; i++ ) mask[i] = (mask[i-1] << 1) | 1; + } + + // initialize member variables. + bitsAvailable = 0; + bytesAvailable = 0; + bufferBits = 0; + currentByte = 0; + maximumBytes = 0; + bitsLeft = intSize << 3; + } + + /** Creates a new BitWriter. */ + BitWriter::BitWriter(){ + init(); + } + + /** Creates a new BitWriter. + * @param output Destination that bits will be written to. + * @param max Maximum number of chars to output. */ + BitWriter::BitWriter( unsigned char * const output, int const &max ){ + outputBuffer( output, max ); + } + + /** Sets the output buffer that bytes will be written to. + * @param output Destination that bits will be written to. + * @param max Maximum number of chars to output. + * @return true if successful, false otherwise. */ + bool BitWriter::outputBuffer( unsigned char * const output, int const &max ){ + init(); // zero the vars. + currentByte = output; + if ( output == 0 ) return false; + if ( max < 1 ) return false; + bytesAvailable = max; + bitsAvailable = max << 3; + maximumBytes = max; + return true; + } + + /** Appends a char worth of bits to the buffer. + * @param bits the bits to append. + * @return true if successful, false otherwise. */ + bool BitWriter::put( unsigned char const &bits ){ + return put( (int)bits, 8 ); + } + + /** Appends a short worth of bits to the buffer. + * @param bits the bits to append. + * @return true if successful, false otherwise. */ + bool BitWriter::put( short const &bits ){ + static int shortBitSize = (sizeof bits) << 3; + return put( (int)bits, shortBitSize ); + } + /** Appends an int worth of bits to the buffer. + * @param bits the bits to append. + * @return true if successful, false otherwise. */ + bool BitWriter::put( int const &bits ){ + static int intBitSize = intSize << 3; + return put( bits, intBitSize); + } + + /** Appends multiple chars from a buffer to this BitWriter. + * @param inputBuffer pointer to char data + * @param count number of chars to read + * @return true if successful, false otherwise. */ + bool BitWriter::put( unsigned char const * const inputBuffer, int count ){ + int i = 0; + + // Read in 4 bytes at a time and send all at once to the bit buffer. + while ( (i + 3) < count ){ + if ( !put( + ((int)inputBuffer[ i ] << 24) | + ((int)inputBuffer[i+1] << 16) | + ((int)inputBuffer[i+2] << 8) | + (int)inputBuffer[i+3], 32 + ) ) return false; + i+=4; + } + + // If any bytes remain, output them one at a time. + while ( i < count ){ + if ( !put( (int)inputBuffer[ i ], 8 ) ) return false; + i++; + } + + return true; + } + + /** Appends a specified number of bits from an int to the buffer. + * @param bits the bits to append.
+ * The bits should be stored in the least significant portion of the int. + * @param count the number of bits to append. + * @return true if successful, false otherwise. */ + bool BitWriter::put( int const &bits, int count ){ + if ( count > bitsAvailable ) return false; + if ( (bitsLeft < 1) && (!flush()) ) return false; + if ( count > bitsLeft ){ + // not enough space in buffer, fill buffer with top end of input bits then flush. + bufferBits |= mask[bitsLeft] & (bits >> (count - bitsLeft)); + count -= bitsLeft; + bitsAvailable -= bitsLeft; + bitsLeft = 0; + + // Buffer's full, needs flushing. + if (!flush()) return false; + } + + // if there are still bits of input... + if ( count > 0 ){ + + // shift the input bits up to the end of the bit buffer. + bufferBits |= (mask[count] & bits) << (bitsLeft - count); + bitsAvailable -= count; + bitsLeft -= count; + } + return true; + } + + /** Writes any full chars of data stored in this BitWriter to the output char buffer. + * @return true if successful, false if an error occurs. */ + bool BitWriter::flush(){ + // static var to hold how many bits are in an int. + static int intBitSize = intSize << 3; + if ( currentByte == 0 ) return false; + int numBits = intBitSize - bitsLeft; + + // while there's at least one octet of data in the buffer. + while ( numBits > 7 ){ + + // fail if no bytes can be written. + if ( bytesAvailable <= 0 ) return false; + + // get a byte off the top end of the buffer. + *currentByte = (bufferBits >> (intBitSize - 8)) & mask[8]; + + // Set variables to reflect the change. + currentByte++; + bytesAvailable--; + bufferBits = bufferBits << 8; + bitsLeft += 8; + numBits -= 8; + } + return true; + } + + /** Flushes this BitWriter then outputs any partial chars by padding them with zeros.
+ * After calling finish() all other calls to update the BitWriter will fail until a buffer is set via outputBuffer(). + * @param bytesWritten out: the number of bytes written to the output buffer. + * @param paddingBits out: the number of padding bits used in the final byte of output. + * @return true if successful, false if an error occurs. */ + bool BitWriter::finish( int &bytesWritten, int &paddingBits ){ + static int intBitSize = intSize << 3; + // set meaningful return values even if flush() fails. + bytesWritten = maximumBytes - bytesAvailable; + paddingBits = 0; + if ( flush() ){ + // use a temp var to avoid setting paddingBits to invalid value on failure. + int pad = (8 - (intBitSize - bitsLeft)) & 7; + if ( pad > 0 ){ + // all empty bits should be zero. Artificially extend by the number of bits needed. + bitsLeft -= pad; + if ( !flush() ){ + // Prevent futher use even on failure. + init(); + return false; + } + // return the temp bit padding value. + paddingBits = pad; + } + bytesWritten = maximumBytes - bytesAvailable; + init(); // set initial state -- no further writing can occur. + return true; + } + // Prevents futher use even on failure. + init(); + return false; + } + +} diff --git a/src/plugins/zandronumq/huffman/bitwriter.h b/src/plugins/zandronumq/huffman/bitwriter.h new file mode 100644 index 00000000..c4f15659 --- /dev/null +++ b/src/plugins/zandronumq/huffman/bitwriter.h @@ -0,0 +1,109 @@ +/* + * skulltag::BitWriter class - Enables writing arbitrary bit lengths of data. + * + * Copyright 2009 Timothy Landers + * email: code.vortexcortex@gmail.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef _BIT_WRITER_VERSION +#define _BIT_WRITER_VERSION 1 + +/** Prevents naming convention problems via encapsulation. */ +namespace skulltag { // scope limitation + +/** BitWriter - Allows writing of varying amounts of bits to a char buffer.
+ * Very usefull for outputting variable bit length encodings such as Huffman. */ + + class BitWriter { + int bufferBits; /**< intermediary buffer of bits. */ + int bitsLeft; /**< number of bits left in the buffer. */ + unsigned char * currentByte; /**< position in memory the next char will be stored. */ + int bytesAvailable; /**< amount of available space left in the output buffer in bytes. Excludes the contents of bufferBits. */ + int bitsAvailable; /**< amount of available space left in the output buffer in bits. Includes the contents of bufferBits. */ + int maximumBytes; /**< total amount of bytes that can be written to the output buffer. */ + static int mask[]; /**< maps a number of bits to a bit mask containing as many bits. */ + static int intSize; /**< number of chars in an int. */ +public: + + /** Creates a new BitWriter. */ + BitWriter(); + + /** Creates a new BitWriter. + * @param output Destination that bits will be written to. + * @param max Maximum number of chars to output. */ + BitWriter( unsigned char * const output, int const &max ); + + /** Appends a char worth of bits to the buffer. + * @param bits the bits to append. + * @return true if successful, false if an error occurs. */ + bool put( unsigned char const &bits ); + + /** Appends a short worth of bits to the buffer. + * @param bits the bits to append. + * @return true if successful, false otherwise. + * @return true if successful, false if an error occurs. */ + bool put( short const &bits ); + + /** Appends an int worth of bits to the buffer. + * @param bits the bits to append. + * @return true if successful, false if an error occurs. */ + bool put( int const &bits ); + + /** Appends a specified number of bits from an int to the buffer. + * @param bits the bits to append.
+ * The bits should be stored in the least significant portion of the int. + * @param count the number of bits to append. + * @return true if successful, false if an error occurs. */ + bool put( int const &bits, int count ); + + /** Appends multiple chars from a buffer to this BitWriter. + * @param inputBuffer pointer to char data + * @param count number of chars to read + * @return true if successful, false if an error occurs. */ + bool put( unsigned char const * const inputBuffer, int count ); + + /** Sets the output buffer that bytes will be written to. + * @param output Destination that bits will be written to. + * @param max Maximum number of chars to output. + * @return true if successful, false if an error occurs. */ + bool outputBuffer( unsigned char * const output, int const &max ); + + /** Writes any full chars of data stored in this BitWriter to the output char buffer. + * @return true if successful, false if an error occurs. */ + bool flush(); + + /** Flushes this BitWriter then outputs any partial chars by padding them with zeros.
+ * After calling finish() all other calls to update the BitWriter will fail until a buffer is set via outputBuffer(). + * @param bytesWritten out: the number of bytes written to the output buffer. + * @param paddingBits out: the number of padding bits used in the final byte of output. + * @return true if successful, false if an error occurs. */ + bool finish( int &bytesWritten, int &paddingBits ); + + private: + + /** Initializes this BitWriter. */ + void init(); + + }; + +} +#endif + diff --git a/src/plugins/zandronumq/huffman/codec.h b/src/plugins/zandronumq/huffman/codec.h new file mode 100644 index 00000000..846e11b1 --- /dev/null +++ b/src/plugins/zandronumq/huffman/codec.h @@ -0,0 +1,71 @@ +/* + * skulltag::Codec class interface - Base class for data encoding or decoding operations. + * + * Copyright 2009 Timothy Landers + * email: code.vortexcortex@gmail.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef _CODEC_VERSION +#define _CODEC_VERSION 1 + +/** Prevents naming convention problems via encapsulation. */ +namespace skulltag { + + /** Huffman tree node -- used to represent a Huffman tree.
+ * Huffman trees are use by compression / decompression codecs. */ + class HuffmanNode { + public: + int bitCount; /**< number of bits in the Huffman code. */ + int code; /**< bit representation of a Huffman code. */ + int value; /**< the value the Huffman code represents. */ + HuffmanNode * branch; /**< the left and right child branches or NULL (0) if leaf. */ + }; + +// Codec Class Interface + + /** Base class for encoding and decoding data. */ + class Codec { + + public: + + /** Decodes data read from an input buffer and stores the result in the output buffer. + * @return number of bytes stored in the output buffer or -1 if an error occurs while encoding. */ + virtual int encode( + unsigned char const * const input, /**< in: pointer to the first byte to encode. */ + unsigned char * const output, /**< out: pointer to an output buffer to store data. */ + int const &inLength, /**< in: number of bytes of input buffer to encoded. */ + int const &outLength /**< in: maximum length of data to output. */ + ) const = 0; + + /** Decodes data read from an input buffer and stores the result in the output buffer. + * @return number of bytes stored in the output buffer or -1 if an error occurs while decoding. */ + virtual int decode( + unsigned char const * const input, /**< in: pointer to data that needs decoding. */ + unsigned char * const output, /**< out: pointer to output buffer to store decoded data. */ + int const &inLength, /**< in: number of bytes of input buffer to read. */ + int const &outLength /**< in: maximum length of data to output. */ + ) = 0; + + }; // end class Codec + +}; // end namespace Codec + +#endif diff --git a/src/plugins/zandronumq/huffman/huffcodec.cpp b/src/plugins/zandronumq/huffman/huffcodec.cpp new file mode 100644 index 00000000..f0d45b3e --- /dev/null +++ b/src/plugins/zandronumq/huffman/huffcodec.cpp @@ -0,0 +1,330 @@ +/* + * skulltag::HuffmanCodec class - Huffman encoder and decoder. + * + * Copyright 2009 Timothy Landers + * email: code.vortexcortex@gmail.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "huffcodec.h" + +/** Prevents naming convention problems via encapsulation. */ +namespace skulltag { + +// HuffmanCodec Implementation + + /** Reverses the order of bits in a byte. + * EG: The statement reverseMap[0xAF] == 0xF5 is true.
+ * The index 10101111 stores the reverse value: 11110101.
+ * Note: One array lookup is much faster than Eight bit manipulating loop iterations. */ + unsigned char const HuffmanCodec::reverseMap[] = { + 0,128, 64,192, 32,160, 96,224, 16,144, 80,208, 48,176,112,240, + 8,136, 72,200, 40,168,104,232, 24,152, 88,216, 56,184,120,248, + 4,132, 68,196, 36,164,100,228, 20,148, 84,212, 52,180,116,244, + 12,140, 76,204, 44,172,108,236, 28,156, 92,220, 60,188,124,252, + 2,130, 66,194, 34,162, 98,226, 18,146, 82,210, 50,178,114,242, + 10,138, 74,202, 42,170,106,234, 26,154, 90,218, 58,186,122,250, + 6,134, 70,198, 38,166,102,230, 22,150, 86,214, 54,182,118,246, + 14,142, 78,206, 46,174,110,238, 30,158, 94,222, 62,190,126,254, + 1,129, 65,193, 33,161, 97,225, 17,145, 81,209, 49,177,113,241, + 9,137, 73,201, 41,169,105,233, 25,153, 89,217, 57,185,121,249, + 5,133, 69,197, 37,165,101,229, 21,149, 85,213, 53,181,117,245, + 13,141, 77,205, 45,173,109,237, 29,157, 93,221, 61,189,125,253, + 3,131, 67,195, 35,163, 99,227, 19,147, 83,211, 51,179,115,243, + 11,139, 75,203, 43,171,107,235, 27,155, 91,219, 59,187,123,251, + 7,135, 71,199, 39,167,103,231, 23,151, 87,215, 55,183,119,247, + 15,143, 79,207, 47,175,111,239, 31,159, 95,223, 63,191,127,255 + }; + + /** Creates a new HuffmanCodec + * @param treeData char array containing the tree data to use. + * @param dataLength number of chars in treeData. */ + HuffmanCodec::HuffmanCodec( + unsigned char const * const treeData, + int dataLength + ) : Codec() { + init(); + // init code table (256 pointers to Huffman Leaf Nodes.) + codeTable = new HuffmanNode*[256]; + for (int i = 0; i < 256; i++) codeTable[i] = 0; + // build root node + root = new HuffmanNode; + root->bitCount = 0; + root->code = 0; + root->value = -1; + // recursive Huffman tree builder. + buildTree( root, treeData, 0, dataLength, codeTable, 256 ); + huffResourceOwner = true; + } + + + /** Creates a new HuffmanCodec that uses the specified Huffman resources. + * @param treeRootNode The root node of a valid huffman tree. + * @param leafCodeTable A code lookup table where references to HuffmanNodes are stored with their array index equal to their value. + * Note: The tree nodes will not be released upon destruction of this HuffmanCodec. */ + HuffmanCodec::HuffmanCodec( + HuffmanNode * treeRootNode, + HuffmanNode ** leafCodeTable + ){ + init(); + // assign values -- no table building or allocations. + root = treeRootNode; + codeTable = leafCodeTable; + huffResourceOwner = false; + } + + /** Checks the ownership state of this HuffmanCodec's resources. + * @return true if the tree & code table will be released upon destruction of this HuffmanCodec.
+ * A false return value means this HuffmanCodec is not responsible for deleting its resources. */ + bool HuffmanCodec::huffmanResourceOwner(){ + return huffResourceOwner; + } + + /** Perform initialization procedures common to all constructors. */ + void HuffmanCodec::init(){ + writer = new BitWriter(); + reverseBits = false; + expandable = true; + huffResourceOwner = false; + } + + /** Increases a codeLength up to the longest Huffman code bit length found in the node or any of its children.
+ * Set to Zero before calling to determine maximum code bit length. + * @param node in: The node to begin searching at. + * @param codeLength out: Variable to hold the longest code bit length found. */ + void HuffmanCodec::maxCodeLength( HuffmanNode const * const node, int &codeLength ){ + // [TL] We must walk each tree node since the codeTable may not contain the set of all leaf nodes. + // bail on NULL node (tree is corrupt). + if ( node == 0) return; + // Recurse across children if they exist. + if ( node->branch != 0 ){ + maxCodeLength( &(node->branch[0]), codeLength ); + maxCodeLength( &(node->branch[1]), codeLength ); + } else if ( codeLength < node->bitCount ){ + // set codeLength if it's smaller than current node's bitCount. + codeLength = node->bitCount; + } + } + + /** Decreases a codeLength to the shortest Huffman code bit length found in the node or any of its children.
+ * Set to Zero before calling to determine minimum code bit length. + * @param node in: The node to begin searching at. + * @param codeLength out: Variable to hold the longest code bit length found. */ + void HuffmanCodec::minCodeLength( HuffmanNode const * const node, int &codeLength ){ + /* [TL] Do not optimize under the assumption child nodes will have longer code Lengths! + * Future subclasses may have trees that diverge from Huffman specs. */ + // bail on NULL node (tree is corrupt). + if ( node == 0 ) return; + // Recurse across children if they exist. + if ( node->branch != 0 ){ + minCodeLength( &(node->branch[0]), codeLength ); + minCodeLength( &(node->branch[1]), codeLength ); + } else if ( (codeLength > node->bitCount) || (codeLength == 0) ) { + // set codeLength if it's Zero or larger than current node's bitCount. + codeLength = node->bitCount; + } + } + + /** Recursively builds a Huffman Tree.
+ * The initial root node should have the following field values:
+ * + * + * + * + * + * + * + *
fieldSetting
bitCount0
code0
value-1
Branch0 (NULL)
+ * @param node in/out: branch node of the Huffman Tree. + * @param treeData in: char array containing the Huffman Tree's byte representation. + * @param index in: Current array element to read the next tree node from. + * @param codeTable in/out: array of pointers to HuffmanNode structs. + * @param tableLenght in: maximum index allowed in the codeTable. + * @return the next index to read from or -1 if an error occurs. + * */ + int HuffmanCodec::buildTree( + HuffmanNode * node, + unsigned char const * const treeData, + int index, + int dataLength, + HuffmanNode ** const &codeTable, + int tableLength + ){ + if ( index >= dataLength ) return -1; + // Read the branch description bit field + int desc = treeData[index]; + index++; + + // Create the array that will hold L/R child nodes of this branch. + node->branch = new HuffmanNode[2]; + + // Read the child Nodes for this branch. + for ( int i = 0; i < 2; i++ ){ + // Increase bit count, and update huffman code to match the node's tree position. + node->branch[i].bitCount = node->bitCount + 1; + node->branch[i].code = (node->code << 1) | i; // appends a 0 or 1 depending on L/R branch. + node->branch[i].value = -1; // default value. + + // Test a bit from the branch description (least significant bit == left) + if ( (desc & (1 << i)) == 0 ){ + // Child node is a branch; Recurse. + if ( (index = buildTree( &(node->branch[i]), treeData, index, dataLength, codeTable, tableLength )) < 0 ) return -1; + // This means the entire left sub tree will be read before the right sub tree gets read. + } else { + // Read leaf value and map its value/index in the nodes array. + if ( index >= dataLength ) return -1; + // set the nodes huffman code values. + node->branch[i].code = (node->code << 1) | i; + node->branch[i].bitCount = node->bitCount+1; + node->branch[i].value = treeData[index] & 0xff; + // NULL the child node's branch to mark it as a leaf. + node->branch[i].branch = 0; + // buffer overflow check. + if ( (node->branch[i].value >= 0) && (node->branch[i].value <= tableLength ) ) + // store a pointer to the leaf node into the code table at the location of its byte value. + codeTable[ node->branch[i].value ] = &node->branch[i]; + index++; + } + } + + return index; + } + + /** Decodes data read from an input buffer and stores the result in the output buffer. + * @return number of bytes stored in the output buffer or -1 if an error occurs while encoding. */ + int HuffmanCodec::encode( + unsigned char const * const input, /**< in: pointer to the first byte to encode. */ + unsigned char * const output, /**< out: pointer to an output buffer to store data. */ + int const &inLength, /**< in: number of bytes of input buffer to encoded. */ + int const &outLength /**< in: maximum length of data to output. */ + ) const { + // setup the bit buffer to output. if not expandable Limit output to input length. + if ( expandable ) writer->outputBuffer( output, outLength ); + else writer->outputBuffer( output, ((inLength + 1) < outLength) ? inLength + 1 : outLength ); + + writer->put( (unsigned char)0 ); // reserve place for padding signal. + + HuffmanNode * node; // temp ptr cache; + for ( int i = 0; i < inLength; i++ ){ + node = codeTable[ 0xff & input[i] ]; //lookup node + // Put the huffman code into the bit buffer and bail if error occurs. + if ( !writer->put( node->code, node->bitCount ) ) return -1; + } + int bytesWritten, padding; + if ( writer->finish( bytesWritten, padding ) ){ + // write padding signal byte to begining of stream. + output[0] = (unsigned char)padding; + } else return -1; + + // Reverse the bit order of each byte (Old Huffman Compatibility Mode) + if ( reverseBits ) for ( int i = 1; i < bytesWritten; i++ ){ + output[i] = reverseMap[ 0xff & output[i] ]; + } + + return bytesWritten; + } // end function encode + + /** Decodes data read from an input buffer and stores the result in the output buffer. + * @return number of bytes stored in the output buffer or -1 if an error occurs while decoding. */ + int HuffmanCodec::decode( + unsigned char const * const input, /**< in: pointer to data that needs decoding. */ + unsigned char * const output, /**< out: pointer to output buffer to store decoded data. */ + int const &inLength, /**< in: number of bytes of input buffer to read. */ + int const &outLength /**< in: maximum length of data to output. */ + ){ + if ( inLength < 1 ) return 0; + int bitsAvailable = ((inLength-1) << 3) - (0xff & input[0]); + int rIndex = 1; // read index of input buffer. + int wIndex = 0; // write index of output buffer. + char byte = 0; // bits of the current byte. + int bitsLeft = 0; // bits left in byte; + + HuffmanNode * node = root; + + // Traverse the tree, output values. + while ( (bitsAvailable > 0) && (node != 0) ){ + + // Get the next byte if we've run out. + if ( bitsLeft <= 0 ){ + byte = input[rIndex++]; + if ( reverseBits ) byte = reverseMap[ 0xff & byte ]; + bitsLeft = 8; + } + + // Traverse the tree according to the most significant bit. + node = &(node->branch[ ((byte >> 7) & 0x01) ]); + + // Is the node Non NULL, and a leaf? + if ( (node != 0) && (node->branch == 0) ){ + // buffer overflow prevention + if ( wIndex >= outLength ) return wIndex; + // Output leaf node's value and restart traversal at root node. + output[ wIndex++ ] = (unsigned char)(node->value & 0xff); + node = root; + } + + byte <<= 1; // cue up the next bit + bitsLeft--; // use up one bit of byte + bitsAvailable--; // decrement total bits left + } + + return wIndex; + } // end function decode + + /** Deletes all sub nodes of a HuffmanNode by traversing and deleting its child nodes. + * @param treeNode pointer to a HuffmanNode whos children will be deleted. */ + void HuffmanCodec::deleteTree( HuffmanNode * treeNode ){ + if ( treeNode == 0 ) return; + if ( treeNode->branch != 0 ){ + deleteTree( &(treeNode->branch[0]) ); + deleteTree( &(treeNode->branch[1]) ); + delete[] treeNode->branch; + } + } + + /** Destructor - frees resources. */ + HuffmanCodec::~HuffmanCodec() { + delete writer; + //check for resource ownership before deletion + if ( huffmanResourceOwner() ){ + delete[] codeTable; + deleteTree( root ); + delete root; + } + } + + /** Enables or Disables backwards bit ordering of bytes. + * @param backwards "true" enables reversed bit order bytes, "false" uses standard byte bit ordering. */ + void HuffmanCodec::reversedBytes( bool backwards ){ reverseBits = backwards; } + + /** Check the state of backwards bit ordering for bytes. + * @return true: bits within bytes are reversed. false: bits within bytes are normal. */ + bool HuffmanCodec::reversedBytes(){ return reverseBits; } + + /** Enable or Disable data expansion during encoding. + * @param expandingAllowed "true" allows encoding to expand data. "false" causes failure upon expansion. */ + void HuffmanCodec::allowExpansion( bool expandingAllowed ){ expandable = expandingAllowed; } + + /** Check the state of data expandability. + * @return true: data expansion is allowed. false: data is not allowed to expand. */ + bool HuffmanCodec::allowExpansion(){ return expandable; } + + +}; // end namespace skulltag diff --git a/src/plugins/zandronumq/huffman/huffcodec.h b/src/plugins/zandronumq/huffman/huffcodec.h new file mode 100644 index 00000000..82c3e4ba --- /dev/null +++ b/src/plugins/zandronumq/huffman/huffcodec.h @@ -0,0 +1,179 @@ +/* + * skulltag::HuffmanCodec class - Huffman encoder and decoder. + * + * Copyright 2009 Timothy Landers + * email: code.vortexcortex@gmail.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef _HUFFMAN_CODEC_VERSION +#define _HUFFMAN_CODEC_VERSION 1 +#define _HUFFMAN_CODEC_REV 2 + +#include "codec.h" +#include "bitwriter.h" + +/** Prevents naming convention problems via encapsulation. */ +namespace skulltag { + + /** HuffmanCodec class - Encodes and Decodes data using a Huffman tree. */ + class HuffmanCodec : public Codec { + + /** top level node of the Huffman tree used for decoding. */ + HuffmanNode * root; + + /** table of Huffman codes and bit lengths used for encoding. */ + HuffmanNode ** codeTable; + + /** intermediary destination of huffman codes. */ + BitWriter * writer; + + /** When true this HuffmanCodec reverses its bytes after encoding and before decoding to + * provide compatibility with the backwards bit ordering of the original ST Huffman Encoding. + * Default value is "false" (do not reverse bits). */ + bool reverseBits; + + /** When false this HuffmanCodec return -1 instead of expanding data during encoding. + * Default value is "true" (allow data expansion). */ + bool expandable; + + /** Determines if this HuffmanCodec owns its Huffman tree nodes. */ + bool huffResourceOwner; + + /** Reverses the order of bits in a byte. + * EG: The statement reverseMap[0xAF] == 0xF5 is true.
+ * The index 10101111 stores the reverse value: 11110101.
+ * Note: One array lookup is much faster than Eight bit manipulating loop iterations. */ + static unsigned char const reverseMap[]; + + /** Number of bits the shortest huffman code in the tree has. */ + int shortestCode; + + public: + + /** Creates a new HuffmanCodec from the Huffman tree data. + * @param treeData pointer to a buffer containing the Huffman tree structure definition. + * @param dataLength length in bytes of the Huffman tree structure data. */ + HuffmanCodec( unsigned char const * const treeData, int dataLength ); + + /** Creates a new HuffmanCodec that uses the specified Huffman resources. + * @param treeRootNode The root node of a valid huffman tree. + * @param leafCodeTable A code lookup table where references to HuffmanNodes are stored with their array index equal to their value. */ + HuffmanCodec( + HuffmanNode * treeRootNode, + HuffmanNode ** leafCodeTable + ); + + /** Frees resources used internally by this HuffmanCodec. */ + ~HuffmanCodec(); + + /** Decodes data read from an input buffer and stores the result in the output buffer. + * @return number of bytes stored in the output buffer or -1 if an error occurs while encoding. */ + virtual int encode( + unsigned char const * const input, /**< in: pointer to the first byte to encode. */ + unsigned char * const output, /**< out: pointer to an output buffer to store data. */ + int const &inLength, /**< in: number of bytes of input buffer to encoded. */ + int const &outLength /**< in: maximum length of data to output. */ + ) const; + + /** Decodes data read from an input buffer and stores the result in the output buffer. + * @return number of bytes stored in the output buffer or -1 if an error occurs while decoding. */ + virtual int decode( + unsigned char const * const input, /**< in: pointer to data that needs decoding. */ + unsigned char * const output, /**< out: pointer to output buffer to store decoded data. */ + int const &inLength, /**< in: number of bytes of input buffer to read. */ + int const &outLength /**< in: maximum length of data to output. */ + ); + + /** Enables or Disables backwards bit ordering of bytes. + * @param backwards "true" enables reversed bit order bytes, "false" uses standard byte bit ordering. */ + void reversedBytes( bool backwards ); + + /** Check the state of backwards bit ordering for bytes. + * @return true: bits within bytes are reversed. false: bits within bytes are normal. */ + bool reversedBytes(); + + /** Enable or Disable data expansion during encoding. + * @param expandable "true" allows encoding to expand data. "false" causes failure upon expansion. */ + void allowExpansion( bool expandable ); + + /** Check the state of data expandability. + * @return true: data expansion is allowed. false: data is not allowed to expand. */ + bool allowExpansion(); + + /** Sets the ownership of this HuffmanCodec's resources. + * @param ownsResources When false the tree will not be released upon destruction of this HuffmanCodec. + * When true deleting this HuffmanCodec will cause the Huffman tree to be released. */ + void huffmanResourceOwner( bool ownsResources ); + + /** Checks the ownership state of this HuffmanCodec's resources. + * @return ownsResources When false the tree will not be released upon destruction of this HuffmanCodec. + * When true deleting this HuffmanCodec will cause the Huffman tree to be released. */ + bool huffmanResourceOwner(); + + /** Deletes all sub nodes of a HuffmanNode by traversing and deleting its child nodes. + * @param treeNode pointer to a HuffmanNode whos children will be deleted. */ + static void deleteTree( HuffmanNode * treeNode ); + + /** Recursively builds a Huffman Tree.
+ * The initial root node should have the following field values:
+ *
+		 * bitCount : 0
+		 * code     : 0
+		 * value    : -1
+		 * branch   : 0 (NULL)
+		 * 
+ * @param node in/out: branch node of the Huffman Tree. + * @param treeData in: char array containing the Huffman Tree's byte representation. + * @param index in: Current array element to read the next tree node from. + * @param codeTable in/out: array of pointers to HuffmanNode structs. + * @param tableLength in: maximum index allowed in the codeTable. + * @return the next index to read from or -1 if an error occurs. + * */ + int buildTree( + HuffmanNode * node, + unsigned char const * const treeData, + int index, + int dataLength, + HuffmanNode ** const &codeTable, + int tableLength + ); + + /** Decreases a codeLength to the shortest Huffman code bit length found in the node or any of its children.
+ * Set to Zero before calling to determine minimum code bit length. + * @param node in: The node to begin searching at. + * @param codeLength out: Variable to hold the longest code bit length found. */ + static void minCodeLength( HuffmanNode const * const node, int &codeLength ); + + /** Increases a codeLength up to the longest Huffman code bit length found in the node or any of its children.
+ * Set to Zero before calling to determine maximum code bit length. + * @param node in: The node to begin searching at. + * @param codeLength out: Variable to hold the longest code bit length found. */ + static void maxCodeLength( HuffmanNode const * const node, int &codeLength ); + + private: + + /** Perform initialization procedures common to all constructors. */ + void init(); + + }; // end class HuffmanCodec +} // end namespace skulltag + +#endif diff --git a/src/plugins/zandronumq/huffman/huffman.cpp b/src/plugins/zandronumq/huffman/huffman.cpp new file mode 100644 index 00000000..21f94daf --- /dev/null +++ b/src/plugins/zandronumq/huffman/huffman.cpp @@ -0,0 +1,155 @@ +/* + * Replacement for older Skulltag Launcher Protocol's huffman.cpp + * + * Copyright 2009 Timothy Landers + * email: code.vortexcortex@gmail.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// required for atexit() +#include + +#include "huffman.h" +#include "huffcodec.h" + +using namespace skulltag; +// Global Variables + +/** Reference to the HuffmanCodec Object that will perform the encoding and decoding. */ +static HuffmanCodec * __codec = 0; + +// Function Implementation + +/** Creates and intitializes a HuffmanCodec Object.
+ * Also arranges for HUFFMAN_Destruct() to be called upon termination. */ +void HUFFMAN_Construct(){ + + // The exact structure description of a Huffman tree + static unsigned char const compatible_huffman_tree[] = { + 0, 0, 0, 1,128, 0, 0, 0, 3, 38, 34, 2, 1, 80, 3,110, + 144, 67, 0, 2, 1, 74, 3,243,142, 37, 2, 3,124, 58,182, 0, + 0, 1, 36, 0, 3,221,131, 3,245,163, 1, 35, 3,113, 85, 0, + 1, 41, 1, 77, 3,199,130, 0, 1,206, 3,185,153, 3, 70,118, + 0, 3, 3, 5, 0, 0, 1, 24, 0, 2, 3,198,190, 63, 2, 3, + 139,186, 75, 0, 1, 44, 2, 3,240,218, 56, 3, 40, 39, 0, 0, + 2, 2, 3,244,247, 81, 65, 0, 3, 9,125, 3, 68, 60, 0, 0, + 1, 25, 3,191,138, 3, 86, 17, 0, 1, 23, 3,220,178, 2, 3, + 165,194, 14, 1, 0, 2, 2, 0, 0, 2, 1,208, 3,150,157,181, + 1,222, 2, 3,216,230,211, 0, 2, 2, 3,252,141, 10, 42, 0, + 2, 3,134,135,104, 1,103, 3,187,225, 95, 32, 0, 0, 0, 0, + 0, 0, 1, 57, 1, 61, 3,183,237, 0, 0, 3,233,234, 3,246, + 203, 2, 3,250,147, 79, 1,129, 0, 1, 7, 3,143,136, 1, 20, + 3,179,148, 0, 0, 0, 3, 28,106, 3,101, 87, 1, 66, 0, 3, + 180,219, 3,227,241, 0, 1, 26, 1,251, 3,229,214, 3, 54, 69, + 0, 0, 0, 0, 0, 3,231,212, 3,156,176, 3, 93, 83, 0, 3, + 96,253, 3, 30, 13, 0, 0, 2, 3,175,254, 94, 3,159, 27, 2, + 1, 8, 3,204,226, 78, 0, 0, 0, 3,107, 88, 1, 31, 3,137, + 169, 2, 2, 3,215,145, 6, 4, 1,127, 0, 1, 99, 3,209,217, + 0, 3,213,238, 3,177,170, 1,132, 0, 0, 0, 2, 3, 22, 12, + 114, 2, 2, 3,158,197, 97, 45, 0, 1, 46, 1,112, 3,174,249, + 0, 3,224,102, 2, 3,171,151,193, 0, 0, 0, 3, 15, 16, 3, + 2,168, 1, 49, 3, 91,146, 0, 1, 48, 3,173, 29, 0, 3, 19, + 126, 3, 92,242, 0, 0, 0, 0, 0, 0, 3,205,192, 2, 3,235, + 149,255, 2, 3,223,184,248, 0, 0, 3,108,236, 3,111, 90, 2, + 3,117,115, 71, 0, 0, 3, 11, 50, 0, 3,188,119, 1,122, 3, + 167,162, 1,160, 1,133, 3,123, 21, 0, 0, 2, 1, 59, 2, 3, + 155,154, 98, 43, 0, 3, 76, 51, 2, 3,201,116, 72, 2, 0, 2, + 3,109,100,121, 2, 3,195,232, 18, 1, 0, 2, 0, 1,164, 2, + 3,120,189, 73, 0, 1,196, 3,239,210, 3, 64, 62, 89, 0, 0, + 1, 33, 2, 3,228,161, 55, 2, 3, 84,152, 47, 0, 0, 2, 3, + 207,172,140, 3, 82,166, 0, 3, 53,105, 1, 52, 3,202,200 + }; + + // create a HuffmanCodec that is compatible with the previous implementation. + __codec = new HuffmanCodec( compatible_huffman_tree, sizeof compatible_huffman_tree ); + + // set up the HuffmanCodec to perform in a backwards compatible fashion. + __codec->reversedBytes( true ); + __codec->allowExpansion( false ); + + // request that the destruct function be called upon exit. + atexit( HUFFMAN_Destruct ); +} + +/** Releases resources allocated by the HuffmanCodec. */ +void HUFFMAN_Destruct(){ + if ( __codec != 0 ) delete __codec; +} + +/** Applies Huffman encoding to a block of data. */ +void HUFFMAN_Encode( + /** in: Pointer to start of data that is to be encoded. */ + unsigned char const * const inputBuffer, + /** out: Pointer to destination buffer where encoded data will be stored. */ + unsigned char * const outputBuffer, + /** in: Number of chars to read from inputBuffer. */ + int const &inputBufferSize, + /**< in+out: Max chars to write into outputBuffer.
+ * Upon return holds the number of chars stored or 0 if an error occurs. */ + int * outputBufferSize +){ + int bytesWritten = __codec->encode( inputBuffer, outputBuffer, inputBufferSize, *outputBufferSize ); + + // expansion occured -- provide backwards compatibility + if ( bytesWritten < 0 ){ + // check buffer sizes + if ( *outputBufferSize < (inputBufferSize + 1) ){ + // outputBuffer too small, return "no bytes written" + *outputBufferSize = 0; + return; + } + + // perform the unencoded copy + for ( int i = 0; i < inputBufferSize; i++ ) outputBuffer[i+1] = inputBuffer[i]; + // supply the "unencoded" signal and bytesWritten + outputBuffer[0] = 0xff; + *outputBufferSize = inputBufferSize + 1; + } else { + // assign the bytesWritten return value + *outputBufferSize = bytesWritten; + } +} // end function HUFFMAN_Encode + +/** Decodes a block of data that is Huffman encoded. */ +void HUFFMAN_Decode( + unsigned char const * const inputBuffer, /**< in: Pointer to start of data that is to be decoded. */ + unsigned char * const outputBuffer, /**< out: Pointer to destination buffer where decoded data will be stored. */ + int const &inputBufferSize, /**< in: Number of chars to read from inputBuffer. */ + int *outputBufferSize /**< in+out: Max chars to write into outputBuffer. Upon return holds the number of chars stored or 0 if an error occurs. */ +){ + // check for "unencoded" signal & provide backwards compatibility + if ((inputBufferSize > 0) && ((inputBuffer[0]&0xff) == 0xff)){ + // check buffer sizes + if ( *outputBufferSize < (inputBufferSize - 1) ){ + // outputBuffer too small, return "no bytes written" + *outputBufferSize = 0; + return; + } + + // perform the unencoded copy + for ( int i = 1; i < inputBufferSize; i++ ) outputBuffer[i-1] = inputBuffer[i]; + + // supply the bytesWritten + *outputBufferSize = inputBufferSize - 1; + } else { + // decode the data + *outputBufferSize = __codec->decode( inputBuffer, outputBuffer, inputBufferSize, *outputBufferSize ); + } +} // end function HUFFMAN_Decode diff --git a/src/plugins/zandronumq/huffman/huffman.h b/src/plugins/zandronumq/huffman/huffman.h new file mode 100644 index 00000000..56e4d883 --- /dev/null +++ b/src/plugins/zandronumq/huffman/huffman.h @@ -0,0 +1,55 @@ +/* + * Replacement for older Skulltag Launcher Protocol's huffman.cpp + * + * Copyright 2009 Timothy Landers + * email: code.vortexcortex@gmail.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +//Macro name kept for backwards compatibility. +#ifndef __HUFFMAN_H__ +#define __HUFFMAN_H__ + +#include "huffcodec.h" + +/** Creates and intitializes a HuffmanCodec Object.
+ * Also arranges for HUFFMAN_Destruct() to be called upon termination. */ +void HUFFMAN_Construct(); + +/** Releases resources allocated by the HuffmanCodec. */ +void HUFFMAN_Destruct(); + +/** Applies Huffman encoding to a block of data. */ +void HUFFMAN_Encode( + unsigned char const * const inputBuffer, /**< in: Pointer to start of data that is to be encoded. */ + unsigned char * const outputBuffer, /**< out: Pointer to destination buffer where encoded data will be stored. */ + int const &inputBufferSize, /**< in: Number of chars to read from inputBuffer. */ + int *outputBufferSize /**< in+out: Max chars to write into outputBuffer. Upon return holds the number of chars stored or 0 if an error occurs. */ +); + +/** Decodes a block of data that is Huffman encoded. */ +void HUFFMAN_Decode( + unsigned char const * const inputBuffer, /**< in: Pointer to start of data that is to be decoded. */ + unsigned char * const outputBuffer, /**< out: Pointer to destination buffer where decoded data will be stored. */ + int const &inputBufferSize, /**< in: Number of chars to read from inputBuffer. */ + int *outputBufferSize /**< in+out: Max chars to write into outputBuffer. Upon return holds the number of chars stored or 0 if an error occurs. */ +); + +#endif // __HUFFMAN_H__ diff --git a/src/plugins/zandronumq/huffmanqt.cpp b/src/plugins/zandronumq/huffmanqt.cpp new file mode 100644 index 00000000..ed1141de --- /dev/null +++ b/src/plugins/zandronumq/huffmanqt.cpp @@ -0,0 +1,61 @@ +//------------------------------------------------------------------------------ +// huffmanqt.cpp +//------------------------------------------------------------------------------ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301 USA +// +//------------------------------------------------------------------------------ +// Copyright (C) 2014 "Zalewa" +//------------------------------------------------------------------------------ +#include "huffmanqt.h" + +#include "huffman/huffman.h" + +QByteArray HuffmanQt::decode(const QByteArray &in) +{ + return decode(in.constData(), in.size()); +} + +QByteArray HuffmanQt::decode(const char *in, int size) +{ + // Below comment is copypasted from Zandronumq's network.cpp: + // + // [BB] Vortex Cortex pointed us to the fact that the smallest huffman code is only 3 bits + // and it turns into 8 bits when it's decompressed. Thus we need to allocate a buffer that + // can hold the biggest possible size we may get after decompressing (aka Huffman decoding). + + int outSize = ((size * 8) / 3) + 1; // compressed/decompressed = 3/8 + auto out = new unsigned char[outSize]; + HUFFMAN_Decode(reinterpret_cast(in), out, size, &outSize); + QByteArray result(reinterpret_cast(out), outSize); + delete [] out; + return result; +} + +QByteArray HuffmanQt::encode(const QByteArray &in) +{ + return encode(in.constData(), in.size()); +} + +QByteArray HuffmanQt::encode(const char *in, int size) +{ + int outSize = size + 1; + auto out = new unsigned char[outSize]; + HUFFMAN_Encode(reinterpret_cast(in), out, size, &outSize); + QByteArray result(reinterpret_cast(out), outSize); + delete [] out; + return result; +} diff --git a/src/plugins/zandronumq/huffmanqt.h b/src/plugins/zandronumq/huffmanqt.h new file mode 100644 index 00000000..df8be93b --- /dev/null +++ b/src/plugins/zandronumq/huffmanqt.h @@ -0,0 +1,37 @@ +//------------------------------------------------------------------------------ +// huffmanqt.h +//------------------------------------------------------------------------------ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301 USA +// +//------------------------------------------------------------------------------ +// Copyright (C) 2014 "Zalewa" +//------------------------------------------------------------------------------ +#ifndef id1c3588fd_6e92_42a0_8128_4daabe456f30 +#define id1c3588fd_6e92_42a0_8128_4daabe456f30 + +#include + +class HuffmanQt +{ +public: + static QByteArray decode(const QByteArray &in); + static QByteArray decode(const char *in, int size); + static QByteArray encode(const QByteArray &in); + static QByteArray encode(const char *in, int size); +}; + +#endif diff --git a/src/plugins/zandronumq/huffmanudpsocket.cpp b/src/plugins/zandronumq/huffmanudpsocket.cpp new file mode 100644 index 00000000..133f2e1f --- /dev/null +++ b/src/plugins/zandronumq/huffmanudpsocket.cpp @@ -0,0 +1,86 @@ +//------------------------------------------------------------------------------ +// huffmanudpsocket.cpp +//------------------------------------------------------------------------------ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301 USA +// +//------------------------------------------------------------------------------ +// Copyright (C) 2014 "Zalewa" +//------------------------------------------------------------------------------ +#include "huffmanudpsocket.h" + +#include "huffmanqt.h" +#include + +class HuffmanUdpSocket::PrivData +{ +public: + QUdpSocket *socket; +}; + + +HuffmanUdpSocket::HuffmanUdpSocket(QUdpSocket *socket) +{ + d = new PrivData(); + d->socket = socket; +} + +HuffmanUdpSocket::~HuffmanUdpSocket() +{ + delete d; +} + +bool HuffmanUdpSocket::hasPendingDatagrams() const +{ + assert(!isNull()); + return d->socket->hasPendingDatagrams(); +} + +bool HuffmanUdpSocket::isNull() const +{ + return d->socket == nullptr; +} + +QByteArray HuffmanUdpSocket::readDatagram(QHostAddress *address, quint16 *port) +{ + assert(!isNull()); + qint64 size = d->socket->pendingDatagramSize(); + char *data = new char[size]; + d->socket->readDatagram(data, size, address, port); + QByteArray decoded = HuffmanQt::decode(data, size); + delete [] data; + return decoded; +} + +void HuffmanUdpSocket::setSocket(QUdpSocket *socket) +{ + d->socket = socket; +} + +bool HuffmanUdpSocket::writeDatagram(const QByteArray &datagram, + const QHostAddress &host, quint16 port) +{ + assert(!isNull()); + QByteArray encoded = HuffmanQt::encode(datagram); + qint64 written = d->socket->writeDatagram(encoded, host, port); + return written == datagram.size(); +} + +bool HuffmanUdpSocket::writeDatagram(const char *data, int size, + const QHostAddress &host, quint16 port) +{ + return writeDatagram(QByteArray(data, size), host, port); +} diff --git a/src/plugins/zandronumq/huffmanudpsocket.h b/src/plugins/zandronumq/huffmanudpsocket.h new file mode 100644 index 00000000..a8c947e0 --- /dev/null +++ b/src/plugins/zandronumq/huffmanudpsocket.h @@ -0,0 +1,48 @@ +//------------------------------------------------------------------------------ +// huffmanudpsocket.h +//------------------------------------------------------------------------------ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301 USA +// +//------------------------------------------------------------------------------ +// Copyright (C) 2014 "Zalewa" +//------------------------------------------------------------------------------ +#ifndef id4301ca8a_c4db_48b7_860b_f1299bd1ff2a +#define id4301ca8a_c4db_48b7_860b_f1299bd1ff2a + +#include +#include +#include + +class HuffmanUdpSocket +{ +public: + HuffmanUdpSocket(QUdpSocket *socket = nullptr); + ~HuffmanUdpSocket(); + + bool hasPendingDatagrams() const; + bool isNull() const; + QByteArray readDatagram(QHostAddress *address = nullptr, quint16 *port = nullptr); + void setSocket(QUdpSocket *socket); + bool writeDatagram(const QByteArray &datagram, const QHostAddress &host, quint16 port); + bool writeDatagram(const char *data, int size, const QHostAddress &host, quint16 port); + +private: + class PrivData; + PrivData *d; +}; + +#endif diff --git a/src/plugins/zandronumq/translations/zandronumq_ca_ES.ts b/src/plugins/zandronumq/translations/zandronumq_ca_ES.ts new file mode 100644 index 00000000..b58c225e --- /dev/null +++ b/src/plugins/zandronumq/translations/zandronumq_ca_ES.ts @@ -0,0 +1,2969 @@ + + + + + EngineZandronumqConfigBox + + + Testing Releases + Versions de prova + + + + Directory for testing releases: + Directori per a les versions de prova: + + + + Doomseeker - choose Zandronumq testing directory + Doomseeker - triï el directori de proves de Zandronumq + + + + FlagsPage + + + Zandronumq + + + + + Zandronumq 3 + + + + + Zandronumq 2 (old) + Zandronumq 2 (vell) + + + + None + Res + + + + Old (ZDoom) + Vell (ZDoom) + + + + Hexen + + + + + Strife + + + + + Default + Per defecte + + + + No + + + + + Yes + Si + + + + Unknown Zandronumq version in the config. Reverting to default. + Versió desconeguda de Zandronumq en la configuració. Es reverteix a predeterminat. + + + + Tried to set unknown Zandronumq version. Reverting to default. + S'ha intentat establir una versió desconeguda de Zandronumq. Revertint a la predeterminada. + + + + Form + Formulari + + + + Game version: + Versió del joc: + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">If this is checked then Zandronumq may override some of the settings selected here.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">(+sv_defaultdmflags)</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Si això està marcat, llavors Zandronumq pot anul·lar algunes de les configuracions seleccionades aquí.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">(+sv_defaultdmflags)</span></p></body></html> + + + + Default DMFlags + DMFlags Per omissió + + + + + Environment + Entorn + + + + Falling damage: + Dany de caiguda: + + + + No monsters + Sense monstres + + + + Items respawn + Els articles reapareixen + + + + Barrels respawn + Els barrils reapareixen + + + + Respawn invulnerability and invisibility spheres. + Fer reaparèixer les esferes de invulnerabilitat i invisibilitat. + + + + Mega powerups respawn + Mega potenciadors reapareixen + + + + Teams + Equips + + + + Server picks teams + El servidor tria equips + + + + Players can't switch teams + Els jugadors no poden canviar d'equip + + + + Keep teams after a map change + Mantenir equips després d'un canvi de mapa + + + + Hide allies on the automap + Amaga aliats al Automap + + + + Don't let players spy on allies + No permetre que els jugadors espiïn als seus aliats + + + + Instant flag/skull return + Retorn de bandera/calavera instantani + + + + Don't use ping-based backwards reconciliation for player-fired hitscans and rails. + No utilitzar reconciliació cap enrere basada en ping per hitscans i rails disparats per jugadors. + + + + No unlagged + Sense unlagged + + + + Apply lmsspectatorsettings in all game modes. + Aplicar lmsspectatorsettings en tots els modes de joc. + + + + Always apply LMS spectator settings + Sempre aplica la configuració d'espectador LMS + + + + Enforces clients not to show medals, i.e. behave as if cl_medals == 0. + Obliga els clients a no mostrar medalles, és a dir, comportar-se com si cl_medals == 0. + + + + No medals + Sense medalles + + + + General + + + + + Disallow + No permetre + + + + Suicide + Suïcidi + + + + Respawn + Reaparèixer + + + + <html><head/><body><p align="justify">P_RadiusAttack doesn't give players any z-momentum if the attack was made by a player. This essentially disables rocket jumping.</p></body></html> + <html><head/><body><p align="justify">P_RadiusAttack no dóna als jugadors cap z-momentum si l'atac s'ha fet per un jugador. Això essencialment desactiva el salt de coet.</p></body></html> + + + + Rocket jump + Salt de coet + + + + Taunt + Burlar-se + + + + Item drop + Deixar anar objecte + + + + Use automap + Utilitzar Automap + + + + Turn off translucency + Desactiva la translucidesa + + + + Use crosshairs + Utilitza punts de mira + + + + Use custom GL lighting settings + Utilitza configuracions d'il·luminació GL personalitzades + + + + Enforces clients not to identify players, i.e. behave as if cl_identifytarget == 0. + Obliga els clients a no identificar jugadors, és a dir, comportar-se com si cl_identifytarget == 0. + + + + Target identify + Identificar objectiu + + + + Enforces clients not to draw coop info, i.e. behave as if cl_drawcoopinfo == 0. + Obliga els clients a no dibuixar la informació del cooperatiu, és a dir, comportar-se com si cl_drawcoopinfo == 0. + + + + Display coop info + Mostra informació cooperatiu + + + + Use autoaim + Usa autoapuntat + + + + Only let the arbitrator set FOV (for all players) + Només deixeu que l'àrbitre estableixi el FOV (per a tots els jugadors) + + + + Use FOV + Utilitza FOV + + + + Use freelook + Utilitza càmera lliure + + + + <html><head/><body><p>Players are not allowed to use the land CCMD. Because of Zandronumq's default amount of air control, flying players can get a huge speed boast with the land CCMD. Disallowing players to land, allows to keep the default air control most people are used to while not giving flying players too much of an advantage.</p></body></html> + <html><head/><body><p>Els jugadors no poden usar el CCMD terrestre. A causa de la quantitat predeterminada de control en aire de Zandronumq, els jugadors que volen poden arribar a una gran velocitat amb el CCMD terrestre. Impedint que els jugadors aterrin, permet mantenir el control d'aire predeterminat al qual la majoria de la gent està acostumada, mentre que no els dóna massa avantatge als jugadors que volen.</p></body></html> + + + + Use 'land' console command + Utilitza la comanda de consola 'land' + + + + <html><head/><body><p>Don't allow players to change how strongly will their screen flash when they get hit.</p></body></html> + <html><head/><body><p>No permetre que els jugadors canviïn la intensitat del flaix quan reben un cop.</p></body></html> + + + + Change bloodied screen brightness + Canviar la brillantor de la pantalla ensagnada + + + + Abilities + Habilitats + + + + Jumping: + Saltar: + + + + Crouching: + Ajupir-se: + + + + Infinite inventory + Inventari infinit + + + + Infinite ammo + Munició infinita + + + + Like Quake 3 + Com Quake 3 + + + + Slowly lose health when over 100% + Perdre lentament la salut per sobre del 100% + + + + Can use chasecam + Pot usar la càmera de persecució + + + + Allow BFG freeaiming + Permet apuntat lliure de la BFG + + + + Behavior + Comportament + + + + Players can walk through each other + Els jugadors poden caminar entre ells + + + + Allies can walk through each other + Els aliats poden travessar-se entre si + + + + Players block each other normally + Els jugadors es bloquegen entre ells + + + + Don't check ammo when switching weapons + No comprovar munició quan es canvia d'armes + + + + Force inactive players to spectate after: + Força als jugadors inactius al mode espectador després: + + + + min. + + + + + Players + Jugadors + + + + Score damage, not kills + Puntua el mal, no els assassinats + + + + Don't spawn Deathmatch weapons + No fer aparèixer armes de Deathmatch + + + + Spawn map actors in coop as if the game was single player. + Fer aparèixer a actors del mapa en cooperatiu com si el joc fós d'un sol jugador. + + + + Don't spawn any multiplayer actor in coop + No generis cap actor multijugador en el cooperatiu + + + + Monsters... + Monstres... + + + + are fast (like Nightmare) + són ràpids (com en Nightmare) + + + + respawn (like Nightmare) + reapareixen (com en Nightmare) + + + + must be killed to enable exit + han de ser assassinats per poder sortir + + + + Kill percentage: + Percentatge d'assassinats: + + + + Multiplier of damage dealt by monsters. + Multiplicador del dany infligit pels monstres. + + + + Damage factor: + Factor de Dany: + + + + <html><body><p>Multiplier of damage dealt by monsters.</p></body></html> + <html><body><p>Multiplicador del dany infligit pels monstres.</p></body></html> + + + + Kill all monsters spawned by a boss cube when the boss dies + Mata a tots els monstres generats per un cub de "boss" quan el "boss" mor + + + + On player death... + Quant el jugador mor... + + + + Respawn where died + Reaparèixer on ha mort + + + + Lose all inventory + Perdre tot l'inventari + + + + Lose armor + Perdre armadura + + + + Lose keys + Perdre claus + + + + Lose powerups + Perdre potenciadors + + + + Lose weapons + Perdre armes + + + + Lose all ammo + Perdre tota la munició + + + + Lose half ammo + Perdre la meitat de la munició + + + + <html><head/><body><p>Affects game modes where &quot;max. lives&quot; can be used. If set, players who become dead spectators (run out of lives) will still keep inventory in accordance to the &quot;Lose *&quot; flags above. If unset, players who lose all lives will always lose entire inventory.</p></body></html> + <html><head/><body><p>Afecta les maneres de joc on &quot;max. vides&quot; pot ser usat. Si s'estableix, els jugadors que es converteixin en espectadors morts (es quedin sense vida) seguiran mantenint l'inventari d'acord amb &quot;Perdre *&quot; indicadors amunt. Si no s'estableix, els jugadors que perdin totes les vides perdran sempre l'inventari complet.</p></body></html> + + + + Players who lose all lives can keep inventory + Els jugadors que perdin totes les vides poden conservar l'inventari + + + + Share keys between players + Compartir claus entre jugadors + + + + <html><head/><body><p>Players will be respawned with full lives but the map will not be reset. Inventory will be preserved in accordance to &quot;Lose inventory&quot; flags. Players will be able to continue from the point where they died.</p></body></html> + <html><head/><body><p>Els jugadors seran reapareguts amb vides completes però el mapa no es reiniciarà. L'inventari es conservarà d'acord amb els indicadors de &quot;Perdre inventari&quot;. Els jugadors podran continuar des del punt on van morir.</p></body></html> + + + + Survival only: no map reset when all players die + Només supervivència: no es restableix el mapa quan tots els jugadors moren + + + + Cooperative + Cooperatiu + + + + When players die, they... + Quan els jugadors moren, ells... + + + + Respawn automatically + Reaparèixer automàticament + + + + Drop their weapon + Deixar anar l'arma + + + + Respawn farthest away from others + Reaparèixer el més lluny possible dels altres + + + + Lose a frag + Perdre un frag + + + + Respawn with a shotgun + Reaparèixer amb una escopeta + + + + Don't get respawn protection + No obtenir protecció de reaparició + + + + When someone exits the level... + Quan algú surt del nivell ... + + + + Continue to the next map + Continuar al següent mapa + + + + Restart the current level + Reiniciar el nivell actual + + + + Kill the player + Mata al jugador + + + + Keep frags after map change + Mantenir frags després del canvi de mapa + + + + Weapons && Ammo + Armes i munició + + + + Weapons stay after pickup + Les armes romanen després de recollir-les + + + + Double ammo + Doble munició + + + + Don't spawn... + No fer aparèixer... + + + + Health + Salut + + + + Armor + Armadura + + + + Runes + Runes + + + + Deathmatch + Combat a mort + + + + Weapons + Armes + + + + Chainsaw + Serra mecànica + + + + Pistol + Pistola + + + + Shotgun + Escopeta + + + + Super shotgun + Súper escopeta + + + + Chaingun + Metralladora + + + + Minigun + + + + + Rocket launcher + Llançacoets + + + + Grenade launcher + Llançagranades + + + + Plasma rifle + Rifle de plasma + + + + Railgun + + + + + lmsallowedweapons: + + + + + + + + + + + + 0 + + + + + lmsspectatorsettings: + + + + + Spectators can... + Els espectadors poden... + + + + Talk to active players + Parlar amb jugadors actius + + + + View the game + Veure el joc + + + + LMS + + + + + Enable buggier wall clipping so players can wallrun. + Habilitar un atravessament de paret pitjor perquè els jugadors puguin fer wallrun. + + + + Enable wall running + Activa wall running + + + + Pickups are only heard locally. + Les recollides d'objectes només s'escolten localment. + + + + Don't let others hear pickups + No deixis que altres sentin la recollida d'objectes + + + + Allow instant respawn + Permetre reaparició instantània + + + + <html><head/><body><p>Disable stealth monsters, since doom2.exe didn't have them.</p><p><span style=" font-weight:600;">Note: this handles ZDoom's invisible monsters.</span></p><p><span style=" font-weight:600;">THIS DOESN'T AFFECT THE PARTIAL INVISIBILITY SPHERE IN ANY WAY. See &quot;Monsters see semi-invisible players&quot; for that.</span></p></body></html> + <html><head/><body><p>Deshabilita els monstres silenciosos, ja que doom2.exe no els tenia.</p><p><span style=" font-weight:600;">Nota: això fa anar els monstres invisibles de ZDoom.</span></p><p><span style=" font-weight:600;">AIXÒ NO AFECTA L'ESFERA DE INVISIBILITAT PARCIAL DE QUALSEVOL FORMA. Veure &quot;Els monstres veuen jugadors semiinvisibles&quot; per això.</span></p></body></html> + + + + Disable stealth monsters + Deshabilitar monstres silenciosos + + + + Limit actors to one sound at a time. + Limitar els actors a un so alhora. + + + + Allow silent BFG trick + Permetre el truc de l'BFG silenciós + + + + Clients use the vanilla Doom weapon on pickup behavior. + Els clients usen el comportament original de Doom en recollir d'armes. + + + + Original weapon switch + Canvi d'armes original + + + + Limited movement in the air + Moviment limitat en l'aire + + + + This affects the partial invisibility sphere. + Això afecta l'esfera d'invisibilitat parcial. + + + + Monsters see semi-invisible players + Els monstres veuen els jugadors semi-invisibles + + + + Allow the map01 "plasma bump" bug. + Permetre error "plasma bump" al map01. + + + + Plasma bump bug + Error plasma bump + + + + Any boss death activates map specials + Qualsevol mort de "Boss" activa especials del mapa + + + + Friction/pushers/pullers affect Monsters + Fricció/empentes/estrebades afecten els monstres + + + + <html><head/><body><p>Crushed monsters are turned into gibs, rather than replaced by gibs.</p></body></html> + <html><head/><body><p>Els monstres aixafats esdevenen vísceres, en lloc de ser reemplaçats per aquestes.</p></body></html> + + + + Crusher gibs by morphing, not replacement + Aixafar transforma en vísceres, en lloc de reemplaçar per aquestes + + + + Block monster lines ignore friendly monsters + Les línies de bloqueig de monstres ignoren els monstres amistosos + + + + Find neighboring light level like Doom + Trobar el nivell de llum proper com en Doom + + + + Use doom2.exe's original intermission screens/music. + Utilitza la pantalla/música originals de l'intermedi de missió de doom2.exe. + + + + Use old intermission screens/music + Utilitza pantalla/música d'intermedi de missió antigues + + + + Scrolling sectors are additive like in Boom. + Els sectors de desplaçament són additius com en Boom. + + + + Scrolling sectors are additive + Els sectors de desplaçament són additius + + + + Sector sounds use original method for sound origin. + Els sons del sector usen el mètode original per a l'origen del so. + + + + Sector sounds use original method + Els sons del sector fan servir el mètode original + + + + Monsters cannot move when hanging over a dropoff. + Els monstres no es poden moure quan estan sobre un abisme. + + + + No monsters dropoff move + Sense monstres moure en abisme + + + + Instantly moving floors are not silent. + Els pisos que es mouen a l'instant no són silenciosos. + + + + Instantly moving floors aren't silent + Els pisos que es mouen a l'instant no són silenciosos + + + + <html><head/><body><p>Clients send ucmd.buttons as &quot;long&quot; instead of as &quot;byte&quot; in CLIENTCOMMANDS_ClientMove. So far this is only necessary if the ACS function GetPlayerInput is used in a server side script to check for buttons bigger than BT_ZOOM. Otherwise this information is completely useless for the server and the additional net traffic to send it should be avoided.</p></body></html> + <html><head/><body><p>Els clients envien ucmd.buttons com &quot;long&quot; en lloc de com &quot;byte&quot; en CLIENTCOMMANDS_ClientMove. Fins ara, això només és necessari si la funció ACS GetPlayerInput s'utilitza en un script del costat del servidor per buscar botons més grans que BT_ZOOM. Altrament, aquesta informació és completament inútil per al servidor i s'ha d'evitar el tràfic de xarxa addicional per a enviar-lo.</p></body></html> + + + + Clients send full button info + Els clients envien tota la informació sobre els botons + + + + <html><head/><body><p>Use Doom's random table instead of ZDoom's random number generator. Affects weapon damage among other things.</p></body></html> + <html><head/><body><p>Utilitza la taula aleatòria de Doom en lloc del generador de nombres aleatoris de ZDoom. Afecta el dany de les armes entre altres coses.</p></body></html> + + + + Old random number generator + Antic generador de nombres aleatoris + + + + Monsters can't be pushed off cliffs + Els monstres no poden ser empesos a abismes + + + + Old damage radius (infinite height) + Ràdio de dany antic (alçada infinita) + + + + Minotaur's floor flame explodes immediately when feet are clipped + El foc del sòl del minotaure explota immediatament quan els peus el travessen + + + + Original velocity calc. for A_Mushroom in Dehacked + Càlcul de velocitat original per A_Mushroom a Dehacked + + + + Sprite sort order inverted for sprites of equal distance + Ordre de Sprites invertit per sprites en la mateixa distància + + + + Hitscans use original blockmap and hit check code + Els Hitscans usen el mapa de blocs original i el codi de verificació d'impacte + + + + Draw polyobjects the old fashioned way + Dibuixar poliobjectes com als bons (i antics) temps + + + + Compatibility + Compatibilitat + + + + Use original missile clipping height + Utilitzar l'alçada original d'atravessament dels míssils + + + + Use sector based sound target code + Utilitza codi de so objectiu basat en sectors + + + + <html><head/><body><p>Doom's hitscan tracing code ignores all lines with both sides in the same sector. ZDoom's does not. This option reverts to the original but less precise behavior. </p></body></html> + <html><head/><body><p>El codi d'escaneig d'impactes de Doom ignora totes les línies amb banda i banda en el mateix sector. ZDoom no. Aquesta opció reverteix al comportament original però és menys precís. </p></body></html> + + + + Trace ignore lines w/ same sector on both sides + El traç ignora les línies amb el mateix sector a banda i banda + + + + Limit deh.MaxHealth to health bonus + Limitar deh.MaxHealth a la bonificació de salut + + + + <html><head/><body><p>The scrolling floor specials in Heretic and Hexen move the player much faster than the actual texture scrolling speed. Enable this option to restore this effect. </p></body></html> + <html><head/><body><p>Els desplaçaments especials del sòl en Heretic i Hexen mouen al jugador molt més ràpid que la velocitat de desplaçament de la textura real. Habilita aquesta opció per restaurar aquest efecte.</p></body></html> + + + + Raven's scrollers use original speed + Els scrollers de Raven fan servir la seva velocitat original + + + + <html><head/><body><p>Add NOGRAVITY to actors named InvulnerabilitySphere, Soulsphere, Megasphere and BlurSphere when spawned by the map.</p></body></html> + <html><head/><body><p>Afegiu NOGRAVITY als actors anomenats InvulnerabilitySphere, Soulsphere, Megasphere i BlurSphere quan apareixen pel mapa.</p></body></html> + + + + Add NOGRAVITY flag to spheres + Afegir l'indicador NOGRAVITY a les esferes + + + + <html><head/><body><p>When a player leaves the game, don't stop any scripts of that player that are still running.</p></body></html> + <html><head/><body><p>Quan un jugador abandona el joc, no aturar cap script que aquest jugador encara estigui executant.</p></body></html> + + + + Don't stop player scripts on disconnect + No aturar els scripts dels jugadors al desconnectar + + + + <html><head/><body><p>If this is enabled, explosions cause a strong horizontal thrust like in old ZDoom versions.</p></body></html> + <html><head/><body><p>Si això està habilitat, les explosions causen una forta empenta horitzontal com en versions antigues de ZDoom.</p></body></html> + + + + Old ZDoom horizontal thrust + Empenta horitzontal de l'antic ZDoom + + + + <html><head/><body><p>If this is enabled, non-SOLID things like flags fall through bridges (as they used to do in old ZDoom versions).</p></body></html> + + <html><head/><body><p>Si això està habilitat, elements no SÒLIDS com banderes cauen a través de ponts (com solien fer en versions antigues de ZDoom).</p></body></html> + + + + + Old ZDoom bridge drops + Caigudes de pont de l'antic ZDoom + + + + <html><head/><body><p>Uses old ZDoom jump physics, it's a minor bug in the gravity code that causes gravity application in the wrong place.</p></body></html> + <html><head/><body><p>Fes servir l'antiga física de salt ZDoom, és un error menor en el codi de gravetat que causa l'aplicació de la gravetat en el lloc equivocat.</p></body></html> + + + + ZDoom 1.23B33 jump physics + Físiques de salt de ZDoom 1.23B33 + + + + <html><head/><p>Zandronumq uses more tracers to fill in the gaps, this reverts it to vanilla's 3 tracer behavior</p></body></html> + <html><head/><p>Zandronumq fa servir més traçadors per omplir els buits, això ho reverteix al comportament original de 3 traçadors</p></body></html> + + + + Use vanilla autoaim tracer behavior + Utilitza el comportament del traçador d'autoapuntat original + + + + Ignore compositing when drawing masked midtextures + Ignorar la composició mentre es dibuixa textures mitjanes emmascarades + + + + It is impossible to face directly NSEW + És impossible mirar directament a l'adreça cardinal + + + + <html><head/><body><p>Use Doom's shortest texture find behavior. This is requied by some WADs in MAP07.</p></body></html> + <html><head/><body><p>Utilitza el comportament de recerca de textura més curta de Doom. Això és requerit per alguns WADs a MAP07.</p></body></html> + + + + Find shortest textures like Doom + Troba les textures més curtes com en Doom + + + + Limit pain elementals to 20 lost souls + Limitar els elementals de dolor a 20 ànimes perdudes + + + + Spawned item drops on the floor + L'element generat cau a terra + + + + <html><head/><body><p>Treat ACS scripts with the SCRIPTF_Net flag to be client side, i.e. executed on the clients, but not on the server.</p></body></html> + <html><head/><body><p>Tractar els scripts ACS amb l'indicador SCRIPTF_Net perquè s'executin en el costat del client, és a dir, executats en els clients, però no al servidor.</p></body></html> + + + + NET scripts are clientside + Els scripts NET són del costat del client + + + + Actors are infinitely tall + Els actors són infinitament alts + + + + Don't fix loop index for stair building. + No arreglar l'índex del bucle per construir escales. + + + + Use buggier stair building + Utilitza un constructor d'escales amb més errors + + + + Disable Boom door light effect + Deshabilitar l'efecte de llum de porta BOOM + + + + All special lines can drop use lines + Totes les línies especials poden deixar anar línies d'ús + + + + Original sound curve + Corba de so original + + + + Disallow weapon change until fully drawn or hidden + No permetre el canvi d'arma fins que estigui completament dibuixat o ocult + + + + West spawns are silent + Les aparicions "West" són silencioses + + + + Use the same floor motion behavior as Doom + Utilitza el comportament de moviment del pis com a Doom + + + + Compatibility 2 + Compatibilitat 2 + + + + Voting + Votacions + + + + zandronumq dmflags + + + + + dmflags + + + + + dmflags2 + + + + + zandronumq compatflags + + + + + compatflags + + + + + compatflags2 + + + + + QObject + + + Time limit: + Límit de temps: + + + + Frag limit: + Límit de frags: + + + + Point limit: + Límit de punts: + + + + Win limit: + Límit de victòries: + + + + Duel limit: + Límit de duels: + + + + Max. lives: + Max. vides: + + + + << Unknown >> + << Desconegut >> + + + + TestingProgressDialog + + + Downloading testing binaries... + Descarregant arxius binaris de prova ... + + + + Cancel + Cancel·lar + + + + VotingSetupWidget + + + Form + Formulari + + + + Use this page + Utilitzeu aquesta pàgina + + + + Who can vote + Qui pot votar + + + + All can vote + Tots poden votar + + + + No one can vote + Ningú pot votar + + + + Spectators can't vote + Els espectadors no poden votar + + + + Minimum number of players required to call a vote: + Nombre mínim de jugadors necessaris per a sol·licitar una votació: + + + + Allow specific votes + Permetre vots específics + + + + duellimit + límit de duel + + + + pointlimit + límit de punts + + + + timelimit + límit de temps + + + + winlimit + límit de victòries + + + + changemap + Canviar mapa + + + + kick + expulsar + + + + map + mapa + + + + fraglimit + límit de frags + + + + force players to spectate + obligar els jugadors al mode espectador + + + + Vote flooding protection enabled + Protecció contra inundacions de vots habilitada + + + + Zandronumq2::Dmflags + + + Use Doom's shortest texture behavior + Utilitza el comportament de textura més ràpid de Doom + + + + Don't fix loop index for stair building + No arreglar l'índex del bucle per a la construcció d'escales + + + + Pain elemental is limited to 20 lost souls + Pain elemental està limitat a 20 ànimes perdudes + + + + Pickups are only heard locally + Recollir articles només es poden escoltar localment + + + + Infinitely tall actors + Actors infinitament alts + + + + Limit actors to only one sound + Limitar els actors a un sol so + + + + Enable wallrunning + Habilitar wallrunning + + + + Dropped items spawn on floor + Els objectes deixats anar apareixen a terra + + + + Special lines block use line + Línies especials bloquegen l'ús de línies + + + + Disable BOOM local door light effect + Deshabilitar l'efecte de llum de porta local BOOM + + + + Raven's scrollers use their original speed + Els scrollers de Raven fan servir la seva velocitat original + + + + Use sector based sound target code + Utilitza codi de so objectiu basat en sectors + + + + Limit dehacked MaxHealth to health bonus + Limitar dehacked MaxHealth a la bonificació de vida + + + + Trace ignores lines with the same sector on both sides + El tracer ignora les línies amb el mateix sector a banda i banda + + + + Monsters can not move when hanging over a drop off + Els monstres no es poden moure quan estan sobre un abisme + + + + Scrolling sectors are additive like Boom + Els sectors de desplaçament són additius com Boom + + + + Monsters can see semi-invisible players + Els monstres poden veure jugadors semi-invisibles + + + + Instantly moving floors are not silent + Els pisos que es mouen a l'instant no dir res + + + + Sector sounds use original method for sound origin + Els sons de sector usen el mètode original per a l'origen del so + + + + Use original Doom heights for clipping against projectiles + Utilitzar altures originals de Doom durant una col·lisió amb míssils + + + + Monsters can't be pushed over dropoffs + Els monstres no poden ser empesos a abismes + + + + Any monster which calls BOSSDEATH counts for level specials + Qualsevol monstre que truqui a BOSSDEATH compten per a nivells especials + + + + Minotaur's floor flame is exploded immediately when feet are clipped + El foc del sòl del minotaure explota immediatament quan els peus el travessen + + + + Force original velocity calculations for A_Mushroom in Dehacked mods + Forçar càlculs de velocitat originals per A_Mushroom a mods Dehacked + + + + Monsters are affected by friction and pushers/pullers + Els monstres es veuen afectats per la fricció i empentes/estrebades + + + + Crushed monsters are turned into gibs, rather than replaced by gibs + Els monstres aixafats esdevenen vísceres, en lloc de ser reemplaçats per aquestes + + + + Friendly monsters aren't blocked by monster-blocking lines + Els monstres amistosos ignoren les línies de bloqueig de monstres + + + + Invert sprite sorting order for sprites of equal distance + Invertir ordre de classificació de sprites per sprites d'igual distància + + + + Hitscans use original blockmap and hit check code + Els Hitscans usen el mapa de blocs original i el codi de verificació d'impacte + + + + Find neighboring light level like like Doom + Busqui el nivell de llum veïna com en Doom + + + + Draw polyobjects the old fashioned way + Dibuixar poliobjectes com als bons (i antics) temps + + + + Net scripts are client side + Els scripts NET s'executen en el client + + + + Clients send full button info + Els clients envien tota la informació sobre els botons + + + + Players can't use 'land' CCMD + Els jugadors no poden usar el comandament 'land' + + + + Use Doom's original random number generator + Utilitzar el generador de xifres aleatòries original de Doom + + + + Spheres have NOGRAVITY flag + Les esferes tenen l'indicador NOGRAVITY + + + + Don't stop player scripts on disconnect + No aturar els scripts dels jugadors al desconnectar + + + + Use horizontal explosion thrust of old ZDoom versions + Utilitzar l'empenta d'explosió horitzontal de versions antigues de ZDoom + + + + Non-SOLID things fall through invisible bridges + Coses no sòlides cauen a través de ponts invisibles + + + + Use old ZDoom jump physics + Fes servir físiques velles de salt de ZDoom + + + + Disallow weapon change when in mid raise/lower + No permetre el canvi d'arma quan està a mig pujar/baixar + + + + Use vanilla's autoaim tracer behavior + Utilitzar el comportament de autoapuntat original + + + + West spawns are silent + Les aparicions "West" són silencioses + + + + Limited movement in the air + Moviment limitat en l'aire + + + + Allow map01 "plasma bump" bug + Permetre error "plasma bump" al map01 + + + + Allow instant respawn after death + Permetre reaparició instantània després de morir + + + + Disable taunting + Desactivar burles + + + + Use doom2.exe's original sound curve + Utilitza la corba sonora original de doom2.exe + + + + Use original doom2 intermission music + Utilitzar la música original d'intermedi de doom2 + + + + Disable stealth monsters + Deshabilitar monstres silenciosos + + + + Radius damage has infinite height + El radi de dany té una alçada infinita + + + + Disable crosshair + Desactivar espiell + + + + Force weapon switch + Forçar el canvi d'arma + + + + Do not spawn health items (DM) + No fer aparèixer ítems de salut (DM) + + + + Do not spawn powerups (DM) + No fer aparèixer potenciadors (DM) + + + + Weapons remain after pickup (DM) + Les armes romanen després de recollir-les (DM) + + + + Falling damage (old ZDoom) + Dany de caiguda (antic ZDoom) + + + + Falling damage (Hexen) + Dany de caiguda (Hexen) + + + + Falling damage (Strife) + Dany de caiguda (Strife) + + + + Stay on same map when someone exits (DM) + Romandre al mapa quan algú ho acabi (DM) + + + + Spawn players as far as possible (DM) + Fer aparèixer els jugadors el més lluny possible (DM) + + + + Automatically respawn dead players (DM) + Reaparició automàtica de jugadors morts (DM) + + + + Don't spawn armor (DM) + No fer aparèixer armadura (DM) + + + + Kill anyone who tries to exit the level (DM) + Mata a qualsevol que intenti acabar el nivell (DM) + + + + Infinite ammo + Munició infinita + + + + No monsters + Sense monstres + + + + Monsters respawn + Els monstres reapareixen + + + + Items other than invuln. and invis. respawn + Els objectes (a excepció d'invulnerabilitat i invisibilitat) reapareixen + + + + Fast monsters + Monstres ràpids + + + + No jumping + No salts + + + + No freelook + No càmera lliure + + + + Respawn invulnerability and invisibility + Reaparició d'invulnerabilitat i invisibilitat + + + + Arbitrator FOV + FOV preestablert + + + + No multiplayer weapons in cooperative + Sense armes multijugador en cooperatiu + + + + No crouching + Sense ajupir-se + + + + Lose all old inventory on respawn (COOP) + Perdre tot l'inventari al reaparèixer (COOP) + + + + Lose keys on respawn (COOP) + Perdre claus en reaparèixer (COOP) + + + + Lose weapons on respawn (COOP) + Perdre armes en reaparèixer (COOP) + + + + Lose armor on respawn (COOP) + Perdre armadura a reaparèixer (COOP) + + + + Lose powerups on respawn (COOP) + Perdre potenciadors en reaparèixer (COOP) + + + + Lose ammo on respawn (COOP) + Perdre munició en reaparèixer (COOP) + + + + Lose half your ammo on respawn (COOP) + Perdre la meitat de la munició al reaparèixer (COOP) + + + + Jumping allowed + Saltar permès + + + + Crouching allowed + Ajupir-se permès + + + + Drop weapons upon death + Deixar anar armes en morir + + + + Don't spawn runes + No generar runes + + + + Instantly return flags (ST/CTF) + Retornar banderes automàticament (ST/CTF) + + + + Don't allow players to switch teams + No permetre que els jugadors canviïn d'equip + + + + Players are automatically assigned teams + Als jugadors se'ls assignen equips automàticament + + + + Double the amount of ammo given + Duplicar la quantitat de munició + + + + Players slowly lose health over 100% like Quake + Els jugadors perden lentament la salut per sobre del 100% com en Quake + + + + Allow BFG freeaiming + Permet apuntat lliure de la BFG + + + + Barrels respawn + Els barrils reapareixen + + + + No respawn protection + No hi ha protecció de reaparició + + + + All players start with a shotgun + Tots els jugadors comencen amb una escopeta + + + + Players respawn where they died (COOP) + Els jugadors reapareixen on van morir (COOP) + + + + Don't clear frags after each level + No esborrar indicadors després de cada nivell + + + + Player can't respawn + El jugador no pot reaparèixer + + + + Lose a frag when killed + Perdre un frag en morir + + + + Infinite inventory + Inventari infinit + + + + All monsters must be killed before exiting + Tots els monstres han de ser assassinats abans de sortir + + + + Players can't see the automap + Els jugadors no poden veure el Automap + + + + Allies can't be seen on the automap + Els aliats no es poden veure al Automap + + + + You can't spy allies + No pots espiar als teus aliats + + + + Players can use chase cam + Els jugadors poden fer servir la càmera de persecució + + + + Players can't suicide + Els jugadors no poden suïcidar-se + + + + Players can't use autoaim + Els jugadors no poden usar autoapuntat + + + + Don't check ammo when switching weapons + No comprovar munició quan es canvia d'armes + + + + Kill all monsters spawned by a boss cube when the boss dies + Mata a tots els monstres generats per un cub de "boss" quan el "boss" mor + + + + Clients can't identify targets + Els clients no poden identificar els objectius + + + + lmsspectatorsettings applied in all game modes + Apliqui lmsspectatorsettings en tots els modes de joc + + + + Clients can't draw coop info + Els clients no poden usar el CVar "Coop Info" + + + + Unlagged is disabled + Unlagged està deshabilitat + + + + Players don't block each other + Els jugadors no es bloquegen entre ells + + + + Clients don't show medals + Els clients no mostren medalles + + + + Keys are shared between players + Les claus es comparteixen entre jugadors + + + + Player teams are preserved between maps + Els equips es conserven entre mapes + + + + Force OpenGL defaults + Força els valors predeterminats d'OpenGL + + + + No rocket jumping + Sense "saltar coets" + + + + Award damage instead of kills + Premiar dany en lloc d'assassinats + + + + Force drawing alpha + Força dibuixant alfa + + + + Don't spawn multiplayer things + No fer aparèixer coses del multijugador + + + + Force blood screen brightness on clients to emulate vanilla + Força la brillantor de la sang en pantalla en els clients per emular l'original + + + + Teammates don't block each other + Els companys d'equip no es bloquegen entre ells + + + + Zandronumq3::Dmflags + + + Use Doom's shortest texture behavior + Utilitza el comportament de textura més ràpid de Doom + + + + Don't fix loop index for stair building + No arreglar l'índex del bucle per a la construcció d'escales + + + + Pain elemental is limited to 20 lost souls + Pain elemental està limitat a 20 ànimes perdudes + + + + Pickups are only heard locally + Recollir articles només es poden escoltar localment + + + + Infinitely tall actors + Actors infinitament alts + + + + Limit actors to only one sound + Limitar els actors a un sol so + + + + Enable wallrunning + Habilitar wallrunning + + + + Dropped items spawn on floor + Els objectes deixats anar apareixen a terra + + + + Special lines block use line + Línies especials bloquegen l'ús de línies + + + + Disable BOOM local door light effect + Deshabilitar l'efecte de llum de porta local BOOM + + + + Raven's scrollers use their original speed + Els scrollers de Raven fan servir la seva velocitat original + + + + Use sector based sound target code + Utilitza codi de so objectiu basat en sectors + + + + Limit dehacked MaxHealth to health bonus + Limitar dehacked MaxHealth a la bonificació de vida + + + + Trace ignores lines with the same sector on both sides + El tracer ignora les línies amb el mateix sector a banda i banda + + + + Monsters can not move when hanging over a drop off + Els monstres no es poden moure quan estan sobre un abisme + + + + Scrolling sectors are additive like Boom + Els sectors de desplaçament són additius com Boom + + + + Monsters can see semi-invisible players + Els monstres poden veure jugadors semi-invisibles + + + + Instantly moving floors are not silent + Els pisos que es mouen a l'instant no dir res + + + + Sector sounds use original method for sound origin + Els sons de sector usen el mètode original per a l'origen del so + + + + Use original Doom heights for clipping against projectiles + Utilitzar altures originals de Doom durant una col·lisió amb míssils + + + + Monsters can't be pushed over dropoffs + Els monstres no poden ser empesos a abismes + + + + Any monster which calls BOSSDEATH counts for level specials + Qualsevol monstre que truqui a BOSSDEATH compten per a nivells especials + + + + Minotaur's floor flame is exploded immediately when feet are clipped + El foc del sòl del minotaure explota immediatament quan els peus el travessen + + + + Force original velocity calculations for A_Mushroom in Dehacked mods + Forçar càlculs de velocitat originals per A_Mushroom a mods Dehacked + + + + Monsters are affected by friction and pushers/pullers + Els monstres es veuen afectats per la fricció i empentes/estrebades + + + + Crushed monsters are turned into gibs, rather than replaced by gibs + Els monstres aixafats esdevenen vísceres, en lloc de ser reemplaçats per aquestes + + + + Friendly monsters aren't blocked by monster-blocking lines + Els monstres amistosos ignoren les línies de bloqueig de monstres + + + + Invert sprite sorting order for sprites of equal distance + Invertir ordre de classificació de sprites per sprites d'igual distància + + + + Hitscans use original blockmap and hit check code + Els Hitscans usen el mapa de blocs original i el codi de verificació d'impacte + + + + Find neighboring light level like like Doom + Busqui el nivell de llum veïna com en Doom + + + + Draw polyobjects the old fashioned way + Dibuixar poliobjectes com als bons (i antics) temps + + + + Ignore compositing when drawing masked midtextures + Ignorar la composició mentre es dibuixa textures mitjanes emmascarades + + + + It is impossible to directly face cardinal direction + És impossible mirar directament la direcció cardinal + + + + Use the same floor motion behavior as Doom + Utilitza el comportament de moviment del pis com a Doom + + + + Net scripts are client side + Els scripts NET s'executen en el client + + + + Clients send full button info + Els clients envien tota la informació sobre els botons + + + + Players can't use 'land' CCMD + Els jugadors no poden usar el comandament 'land' + + + + Use Doom's original random number generator + Utilitzar el generador de xifres aleatòries original de Doom + + + + Spheres have NOGRAVITY flag + Les esferes tenen l'indicador NOGRAVITY + + + + Don't stop player scripts on disconnect + No aturar els scripts dels jugadors al desconnectar + + + + Use horizontal explosion thrust of old ZDoom versions + Utilitzar l'empenta d'explosió horitzontal de versions antigues de ZDoom + + + + Non-SOLID things fall through invisible bridges + Coses no sòlides cauen a través de ponts invisibles + + + + Use old ZDoom jump physics + Fes servir físiques velles de salt de ZDoom + + + + Disallow weapon change when in mid raise/lower + No permetre el canvi d'arma quan està a mig pujar/baixar + + + + Use vanilla's autoaim tracer behavior + Utilitzar el comportament de autoapuntat original + + + + West spawns are silent + Les aparicions "West" són silencioses + + + + Limited movement in the air + Moviment limitat en l'aire + + + + Allow map01 "plasma bump" bug + Permetre error "plasma bump" al map01 + + + + Allow instant respawn after death + Permetre reaparició instantània després de morir + + + + Disable taunting + Desactivar burles + + + + Use doom2.exe's original sound curve + Utilitza la corba sonora original de doom2.exe + + + + Use original doom2 intermission music + Utilitzar la música original d'intermedi de doom2 + + + + Disable stealth monsters + Deshabilitar monstres silenciosos + + + + Radius damage has infinite height + El radi de dany té una alçada infinita + + + + Disable crosshair + Desactivar espiell + + + + Force weapon switch + Forçar el canvi d'arma + + + + Do not spawn health items (DM) + No fer aparèixer ítems de salut (DM) + + + + Do not spawn powerups (DM) + No fer aparèixer potenciadors (DM) + + + + Weapons remain after pickup (DM) + Les armes romanen després de recollir-les (DM) + + + + Falling damage (old ZDoom) + Dany de caiguda (antic ZDoom) + + + + Falling damage (Hexen) + Dany de caiguda (Hexen) + + + + Falling damage (Strife) + Dany de caiguda (Strife) + + + + Stay on same map when someone exits (DM) + Romandre al mapa quan algú ho acabi (DM) + + + + Spawn players as far as possible (DM) + Fer aparèixer els jugadors el més lluny possible (DM) + + + + Automatically respawn dead players (DM) + Reaparició automàtica de jugadors morts (DM) + + + + Don't spawn armor (DM) + No fer aparèixer armadura (DM) + + + + Kill anyone who tries to exit the level (DM) + Mata a qualsevol que intenti acabar el nivell (DM) + + + + Infinite ammo + Munició infinita + + + + No monsters + Sense monstres + + + + Monsters respawn + Els monstres reapareixen + + + + Items other than invuln. and invis. respawn + Els objectes (a excepció d'invulnerabilitat i invisibilitat) reapareixen + + + + Fast monsters + Monstres ràpids + + + + No jumping + No salts + + + + No freelook + No càmera lliure + + + + Respawn invulnerability and invisibility + Reaparició d'invulnerabilitat i invisibilitat + + + + Arbitrator FOV + FOV preestablert + + + + No multiplayer weapons in cooperative + Sense armes multijugador en cooperatiu + + + + No crouching + Sense ajupir-se + + + + Lose all old inventory on respawn (COOP) + Perdre tot l'inventari al reaparèixer (COOP) + + + + Lose keys on respawn (COOP) + Perdre claus en reaparèixer (COOP) + + + + Lose weapons on respawn (COOP) + Perdre armes en reaparèixer (COOP) + + + + Lose armor on respawn (COOP) + Perdre armadura a reaparèixer (COOP) + + + + Lose powerups on respawn (COOP) + Perdre potenciadors en reaparèixer (COOP) + + + + Lose ammo on respawn (COOP) + Perdre munició en reaparèixer (COOP) + + + + Lose half your ammo on respawn (COOP) + Perdre la meitat de la munició al reaparèixer (COOP) + + + + Jumping allowed + Saltar permès + + + + Crouching allowed + Ajupir-se permès + + + + Drop weapons upon death + Deixar anar armes en morir + + + + Don't spawn runes + No generar runes + + + + Instantly return flags (ST/CTF) + Retornar banderes automàticament (ST/CTF) + + + + Don't allow players to switch teams + No permetre que els jugadors canviïn d'equip + + + + Players are automatically assigned teams + Als jugadors se'ls assignen equips automàticament + + + + Double the amount of ammo given + Duplicar la quantitat de munició + + + + Players slowly lose health over 100% like Quake + Els jugadors perden lentament la salut per sobre del 100% com en Quake + + + + Allow BFG freeaiming + Permet apuntat lliure de la BFG + + + + Barrels respawn + Els barrils reapareixen + + + + No respawn protection + No hi ha protecció de reaparició + + + + All players start with a shotgun + Tots els jugadors comencen amb una escopeta + + + + Players respawn where they died (COOP) + Els jugadors reapareixen on van morir (COOP) + + + + Don't clear frags after each level + No esborrar indicadors després de cada nivell + + + + Player can't respawn + El jugador no pot reaparèixer + + + + Lose a frag when killed + Perdre un frag en morir + + + + Infinite inventory + Inventari infinit + + + + All monsters must be killed before exiting + Tots els monstres han de ser assassinats abans de sortir + + + + Players can't see the automap + Els jugadors no poden veure el Automap + + + + Allies can't be seen on the automap + Els aliats no es poden veure al Automap + + + + You can't spy allies + No pots espiar als teus aliats + + + + Players can use chase cam + Els jugadors poden fer servir la càmera de persecució + + + + Players can't suicide + Els jugadors no poden suïcidar-se + + + + Players can't use autoaim + Els jugadors no poden usar autoapuntat + + + + Don't check ammo when switching weapons + No comprovar munició quan es canvia d'armes + + + + Kill all monsters spawned by a boss cube when the boss dies + Mata a tots els monstres generats per un cub de "boss" quan el "boss" mor + + + + Do not count monsters in 'end level when dying' sectors towards kill count + No compti els assassinats de monstres en els sectors de 'fi de nivell en cas de mort' + + + + Clients can't identify targets + Els clients no poden identificar els objectius + + + + lmsspectatorsettings applied in all game modes + Apliqui lmsspectatorsettings en tots els modes de joc + + + + Clients can't draw coop info + Els clients no poden usar el CVar "Coop Info" + + + + Unlagged is disabled + Unlagged està deshabilitat + + + + Players don't block each other + Els jugadors no es bloquegen entre ells + + + + Clients don't show medals + Els clients no mostren medalles + + + + Keys are shared between players + Les claus es comparteixen entre jugadors + + + + Player teams are preserved between maps + Els equips es conserven entre mapes + + + + Force OpenGL defaults + Força els valors predeterminats d'OpenGL + + + + No rocket jumping + Sense "saltar coets" + + + + Award damage instead of kills + Premiar dany en lloc d'assassinats + + + + Force drawing alpha + Força dibuixant alfa + + + + Don't spawn multiplayer things + No fer aparèixer coses del multijugador + + + + Force blood screen brightness on clients to emulate vanilla + Força la brillantor de la sang en pantalla en els clients per emular l'original + + + + Teammates don't block each other + Els companys d'equip no es bloquegen entre ells + + + + No dropping allowed + No es permet deixar anar articles + + + + No map reset on death in survival + No es restableix el mapa al morir en supervivència + + + + Dead players can keep inventory + Els jugadors morts poden conservar l'inventari + + + + ZandronumqAboutProvider + + + This plugin is distributed under the terms of the LGPL v2.1 or later. + + + Aquest complement es distribueix sota els termes de la llicència LGPL v2.1 o posterior. + + + + + + ZandronumqBroadcast + + + Listening to Zandronumq's LAN servers broadcasts on port %1. + Cercant transmissions de servidors Zandronumq en LAN al port %1. + + + + Failed to bind Zandronumq's LAN broadcasts listening socket on port %1. Will keep retrying silently. + Error en enllaçar la connexió d'escolta de les transmissions LAN de Zandronumq al port %1. Seguirem reintentant-ho en silenci. + + + + ZandronumqClientExeFile + + + client + client + + + + + No testing directory specified for Zandronumq + No s'ha especificat cap directori de proves per Zandronumq + + + + Unable to create directory: +%1 + No es pot crear directori: +%1 + + + + Unable to create directory: +%1/%2 + No es pot crear directori: +%1/%2 + + + + Doomseeker + + + + + Please install now version "%1" into: +%2 + Instal·li ara la versió "%1" a: +%2 + + + + <p>Installation of testing binaries for version %1 can potentially <b>overwrite</b> your files.</p><p>Game will be installed to:<br>%2</p><p>Do you want Doomseeker to extract Zandronumq files, potentially <b>overwriting existing ones</b>, and to copy all your configuration files from your base directory?</p> + <p>La instal·lació dels binaris de prova per a la versió%1 pot potencialment <b>reescriure</b> els teus arxius.</p><p>El joc s'instal·larà a:<br>%2</p><p>Vols que Doomseeker extregui els arxius de Zandronumq, potencialment <b>reescrivint els arxius ja existents</b>, i copiar tots els arxius de configuració del teu directori base?</p> + + + + Zandronumq testing version %1 can be installed. + +Game will be installed to: +%2 + +Do you want Doomseeker to install that version and copy all your configuration files from your base directory? + La versió de prova de Zandronumq%1 pot instal·lar-se. + +El joc pot instal·lar-se a: +%2 + +Vols que Doomseeker instal aquesta versió i copieu tots els teus arxius de configuració del teu directori base? + + + + Doomseeker - install Zandronumq testing version + Doomseeker - instal·lar la versió de prova de Zandronumq + + + + %1 +doesn't exist. +You need to install new testing binaries. + %1 +No existeix. +Ha d'instal·lar els nous executables de prova. + + + + %1 +exists but is NOT a directory. +Cannot proceed. + %1 +existeix però NO és un directori. +No es pot procedir. + + + + %1 +exists but doesn't contain Zandronumq executable. + +Doomseeker can still install the game there if you want. + %1 +existeix, però no conté l'executable de Zandronumq. + +Doomseeker pot instal lar el joc allà igualment si ho desitja. + + + + Downloading Zandronumq testing binary from URL: %1 + Descarregant l'arxiu binari de prova de Zandronumq des de la URL: %1 + + + + Doomseeker - download failed + Doomseeker - descàrrega fallida + + + + Failed to download testing binary. + +%1 + Error al descarregar el binari de la versió de prova. + +%1 + + + + Unpacking file: %1 + Desempaquetant arxiu: %1 + + + + Doomseeker - unpack failed + Doomseeker - error en desempaquetar + + + + Failed to unpack: %1 + Error al desempaquetar: %1 + + + + %1 + should be a script file but is a directory! + %1 + hauria de ser un script, però és un directori! + + + + You don't have permissions to execute file: %1 + + No tens permisos per executar l'arxiu: %1 + + + + + Couldn't open batch file "%1" for writing + No s'ha pogut obrir l'script "%1" per escriure + + + + Error while writing batch file "%1" + Error en escriure l'script "%1" + + + + Cannot set permissions for file: +%1 + No es poden definir els permisos per a l'arxiu: +%1 + + + + ZandronumqGameInfo + + + Survival + Supervivència + + + + Invasion + Invasió + + + + Duel + Duel + + + + Terminator + + + + + LMS + + + + + Team LMS + LMS per equips + + + + Possession + Possessió + + + + Team Poss + Possessió per equips + + + + Team Game + Joc per equips + + + + One Flag CTF + CTF amb una bandera + + + + Skulltag + Skulltag + + + + Domination + Dominació + + + + ZandronumqMasterClient + + + You may contact Zandronumq staff about this through IRC: <b>irc.qzandronum.com #zandronumq</b> or on the forum: <a href="https://qzandronum.com/forum">https://qzandronum.com/forum.</a> + Pot posar-se en contacte amb el personal de Zandronumq a través d'IRC: <b>irc.qzandronum.com #zandronumq</b> o al fòrum: <a href="https://qzandronum.com/forum">https://qzandronum.com/forum.</a> + + + + ZandronumqRConProtocol + + + Connection attempt ... + Intent de connexió ... + + + + Too many failed connection attempts. Aborting. + Massa intents fallits de connexió. Avortant. + + + + Authenticating ... + Autenticant ... + + + + Too many failed authentication attempts. Aborting. + Massa intents d'autenticació fallits. Avortant. + + + + Delaying for about %n seconds before next authentication attempt. + + Retard d'aproximadament %n segon abans del pròxim intent d'autenticació. + Retard d'aproximadament %n segons abans del pròxim intent d'autenticació. + + + + + Failed to establish connection. + Error en establir la connexió. + + + + Timeout on authentication. + Límit de temps excedit en l'autenticació. + + + + You have been banned from this server. + Has estat expulsat d'aquest servidor. + + + + The protocol appears to be outdated. + El protocol sembla estar desactualitzat. + + + + Authentication failure. + Error d’autenticació. + + + + Remote console connection established. + Connexió a la consola remota establerta. + + + + ----- + + + + + ZandronumqServer + + + Blue + Blau + + + + Red + Vermell + + + + Green + Verd + + + + Gold + Or + + + diff --git a/src/plugins/zandronumq/translations/zandronumq_es_ES.ts b/src/plugins/zandronumq/translations/zandronumq_es_ES.ts new file mode 100644 index 00000000..a0c45f51 --- /dev/null +++ b/src/plugins/zandronumq/translations/zandronumq_es_ES.ts @@ -0,0 +1,2973 @@ + + + + + EngineZandronumqConfigBox + + + Testing Releases + Versiones de prueba + + + + Directory for testing releases: + Directorio para las versiones de prueba: + + + Allow servers to display my country + Permitir que los servidores muestren mi país + + + + Doomseeker - choose Zandronumq testing directory + Doomseeker - elija el directorio de pruebas de Zandronumq + + + + FlagsPage + + + Zandronumq + Zandronumq + + + + Zandronumq 3 + Zandronumq 3 + + + + Zandronumq 2 (old) + Zandronumq 2 (viejo) + + + + None + Nada + + + + Old (ZDoom) + Viejo (ZDoom) + + + + Hexen + Hexen + + + + Strife + Strife + + + + Default + Predeterminado + + + + No + No + + + + Yes + Si + + + + Unknown Zandronumq version in the config. Reverting to default. + Versión desconocida de Zandronumq en la configuración. Revirtiendo a predeterminado. + + + + Tried to set unknown Zandronumq version. Reverting to default. + Se ha intentado establecer una versión desconocida de Zandronumq. Revertirtiendo a predeterminado. + + + + Form + Formulario + + + + Game version: + Versión del juego: + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">If this is checked then Zandronumq may override some of the settings selected here.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">(+sv_defaultdmflags)</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Si esto está marcado, entonces Zandronumq puede anular algunas de las configuraciones seleccionadas aquí.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">(+sv_defaultdmflags)</span></p></body></html> + + + + Default DMFlags + DMFlags Predefinidas + + + + + Environment + Entorno + + + + Falling damage: + Daño de caída: + + + + No monsters + Sin monstruos + + + + Items respawn + Los artículos reaparecen + + + + Barrels respawn + Los barriles reaparecen + + + + Respawn invulnerability and invisibility spheres. + Hacer reaparecer las esferas de invulnerabilidad y invisibilidad. + + + + Mega powerups respawn + Mega potenciadores reaparecen + + + + Teams + Equipos + + + + Server picks teams + El servidor elige equipos + + + + Players can't switch teams + Los jugadores no pueden cambiar de equipo + + + + Keep teams after a map change + Mantener equipos después de un cambio de mapa + + + + Hide allies on the automap + Ocultar aliados en el automap + + + + Don't let players spy on allies + No permitir que los jugadores espíen a sus aliados + + + + Instant flag/skull return + Regreso de bandera/calavera instantáneo + + + + Don't use ping-based backwards reconciliation for player-fired hitscans and rails. + No utilizar reconciliación hacia atrás basada en ping para hitscans y rieles disparados por jugadores. + + + + No unlagged + Sin unlagged + + + + Apply lmsspectatorsettings in all game modes. + Aplicar lmsspectatorsettings en todos los modos de juego. + + + + Always apply LMS spectator settings + Siempre aplica la configuración de espectador LMS + + + + Enforces clients not to show medals, i.e. behave as if cl_medals == 0. + Obliga a los clientes a no mostrar medallas, es decir, comportarse como si cl_medals == 0. + + + + No medals + Sin medallas + + + + General + General + + + + Disallow + No permitir + + + + Suicide + Suicidio + + + + Respawn + Reaparecer + + + + <html><head/><body><p align="justify">P_RadiusAttack doesn't give players any z-momentum if the attack was made by a player. This essentially disables rocket jumping.</p></body></html> + <html><head/><body><p align="justify">P_RadiusAttack no les da a los jugadores ningún z-momentum si el ataque fue hecho por un jugador. Esto esencialmente desactiva el salto de cohete.</p></body></html> + + + + Rocket jump + Salto de coete + + + + Taunt + Burlarse + + + + Item drop + Soltar objeto + + + + Use automap + Usar automap + + + + Turn off translucency + Desactiva la translucidez + + + + Use crosshairs + Usar puntos de mira + + + + Use custom GL lighting settings + Usar configuraciones de iluminación GL personalizadas + + + + Enforces clients not to identify players, i.e. behave as if cl_identifytarget == 0. + Obliga a los clientes a no identificar jugadores, es decir, comportarse como si cl_identifytarget == 0. + + + + Target identify + Identificar objetivo + + + + Enforces clients not to draw coop info, i.e. behave as if cl_drawcoopinfo == 0. + Obliga a los clientes a no dibujar la información del cooperativo, es decir, comportarse como si cl_drawcoopinfo == 0. + + + + Display coop info + Mostrar información cooperativo + + + + Use autoaim + Usar autoapuntado + + + + Only let the arbitrator set FOV (for all players) + Solo deje que el árbitro establezca el FOV (para todos los jugadores) + + + + Use FOV + Usar FOV + + + + Use freelook + Usar cámara libre + + + + <html><head/><body><p>Players are not allowed to use the land CCMD. Because of Zandronumq's default amount of air control, flying players can get a huge speed boast with the land CCMD. Disallowing players to land, allows to keep the default air control most people are used to while not giving flying players too much of an advantage.</p></body></html> + <html><head/><body><p>Los jugadores no pueden usar el CCMD terrestre. Debido a la cantidad predeterminada de control en aire de Zandronumq, los jugadores que vuelan pueden alcanzar una gran velocidad con el CCMD terrestre. Impidiendo que los jugadores aterricen, permite mantener el control de aire predeterminado al que la mayoría de la gente está acostumbrada, mientras que no les da demasiada ventaja a los jugadores que vuelan.</p></body></html> + + + + Use 'land' console command + Usar el comando de consola 'land' + + + + <html><head/><body><p>Don't allow players to change how strongly will their screen flash when they get hit.</p></body></html> + <html><head/><body><p>No permita que los jugadores cambien la intensidad del destello cuando reciben un golpe.</p></body></html> + + + + Change bloodied screen brightness + Cambiar el brillo de la pantalla ensangrentada + + + + Abilities + Habilidades + + + + Jumping: + Saltar: + + + + Crouching: + Agacharse: + + + + Infinite inventory + Inventario infinito + + + + Infinite ammo + Munición infinita + + + + Like Quake 3 + Como Quake 3 + + + + Slowly lose health when over 100% + Poco a poco perder salud cuando esta esté por encima del 100% + + + + Can use chasecam + Puede usar cámara de persecución + + + + Allow BFG freeaiming + Permite apuntado libre de la BFG + + + + Behavior + Comportamiento + + + + Players can walk through each other + Los jugadores pueden caminar a través de ellos + + + + Allies can walk through each other + Los aliados pueden atravesarse entre sí + + + + Players block each other normally + Los jugadores se bloquean entre ellos + + + + Don't check ammo when switching weapons + No comprobar munición cuando se cambia de armas + + + + Force inactive players to spectate after: + Fuerza a los jugadores inactivos al modo espectador después: + + + + min. + + + + + Players + Jugadores + + + + Score damage, not kills + Puntúa el daño, no los asesinatos + + + + Don't spawn Deathmatch weapons + No hacer aparecer armas de Deathmatch + + + + Spawn map actors in coop as if the game was single player. + Hacer aparecer a actores del mapa en cooperativo como si el juego fuera de un solo jugador. + + + + Don't spawn any multiplayer actor in coop + No generes ningún actor multijugador en el cooperativo + + + + Monsters... + Monstruos... + + + + are fast (like Nightmare) + son rápidos (como en Nightmare) + + + + respawn (like Nightmare) + reaparecen (como en Nightmare) + + + + must be killed to enable exit + deben ser asesinados para poder salir + + + + Kill percentage: + Porcentaje de asesinatos: + + + + Multiplier of damage dealt by monsters. + Multiplicador del daño infligido por los monstruos. + + + + Damage factor: + Factor de Daño: + + + + <html><body><p>Multiplier of damage dealt by monsters.</p></body></html> + <html><body><p>Multiplicador del daño infligido por los monstruos.</p></body></html> + + + + Kill all monsters spawned by a boss cube when the boss dies + Mata a todos los monstruos generados por un cubo de jefe cuando el jefe muere + + + + On player death... + Quando el jugador muere... + + + + Respawn where died + Reaparecer donde murió + + + + Lose all inventory + Perder todo el inventario + + + + Lose armor + Perder armadura + + + + Lose keys + Perder llaves + + + + Lose powerups + Perder potenciadores + + + + Lose weapons + Perder armas + + + + Lose all ammo + Perder toda la munición + + + + Lose half ammo + Perder la mitad de la munición + + + + <html><head/><body><p>Affects game modes where &quot;max. lives&quot; can be used. If set, players who become dead spectators (run out of lives) will still keep inventory in accordance to the &quot;Lose *&quot; flags above. If unset, players who lose all lives will always lose entire inventory.</p></body></html> + <html><head/><body><p>Afecta los modos de juego donde &quot;max. vidas&quot; puede ser usado. Si se establece, los jugadores que se conviertan en espectadores muertos (se queden sin vida) seguirán manteniendo el inventario de acuerdo con &quot; Perder *&quot; indicadores arriba. Si no se establece, los jugadores que pierdan todas las vidas perderán siempre el inventario completo.</p></body></html> + + + + Players who lose all lives can keep inventory + Los jugadores que pierdan todas las vidas pueden conservar el inventario + + + + Share keys between players + Compartir claves entre jugadores + + + + <html><head/><body><p>Players will be respawned with full lives but the map will not be reset. Inventory will be preserved in accordance to &quot;Lose inventory&quot; flags. Players will be able to continue from the point where they died.</p></body></html> + <html><head/><body><p>Los jugadores serán reaparecidos con vidas completas pero el mapa no se reiniciará. El inventario se conservará de acuerdo con los indicadores de &quot;Perder inventario&quot;. Los jugadores podrán continuar desde el punto donde murieron.</p></body></html> + + + + Survival only: no map reset when all players die + Solo supervivencia: no se restablece el mapa cuando todos los jugadores mueren + + + + Cooperative + Cooperativo + + + + When players die, they... + Cuando los jugadores mueren, ellos... + + + + Respawn automatically + Reaparecer automáticamente + + + + Drop their weapon + Soltar su arma + + + + Respawn farthest away from others + Reaparecer lo más lejos posible de los demás + + + + Lose a frag + Perder un frag + + + + Respawn with a shotgun + Reaparecer con una escopeta + + + + Don't get respawn protection + No obtener protección de reaparición + + + + When someone exits the level... + Cuando alguien sale del nivel... + + + + Continue to the next map + Continuar al siguiente mapa + + + + Restart the current level + Reiniciar el nivel actual + + + + Kill the player + Mata al jugador + + + + Keep frags after map change + Mantener frags después del cambio de mapa + + + + Weapons && Ammo + Armas y munición + + + + Weapons stay after pickup + Las armas permanecen después de recogerlas + + + + Double ammo + Doble munición + + + + Don't spawn... + No hacer aparecer... + + + + Health + Salud + + + + Armor + Armadura + + + + Runes + Runas + + + + Deathmatch + Combate a muerte + + + + Weapons + Armas + + + + Chainsaw + Motosierra + + + + Pistol + Pistola + + + + Shotgun + Escopeta + + + + Super shotgun + Súper escopeta + + + + Chaingun + Ametralladora + + + + Minigun + + + + + Rocket launcher + Lanzacohetes + + + + Grenade launcher + Lanzagranadas + + + + Plasma rifle + Rifle de plasma + + + + Railgun + + + + + lmsallowedweapons: + lmsallowedweapons: + + + + + + + + + + + 0 + + + + + lmsspectatorsettings: + + + + + Spectators can... + Los espectadores pueden... + + + + Talk to active players + Hablar con jugadores activos + + + + View the game + Ver el juego + + + + LMS + LMS + + + + Enable buggier wall clipping so players can wallrun. + Habilitar un atravesamiento de pared peor para que los jugadores puedan hacer wallrun. + + + + Enable wall running + Activar wall running + + + + Pickups are only heard locally. + Las recogidas de objetos solo se escuchan localmente. + + + + Don't let others hear pickups + No dejes que otros oigan la recogida de objetos + + + + Allow instant respawn + Permitir reaparición instantánea + + + + <html><head/><body><p>Disable stealth monsters, since doom2.exe didn't have them.</p><p><span style=" font-weight:600;">Note: this handles ZDoom's invisible monsters.</span></p><p><span style=" font-weight:600;">THIS DOESN'T AFFECT THE PARTIAL INVISIBILITY SPHERE IN ANY WAY. See &quot;Monsters see semi-invisible players&quot; for that.</span></p></body></html> + <html><head/><body><p>Deshabilita los monstruos sigilosos, ya que doom2.exe no los tenía.</p><p><span style=" font-weight:600;">Nota: esto maneja los monstruos invisibles de ZDoom.</span></p><p><span style=" font-weight:600;">ESTO NO AFECTA LA ESFERA DE INVISIBILIDAD PARCIAL DE CUALQUIER FORMA. Ver &quot;Los monstruos ven jugadores semiinvisibles&quot; para eso.</span></p></body></html> + + + + Disable stealth monsters + Deshabilitar monstruos sigilosos + + + + Limit actors to one sound at a time. + Limitar los actores a un sonido a la vez. + + + + Allow silent BFG trick + Permitir el truco del BFG silencioso + + + + Clients use the vanilla Doom weapon on pickup behavior. + Los clientes usan el comportamiento original de Doom al recoger de armas. + + + + Original weapon switch + Cambio de armas original + + + + Limited movement in the air + Movimiento limitado en el aire + + + + This affects the partial invisibility sphere. + Esto afecta la esfera de invisibilidad parcial. + + + + Monsters see semi-invisible players + Los monstruos ven a los jugadores semi-invisibles + + + + Allow the map01 "plasma bump" bug. + Permitir error "plasma bump" en map01. + + + + Plasma bump bug + Error plasma bump + + + + Any boss death activates map specials + Cualquier muerte de jefe activa especiales del mapa + + + + Friction/pushers/pullers affect Monsters + Fricción/empujones/tirones afectan los monstruos + + + + <html><head/><body><p>Crushed monsters are turned into gibs, rather than replaced by gibs.</p></body></html> + <html><head/><body><p>Los monstruos aplastados se convierten en vísceras, en lugar de ser reemplazados por estas.</p></body></html> + + + + Crusher gibs by morphing, not replacement + Aplastar transforma en vísceras, en lugar de reemplazar por estas + + + + Block monster lines ignore friendly monsters + Las líneas de bloqueo de monstruos ignoran los monstruos amistosos + + + + Find neighboring light level like Doom + Encontrar el nivel de luz cercano como en Doom + + + + Use doom2.exe's original intermission screens/music. + Usar la pantalla/música originales del intermedio de misión de doom2.exe. + + + + Use old intermission screens/music + Usar pantalla/música de intermedio de misión antiguas + + + + Scrolling sectors are additive like in Boom. + Los sectores de desplazamiento son aditivos como en Boom. + + + + Scrolling sectors are additive + Los sectores de desplazamiento son aditivos + + + + Sector sounds use original method for sound origin. + Los sonidos del sector usan el método original para el origen del sonido. + + + + Sector sounds use original method + Los sonidos del sector usan el método original + + + + Monsters cannot move when hanging over a dropoff. + Los monstruos no se pueden mover cuando están sobre un abismo. + + + + No monsters dropoff move + Sin monstruos moverse en abismo + + + + Instantly moving floors are not silent. + Los pisos que se mueven al instante no son silenciosos. + + + + Instantly moving floors aren't silent + Los pisos que se mueven al instante no son silenciosos + + + + <html><head/><body><p>Clients send ucmd.buttons as &quot;long&quot; instead of as &quot;byte&quot; in CLIENTCOMMANDS_ClientMove. So far this is only necessary if the ACS function GetPlayerInput is used in a server side script to check for buttons bigger than BT_ZOOM. Otherwise this information is completely useless for the server and the additional net traffic to send it should be avoided.</p></body></html> + <html><head/><body><p>Los clientes envían ucmd.buttons como &quot;long&quot; en lugar de como &quot;byte&quot; en CLIENTCOMMANDS_ClientMove. Hasta ahora, esto solo es necesario si la función ACS GetPlayerInput se utiliza en un script del lado del servidor para buscar botones más grandes que BT_ZOOM. De lo contrario, esta información es completamente inútil para el servidor y se debe evitar el tráfico de red adicional para enviarlo.</p></body></html> + + + + Clients send full button info + Los clientes envían toda la información sobre los botones + + + + <html><head/><body><p>Use Doom's random table instead of ZDoom's random number generator. Affects weapon damage among other things.</p></body></html> + <html><head/><body><p>Use la tabla aleatoria de Doom en lugar del generador de números aleatorios de ZDoom. Afecta el daño de las armas entre otras cosas.</p></body></html> + + + + Old random number generator + Antiguo generador de números aleatorios + + + + Monsters can't be pushed off cliffs + Los monstruos no pueden ser empujados a abismos + + + + Old damage radius (infinite height) + Radio de daño antiguo (altura infinita) + + + + Minotaur's floor flame explodes immediately when feet are clipped + El fuego del suelo del minotauro explota inmediatamente cuando los pies lo atraviesan + + + + Original velocity calc. for A_Mushroom in Dehacked + Calculo de velocidad original para A_Mushroom en Dehacked + + + + Sprite sort order inverted for sprites of equal distance + Orden de Sprites invertido para sprites en la misma distancia + + + + Hitscans use original blockmap and hit check code + Los Hitscans usan el mapa de bloques original y el código de verificación de impacto + + + + Draw polyobjects the old fashioned way + Dibujar poliobjetos a la antigua usanza + + + + Compatibility + Compatibilidad + + + + Use original missile clipping height + Utilizar la altura original de atravesamiento de misiles + + + + Use sector based sound target code + Usar código de sonido objetivo basado en sectores + + + + <html><head/><body><p>Doom's hitscan tracing code ignores all lines with both sides in the same sector. ZDoom's does not. This option reverts to the original but less precise behavior. </p></body></html> + <html><head/><body><p>El código de escaneo de impactos de Doom ignora todas las líneas con ambos lados en el mismo sector. ZDoom no. Esta opción revierte al comportamiento original pero es menos preciso. </p></body></html> + + + + Trace ignore lines w/ same sector on both sides + El trazo ignora las líneas con el mismo sector en ambos lados + + + + Limit deh.MaxHealth to health bonus + Limitar deh.MaxHealth a la bonificación de salud + + + + <html><head/><body><p>The scrolling floor specials in Heretic and Hexen move the player much faster than the actual texture scrolling speed. Enable this option to restore this effect. </p></body></html> + <html><head/><body><p>Los desplazamientos especiales del suelo en Heretic y Hexen mueven al jugador mucho más rápido que la velocidad de desplazamiento de la textura real. Habilita esta opción para restaurar este efecto.</p></body></html> + + + + Raven's scrollers use original speed + Los scrollers de Raven usan su velocidad original + + + + <html><head/><body><p>Add NOGRAVITY to actors named InvulnerabilitySphere, Soulsphere, Megasphere and BlurSphere when spawned by the map.</p></body></html> + <html><head/><body><p>Agregue NOGRAVITY a los actores llamados InvulnerabilitySphere, Soulsphere, Megasphere y BlurSphere cuando aparecen por el mapa.</p></body></html> + + + + Add NOGRAVITY flag to spheres + Agregar la bandera NOGRAVITY a las esferas + + + + <html><head/><body><p>When a player leaves the game, don't stop any scripts of that player that are still running.</p></body></html> + <html><head/><body><p>Cuando un jugador abandona el juego, no detener ningún script que ese jugador todavía esté ejecutando.</p></body></html> + + + + Don't stop player scripts on disconnect + No detener los scripts de los jugadores al desconectarse + + + + <html><head/><body><p>If this is enabled, explosions cause a strong horizontal thrust like in old ZDoom versions.</p></body></html> + <html><head/><body><p>Si esto está habilitado, las explosiones causan un fuerte empuje horizontal como en versiones antiguas de ZDoom.</p></body></html> + + + + Old ZDoom horizontal thrust + Empuje horizontal del antiguo ZDoom + + + + <html><head/><body><p>If this is enabled, non-SOLID things like flags fall through bridges (as they used to do in old ZDoom versions).</p></body></html> + + <html><head/><body><p>Si esto está habilitado, elementos no SÓLIDOS como banderas caen a través de puentes (como solían hacer en versiones antiguas de ZDoom).</p></body></html> + + + + + Old ZDoom bridge drops + Caídas de puente del antiguo ZDoom + + + + <html><head/><body><p>Uses old ZDoom jump physics, it's a minor bug in the gravity code that causes gravity application in the wrong place.</p></body></html> + <html><head/><body><p>Usa la antigua física de salto ZDoom, es un error menor en el código de gravedad que causa la aplicación de la gravedad en el lugar equivocado.</p></body></html> + + + + ZDoom 1.23B33 jump physics + Físicas de salto de ZDoom 1.23B33 + + + + <html><head/><p>Zandronumq uses more tracers to fill in the gaps, this reverts it to vanilla's 3 tracer behavior</p></body></html> + <html><head/><p>Zandronumq usa más trazadores para llenar los huecos, esto lo revierte al comportamiento original de 3 trazadores</p></body></html> + + + + Use vanilla autoaim tracer behavior + Usar el comportamiento del trazador de autoapuntado original + + + + Ignore compositing when drawing masked midtextures + Ignore la composición mientras se dibuja texturas medias enmascaradas + + + + It is impossible to face directly NSEW + Es imposible mirar directamente en la dirección cardinal + + + + <html><head/><body><p>Use Doom's shortest texture find behavior. This is requied by some WADs in MAP07.</p></body></html> + <html><head/><body><p>Usa el comportamiento de búsqueda de textura más corta de Doom. Esto es requerido por algunos WADs en MAP07.</p></body></html> + + + + Find shortest textures like Doom + Encuentra las texturas más cortas como en Doom + + + + Limit pain elementals to 20 lost souls + Limitar los elementales de dolor a 20 almas perdidas + + + + Spawned item drops on the floor + El elemento generado cae en el suelo + + + + <html><head/><body><p>Treat ACS scripts with the SCRIPTF_Net flag to be client side, i.e. executed on the clients, but not on the server.</p></body></html> + <html><head/><body><p>Tratar los scripts ACS con el indicador SCRIPTF_Net para que se ejecuten en el lado del cliente, es decir, ejecutados en los clientes, pero no en el servidor.</p></body></html> + + + + NET scripts are clientside + Los scripts NET son del lado del cliente + + + + Actors are infinitely tall + Los actores son infinitamente altos + + + + Don't fix loop index for stair building. + No arreglar el índice del bucle para construir escaleras. + + + + Use buggier stair building + Usar un constructor de escaleras con más errores + + + + Disable Boom door light effect + Deshabilitar el efecto de luz de puerta BOOM + + + + All special lines can drop use lines + Todas las líneas especiales pueden soltar líneas de uso + + + + Original sound curve + Curva de sonido original + + + + Disallow weapon change until fully drawn or hidden + No permitir el cambio de arma hasta que esté completamente dibujado u oculto + + + + West spawns are silent + Las apariciones "West" son silenciosas + + + + Use the same floor motion behavior as Doom + Usar el comportamiento de movimiento del piso como en Doom + + + + Compatibility 2 + Compatibilidad 2 + + + + Voting + Votaciones + + + + zandronumq dmflags + + + + + dmflags + + + + + dmflags2 + + + + + zandronumq compatflags + + + + + compatflags + + + + + compatflags2 + + + + + QObject + + + Time limit: + Límite de tiempo: + + + + Frag limit: + Límite de frags: + + + + Point limit: + Límite de puntos: + + + + Win limit: + Límite de victorias: + + + + Duel limit: + Límite de duelos: + + + + Max. lives: + Max. vidas: + + + + << Unknown >> + << Desconocido >> + + + + TestingProgressDialog + + + Downloading testing binaries... + Descargando archivos binarios de prueba ... + + + + Cancel + Cancelar + + + + VotingSetupWidget + + + Form + Formulario + + + + Use this page + Use esta página + + + + Who can vote + Quién puede votar + + + + All can vote + Todos pueden votar + + + + No one can vote + Nadie puede votar + + + + Spectators can't vote + Los espectadores no pueden votar + + + + Minimum number of players required to call a vote: + Número mínimo de jugadores necesarios para solicitar una votación: + + + + Allow specific votes + Permitir votos específicos + + + + duellimit + límite de duelo + + + + pointlimit + límite de puntos + + + + timelimit + límite de tiempo + + + + winlimit + límite de victorias + + + + changemap + Canviar mapa + + + + kick + expulsar + + + + map + mapa + + + + fraglimit + límite de frags + + + + force players to spectate + obligar a los jugadores al modo espectador + + + + Vote flooding protection enabled + Protección contra inundaciones de votos habilitada + + + + Zandronumq2::Dmflags + + + Use Doom's shortest texture behavior + Use el comportamiento de textura más rápido de Doom + + + + Don't fix loop index for stair building + No arreglar el índice del bucle para la construcción de escaleras + + + + Pain elemental is limited to 20 lost souls + Pain elemental está limitado a 20 almas perdidas + + + + Pickups are only heard locally + Recoger artículos solo se pueden escuchar localmente + + + + Infinitely tall actors + Actores infinitamente altos + + + + Limit actors to only one sound + Limitar los actores a un solo sonido + + + + Enable wallrunning + Habilitar wallrunning + + + + Dropped items spawn on floor + Los objetos soltados aparecen en el suelo + + + + Special lines block use line + Líneas especiales bloquean el uso de líneas + + + + Disable BOOM local door light effect + Deshabilitar el efecto de luz de puerta local BOOM + + + + Raven's scrollers use their original speed + Los scrollers de Raven usan su velocidad original + + + + Use sector based sound target code + Usar código de sonido objetivo basado en sectores + + + + Limit dehacked MaxHealth to health bonus + Limitar dehacked MaxHealth a la bonificación de vida + + + + Trace ignores lines with the same sector on both sides + El tracer ignora las líneas con el mismo sector en ambos lados + + + + Monsters can not move when hanging over a drop off + Los monstruos no se pueden mover cuando están sobre un abismo + + + + Scrolling sectors are additive like Boom + Los sectores de desplazamiento son aditivos como Boom + + + + Monsters can see semi-invisible players + Los monstruos pueden ver jugadores semi-invisibles + + + + Instantly moving floors are not silent + Los pisos que se mueven al instante no son silenciosos + + + + Sector sounds use original method for sound origin + Los sonidos de sector usan el método original para el origen del sonido + + + + Use original Doom heights for clipping against projectiles + Utilizar alturas originales de Doom durante una colisión con misiles + + + + Monsters can't be pushed over dropoffs + Los monstruos no pueden ser empujados a abismos + + + + Any monster which calls BOSSDEATH counts for level specials + Cualquier monstruo que llame a BOSSDEATH cuentan para niveles especiales + + + + Minotaur's floor flame is exploded immediately when feet are clipped + El fuego del suelo del minotauro explota inmediatamente cuando los pies lo atraviesan + + + + Force original velocity calculations for A_Mushroom in Dehacked mods + Forzar cálculos de velocidad originales para A_Mushroom en mods Dehacked + + + + Monsters are affected by friction and pushers/pullers + Los monstruos se ven afectados por la fricción y empujones/tirones + + + + Crushed monsters are turned into gibs, rather than replaced by gibs + Los monstruos aplastados se convierten en vísceras, en lugar de ser reemplazados por estas + + + + Friendly monsters aren't blocked by monster-blocking lines + Los monstruos amistosos ignoran las líneas de bloqueo de monstruos + + + + Invert sprite sorting order for sprites of equal distance + Invertir orden de clasificación de sprites para sprites de igual distancia + + + + Hitscans use original blockmap and hit check code + Los Hitscans usan el mapa de bloques original y el código de verificación de impacto + + + + Find neighboring light level like like Doom + Busque el nivel de luz vecina como en Doom + + + + Draw polyobjects the old fashioned way + Dibujar poliobjetos a la antigua usanza + + + + Net scripts are client side + Los scripts NET se ejecutan en el cliente + + + + Clients send full button info + Los clientes envían toda la información sobre los botones + + + + Players can't use 'land' CCMD + Los jugadores no pueden usar el comando 'land' + + + + Use Doom's original random number generator + Utilizar el generador de números aleatorios original de Doom + + + + Spheres have NOGRAVITY flag + Las esferas tienen el indicador NOGRAVITY + + + + Don't stop player scripts on disconnect + No detener los scripts de los jugadores al desconectarse + + + + Use horizontal explosion thrust of old ZDoom versions + Utilizar el empuje de explosión horizontal de versiones antiguas de ZDoom + + + + Non-SOLID things fall through invisible bridges + Cosas no sólidas caen a través de puentes invisibles + + + + Use old ZDoom jump physics + Usa las viejas físicas de salto de ZDoom + + + + Disallow weapon change when in mid raise/lower + No permitir el cambio de arma cuando está a medio subir/bajar + + + + Use vanilla's autoaim tracer behavior + Utilizar el comportamiento de autoapuntado original + + + + West spawns are silent + Las apariciones "West" son silenciosas + + + + Limited movement in the air + Movimiento limitado en el aire + + + + Allow map01 "plasma bump" bug + Permitir error "plasma bump" en map01 + + + + Allow instant respawn after death + Permitir reaparición instantánea después de morir + + + + Disable taunting + Desactivar burlas + + + + Use doom2.exe's original sound curve + Use la curva de sonido original de doom2.exe + + + + Use original doom2 intermission music + Utilizar la música original de intermedio de doom2 + + + + Disable stealth monsters + Deshabilitar monstruos sigilosos + + + + Radius damage has infinite height + El radio de daño tiene una altura infinita + + + + Disable crosshair + Desactivar mirilla + + + + Force weapon switch + Forzar el cambio de arma + + + + Do not spawn health items (DM) + No hacer aparecer items de salud (DM) + + + + Do not spawn powerups (DM) + No hacer aparecer potenciadores (DM) + + + + Weapons remain after pickup (DM) + Las armas permanecen después de recogerlas (DM) + + + + Falling damage (old ZDoom) + Daño de caída (antiguo ZDoom) + + + + Falling damage (Hexen) + Daño de caída (Hexen) + + + + Falling damage (Strife) + Daño de caída (Strife) + + + + Stay on same map when someone exits (DM) + Permanecer en el mapa cuando alguien lo termine (DM) + + + + Spawn players as far as possible (DM) + Hacer aparecer los jugadores lo más lejos posible (DM) + + + + Automatically respawn dead players (DM) + Reaparición automática de jugadores muertos (DM) + + + + Don't spawn armor (DM) + No hacer aparecer armadura (DM) + + + + Kill anyone who tries to exit the level (DM) + Mata a cualquiera que intente terminar el nivel (DM) + + + + Infinite ammo + Munición infinita + + + + No monsters + Sin monstruos + + + + Monsters respawn + Los monstruos reaparecen + + + + Items other than invuln. and invis. respawn + Los objetos (a excepción de invulnerabilidad y invisibilidad) reaparecen + + + + Fast monsters + Monstruos rápidos + + + + No jumping + Sin saltar + + + + No freelook + Sin cámara libre + + + + Respawn invulnerability and invisibility + Reaparición de invulnerabilidad e invisibilidad + + + + Arbitrator FOV + FOV preestablecido + + + + No multiplayer weapons in cooperative + Sin armas multijugador en cooperativo + + + + No crouching + Sin agachado + + + + Lose all old inventory on respawn (COOP) + Perder todo el inventario al reaparecer (COOP) + + + + Lose keys on respawn (COOP) + Perder llaves al reaparecer (COOP) + + + + Lose weapons on respawn (COOP) + Perder armas al reaparecer (COOP) + + + + Lose armor on respawn (COOP) + Perder armadura al reaparecer (COOP) + + + + Lose powerups on respawn (COOP) + Perder potenciadores al reaparecer (COOP) + + + + Lose ammo on respawn (COOP) + Perder munición al reaparecer (COOP) + + + + Lose half your ammo on respawn (COOP) + Perder la mitad de la munición al reaparecer (COOP) + + + + Jumping allowed + Saltar permitido + + + + Crouching allowed + Agachado permitido + + + + Drop weapons upon death + Soltar armas al morir + + + + Don't spawn runes + No generar runas + + + + Instantly return flags (ST/CTF) + Devolver banderas automáticamente (ST/CTF) + + + + Don't allow players to switch teams + No permitir que los jugadores cambien de equipo + + + + Players are automatically assigned teams + A los jugadores se les asignan equipos automáticamente + + + + Double the amount of ammo given + Duplicar la cantidad de munición + + + + Players slowly lose health over 100% like Quake + Los jugadores pierden lentamente la salud por encima del 100% como en Quake + + + + Allow BFG freeaiming + Permite apuntado libre de la BFG + + + + Barrels respawn + Los barriles reaparecen + + + + No respawn protection + No hay protección de reaparición + + + + All players start with a shotgun + Todos los jugadores comienzan con una escopeta + + + + Players respawn where they died (COOP) + Los jugadores reaparecen donde murieron (COOP) + + + + Don't clear frags after each level + No borrar indicadores después de cada nivel + + + + Player can't respawn + El jugador no puede reaparecer + + + + Lose a frag when killed + Perder un frag al morir + + + + Infinite inventory + Inventario infinito + + + + All monsters must be killed before exiting + Todos los monstruos deben ser asesinados antes de salir + + + + Players can't see the automap + Los jugadores no pueden ver el automap + + + + Allies can't be seen on the automap + Los aliados no se pueden ver en el automap + + + + You can't spy allies + No puedes espiar a tus aliados + + + + Players can use chase cam + Los jugadores pueden usar la cámara de persecución + + + + Players can't suicide + Los jugadores no pueden suicidarse + + + + Players can't use autoaim + Los jugadores no pueden usar autoapuntado + + + + Don't check ammo when switching weapons + No comprobar munición cuando se cambia de armas + + + + Kill all monsters spawned by a boss cube when the boss dies + Mata a todos los monstruos generados por un cubo de jefe cuando el jefe muere + + + + Clients can't identify targets + Los clientes no pueden identificar los objetivos + + + + lmsspectatorsettings applied in all game modes + Aplique lmsspectatorsettings en todos los modos de juego + + + + Clients can't draw coop info + Los clientes no pueden usar el CVar "Coop Info" + + + + Unlagged is disabled + Unlagged está deshabilitado + + + + Players don't block each other + Los jugadores no se bloquean entre ellos + + + + Clients don't show medals + Los clientes no muestran medallas + + + + Keys are shared between players + Las claves se comparten entre jugadores + + + + Player teams are preserved between maps + Los equipos se conservan entre mapas + + + + Force OpenGL defaults + Fuerza los valores predeterminados de OpenGL + + + + No rocket jumping + Sin "saltar cohetes" + + + + Award damage instead of kills + Premiar daño en lugar de asesinatos + + + + Force drawing alpha + Fuerza dibujando alfa + + + + Don't spawn multiplayer things + No hacer aparecer cosas del multijugador + + + + Force blood screen brightness on clients to emulate vanilla + Fuerza el brillo de la sangre en pantalla en los clientes para emular el original + + + + Teammates don't block each other + Los compañeros de equipo no se bloquean entre ellos + + + + Zandronumq3::Dmflags + + + Use Doom's shortest texture behavior + Use el comportamiento de textura más rápido de Doom + + + + Don't fix loop index for stair building + No arreglar el índice del bucle para la construcción de escaleras + + + + Pain elemental is limited to 20 lost souls + Pain elemental está limitado a 20 almas perdidas + + + + Pickups are only heard locally + Recoger artículos solo se pueden escuchar localmente + + + + Infinitely tall actors + Actores infinitamente altos + + + + Limit actors to only one sound + Limitar los actores a un solo sonido + + + + Enable wallrunning + Habilitar wallrunning + + + + Dropped items spawn on floor + Los objetos soltados aparecen en el suelo + + + + Special lines block use line + Líneas especiales bloquean el uso de líneas + + + + Disable BOOM local door light effect + Deshabilitar el efecto de luz de puerta local BOOM + + + + Raven's scrollers use their original speed + Los scrollers de Raven usan su velocidad original + + + + Use sector based sound target code + Usar código de sonido objetivo basado en sectores + + + + Limit dehacked MaxHealth to health bonus + Limitar dehacked MaxHealth a la bonificación de vida + + + + Trace ignores lines with the same sector on both sides + El tracer ignora las líneas con el mismo sector en ambos lados + + + + Monsters can not move when hanging over a drop off + Los monstruos no se pueden mover cuando están sobre un abismo + + + + Scrolling sectors are additive like Boom + Los sectores de desplazamiento son aditivos como Boom + + + + Monsters can see semi-invisible players + Los monstruos pueden ver jugadores semi-invisibles + + + + Instantly moving floors are not silent + Los pisos que se mueven al instante no son silenciosos + + + + Sector sounds use original method for sound origin + Los sonidos de sector usan el método original para el origen del sonido + + + + Use original Doom heights for clipping against projectiles + Utilizar alturas originales de Doom durante una colisión con misiles + + + + Monsters can't be pushed over dropoffs + Los monstruos no pueden ser empujados a abismos + + + + Any monster which calls BOSSDEATH counts for level specials + Cualquier monstruo que llame a BOSSDEATH cuentan para niveles especiales + + + + Minotaur's floor flame is exploded immediately when feet are clipped + El fuego del suelo del minotauro explota inmediatamente cuando los pies lo atraviesan + + + + Force original velocity calculations for A_Mushroom in Dehacked mods + Forzar cálculos de velocidad originales para A_Mushroom en mods Dehacked + + + + Monsters are affected by friction and pushers/pullers + Los monstruos se ven afectados por la fricción y empujones/tirones + + + + Crushed monsters are turned into gibs, rather than replaced by gibs + Los monstruos aplastados se convierten en vísceras, en lugar de ser reemplazados por estas + + + + Friendly monsters aren't blocked by monster-blocking lines + Los monstruos amistosos ignoran las líneas de bloqueo de monstruos + + + + Invert sprite sorting order for sprites of equal distance + Invertir orden de clasificación de sprites para sprites de igual distancia + + + + Hitscans use original blockmap and hit check code + Los Hitscans usan el mapa de bloques original y el código de verificación de impacto + + + + Find neighboring light level like like Doom + Busque el nivel de luz vecina como en Doom + + + + Draw polyobjects the old fashioned way + Dibujar poliobjetos a la antigua usanza + + + + Ignore compositing when drawing masked midtextures + Ignore la composición mientras se dibuja texturas medias enmascaradas + + + + It is impossible to directly face cardinal direction + Es imposible mirar directamente la dirección cardinal + + + + Use the same floor motion behavior as Doom + Use el comportamiento de movimiento del piso como en Doom + + + + Net scripts are client side + Los scripts NET se ejecutan en el cliente + + + + Clients send full button info + Los clientes envían toda la información sobre los botones + + + + Players can't use 'land' CCMD + Los jugadores no pueden usar el comando 'land' + + + + Use Doom's original random number generator + Utilizar el generador de números aleatorios original de Doom + + + + Spheres have NOGRAVITY flag + Las esferas tienen el indicador NOGRAVITY + + + + Don't stop player scripts on disconnect + No detener los scripts de los jugadores al desconectarse + + + + Use horizontal explosion thrust of old ZDoom versions + Utilizar el empuje de explosión horizontal de versiones antiguas de ZDoom + + + + Non-SOLID things fall through invisible bridges + Cosas no sólidas caen a través de puentes invisibles + + + + Use old ZDoom jump physics + Usa las viejas físicas de salto de ZDoom + + + + Disallow weapon change when in mid raise/lower + No permitir el cambio de arma cuando está a medio subir/bajar + + + + Use vanilla's autoaim tracer behavior + Utilizar el comportamiento de autoapuntado original + + + + West spawns are silent + Las apariciones "West" son silenciosas + + + + Limited movement in the air + Movimiento limitado en el aire + + + + Allow map01 "plasma bump" bug + Permitir error "plasma bump" en map01 + + + + Allow instant respawn after death + Permitir reaparición instantánea después de morir + + + + Disable taunting + Desactivar burlas + + + + Use doom2.exe's original sound curve + Use la curva de sonido original de doom2.exe + + + + Use original doom2 intermission music + Utilizar la música original de intermedio de doom2 + + + + Disable stealth monsters + Deshabilitar monstruos sigilosos + + + + Radius damage has infinite height + El radio de daño tiene una altura infinita + + + + Disable crosshair + Desactivar mirilla + + + + Force weapon switch + Forzar el cambio de arma + + + + Do not spawn health items (DM) + No hacer aparecer items de salud (DM) + + + + Do not spawn powerups (DM) + No hacer aparecer potenciadores (DM) + + + + Weapons remain after pickup (DM) + Las armas permanecen después de recogerlas (DM) + + + + Falling damage (old ZDoom) + Daño de caída (antiguo ZDoom) + + + + Falling damage (Hexen) + Daño de caída (Hexen) + + + + Falling damage (Strife) + Daño de caída (Strife) + + + + Stay on same map when someone exits (DM) + Permanecer en el mapa cuando alguien lo termine (DM) + + + + Spawn players as far as possible (DM) + Hacer aparecer los jugadores lo más lejos posible (DM) + + + + Automatically respawn dead players (DM) + Reaparición automática de jugadores muertos (DM) + + + + Don't spawn armor (DM) + No hacer aparecer armadura (DM) + + + + Kill anyone who tries to exit the level (DM) + Mata a cualquiera que intente terminar el nivel (DM) + + + + Infinite ammo + Munición infinita + + + + No monsters + Sin monstruos + + + + Monsters respawn + Los monstruos reaparecen + + + + Items other than invuln. and invis. respawn + Los objetos (a excepción de invulnerabilidad e invisibilidad) reaparecen + + + + Fast monsters + Monstruos rápidos + + + + No jumping + Sin saltar + + + + No freelook + Sin cámara libre + + + + Respawn invulnerability and invisibility + Reaparición de invulnerabilidad e invisibilidad + + + + Arbitrator FOV + FOV preestablecido + + + + No multiplayer weapons in cooperative + Sin armas multijugador en cooperativo + + + + No crouching + Sin agachado + + + + Lose all old inventory on respawn (COOP) + Perder todo el inventario al reaparecer (COOP) + + + + Lose keys on respawn (COOP) + Perder llaves al reaparecer (COOP) + + + + Lose weapons on respawn (COOP) + Perder armas al reaparecer (COOP) + + + + Lose armor on respawn (COOP) + Perder armadura al reaparecer (COOP) + + + + Lose powerups on respawn (COOP) + Perder potenciadores al reaparecer (COOP) + + + + Lose ammo on respawn (COOP) + Perder munición al reaparecer (COOP) + + + + Lose half your ammo on respawn (COOP) + Perder la mitad de la munición al reaparecer (COOP) + + + + Jumping allowed + Saltar permitido + + + + Crouching allowed + Agachado permitido + + + + Drop weapons upon death + Soltar armas al morir + + + + Don't spawn runes + No generar runas + + + + Instantly return flags (ST/CTF) + Devolver banderas automáticamente (ST/CTF) + + + + Don't allow players to switch teams + No permitir que los jugadores cambien de equipo + + + + Players are automatically assigned teams + A los jugadores se les asignan equipos automáticamente + + + + Double the amount of ammo given + Duplicar la cantidad de munición + + + + Players slowly lose health over 100% like Quake + Los jugadores pierden lentamente la salud por encima del 100% como en Quake + + + + Allow BFG freeaiming + Permite apuntado libre de la BFG + + + + Barrels respawn + Los barriles reaparecen + + + + No respawn protection + No hay protección de reaparición + + + + All players start with a shotgun + Todos los jugadores comienzan con una escopeta + + + + Players respawn where they died (COOP) + Los jugadores reaparecen donde murieron (COOP) + + + + Don't clear frags after each level + No borrar indicadores después de cada nivel + + + + Player can't respawn + El jugador no puede reaparecer + + + + Lose a frag when killed + Perder un frag al morir + + + + Infinite inventory + Inventario infinito + + + + All monsters must be killed before exiting + Todos los monstruos deben ser asesinados antes de salir + + + + Players can't see the automap + Los jugadores no pueden ver el automap + + + + Allies can't be seen on the automap + Los aliados no se pueden ver en el automap + + + + You can't spy allies + No puedes espiar a tus aliados + + + + Players can use chase cam + Los jugadores pueden usar la cámara de persecución + + + + Players can't suicide + Los jugadores no pueden suicidarse + + + + Players can't use autoaim + Los jugadores no pueden usar autoapuntado + + + + Don't check ammo when switching weapons + No comprobar munición cuando se cambia de armas + + + + Kill all monsters spawned by a boss cube when the boss dies + Mata a todos los monstruos generados por un cubo de jefe cuando el jefe muere + + + + Do not count monsters in 'end level when dying' sectors towards kill count + No cuente los asesinatos de monstruos en los sectores de 'fin de nivel en caso de muerte' + + + + Clients can't identify targets + Los clientes no pueden identificar los objetivos + + + + lmsspectatorsettings applied in all game modes + Aplique lmsspectatorsettings en todos los modos de juego + + + + Clients can't draw coop info + Los clientes no pueden usar el CVar "Coop Info" + + + + Unlagged is disabled + Unlagged está deshabilitado + + + + Players don't block each other + Los jugadores no se bloquean entre ellos + + + + Clients don't show medals + Los clientes no muestran medallas + + + + Keys are shared between players + Las claves se comparten entre jugadores + + + + Player teams are preserved between maps + Los equipos se conservan entre mapas + + + + Force OpenGL defaults + Fuerza los valores predeterminados de OpenGL + + + + No rocket jumping + Sin "saltar cohetes" + + + + Award damage instead of kills + Premiar daño en lugar de asesinatos + + + + Force drawing alpha + Fuerza dibujando alfa + + + + Don't spawn multiplayer things + No hacer aparecer cosas del multijugador + + + + Force blood screen brightness on clients to emulate vanilla + Fuerza el brillo de la sangre en pantalla en los clientes para emular el original + + + + Teammates don't block each other + Los compañeros de equipo no se bloquean entre ellos + + + + No dropping allowed + No se permite soltar artículos + + + + No map reset on death in survival + No se restablece el mapa al morir en supervivencia + + + + Dead players can keep inventory + Los jugadores muertos pueden conservar el inventario + + + + ZandronumqAboutProvider + + + This plugin is distributed under the terms of the LGPL v2.1 or later. + + + Este complemento se distribuye bajo los términos de la licencia LGPL v2.1 o posterior. + + + + + + ZandronumqBroadcast + + + Listening to Zandronumq's LAN servers broadcasts on port %1. + Buscando transmisiones de servidores Zandronumq en LAN en el puerto %1. + + + + Failed to bind Zandronumq's LAN broadcasts listening socket on port %1. Will keep retrying silently. + Error al enlazar la conexión de escucha de las transmisiones LAN de Zandronumq en el puerto %1. Seguiremos reintentándolo en silencio. + + + + ZandronumqClientExeFile + + + client + cliente + + + + + No testing directory specified for Zandronumq + No se especificó ningún directorio de pruebas para Zandronumq + + + + Unable to create directory: +%1 + No se puede crear directorio: +%1 + + + + Unable to create directory: +%1/%2 + No se puede crear directorio: +%1/%2 + + + + Doomseeker + Doomseeker + + + + Please install now version "%1" into: +%2 + Instale ahora la versión "%1" en: +%2 + + + + <p>Installation of testing binaries for version %1 can potentially <b>overwrite</b> your files.</p><p>Game will be installed to:<br>%2</p><p>Do you want Doomseeker to extract Zandronumq files, potentially <b>overwriting existing ones</b>, and to copy all your configuration files from your base directory?</p> + <p>La instalación de los binarios de prueba para la versión %1 puede potencialmente <b>rescribir</b> tus archivos.</p><p>El juego se instalará en:<br>%2</p><p>Quieres que Doomseeker extraiga los archivos de Zandronumq, potencialmente <b>reescribiendo los archivos ya existentes</b>, y copiar todos los archivos de configuración de tu directorio base?</p> + + + + Zandronumq testing version %1 can be installed. + +Game will be installed to: +%2 + +Do you want Doomseeker to install that version and copy all your configuration files from your base directory? + La versión de prueba de Zandronumq %1 puede instalarse. + +El juego puede instalarse en: +%2 + +Quieres que Doomseeker instale esta versión y copie todos tus archivos de configuración de tu directorio base? + + + + Doomseeker - install Zandronumq testing version + Doomseeker - instalar la versión de prueba de Zandronumq + + + + %1 +doesn't exist. +You need to install new testing binaries. + %1 +No existe. +Debe instalar los nuevos ejecutables de prueba. + + + + %1 +exists but is NOT a directory. +Cannot proceed. + %1 +existe pero NO es un directorio. +No se puede proceder. + + + + %1 +exists but doesn't contain Zandronumq executable. + +Doomseeker can still install the game there if you want. + %1 +existe, pero no contiene el ejecutable de Zandronumq. + +Doomseeker puede instalar el juego allí igualmente si lo desea. + + + + Downloading Zandronumq testing binary from URL: %1 + Descargando el archivo binario de prueba de Zandronumq desde la URL: %1 + + + + Doomseeker - download failed + Doomseeker - descarga fallida + + + + Failed to download testing binary. + +%1 + Error al descargar el binario de la versión de prueba. + +%1 + + + + Unpacking file: %1 + Desempaquetando archivo: %1 + + + + Doomseeker - unpack failed + Doomseeker - error al desempaquetar + + + + Failed to unpack: %1 + Error al desempaquetar: %1 + + + + %1 + should be a script file but is a directory! + %1 + debería ser un script, pero es un directorio! + + + + You don't have permissions to execute file: %1 + + No tienes permisos para ejecutar el archivo: %1 + + + + + Couldn't open batch file "%1" for writing + No se pudo abrir el script "%1" para escribir + + + + Error while writing batch file "%1" + Error al escribir el script "%1" + + + + Cannot set permissions for file: +%1 + No se pueden definir los permisos para el archivo: +%1 + + + + ZandronumqGameInfo + + + Survival + Supervivencia + + + + Invasion + Invasión + + + + Duel + Duelo + + + + Terminator + Terminator + + + + LMS + LMS + + + + Team LMS + LMS por equipos + + + + Possession + Posesión + + + + Team Poss + Posesión por equipos + + + + Team Game + Juego por equipos + + + + One Flag CTF + CTF con una bandera + + + + Skulltag + Skulltag + + + + Domination + Dominación + + + + ZandronumqMasterClient + + + You may contact Zandronumq staff about this through IRC: <b>irc.qzandronum.com #zandronumq</b> or on the forum: <a href="https://qzandronum.com/forum">https://qzandronum.com/forum.</a> + Puede ponerse en contacto con el personal de Zandronumq a través de IRC: <b>irc.qzandronum.com #zandronumq</b> o en el foro: <a href="https://qzandronum.com/forum">https://qzandronum.com/forum.</a> + + + + ZandronumqRConProtocol + + + Connection attempt ... + Intento de conexión ... + + + + Too many failed connection attempts. Aborting. + Demasiados intentos fallidos de conexión. Abortando. + + + + Authenticating ... + Autenticando ... + + + + Too many failed authentication attempts. Aborting. + Demasiados intentos de autenticación fallidos. Abortando. + + + + Delaying for about %n seconds before next authentication attempt. + + Retraso de aproximadamente %n segundo antes del próximo intento de autenticación. + Retraso de aproximadamente %n segundos antes del próximo intento de autenticación. + + + + + Failed to establish connection. + Error al establecer la conexión. + + + + Timeout on authentication. + Límite de tiempo alcanzado en la autenticación. + + + + You have been banned from this server. + Has sido expulsado de este servidor. + + + + The protocol appears to be outdated. + El protocolo parece estar desactualizado. + + + + Authentication failure. + Fallo de autenticación. + + + + Remote console connection established. + Conexión a la consola remota establecida. + + + + ----- + ----- + + + + ZandronumqServer + + + Blue + Azul + + + + Red + Rojo + + + + Green + Verde + + + + Gold + Oro + + + diff --git a/src/plugins/zandronumq/translations/zandronumq_pl_PL.ts b/src/plugins/zandronumq/translations/zandronumq_pl_PL.ts new file mode 100644 index 00000000..b4a9d1cd --- /dev/null +++ b/src/plugins/zandronumq/translations/zandronumq_pl_PL.ts @@ -0,0 +1,3609 @@ + + + + + EngineZandronumqConfigBox + + + Testing Releases + Wydania testowe + + + + Directory for testing releases: + Katalog dla wydań testowych: + + + + Allow servers to display my country + Pozwól serwerom wyświetlać mój kraj + + + + Doomseeker - choose Zandronumq testing directory + Doomseeker - wybierz katalog testowy dla Zandronumq + + + + FlagsPage + + Flags + Flagi + + + + Zandronumq + Zandronumq + + + + Zandronumq 2 (old) + Zandronumq 2 (stary) + + + + Zandronumq 3 + Zandronumq 3 + + + + None + Brak + + + + Old (ZDoom) + Stary (ZDoom) + + + + Hexen + Hexen + + + + Strife + Strife + + + + Default + Domyślnie + + + + No + Nie + + + + Yes + Tak + + + + Unknown Zandronumq version in the config. Reverting to default. + Nieznana wersja Zandronumq w pliku konfiguracyjnym. Używam wartości domyślnej. + + + + Tried to set unknown Zandronumq version. Reverting to default. + Próbowano ustawić nieznaną wersję Zandronumq. Powracam do wartości domyślnej. + + + + Form + + + + + Game version: + Wersja gry: + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">If this is checked then Zandronumq may override some of the settings selected here.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">(+sv_defaultdmflags)</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Gdy to jest zaznaczone, to Zandronumq może nadpisać niektóre z ustawień, które są tu wybrane.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">(+sv_defaultdmflags)</span></p></body></html> + + + + Default DMFlags + Domyślne DMFlagi + + + + + Environment + Środowisko + + + + Falling damage: + Ból od upadku: + + + + No monsters + Brak potworów + + + + Items respawn + Odradzanie przedmiotów + + + + Barrels respawn + Odradzanie beczek + + + + Respawn invulnerability and invisibility spheres. + Odradzanie kul nieśmiertelności i niewidzialności. + + + + Mega powerups respawn + Odradzanie mega-powerupów + + + + Teams + Drużyny + + + + Server picks teams + Serwer wybiera drużyny + + + + Players can't switch teams + Gracze nie mogą zmieniać drużyn + + + + Keep teams after a map change + Zachowuj drużyny po zmianie mapy + + + + Hide allies on the automap + Ukrywaj sojuszników na automapie + + + + Don't let players spy on allies + Nie pozwalaj graczom podglądać sojuszników + + + + Instant flag/skull return + Natychmiastowy zwrot flagi/czaszki + + + + Don't use ping-based backwards reconciliation for player-fired hitscans and rails. + Nie używaj opartego na pingu wstecznego poprawiania dla wystrzelonych przez graczy hitscanów i promieni. + + + + No unlagged + Wyłącz unlagged + + + + Apply lmsspectatorsettings in all game modes. + Zastosuj lmsspectatorsettings we wszystkich trybach gry. + + + + Always apply LMS spectator settings + Zawsze stostuj ustawienia widzów LMS + + + + Enforces clients not to show medals, i.e. behave as if cl_medals == 0. + Wymusza na klientach nie pokazywanie medali, tak jakby cl_medals == 0. + + + + No medals + Brak medali + + + + General + Ogólne + + + + Disallow + Nie pozwalaj + + + + Suicide + Samobójstwo + + + + Respawn + Respawn + + + + <html><head/><body><p align="justify">P_RadiusAttack doesn't give players any z-momentum if the attack was made by a player. This essentially disables rocket jumping.</p></body></html> + <html><head/><body><p align="justify">P_RadiusAttack nie nadaje graczom z-pędu jeżeli źródłem ataku jest sam gracz. To wyłącza skakanie na rakietach.</p></body></html> + + + + Rocket jump + Skakanie na rakietach + + + + Taunt + Okrzyki + + + + Item drop + Upuszczanie przedmiotów + + + + Use automap + Używanie automapy + + + + Turn off translucency + Wyłączanie przezroczystości + + + + Use crosshairs + Używanie celownika + + + + Use custom GL lighting settings + Używanie własnych ustawień światła w OpenGL + + + + Enforces clients not to identify players, i.e. behave as if cl_identifytarget == 0. + Wymusza na klientach brak identyfikacji graczy, tak jakby cl_identifytarget == 0. + + + + Target identify + Identyfikacja celów + + + + Enforces clients not to draw coop info, i.e. behave as if cl_drawcoopinfo == 0. + Wymusza na klientach brak rysowania informacji w coopie, tak jakby cl_drawcoopinfo == 0. + + + + Display coop info + Wyświetlanie informacji coop + + + + Use autoaim + Używanie autocelowania + + + + Only let the arbitrator set FOV (for all players) + Tylko serwer może ustalić FOV (wszystkim graczom) + + + + Use FOV + Używanie FOV + + + + Use freelook + Patrzenia góra-dół + + + + <html><head/><body><p>Players are not allowed to use the land CCMD. Because of Zandronumq's default amount of air control, flying players can get a huge speed boast with the land CCMD. Disallowing players to land, allows to keep the default air control most people are used to while not giving flying players too much of an advantage.</p></body></html> + <html><head/><body><p>Gracze nie mogą używać komendy konsolowej land. Ze względu na domyślną swobodę kontroli w powietrzu, latający gracze mogą ogromnie przyspieszać za pomocą komendy land. Zabranianie graczom lądować pozwala zachować domyślną kontrolę w powietrzu, do której gracze są przyzwyczajeni, nie dając im jednocześnie znacznej przewagi.</p></body></html> + + + + Use 'land' console command + Używania komendy 'land' + + + + <html><head/><body><p>Don't allow players to change how strongly will their screen flash when they get hit.</p></body></html> + <html><head/><body><p>Zabroń graczom zmieniać, jak mocno zabłyśnie ich ekran, gdy otrzymają obrażenia.</p></body></html> + + + + Change bloodied screen brightness + Zmiana jasności zakrwawionego ekranu + + + + Abilities + Zdolności + + + + Jumping: + Skakanie: + + + + Crouching: + Kucanie: + + + + Infinite inventory + Nieskończony ekwipunek + + + + Infinite ammo + Nieskończona amunicja + + + + Like Quake 3 + Jak w Quake 3 + + + + Slowly lose health when over 100% + Powoli trać zdrowie powyżej 100% + + + + Can use chasecam + Można używać kamery z 3 osoby + + + Disallow BFG freeaiming in multiplayer games. + Zabroń celowania góra-dól z BFG w grach wieloosobowych. + + + + Allow BFG freeaiming + Pozwól na celowanie góra-dół z BFG + + + + Behavior + Zachowanie + + + + Players can walk through each other + Gracze mogą przenikać przez siebie + + + + Allies can walk through each other + Sojusznicy mogą przez siebie przechodzić + + + + Players block each other normally + Gracze blokują się normalnie + + + + Don't check ammo when switching weapons + Nie sprawdzaj amunicji podczas zmiany broni + + + + Force inactive players to spectate after: + Wymuś tryb widza dla nieaktywnych graczy po: + + + + min. + min. + + + + Players + Gracze + + + + Score damage, not kills + Nagradzaj obrażenia, nie zabójstwa + + + + Don't spawn Deathmatch weapons + Nie spawnuj broni z Deathmatcha + + + + Spawn map actors in coop as if the game was single player. + Spawnuj aktorów na mapie w trybie coop, tak jakby była to gra single player. + + + + Don't spawn any multiplayer actor in coop + Nie spawnuj żadnego aktora wieloosobowego w coopie + + + + Monsters... + Potwory... + + + + are fast (like Nightmare) + są szybkie (jak na Nightmare) + + + + respawn (like Nightmare) + odradzają się (jak na Nightmare) + + + + must be killed to enable exit + muszą zostać zabite aby można było wyjść + + + + Kill percentage: + Procent zabójstw: + + + + Multiplier of damage dealt by monsters. + Mnożnik obrażeń zadawanych przez potwory. + + + + Damage factor: + Mnożnik obrażeń: + + + + <html><body><p>Multiplier of damage dealt by monsters.</p></body></html> + <html><body><p>Mnożnik obrażeń zadawanych przez potwory.</p></body></html> + + + + Kill all monsters spawned by a boss cube when the boss dies + Zabij wszystkie potwory spawnięte przez kostkę bossa gdy boss zginie + + + + On player death... + Gdy gracz zginie... + + + + Respawn where died + Odradza się tam, gdzie zginął + + + + Lose all inventory + Traci cały ekwipunek + + + + Lose armor + Traci zbroję + + + + Lose keys + Traci klucze + + + + Lose powerups + Traci powerupy + + + + Lose weapons + Traci bronie + + + + Lose all ammo + Traci całą amunicję + + + + Lose half ammo + Traci połowę amunicji + + + + <html><head/><body><p>Affects game modes where &quot;max. lives&quot; can be used. If set, players who become dead spectators (run out of lives) will still keep inventory in accordance to the &quot;Lose *&quot; flags above. If unset, players who lose all lives will always lose entire inventory.</p></body></html> + <html><head/><body><p>Wpływa na tryby gry w których można używać &quot;maks. ilości żyć&quot;. Przy włączeniu, gracze którzy stają się martwymi widzami (tracą wszystkie życia), mogą wciąż zachować swój ekwipunek zgodnie z powyższymi flagami &quot;Traci *&quot;. Przy wyłączeniu, gracze którzy tracą wszystkie życia, zawsze tracą też cały ekwipunek.</p></body></html> + + + + Players who lose all lives can keep inventory + Gracze którzy tracą wszystkie życia mogą zachować ekwipunek + + + + Share keys between players + Współdziel klucze pomiędzy graczami + + + + <html><head/><body><p>Players will be respawned with full lives but the map will not be reset. Inventory will be preserved in accordance to &quot;Lose inventory&quot; flags. Players will be able to continue from the point where they died.</p></body></html> + <html><head/><body><p>Gracze zostaną odrodzeni z pełną ilością żyć, ale mapa nie zostanie zresetowana. Ekwipunek zostanie zachowany zgodnie z flagami &quot;Tracenia ekwipunku&quot;. Gracze będą mogli kontynuować grę od tego punktu, w którym zginęli.</p></body></html + + + + Survival only: no map reset when all players die + Tylko w surwiwalu: nie resetuj mapy, gdy wszyscy gracze zginą + + + + Cooperative + Kooperacja + + + + When players die, they... + Gdy gracze giną, to... + + + + Respawn automatically + Od razu się odradzają + + + + Drop their weapon + Upuszczają swoją broń + + + + Respawn farthest away from others + Odradzają się najdalej od innych + + + + Lose a frag + Tracą fraga + + + + Respawn with a shotgun + Odradzają się z shotgunem + + + + Don't get respawn protection + Nie mają ochrony po respawnie + + + + When someone exits the level... + Gdy ktoś opuści poziom... + + + + Continue to the next map + Kontynuuj do następnej mapy + + + + Restart the current level + Restartuj obecny poziom + + + + Kill the player + Zabij tego gracza + + + + Keep frags after map change + Zachowuj fragi po zmianie mapy + + + + Weapons && Ammo + Bronie i amunicja + + + + Weapons stay after pickup + Bronie nie znikają po podniesieniu + + + + Double ammo + Podwójna amunicja + + + + Don't spawn... + Nie spawnuj... + + + + Health + Zdrowia + + + + Armor + Zbroi + + + + Runes + Run + + + + Deathmatch + Deathmatch + + + + Weapons + Bronie + + + + Chainsaw + Piła + + + + Pistol + Pistolet + + + + Shotgun + Shotgun + + + + Super shotgun + Dwururka + + + + Chaingun + Chaingun + + + + Minigun + Minigun + + + + Rocket launcher + Rakietnica + + + + Grenade launcher + Granatnik + + + + Plasma rifle + Plazmówka + + + + Railgun + Railgun + + + + lmsallowedweapons: + lsmallowedweapons: + + + + + + + + + + + 0 + 0 + + + + lmsspectatorsettings: + lmsspectatorsettings: + + + + Spectators can... + Widzowie mogą... + + + + Talk to active players + Rozmawiać z żyjącymi graczami + + + + View the game + Oglądać grę + + + + LMS + LMS + + + + Enable buggier wall clipping so players can wallrun. + Włącz zbugowaną kolizję ze ścianami, aby gracze mogli robić wallrun. + + + + Enable wall running + Włącz wall running + + + + Pickups are only heard locally. + Podniesione przedmioty słychać tylko lokalnie. + + + + Don't let others hear pickups + Inni nie słyszą podniesień + + + + Allow instant respawn + Zezwól na natychmiastowy respawn + + + + <html><head/><body><p>Disable stealth monsters, since doom2.exe didn't have them.</p><p><span style=" font-weight:600;">Note: this handles ZDoom's invisible monsters.</span></p><p><span style=" font-weight:600;">THIS DOESN'T AFFECT THE PARTIAL INVISIBILITY SPHERE IN ANY WAY. See &quot;Monsters see semi-invisible players&quot; for that.</span></p></body></html> + <html><head/><body><p>Wyłącz potwory "stealth", ponieważ doom2.exe ich nie miało.</p><p><span style=" font-weight:600;">Uwaga: to odnosi się do niewidzialnych potworów z ZDooma.</span></p><p><span style=" font-weight:600;">TO NIE WPŁYWA NA KULĘ POŁOWICZNEJ NIEWIDZIALNOŚCI W ŻADEN SPOSÓB. Użyj do tego ustawienia &quot;Potwory widzą na wpół-niewidzialnych graczy&quot;.</span></p></body></html> + + + + Disable stealth monsters + Wyłącz potwory "stealth" + + + + Limit actors to one sound at a time. + Ogranicz aktorów do jednego dźwięku na raz. + + + + Allow silent BFG trick + Pozwól na trick z cichym BFG + + + + Clients use the vanilla Doom weapon on pickup behavior. + Klienci używają zachowania z vanilla Dooma po podniesieniu broni. + + + + Original weapon switch + Oryginalna zmiana broni + + + + Limited movement in the air + Ograniczone poruszanie w powietrzu + + + + This affects the partial invisibility sphere. + To wpływa na kulę połowicznej niewidzialności. + + + + Monsters see semi-invisible players + Potwory widzą na wpół-niewidzialnych graczy + + + + Allow the map01 "plasma bump" bug. + Zezwól na błąd "plasma bump" z map01. + + + + Plasma bump bug + Błąd plasma bump + + + + Any boss death activates map specials + Śmierć dowolnego bossa aktywuje speciale na mapie + + + + Friction/pushers/pullers affect Monsters + Tarcie/popychacze i ciągniki wpływają na potwory + + + + <html><head/><body><p>Crushed monsters are turned into gibs, rather than replaced by gibs.</p></body></html> + <html><head/><body><p>Zgniecione potwory zamieniają się we flaki, a nie są przez nie zastępowane.</p></body></html> + + + + Crusher gibs by morphing, not replacement + Zgniatarka zmienia we flaki, zamiast podmieniać + + + + Block monster lines ignore friendly monsters + Linie blokujące potwory ignorują przyjazne potwory + + + + Find neighboring light level like Doom + Szukaj sąsiadującego poziomu światła jak w Doomie + + + + Use doom2.exe's original intermission screens/music. + Używaj muzyki i ekranów z doom2.exe podczas intermisji. + + + + Use old intermission screens/music + Używaj starych intermisji + + + + Scrolling sectors are additive like in Boom. + Przesuwające się sektory dodają się jak w Boomie. + + + + Scrolling sectors are additive + Przesuwające sektory dodają się + + + + Sector sounds use original method for sound origin. + Dźwięki sektorów używają oryginalnej metody pozycjonowania dźwięku. + + + + Sector sounds use original method + Dźwięki sektorów używają oryginalnej metody + + + + Monsters cannot move when hanging over a dropoff. + Potwory utykają nad krawędziami. + + + + No monsters dropoff move + Potwory utykają nad krawędziami + + + + Instantly moving floors are not silent. + Natychmiastowo poruszane podłogi nie są ciche. + + + + Instantly moving floors aren't silent + Natychmiastowo poruszane podłogi nie są ciche + + + + <html><head/><body><p>Clients send ucmd.buttons as &quot;long&quot; instead of as &quot;byte&quot; in CLIENTCOMMANDS_ClientMove. So far this is only necessary if the ACS function GetPlayerInput is used in a server side script to check for buttons bigger than BT_ZOOM. Otherwise this information is completely useless for the server and the additional net traffic to send it should be avoided.</p></body></html> + <html><head/><body><p>Klienci wysyłają ucmd.buttons jako &quot;long&quot; zamiast jako &quot;byte&quot; w CLIENTCOMMANDS_ClientMove. Jak do tej pory, było to jedynie potrzebne w funkcji ACS GetPlayerInput, gdy jest ona użyta po stronie serwera do sprawdzenia przycisku większego niż BT_ZOOM. W każdym innym przypadku ta informacja jest całkowicie bezużyteczna dla serwera i powinno się unikać dodatkowego zużycia łącza.</p></body></html> + + + + Clients send full button info + Klienci wysyłają pełne info o przyciskach + + + + <html><head/><body><p>Use Doom's random table instead of ZDoom's random number generator. Affects weapon damage among other things.</p></body></html> + <html><head/><body><p>Używaj losowej tablicy z Dooma zamiast generatora liczb losowych z ZDooma. Wpływa to, między innymi, na obrażenia od broni.</p></body></html> + + + + Old random number generator + Stary generator liczb losowych + + + + Monsters can't be pushed off cliffs + Potwory nie mogą być wypchnięte przez przepaść + + + + Old damage radius (infinite height) + Obrażenia obszarowe mają nieskończoną wysokość + + + + Minotaur's floor flame explodes immediately when feet are clipped + Ogień podłogowy Minotaura eksploduje natychmiast gdy stopy są przycięte + + + + Original velocity calc. for A_Mushroom in Dehacked + Oryginalne obliczanie prędkości dla A_Mushroom w Dehacked + + + + Sprite sort order inverted for sprites of equal distance + Odwrócone sortowanie sprite'ów gdy są w tej samej odległości + + + + Hitscans use original blockmap and hit check code + Hitscany używają oryginalnego kodu blockmap i detekcji trafień + + + + Draw polyobjects the old fashioned way + Rysuj polyobjekty w stary sposób + + + + Compatibility + Kompatybilność + + + + Use original missile clipping height + Używaj oryginalnej wysokości kolizji pocisków + + + + Use sector based sound target code + Używaj kodu celowania dźwiękiem opartego na sektorach + + + + <html><head/><body><p>Doom's hitscan tracing code ignores all lines with both sides in the same sector. ZDoom's does not. This option reverts to the original but less precise behavior. </p></body></html> + <html><head/><body><p>Kod w Doomie odpowiedzialny za śledzenie hitscanów ignoruje wszystkie linie, które mają ten sam sektor po obu stronach. ZDoom tego nie robi. Ta opcja przywraca oryginalne, lecz mniej dokładne zachowanie. </p></body></html> + + + + Trace ignore lines w/ same sector on both sides + Trasowanie ignoruje linie o tym samym sektorze po obu stronach + + + + Limit deh.MaxHealth to health bonus + Ogranicz deh.MaxHealth do bonusu energii + + + + <html><head/><body><p>The scrolling floor specials in Heretic and Hexen move the player much faster than the actual texture scrolling speed. Enable this option to restore this effect. </p></body></html> + <html><head/><body><p>Akcje przesuwające podłogę w Hereticu i Hexenie przesuwają graczy znacznie szybciej, niż teksturę. Włączenie tej opcji przywraca ten efekt.</p></body></html> + + + + Raven's scrollers use original speed + Przesuwniki Ravena używają oryginalnych prędkości + + + + <html><head/><body><p>Add NOGRAVITY to actors named InvulnerabilitySphere, Soulsphere, Megasphere and BlurSphere when spawned by the map.</p></body></html> + <html><head/><body><p>Dodaj NOGRAVITY aktorom o nazwach InvulnerabilitySphere, Soulsphere, Megasphere i BlurSphere gdy są spawnowane przez mapę.</p></body></html> + + + + Add NOGRAVITY flag to spheres + Dodaj flagę NOGRAVITY kulom + + + + <html><head/><body><p>When a player leaves the game, don't stop any scripts of that player that are still running.</p></body></html> + <html><head/><body><p>Gdy gracz opuści grę, nie zatrzymuj skryptów, które są dla niego uruchomione.</p></body></html> + + + + Don't stop player scripts on disconnect + Nie zatrzymuj skryptów gracza po rozłączeniu + + + + <html><head/><body><p>If this is enabled, explosions cause a strong horizontal thrust like in old ZDoom versions.</p></body></html> + <html><head/><body><p>Gdy jest to włączone, eksplozje silnie popychają w poziomie jak w starych wersjach ZDooma.</p></body></html> + + + + Old ZDoom horizontal thrust + Popychanie poziome ze starego ZDooma + + + + <html><head/><body><p>If this is enabled, non-SOLID things like flags fall through bridges (as they used to do in old ZDoom versions).</p></body></html> + + <html><head/><body><p>Gdy to jest włączone, nie-SOLIDne obiekty jak flagi wpadają pod mosty (tak jak to było w starych wersjach ZDooma).</p></body></html> + + + + Old ZDoom bridge drops + Upuszczanie pod most ze starego ZDooma + + + + <html><head/><body><p>Uses old ZDoom jump physics, it's a minor bug in the gravity code that causes gravity application in the wrong place.</p></body></html> + <html><head/><body><p>Używaj fizyki skoku ze starego ZDooma. To mały błąd w kodzie, który aplikuje grawitację nie w tym miejscu, co trzeba.</p></body></html> + + + + Ignore compositing when drawing masked midtextures + Ignoruj kompozycję podczas rysowania maskowanych midtekstur + + + + It is impossible to face directly NSEW + Nie można obrócić się bezpośrednio w kierunku kardynalnym + + + + Use the same floor motion behavior as Doom + Użyj takiego zachowania ruchu podłóg, jak w Doomie + + + + zandronumq compatflags + zandronumq compatflags + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Uses old ZDoom jump physics, it's a minor bug in the gravity code that causes gravity application in the wrong place.</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Używaj fizyki skoku ze starego ZDooma. To mały błąd w kodzie, który aplikuje grawitację nie w tym miejscu, co trzeba.</span></p></body></html> + + + + ZDoom 1.23B33 jump physics + Fizyka skoku z ZDooma 1.23B33 + + + + <html><head/><p>Zandronumq uses more tracers to fill in the gaps, this reverts it to vanilla's 3 tracer behavior</p></body></html> + <html><head/><p>Zandronumq używa więcej promieni do wypełnienia dziur. To przywraca używanie tylko 3 promieni z vanilli.</p></body></html> + + + + Use vanilla autoaim tracer behavior + Trasowanie autocelowania takie jak w vanilli + + + + <html><head/><body><p>Use Doom's shortest texture find behavior. This is requied by some WADs in MAP07.</p></body></html> + <html><head/><body><p>Używaj najkrótszego wyszukiwania tekstury z Dooma. Jest to wymagane przez niektóre WADy w MAP07.</p></body></html> + + + + Find shortest textures like Doom + Wyszukuj najkrótszej tekstury jak w Doomie + + + + Limit pain elementals to 20 lost souls + Ogranicz pain elemental do 20 lost souls + + + + Spawned item drops on the floor + Spawnięte przedmioty spadają na podłogę + + + + <html><head/><body><p>Treat ACS scripts with the SCRIPTF_Net flag to be client side, i.e. executed on the clients, but not on the server.</p></body></html> + <html><head/><body><p>Traktuj skrypty ACS z flagą SCRIPTF_Net jako skrypty po stronie klienta, tzn. wykonuj je u klientów, a nie na serwerze.</p></body></html> + + + + NET scripts are clientside + Skrypty NET są po stronie klienta + + + + Actors are infinitely tall + Nieskończenie wysocy aktorzy + + + + Don't fix loop index for stair building. + Nie naprawiaj indeksu pętli do budowania schodów. + + + + Use buggier stair building + Używaj zbugowanego budowania schodów + + + + Disable Boom door light effect + Wyłącz Boomowy efekt świateł z drzwi + + + + All special lines can drop use lines + Wszystkie specjalne linie mogą anulować używanie linii + + + + Original sound curve + Oryginalna krzywa dźwięku + + + + Disallow weapon change until fully drawn or hidden + Nie można zmieniać broni w trakcie wyciągania/chowania + + + + West spawns are silent + Zachodnie spawny są ciche + + + + Compatibility 2 + Kompatybilność 2 + + + + Voting + Głosowanie + + + + zandronumq dmflags + zandronumq dmflags + + + + dmflags + dmflags + + + + dmflags2 + dmflags2 + + + dmflags3 + dmflags3 + + + + compatflags + compatflags + + + + compatflags2 + compatflags2 + + + + QObject + + + Time limit: + Limit czasu: + + + + Frag limit: + Limit fragów: + + + + Point limit: + Limit punktów: + + + + Win limit: + Limit zwycięstw: + + + + Duel limit: + Limit pojedynków: + + + + Max. lives: + Max. żyć: + + + + << Unknown >> + << Nieznana >> + + + + TestingProgressDialog + + + Downloading testing binaries... + Pobieram binarki testowe ... + + + + Cancel + Anuluj + + + + VotingSetupWidget + + + Form + + + + + Use this page + Używaj tej strony + + + + Who can vote + Kto może głosować + + + + All can vote + Wszyscy mogą głosować + + + + No one can vote + Nikt nie może głosować + + + + Spectators can't vote + Widzowie nie mogą głosować + + + + Minimum number of players required to call a vote: + Minimalna ilość graczy wymagana do głosu: + + + + Allow specific votes + Zezwól na głosowanie + + + + pointlimit + limit punktów + + + + duellimit + limit pojedynków + + + + timelimit + limit czasu + + + + winlimit + limit zwycięstw + + + + changemap + changemap + + + + kick + kopnięcie + + + + map + map + + + + fraglimit + limit fragów + + + + force players to spectate + wymuszanie oglądania na graczach + + + + Vote flooding protection enabled + Chroń przed floodowaniem głosowaniami + + + + Zandronumq2::Dmflags + + + Use Doom's shortest texture behavior + Użyj Doomowego zachowania najkrótszej tekstury + + + + Don't fix loop index for stair building + Nie naprawiaj indeksu pętli do budowania schodów + + + + Pain elemental is limited to 20 lost souls + Pain elemental jest ograniczony do 20 lost souls + + + + Pickups are only heard locally + Podniesienia przedmiotów słychać tylko lokalnie + + + + Infinitely tall actors + Nieskończenie wysocy aktorzy + + + + Limit actors to only one sound + Ogranicz aktorów do tylko jednego dźwięku + + + + Enable wallrunning + Włącz wallrunning + + + + Dropped items spawn on floor + Upuszczane przedmioty tworzone są na podłodze + + + + Special lines block use line + Linie specjalne blokują użycie linii + + + + Disable BOOM local door light effect + Wyłącz efekt lokalnego światła drzwi z BOOMa + + + + Raven's scrollers use their original speed + Przewijacze Ravena używają oryginalnych prędkości + + + + Use sector based sound target code + Używaj kodu celowania dźwięków opartego na sektorach + + + + Limit dehacked MaxHealth to health bonus + Ogranicz maks. zdrowie z dehacked do bonusowego zdrowia + + + + Trace ignores lines with the same sector on both sides + Śledzenie ignoruje linie z tym samym sektorem po obu stronach + + + + Monsters can not move when hanging over a drop off + Potwory utykają gdy wiszą nad przepaścią + + + + Scrolling sectors are additive like Boom + Przesuwające sektory dodają się jak w Boomie + + + + Monsters can see semi-invisible players + Potwory mogą widzieć na-wpół-niewidzialnych graczy + + + + Instantly moving floors are not silent + Natychmiastowo ruszające się podłogi nie są ciche + + + + Sector sounds use original method for sound origin + Dźwięki sektorów używają oryginalnej metody pozycjonowania dźwięku + + + + Use original Doom heights for clipping against projectiles + Używaj oryginalnych wysokości z Dooma podczas kolizji z pociskami + + + + Monsters can't be pushed over dropoffs + Potwory nie mogą być wypchnięte przez przepaść + + + + Any monster which calls BOSSDEATH counts for level specials + Każdy potwór, który wywołuje BOSSDEATH liczy się dla specjali na poziomie + + + + Minotaur's floor flame is exploded immediately when feet are clipped + Ogień podłogowy Minotaura eksploduje natychmiast gdy stopy są przycięte + + + + Force original velocity calculations for A_Mushroom in Dehacked mods + Oryginalne obliczanie prędkości dla A_Mushroom w Dehacked + + + + Monsters are affected by friction and pushers/pullers + Tarcie oraz popychacze i ciągniki wpływają na potwory + + + + Crushed monsters are turned into gibs, rather than replaced by gibs + Zgniecione potwory zamieniają się we flaki, a nie są przez nie zastępowane + + + + Friendly monsters aren't blocked by monster-blocking lines + Linie blokujące potwory ignorują przyjazne potwory + + + + Invert sprite sorting order for sprites of equal distance + Odwrócone sortowanie sprite'ów gdy są w tej samej odległości + + + + Hitscans use original blockmap and hit check code + Hitscany używają oryginalnego kodu blockmap i detekcji trafień + + + + Find neighboring light level like like Doom + Szukaj sąsiadującego poziomu światła jak w Doomie + + + + Draw polyobjects the old fashioned way + Rysuj polyobjecty w stary sposób + + + + Net scripts are client side + Skrypty NET są po stronie klienta + + + + Clients send full button info + Klienci wysyłają pełne info o przyciskach + + + + Players can't use 'land' CCMD + Gracze nie mogą używać komendy 'land' + + + + Use Doom's original random number generator + Używaj oryginalnego generatora liczb losowych z Dooma + + + + Spheres have NOGRAVITY flag + Kule mają flagę NOGRAVITY + + + + Don't stop player scripts on disconnect + Nie zatrzymuj skryptów gracza po rozłączeniu + + + + Use horizontal explosion thrust of old ZDoom versions + Eksplozje popychają w poziomie jak w starym ZDoomie + + + + Non-SOLID things fall through invisible bridges + Nie-SOLIDne obiekty przenikają przez aktorów mostu + + + + Use old ZDoom jump physics + Fizyka skoku ze starego ZDooma + + + + Disallow weapon change when in mid raise/lower + Nie można zmieniać broni w trakcie wyciągania/chowania + + + + Use vanilla's autoaim tracer behavior + Trasowanie autocelowania takie jak w vanilli + + + + West spawns are silent + Zachodnie spawny są ciche + + + + Limited movement in the air + Ograniczone poruszanie w powietrzu + + + + Allow map01 "plasma bump" bug + Pozwól na błąd "plasma bump" z map01 + + + + Allow instant respawn after death + Pozwól na natychmiastowy respawn po śmierci + + + + Disable taunting + Wyłącz okrzyki + + + + Use doom2.exe's original sound curve + Używaj krzywej dźwięku z doom2.exe + + + + Use original doom2 intermission music + Używaj oryginalnej (doom2) muzyki podczas intermisji + + + + Disable stealth monsters + Wyłącz potwory "stealth" + + + + Radius damage has infinite height + Obrażenia obszarowe mają nieskończoną wysokość + + + + Disable crosshair + Wyłącz celownik + + + + Force weapon switch + Wymuś zmianę broni + + + + Do not spawn health items (DM) + Nie spawnuj przedmiotów ze zdrowiem (DM) + + + + Do not spawn powerups (DM) + Nie spawnuj powerupów (DM) + + + + Weapons remain after pickup (DM) + Bronie zostają po podniesieniu (DM) + + + + Falling damage (old ZDoom) + Upadek boli (stary ZDoom) + + + + Falling damage (Hexen) + Upadek boli (Hexen) + + + + Falling damage (Strife) + Upadek boli (Strife) + + + + Stay on same map when someone exits (DM) + Nie zmieniaj mapy gdy ktoś ją ukończy (DM) + + + + Spawn players as far as possible (DM) + Spawnuj graczy jak najdalej od siebie (DM) + + + + Automatically respawn dead players (DM) + Automatycznie respawnuj martwych graczy (DM) + + + + Don't spawn armor (DM) + Nie spawnuj zbroi (DM) + + + + Kill anyone who tries to exit the level (DM) + Zabijaj graczy gdy aktywują wyjście (DM) + + + + Infinite ammo + Nieskończona amunicja + + + + No monsters + Brak potworów + + + + Monsters respawn + Potwory odradzają się + + + + Items other than invuln. and invis. respawn + Przedmioty (oprócz nieśmier. i niewidz.) się odnawiają + + + + Fast monsters + Szybkie potwory + + + + No jumping + Brak skoku + + + + No freelook + Brak patrzenia góra-dół + + + + Respawn invulnerability and invisibility + Odradzaj nieśmiertelność i niewidzialność + + + + Arbitrator FOV + FOV ustalony z góry + + + + No multiplayer weapons in cooperative + Wyłącz bronie multiplayer w kooperacji + + + + No crouching + Brak kucania + + + + Lose all old inventory on respawn (COOP) + Zabieraj cały ekwipunek po odrodzeniu (COOP) + + + + Lose keys on respawn (COOP) + Zabieraj klucze po odrodzeniu (COOP) + + + + Lose weapons on respawn (COOP) + Zabieraj bronie po odrodzeniu (COOP) + + + + Lose armor on respawn (COOP) + Zabieraj zbroję po odrodzeniu (COOP) + + + + Lose powerups on respawn (COOP) + Zabieraj powerupy po odrodzeniu (COOP) + + + + Lose ammo on respawn (COOP) + Zabieraj amunicję po odrodzeniu (COOP) + + + + Lose half your ammo on respawn (COOP) + Zabieraj połowę amunicji po odrodzeniu (COOP) + + + + Jumping allowed + Skakanie dozwolone + + + + Crouching allowed + Kucanie dozwolone + + + + Drop weapons upon death + Upuszczaj bronie po śmierci + + + + Don't spawn runes + Nie spawnuj run + + + + Instantly return flags (ST/CTF) + Natychmiastowo zwracaj flagi (ST/CTF) + + + + Don't allow players to switch teams + Nie pozwalaj graczom na zmianę drużyn + + + + Players are automatically assigned teams + Gracze są automatycznie przydzielani do drużyn + + + + Double the amount of ammo given + Podwójna amunicja + + + + Players slowly lose health over 100% like Quake + Gracze powoli tracą zdrowie, gdy powyżej 100% + + + + Allow BFG freeaiming + Zezwól na celowanie BFG + + + + Barrels respawn + Odradzaj beczki + + + + No respawn protection + Nie chroń po odrodzeniu + + + + All players start with a shotgun + Wszyscy gracze dostają shotguna + + + + Players respawn where they died (COOP) + Gracze odradzają się tam, gdzie zginęli (COOP) + + + + Don't clear frags after each level + Nie resetuj fragów po ukończeniu poziomu + + + + Player can't respawn + Gracz nie może się odrodzić + + + + Lose a frag when killed + Zabieraj fraga w momencie śmierci + + + + Infinite inventory + Nieskończony ekwipunek + + + + All monsters must be killed before exiting + Wszystkie potwory muszą zostać zabite przed wyjściem + + + + Players can't see the automap + Gracze nie widzą automapy + + + + Allies can't be seen on the automap + Sojusznicy są niewidoczni na automapie + + + + You can't spy allies + Nie możesz podglądać sojuszników + + + + Players can use chase cam + Można używać kamery z trzeciej osoby + + + + Players can't suicide + Gracze nie mogą popełniać samobójstwa + + + + Players can't use autoaim + Gracze nie mogą używać autocelowania + + + + Don't check ammo when switching weapons + Nie sprawdzaj amunicji podczas zmiany broni + + + + Kill all monsters spawned by a boss cube when the boss dies + Zabij wszystkie potwory spawnięte przez kostkę bossa gdy boss zginie + + + + Clients can't identify targets + Klienci nie mogą identyfikować celów + + + + lmsspectatorsettings applied in all game modes + Zastosuj lmsspectatorsettings we wszystkich trybach gry + + + + Clients can't draw coop info + Klienci nie mogą rysować informacji o kooperacji + + + + Unlagged is disabled + Unlagged jest wyłączone + + + + Players don't block each other + Gracze nie mogą się nawzajem blokować + + + + Clients don't show medals + Klienci nie pokazują medali + + + + Keys are shared between players + Klucze są współdzielone pomiędzy graczami + + + + Player teams are preserved between maps + Gracze są w tych samych drużynach po zmianie mapy + + + + Force OpenGL defaults + Wymuś domyślne ustawienia OpenGL + + + + No rocket jumping + Wyłącz skakanie na rakietach + + + + Award damage instead of kills + Nagradzaj obrażenia, nie zabójstwa + + + + Force drawing alpha + Wymuś rysowanie przezroczystości + + + + Don't spawn multiplayer things + Nie spawnuj aktorów wieloosobowych + + + + Force blood screen brightness on clients to emulate vanilla + Wymuszaj na klientach jasność zakrwawionego ekranu taką, jak w vanilli + + + + Teammates don't block each other + Członkowie drużyny nie mogą się nawzajem blokować + + + + Zandronumq3::Dmflags + + + Use Doom's shortest texture behavior + Użyj Doomowego zachowania najkrótszej tekstury + + + + Don't fix loop index for stair building + Nie naprawiaj indeksu pętli do budowania schodów + + + + Pain elemental is limited to 20 lost souls + Pain elemental jest ograniczony do 20 lost souls + + + + Pickups are only heard locally + Podniesienia przedmiotów słychać tylko lokalnie + + + + Infinitely tall actors + Nieskończenie wysocy aktorzy + + + + Limit actors to only one sound + Ogranicz aktorów do tylko jednego dźwięku + + + + Enable wallrunning + Włącz wallrunning + + + + Dropped items spawn on floor + Upuszczane przedmioty tworzone są na podłodze + + + + Special lines block use line + Linie specjalne blokują użycie linii + + + + Disable BOOM local door light effect + Wyłącz efekt lokalnego światła drzwi z BOOMa + + + + Raven's scrollers use their original speed + Przewijacze Ravena używają oryginalnych prędkości + + + + Use sector based sound target code + Używaj kodu celowania dźwiękiem opartego na sektorach + + + + Limit dehacked MaxHealth to health bonus + Ogranicz maks. zdrowie z dehacked do bonusowego zdrowia + + + + Trace ignores lines with the same sector on both sides + Śledzenie ignoruje linie z tym samym sektorem po obu stronach + + + + Monsters can not move when hanging over a drop off + Potwory utykają gdy wiszą nad przepaścią + + + + Scrolling sectors are additive like Boom + Przesuwające sektory dodają się jak w Boomie + + + + Monsters can see semi-invisible players + Potwory mogą widzieć na-wpół-niewidzialnych graczy + + + + Instantly moving floors are not silent + Natychmiastowo ruszające się podłogi nie są ciche + + + + Sector sounds use original method for sound origin + Dźwięki sektorów używają oryginalnej metody pozycjonowania dźwięku + + + + Use original Doom heights for clipping against projectiles + Używaj oryginalnych wysokości z Dooma podczas kolizji z pociskami + + + + Monsters can't be pushed over dropoffs + Potwory nie mogą być wypchnięte przez przepaść + + + + Any monster which calls BOSSDEATH counts for level specials + Każdy potwór, który wywołuje BOSSDEATH liczy się dla specjali na poziomie + + + + Minotaur's floor flame is exploded immediately when feet are clipped + Ogień podłogowy Minotaura eksploduje natychmiast gdy stopy są przycięte + + + + Force original velocity calculations for A_Mushroom in Dehacked mods + Oryginalne obliczanie prędkości dla A_Mushroom w Dehacked + + + + Monsters are affected by friction and pushers/pullers + Tarcie oraz popychacze i ciągniki wpływają na potwory + + + + Crushed monsters are turned into gibs, rather than replaced by gibs + Zgniecione potwory zamieniają się we flaki, a nie są przez nie zastępowane + + + + Friendly monsters aren't blocked by monster-blocking lines + Linie blokujące potwory ignorują przyjazne potwory + + + + Invert sprite sorting order for sprites of equal distance + Odwrócone sortowanie sprite'ów gdy są w tej samej odległości + + + + Hitscans use original blockmap and hit check code + Hitscany używają oryginalnego kodu blockmap i detekcji trafień + + + + Find neighboring light level like like Doom + Szukaj sąsiadującego poziomu światła jak w Doomie + + + + Draw polyobjects the old fashioned way + Rysuj polyobjecty w stary sposób + + + + Ignore compositing when drawing masked midtextures + Ignoruj kompozycję podczas rysowania maskowanych midtekstur + + + + It is impossible to directly face cardinal direction + Nie można obrócić się bezpośrednio w kierunku kardynalnym + + + + Use the same floor motion behavior as Doom + Użyj takiego zachowania ruchu podłóg, jak w Doomie + + + + Net scripts are client side + Skrypty NET są po stronie klienta + + + + Clients send full button info + Klienci wysyłają pełne info o przyciskach + + + + Players can't use 'land' CCMD + Gracze nie mogą używać komendy 'land' + + + + Use Doom's original random number generator + Używaj oryginalnego generatora liczb losowych z Dooma + + + + Spheres have NOGRAVITY flag + Kule mają flagę NOGRAVITY + + + + Don't stop player scripts on disconnect + Nie zatrzymuj skryptów gracza po rozłączeniu + + + + Use horizontal explosion thrust of old ZDoom versions + Eksplozje popychają w poziomie jak w starym ZDoomie + + + + Non-SOLID things fall through invisible bridges + Nie-SOLIDne obiekty przenikają przez aktorów mostu + + + + Use old ZDoom jump physics + Fizyka skoku ze starego ZDooma + + + + Disallow weapon change when in mid raise/lower + Nie można zmieniać broni w trakcie wyciągania/chowania + + + + Use vanilla's autoaim tracer behavior + Trasowanie autocelowania takie jak w vanilli + + + + West spawns are silent + Zachodnie spawny są ciche + + + + Limited movement in the air + Ograniczone poruszanie w powietrzu + + + + Allow map01 "plasma bump" bug + Pozwól na błąd "plasma bump" z map01 + + + + Allow instant respawn after death + Pozwól na natychmiastowy respawn po śmierci + + + + Disable taunting + Wyłącz okrzyki + + + + Use doom2.exe's original sound curve + Używaj krzywej dźwięku z doom2.exe + + + + Use original doom2 intermission music + Używaj oryginalnej (doom2) muzyki podczas intermisji + + + + Disable stealth monsters + Wyłącz potwory "stealth" + + + + Radius damage has infinite height + Obrażenia obszarowe mają nieskończoną wysokość + + + + Disable crosshair + Wyłącz celownik + + + + Force weapon switch + Wymuś zmianę broni + + + + Do not spawn health items (DM) + Nie spawnuj przedmiotów ze zdrowiem (DM) + + + + Do not spawn powerups (DM) + Nie spawnuj powerupów (DM) + + + + Weapons remain after pickup (DM) + Bronie zostają po podniesieniu (DM) + + + + Falling damage (old ZDoom) + Upadek boli (stary ZDoom) + + + + Falling damage (Hexen) + Upadek boli (Hexen) + + + + Falling damage (Strife) + Upadek boli (Strife) + + + + Stay on same map when someone exits (DM) + Nie zmieniaj mapy gdy ktoś ją ukończy (DM) + + + + Spawn players as far as possible (DM) + Spawnuj graczy jak najdalej od siebie (DM) + + + + Automatically respawn dead players (DM) + Automatycznie respawnuj martwych graczy (DM) + + + + Don't spawn armor (DM) + Nie spawnuj zbroi (DM) + + + + Kill anyone who tries to exit the level (DM) + Zabijaj graczy gdy aktywują wyjście (DM) + + + + Infinite ammo + Nieskończona amunicja + + + + No monsters + Brak potworów + + + + Monsters respawn + Potwory odradzają się + + + + Items other than invuln. and invis. respawn + Przedmioty (oprócz nieśmier. i niewidz.) się odnawiają + + + + Fast monsters + Szybkie potwory + + + + No jumping + Brak skoku + + + + No freelook + Brak patrzenia góra-dół + + + + Respawn invulnerability and invisibility + Odradzaj nieśmiertelność i niewidzialność + + + + Arbitrator FOV + FOV ustalony z góry + + + + No multiplayer weapons in cooperative + Wyłącz bronie multiplayer w kooperacji + + + + No crouching + Brak kucania + + + + Lose all old inventory on respawn (COOP) + Zabieraj cały ekwipunek po odrodzeniu (COOP) + + + + Lose keys on respawn (COOP) + Zabieraj klucze po odrodzeniu (COOP) + + + + Lose weapons on respawn (COOP) + Zabieraj bronie po odrodzeniu (COOP) + + + + Lose armor on respawn (COOP) + Zabieraj zbroję po odrodzeniu (COOP) + + + + Lose powerups on respawn (COOP) + Zabieraj powerupy po odrodzeniu (COOP) + + + + Lose ammo on respawn (COOP) + Zabieraj amunicję po odrodzeniu (COOP) + + + + Lose half your ammo on respawn (COOP) + Zabieraj połowę amunicji po odrodzeniu (COOP) + + + + Jumping allowed + Skakanie dozwolone + + + + Crouching allowed + Kucanie dozwolone + + + + Drop weapons upon death + Upuszczaj bronie po śmierci + + + + Don't spawn runes + Nie spawnuj run + + + + Instantly return flags (ST/CTF) + Natychmiastowo zwracaj flagi (ST/CTF) + + + + Don't allow players to switch teams + Nie pozwalaj graczom na zmianę drużyn + + + + Players are automatically assigned teams + Gracze są automatycznie przydzielani do drużyn + + + + Double the amount of ammo given + Podwójna amunicja + + + + Players slowly lose health over 100% like Quake + Gracze powoli tracą zdrowie, gdy powyżej 100% + + + + Allow BFG freeaiming + Zezwól na celowanie BFG + + + + Barrels respawn + Odradzaj beczki + + + + No respawn protection + Nie chroń po odrodzeniu + + + + All players start with a shotgun + Wszyscy gracze dostają shotguna + + + + Players respawn where they died (COOP) + Gracze odradzają się tam, gdzie zginęli (COOP) + + + + Don't clear frags after each level + Nie resetuj fragów po ukończeniu poziomu + + + + Player can't respawn + Gracz nie może się odrodzić + + + + Lose a frag when killed + Zabieraj fraga w momencie śmierci + + + + Infinite inventory + Nieskończony ekwipunek + + + + All monsters must be killed before exiting + Wszystkie potwory muszą zostać zabite przed wyjściem + + + + Players can't see the automap + Gracze nie widzą automapy + + + + Allies can't be seen on the automap + Sojusznicy są niewidoczni na automapie + + + + You can't spy allies + Nie możesz podglądać sojuszników + + + + Players can use chase cam + Można używać kamery z trzeciej osoby + + + + Players can't suicide + Gracze nie mogą popełniać samobójstwa + + + + Players can't use autoaim + Gracze nie mogą używać autocelowania + + + + Don't check ammo when switching weapons + Nie sprawdzaj amunicji podczas zmiany broni + + + + Kill all monsters spawned by a boss cube when the boss dies + Zabij wszystkie potwory spawnięte przez kostkę bossa gdy boss zginie + + + + Do not count monsters in 'end level when dying' sectors towards kill count + Nie licz zabójstw potworów znajdujących się w sektorach typu 'zakończ poziom przy śmierci' + + + + Clients can't identify targets + Klienci nie mogą identyfikować celów + + + + lmsspectatorsettings applied in all game modes + Zastosuj lmsspectatorsettings we wszystkich trybach gry + + + + Clients can't draw coop info + Klienci nie mogą rysować informacji o kooperacji + + + + Unlagged is disabled + Unlagged jest wyłączone + + + + Players don't block each other + Gracze nie mogą się nawzajem blokować + + + + Clients don't show medals + Klienci nie pokazują medali + + + + Keys are shared between players + Klucze są współdzielone pomiędzy graczami + + + + Player teams are preserved between maps + Gracze są w tych samych drużynach po zmianie mapy + + + + Force OpenGL defaults + Wymuś domyślne ustawienia OpenGL + + + + No rocket jumping + Wyłącz skakanie na rakietach + + + + Award damage instead of kills + Nagradzaj obrażenia, nie zabójstwa + + + + Force drawing alpha + Wymuś rysowanie przezroczystości + + + + Don't spawn multiplayer things + Nie spawnuj aktorów wieloosobowych + + + + Force blood screen brightness on clients to emulate vanilla + Wymuszaj na klientach jasność zakrwawionego ekranu taką, jak w vanilli + + + + Teammates don't block each other + Członkowie drużyny nie mogą się nawzajem blokować + + + + No dropping allowed + Nie wolno upuszczać przedmiotów + + + + No map reset on death in survival + Mapa nie jest resetowana gdy gracze zginą w surwiwalu + + + + Dead players can keep inventory + Martwi gracze mogą zachować ekwipunek + + + + ZandronumqAboutProvider + + + This plugin is distributed under the terms of the LGPL v2.1 or later. + + + Ta wtyczka jest rozprowadzana na zasadach licencji LGPL v2.1 lub późniejszej. + + + + + + ZandronumqBroadcast + + Listening to Zandronumq LAN server broadcasts. + Nasłuchuję rozgłoszeń serwerów LAN Zandronumq. + + + + Listening to Zandronumq's LAN servers broadcasts on port %1. + Nasłuchuję rozgłoszeń serwerów LAN Zandronumq na porcie %1. + + + + Failed to bind Zandronumq's LAN broadcasts listening socket on port %1. Will keep retrying silently. + Nie udało się rozpoczęcie nasłuchu rozgłoszeń LAN dla Zandronumq na porcie %1. Będą podejmowane ciche próby naprawy. + + + + ZandronumqClientExeFile + + + client + klient + + + Testing binaries for version %1 can be installed. + +Do you want Doomseeker to create %1 directory and copy all your .ini files from your base directory? + Binarki testowe dla wersji %1 mogą zostać zainstalowane. + +Czy chcesz aby Doomseeker utworzył katalog %1 i skopiował do niego wszystkie twoje pliki .ini z katalogu bazowego? + + + Doomseeker - missing testing binaries + Doomseeker - brakuje binarek testowych + + + + + No testing directory specified for Zandronumq + Nie podano katalogu testowego dla Zandronumq + + + + Unable to create directory: +%1 + Nie można utworzyć katalogu: +%1 + + + + Unable to create directory: +%1/%2 + Nie można utworzyć katalogu: +%1/%2 + + + + Doomseeker + Doomseeker + + + + Please install now version "%1" into: +%2 + Proszę teraz zainstalować wersję "%1" do: +%2 + + + + <p>Installation of testing binaries for version %1 can potentially <b>overwrite</b> your files.</p><p>Game will be installed to:<br>%2</p><p>Do you want Doomseeker to extract Zandronumq files, potentially <b>overwriting existing ones</b>, and to copy all your configuration files from your base directory?</p> + <p>Instalacja binarek testowych dla wersji %1 może potencjalnie <b>nadpisać</b> Twoje pliki.</p><p>Gra zostanie zainstalowana pod ścieżką:<br>%2</p><p>Czy chcesz aby Doomseeker wypakował pliki Zandronumq, potencjalnie <b>nadpisując już istniejące</b>, oraz aby skopiował wszystkie Twoje pliki konfiguracyjne z katalogu bazowego?</p> + + + + Zandronumq testing version %1 can be installed. + +Game will be installed to: +%2 + +Do you want Doomseeker to install that version and copy all your configuration files from your base directory? + Wersja testowa Zandronumq %1 może zostać zainstalowana. + +Gra zostanie zainstalowana do: +%2 + +Czy chcesz, aby Doomseeker zainstalował tą wersję i skopiował wszystkie Twoje pliki konfiguracyjne z katalogu bazowego? + + + + Doomseeker - install Zandronumq testing version + Doomseeker - instalacja testowej wersji Zandronumq + + + + %1 +doesn't exist. +You need to install new testing binaries. + %1 +nie istnieje. +Musisz zainstalować nowe binarki testowe. + + + + %1 +exists but is NOT a directory. +Cannot proceed. + %1 +istnieje ale NIE JEST katalogiem. +Nie można kontynuować. + + + + %1 +exists but doesn't contain Zandronumq executable. + +Doomseeker can still install the game there if you want. + %1 +istnieje, ale nie zawiera pliku wykonywalnego Zandronumq. + +Doomseeker może tam zainstalować grę, jeżeli chcesz. + + + %1 +doesn't contain Zandronumq executable + %1 +nie zawiera pliku wykonywalnego Zandronumq + + + + Downloading Zandronumq testing binary from URL: %1 + Pobieram binarkę testową Zandronumq z URLa: %1 + + + + Doomseeker - download failed + Doomseeker - pobieranie sfiaskowało + + + + Failed to download testing binary. + +%1 + Nie udało się pobrać binarki testowe. + +%1 + + + + Unpacking file: %1 + Wypakowuję plik: %1 + + + + Doomseeker - unpack failed + Doomseeker - błąd wypakowania + + + + Failed to unpack: %1 + Nie udało się wypakować: %1 + + + + %1 + should be a script file but is a directory! + %1 + powinien być plikiem skryptowym, ale jest katalogiem! + + + + You don't have permissions to execute file: %1 + + Nie masz uprawnień aby uruchomić plik: %1 + + + + Couldn't open batch file "%1" for writing + Nie można otworzyć pliku skryptowego "%1" do zapisu + + + + Error while writing batch file "%1" + Błąd podczas zapisywania pliku skryptowego "%1" + + + + Cannot set permissions for file: +%1 + Nie można ustawić uprawnień plikowi: +%1 + + + + ZandronumqDmflags + + Use Doom's shortest texture behavior + Użyj Doomowego zachowania najkrótszej tekstury + + + Don't fix loop index for stair building + Nie naprawiaj indeksu pętli do budowania schodów + + + Pain elemental is limited to 20 lost souls + Pain elemental jest ograniczony do 20 lost souls + + + Pickups are only heard locally + Podniesienia przedmiotów słychać tylko lokalnie + + + Infinitly tall actors + Nieskończenie wysocy aktorzy + + + Limit actors to only one sound + Ogranicz aktorów do tylko jednego dźwięku + + + Enable wallrunning + Włącz wallrunning + + + Dropped items spawn on floor + Upuszczane przedmioty tworzone są na podłodze + + + Special lines block use line + Linie specjalne blokują użycie linii + + + Disable BOOM local door light effect + Wyłącz efekt lokalnego światła drzwi z BOOMa + + + Raven's scrollers use their original speed + Przewijacze Ravena używają oryginalnych prędkości + + + Use sector based sound target code + Opieraj kod celu dźwięku na sektorach + + + Limit dehacked MaxHealth to health bonus + Ogranicz maks. zdrowie z dehacked do bonusowego zdrowia + + + Trace ignores lines with the same sector on both sides + Śledzenie ignoruje linie z tym samym sektorem po obu stronach + + + Monsters can not move when hanging over a drop off + Potwory utykają gdy wiszą nad przepaścią + + + Scrolling sectors are additive like Boom + Przesuwające sektory dodają się jak w Boomie + + + Monsters can see semi-invisible players + Potwory mogą widzieć na-wpół-niewidzialnych graczy + + + Sector sounds use original method for sound origin + Dźwięki sektorów używają oryginalnej metody pozycjonowania dźwięku + + + Use original Doom heights for clipping against projectiles + Używaj oryginalnych wysokości z Dooma podczas kolizji z pociskami + + + Monsters can't be pushed over dropoffs + Potwory nie mogą być wypchnięte przez przepaść + + + Any monster which calls BOSSDEATH counts for level specials + Każdy potwór, który wywołuje BOSSDEATH liczy się dla specjali na poziomie + + + Minotaur's floor flame is exploded immediately when feet are clipped + Ogień podłogowy Minotaura eksploduje natychmiast gdy stopy są przycięte + + + Force original velocity calculations for A_Mushroom in Dehacked mods + Oryginalne obliczanie prędkości dla A_Mushroom w Dehacked + + + Monsters are affected by friction and pushers/pullers + Tarcie/popychacze i ciągniki wpływają na potwory + + + Crushed monsters are turned into gibs, rather than replaced by gibs + Zgniecione potwory zamieniają się we flaki, a nie są przez nie zastępowane + + + Friendly monsters aren't blocked by monster-blocking lines + Linie blokujące potwory ignorują przyjazne potwory + + + Invert sprite sorting order for sprites of equal distance + Odwrócone sortowanie sprite'ów gdy są w tej samej odległości + + + Hitscans use original blockmap and hit check code + Hitscany używają oryginalnego kodu blockmap i detekcji trafień + + + Find neighboring light level like like Doom + Szukaj sąsiadującego poziomu światła jak w Doomie + + + Draw polyobjects the old fashioned way + Rysuj polyobjekty w stary sposób + + + Net scripts are client side + Skrypty NET są po stronie klienta + + + Clients send full button info + Klienci wysyłają pełne info o przyciskach + + + Players can't use 'land' CCMD + Gracze nie mogą używać komendy 'land' + + + Use Doom's original random number generator + Używaj oryginalnego generatora liczb losowych z Dooma + + + Spheres have NOGRAVITY flag + Kule mają flagę NOGRAVITY + + + Don't stop player scripts on disconnect + Nie zatrzymuj skryptów gracza po rozłączeniu + + + Use horizontal explosion thrust of old ZDoom versions + Eksplozje popychają w poziomie jak w starym ZDoomie + + + Non-SOLID things fall through invisible bridges + Nie-SOLIDne obiekty przenikają przez aktorów mostu + + + Use old ZDoom jump physics + Fizyka skoku ze starego ZDooma + + + Disallow weapon change when in mid raise/lower + Nie można zmieniać broni w trakcie wyciągania/chowania + + + Use vanilla's autoaim tracer behavior + Trasowanie autocelowania takie jak w vanilli + + + West spawns are silent + Zachodnie spawny są ciche + + + Limited movement in the air + Ograniczone poruszanie w powietrzu + + + Allow map01 "plasma bump" bug + Pozwól na błąd "plasma bump" z map01 + + + Allow instant respawn after death + Pozwól na natychmiastowy respawn po śmierci + + + Disable taunting + Wyłącz okrzyki + + + Use doom2.exe's original sound curve + Używaj krzywej dźwięku z doom2.exe + + + Use original doom2 intermission music + Używaj oryginalnej (doom2) muzyki podczas intermisji + + + Disable stealth monsters + Wyłącz potwory "stealth" + + + Radius damage has infinite height + Obrażenia obszarowe mają nieskończoną wysokość + + + Disable crosshair + Wyłącz celownik + + + Force weapon switch + Wymuś zmianę broni + + + Award damage instead of kills + Nagradzaj obrażenia, nie zabójstwa + + + Don't spawn multiplayer things + Nie spawnuj aktorów wieloosobowych + + + Force blood screen brightness on clients to emulate vanilla + Wymuszaj na klientach jasność zakrwawionego ekranu takie, jak w vanilli + + + Teammates don't block each other + Członkowie drużyny nie mogą się nawzajem blokować + + + Instantly moving floors are not silent + Natychmiastowo ruszające się podłogi nie są ciche + + + Sector sounds use original method for sound orgin + Dźwięki sektorów używają oryginalnej metody pozycjonowania dźwięku + + + Use original Doom heights for clipping against projetiles + Używaj oryginalnych wysokości z Dooma podczas kolizji z pociskami + + + Monsters can't be pushed over drop offs + Potwory nie mogą być wypchnięte przez przepaść + + + Do not spawn health items (DM) + Nie spawnuj przedmiotów ze zdrowiem (DM) + + + Do not spawn powerups (DM) + Nie spawnuj dopalaczy (DM) + + + Weapons remain after pickup (DM) + Bronie zostają po podniesieniu (DM) + + + Falling damage (old ZDoom) + Upadek boli (stary ZDoom) + + + Falling damage (Hexen) + Upadek boli (Hexen) + + + Falling damage (Strife) + Upadek boli (Strife) + + + Stay on same map when someone exits (DM) + Nie zmieniaj mapy gdy ktoś ją ukończy (DM) + + + Spawn players as far as possible (DM) + Spawnuj graczy jak najdalej od siebie (DM) + + + Automatically respawn dead players (DM) + Automatycznie respawnuj martwych graczy (DM) + + + Don't spawn armor (DM) + Nie spawnuj zbroi (DM) + + + Kill anyone who tries to exit the level (DM) + Zabijaj graczy gdy aktywują wyjście (DM) + + + Infinite ammo + Nieskończona amunicja + + + No monsters + Brak potworów + + + Monsters respawn + Potwory odradzają się + + + Items other than invuln. and invis. respawn + Przedmioty (oprócz nieśmier. i niewidz.) się odnawiają + + + Fast monsters + Szybkie potwory + + + No jumping + Brak skoku + + + No freelook + Brak patrzenia góra-dół + + + Respawn invulnerability and invisibility + Odradzaj nieśmiertelność i niewidzialność + + + Arbitrator FOV + FOV ustalony z góry + + + No multiplayer weapons in cooperative + Wyłącz bronie multiplayer w kooperacji + + + No crouching + Brak kucania + + + Lose all old inventory on respawn (COOP) + Zabieraj cały ekwipunek po odrodzeniu (COOP) + + + Lose keys on respawn (COOP) + Zabieraj klucze po odrodzeniu (COOP) + + + Lose weapons on respawn (COOP) + Zabieraj bronie po odrodzeniu (COOP) + + + Lose armor on respawn (COOP) + Zabieraj zbroję po odrodzeniu (COOP) + + + Lose powerups on respawn (COOP) + Zabieraj dopalacze po odrodzeniu (COOP) + + + Lose ammo on respawn (COOP) + Zabieraj amunicję po odrodzeniu (COOP) + + + Lose half your ammo on respawn (COOP) + Zabieraj połowę amunicji po odrodzeniu (COOP) + + + Jumping allowed + Skakanie dozwolone + + + Crouching allowed + Kucanie dozwolone + + + Drop weapons upon death + Upuszczaj bronie po śmierci + + + Don't spawn runes + Nie spawnuj run + + + Instantly return flags (ST/CTF) + Natychmiastowo zwracaj flagi (ST/CTF) + + + Don't allow players to switch teams + Nie pozwalaj graczom na zmianę drużyn + + + Players are automatically assigned teams + Gracze są automatycznie przydzielani do drużyn + + + Double the amount of ammo given + Podwójna amunicja + + + Players slowly lose health over 100% like Quake + Gracze powoli tracą zdrowie, gdy powyżej 100% + + + Allow BFG freeaiming + Pozwól celować góra-dół BFG + + + Barrels respawn + Beczki się odradzają + + + No respawn protection + Nie chroń po odrodzeniu + + + All players start with a shotgun + Wszyscy gracze dostają szotgana + + + Players respawn where they died (COOP) + Gracze odradzają się tam, gdzie zginęli (COOP) + + + Players keep teams after map change + Gracze są w tych samych drużynach po zmianie mapy + + + Don't clear frags after each level + Nie resetuj fragów po ukończeniu poziomu + + + Player can't respawn + Gracz nie może się odrodzić + + + Lose a frag when killed + Zabieraj fraga w momencie śmierci + + + Infinite inventory + Nieskończony ekwipunek + + + Don't check ammo when switching weapons + Nie sprawdzaj amunicji podczas zmiany broni + + + Kill all monsters spawned by a boss cube when the boss dies + Zabij wszystkie potwory spawnięte przez kostkę bossa gdy boss zginie + + + Clients can't identify targets + Klienci nie mogą identyfikować celów + + + lmsspectatorsettings applied in all game modes + Zastosuj lmsspectatorsettings we wszystkich trybach gry + + + Clients can't draw coop info + Klienci nie mogą rysować informacji o kooperacji + + + Unlagged is disabled + Unlagged jest wyłączone + + + Players don't block each other + Gracze nie mogą się nawzajem blokować + + + Clients don't show medals + Klienci nie pokazują medali + + + Keys are shared between players + Klucze są współdzielone pomiędzy graczami + + + Player teams are preserved between maps + Gracze są w tych samych drużynach po zmianie mapy + + + Force OpenGL defaults + Wymuś domyślne ustawienia OpenGL + + + No rocket jumping + Wyłącz skakanie na rakietach + + + Award damage not kills + Nagradzaj obrażenia, nie zabójstwa + + + Force drawing alpha + Wymuś rysowanie przezroczystości + + + All monsters must be killed before exiting + Wszystkie potwory muszą zostać zabite przed wyjściem + + + Players can't see the automap + Gracze nie widzą automapy + + + Allies can't be seen on the automap + Sojusznicy są niewidoczni na automapie + + + You can't spy allies + Nie możesz podglądać sojuszników + + + Players can use chase cam + Można używać kamery z trzeciej osoby + + + Players can't suicide + Gracze nie mogą popełniać samobójstwa + + + Players can't use autoaim + Gracze nie mogą używać autocelowania + + + Spawn map actors in coop as if the game was single player + Spawnuj przedmioty na mapie tak, jakby była to gra single player + + + + ZandronumqDmflags1point0 + + NETSCRIPTS are clientside + Skrypty NET są po stronie klienta + + + Clients send full button info + Klienci wysyłają pełne info o przyciskach + + + Disallow 'land' console command + Wyłącz komendę 'land' + + + Old random generator + Stary generator numerów + + + Powerup spheres have NOGRAVITY flag + Kule dopalacze mają flagę NOGRAVITY + + + Don't stop scripts running on a player when player leaves the server + Nie wyłączaj skryptów oddziałujących na gracza gdy opuści on serwer + + + Explosion causes strong horizontal thrust (like old ZDoom) + Eksplozje mocno odpychają w poziomie (jak w starym ZDoomie) + + + Non-SOLID things fall through thing bridges + Nie-SOLIDne obiekty przenikają przez aktorów mostu + + + ZDoom 123B33 jump physics + Fizyka skakania z ZDooma 123B33 + + + Can't change weapons during raise/lower + Nie można zmieniać broni w trakcie wyciągania/chowania + + + Don't display names of targeted players + Nie pokazuj imion namierzanych graczy + + + Apply lmsspectatorsettings in all game modes + Zastosuj lmsspectatorsettings we wszystkich trybach gry + + + Force no coop info + Wyłącz info z kooperacji + + + No unlagged + Wyłącz unlagged + + + Noclip through other players + Przenikaj przez innych graczy + + + No medals + Brak medali + + + + ZandronumqGameInfo + + + Survival + Surwiwal + + + + Invasion + Inwazja + + + + Duel + Pojedynek + + + + Terminator + Terminator + + + + LMS + LMS + + + + Team LMS + Drużynowy LMS + + + + Possession + Posesja + + + + Team Poss + Drużynowa Posesja + + + + Team Game + Gra Drużynowa + + + + One Flag CTF + CTF z jedną flagą + + + + Skulltag + Skulltag + + + + Domination + Dominacja + + + + ZandronumqMasterClient + + + You may contact Zandronumq staff about this through IRC: <b>irc.qzandronum.com #zandronumq</b> or on the forum: <a href="https://qzandronum.com/forum">https://qzandronum.com/forum.</a> + Możesz skontaktować się z ekipą Zandronumq w tym temacie poprzez IRC: <b>irc.qzandronum.com #zandronumq</b>, albo na forum: <a href="https://qzandronum.com/forum">https://qzandronum.com/forum.</a> + + + + ZandronumqRConProtocol + + + Connection attempt ... + Próba połączenia ... + + + + Too many failed connection attempts. Aborting. + Zbyt wiele nieudanych prób połączenia. Przerywam. + + + + Authenticating ... + Autentykacja ... + + + + Too many failed authentication attempts. Aborting. + Zbyt wiele nieudanych prób autentykacji. Przerywam. + + + + Delaying for about %n seconds before next authentication attempt. + + Opóźniam na około %n sekundę przed następną próbą autentykacji. + Opóźniam na około %n sekundy przed następną próbą autentykacji. + Opóźniam na około %n sekund przed następną próbą autentykacji. + + + + + Failed to establish connection. + Nie udało się zestawić połączenia. + + + + Timeout on authentication. + Przekroczono czas autentykacji. + + + + You have been banned from this server. + Masz bana na tym serwerze. + + + + The protocol appears to be outdated. + Protokół wydaje się być przestarzały. + + + + Authentication failure. + Błąd autentykacji. + + + + Remote console connection established. + Połączenie z konsolą zdalną zestawione. + + + + ----- + ----- + + + + ZandronumqServer + + + Blue + Niebieska + + + + Red + Czerwona + + + + Green + Zielona + + + + Gold + Złota + + + diff --git a/src/plugins/zandronumq/zandronumq.xpm b/src/plugins/zandronumq/zandronumq.xpm new file mode 100644 index 00000000..20495601 --- /dev/null +++ b/src/plugins/zandronumq/zandronumq.xpm @@ -0,0 +1,149 @@ +/* XPM */ +static char * zandronumq_xpm[] = { +"24 24 122 2", +" c None", +". c #000000", +"+ c #080808", +"@ c #0A0A0A", +"# c #0B0B0B", +"$ c #081010", +"% c #101010", +"& c #141414", +"* c #161616", +"= c #171717", +"- c #101018", +"; c #181818", +"> c #191919", +", c #1A1A1A", +"' c #1B1B1B", +") c #1E1E1E", +"! c #1F1F1F", +"~ c #1E2E1E", +"{ c #210000", +"] c #212121", +"^ c #222222", +"/ c #232323", +"( c #242424", +"_ c #272727", +": c #292929", +"< c #2A2A2A", +"[ c #2C2C2C", +"} c #2D2D2D", +"| c #2E2E2E", +"1 c #2F2F2F", +"2 c #313131", +"3 c #323232", +"4 c #353535", +"5 c #373737", +"6 c #383838", +"7 c #393939", +"8 c #3A3A3A", +"9 c #3B3B3B", +"0 c #3C3C3C", +"a c #3E3E3E", +"b c #3F3F3F", +"c c #014B01", +"d c #1F481F", +"e c #2B4C2B", +"f c #285A28", +"g c #335433", +"h c #2C662C", +"i c #207A20", +"j c #424242", +"k c #434343", +"l c #464646", +"m c #474747", +"n c #4A4A4A", +"o c #4E4E4E", +"p c #4F4F4F", +"q c #534040", +"r c #505050", +"s c #515151", +"t c #525252", +"u c #535353", +"v c #575555", +"w c #575757", +"x c #595959", +"y c #5A5A5A", +"z c #5B5B5B", +"A c #5C5C5C", +"B c #5F5F5F", +"C c #417241", +"D c #457F45", +"E c #636363", +"F c #656565", +"G c #696969", +"H c #6A6A6A", +"I c #6B6B6B", +"J c #717171", +"K c #737373", +"L c #777777", +"M c #7A7A7A", +"N c #7B7B7B", +"O c #7C7C7C", +"P c #1E9A1E", +"Q c #468046", +"R c #4A844A", +"S c #4E884E", +"T c #4E904E", +"U c #508250", +"V c #5A8B5A", +"W c #579957", +"X c #5CA65C", +"Y c #5DB75D", +"Z c #6DC06D", +"` c #72D572", +" . c #7AD47A", +".. c #7BDE7B", +"+. c #FF00FF", +"@. c #848484", +"#. c #858585", +"$. c #8A8A8A", +"%. c #8C8C8C", +"&. c #8F8F8F", +"*. c #939393", +"=. c #949494", +"-. c #969696", +";. c #999999", +">. c #9C9C9C", +",. c #A2A2A2", +"'. c #A3A3A3", +"). c #A5A5A5", +"!. c #A9A9A9", +"~. c #ADADAD", +"{. c #AFAFAF", +"]. c #B5B5B5", +"^. c #B6B6B6", +"/. c #BDBDBD", +"(. c #82D482", +"_. c #9BF59B", +":. c #A5FFA5", +"<. c #C2C2C2", +"[. c #C8C8C8", +"}. c #CECECE", +"|. c #D4D4D4", +"1. c #E0E0E0", +" ", +" j n E E N y n 7 : ", +" 2 y I x F ~.K I E y o = . ", +" . l I }.%.~.>.=.K y E : ( & * ", +" j y =./.$.}.].;.H M G z ! 6 & 0 # ", +" t K !.'.!.1./.,.#.w 9 k ' , / } ) ", +" 2 y -.).<.|.]./.*.L J s _ ] 3 k : * . ", +" : y ~.[.].'.!.@.O A y 9 } , : 6 } ] = ", +" . N =.].{.].^.=.y p 4 a < 7 = } } = # ", +" : : F ).!.{.@.K t 2 p | > 5 6 6 [ ] # ", +" ] b A u &.J I E j 2 6 o } _ 6 z 6 ] ^ ", +" ] 7 T ` . .:. . . .Y i _...` .W * * ", +" ] n n j D Z Z Z R h R P (.Z V ] ] ] # ", +" ] j y %.j f X C t j 1 C c U 7 6 @ 8 ] ", +" ; 7 I E N n S d j 7 j d Q & & ' j 7 + ", +" ] m N B { g 7 j 7 7 2 e & n ] ; ; ", +" ] r q K ~ j 2 : : : ~ : ] ] ] ", +" ] : v K - n : ] : 7 $ : * 7 ; ", +" : E t . 7 : ] : 2 . ] * # ", +" 2 ] n n 2 ] ] ] 7 2 : ] % ", +" ] j j : ; ; ] 2 2 2 * ", +" ; ] : ] ; % ; : 7 ] ; ", +" ; ] ] ; + % ; : ] ", +" "}; diff --git a/src/plugins/zandronumq/zandronumq2dmflags.cpp b/src/plugins/zandronumq/zandronumq2dmflags.cpp new file mode 100644 index 00000000..4214c546 --- /dev/null +++ b/src/plugins/zandronumq/zandronumq2dmflags.cpp @@ -0,0 +1,341 @@ +//------------------------------------------------------------------------------ +// zandronumq2dmflags.cpp +//------------------------------------------------------------------------------ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301 USA +// +//------------------------------------------------------------------------------ +// Copyright (C) 2014 "Zalewa" +//------------------------------------------------------------------------------ +#include "zandronumq2dmflags.h" + +#include "zandronumqgamesettings.h" +#include +#include + +namespace Zandronumq2 +{ +static QList cachedFlags; +static QMutex cacheMutex; + +DMFlagsSection Dmflags::compatFlags() +{ + using namespace ZandronumqGameSettingsNames; + + DMFlagsSection section("Compat. flags"); + section << DMFlag(COMPAT_FIND_SHORTEST_TEXTURES_LIKE_DOOM, COMPATF_SHORTTEX, + tr("Use Doom's shortest texture behavior")); + section << DMFlag(COMPAT_USE_BUGGIER_STAIR_BUILDING, COMPATF_STAIRINDEX, + tr("Don't fix loop index for stair building")); + section << DMFlag(COMPAT_LIMIT_PAIN_ELEMENTALS, COMPATF_LIMITPAIN, + tr("Pain elemental is limited to 20 lost souls")); + section << DMFlag(COMPAT_DONT_LET_OTHERS_HEAR_PICKUPS, COMPATF_SILENTPICKUP, + tr("Pickups are only heard locally")); + section << DMFlag(COMPAT_ACTORS_ARE_INFINITELY_TALL, COMPATF_NO_PASSMOBJ, + tr("Infinitely tall actors")); + section << DMFlag(COMPAT_ALLOW_SILENT_BFGTRICK, COMPATF_MAGICSILENCE, + tr("Limit actors to only one sound")); + section << DMFlag(COMPAT_ENABLE_WALL_RUNNING, COMPATF_WALLRUN, + tr("Enable wallrunning")); + section << DMFlag(COMPAT_SPAWN_ITEM_DROPS_ON_THE_FLOOR, COMPATF_NOTOSSDROPS, + tr("Dropped items spawn on floor")); + section << DMFlag(COMPAT_ALL_SPECIAL_LINES_CAN_DROP_USE_LINES, COMPATF_USEBLOCKING, + tr("Special lines block use line")); + section << DMFlag(COMPAT_DISABLE_BOOM_DOOR_LIGHT_EFFECT, COMPATF_NODOORLIGHT, + tr("Disable BOOM local door light effect")); + section << DMFlag(COMPAT_RAVENS_SCROLLERS_USE_ORIGINAL_SPEED, COMPATF_RAVENSCROLL, + tr("Raven's scrollers use their original speed")); + section << DMFlag(COMPAT_USE_SECTOR_BASED_SOUND_TARGET_CODE, COMPATF_SOUNDTARGET, + tr("Use sector based sound target code")); + section << DMFlag(COMPAT_LIMIT_DEH_MAX_HEALTH_TO_HEALTH_BONUS, COMPATF_DEHHEALTH, + tr("Limit dehacked MaxHealth to health bonus")); + section << DMFlag(COMPAT_TRACE_IGNORE_LINES_WITHOUT_SAME_SECTOR_ON_BOTH_SIDES, COMPATF_TRACE, + tr("Trace ignores lines with the same sector on both sides")); + section << DMFlag(COMPAT_NO_MONSTERS_DROPOFF_MOVE, COMPATF_DROPOFF, + tr("Monsters can not move when hanging over a drop off")); + section << DMFlag(COMPAT_SCROLLING_SECTORS_ARE_ADDITIVE, COMPATF_BOOMSCROLL, + tr("Scrolling sectors are additive like Boom")); + section << DMFlag(COMPAT_MONSTERS_SEE_SEMI_INVISIBLE_PLAYERS, COMPATF_INVISIBILITY, + tr("Monsters can see semi-invisible players")); + section << DMFlag(COMPAT_INSTANTLY_MOVING_FLOORS_ARENT_SILENT, COMPATF_SILENT_INSTANT_FLOORS, + tr("Instantly moving floors are not silent")); + section << DMFlag(COMPAT_SECTOR_SOUNDS_USE_ORIGINAL_METHOD, COMPATF_SECTORSOUNDS, + tr("Sector sounds use original method for sound origin")); + section << DMFlag(COMPAT_USE_ORIGINAL_MISSILE_CLIPPING_HEIGHT, COMPATF_MISSILECLIP, + tr("Use original Doom heights for clipping against projectiles")); + section << DMFlag(COMPAT_MONSTERS_CANT_BE_PUSHED_OFF_CLIFFS, COMPATF_CROSSDROPOFF, + tr("Monsters can't be pushed over dropoffs")); + section << DMFlag(COMPAT_ANY_BOSS_DEATH_ACTIVATES_MAP_SPECIALS, COMPATF_ANYBOSSDEATH, + tr("Any monster which calls BOSSDEATH counts for level specials")); + section << DMFlag(COMPAT_MINOTAUR, COMPATF_MINOTAUR, + tr("Minotaur's floor flame is exploded immediately when feet are clipped")); + section << DMFlag(COMPAT_ORIGINAL_VELOCITY_CALC_FOR_MUSHROOM_IN_DEHACKED, COMPATF_MUSHROOM, + tr("Force original velocity calculations for A_Mushroom in Dehacked mods")); + section << DMFlag(COMPAT_FRICTION_PUSHERS_PULLERS_AFFECT_MONSTERS, COMPATF_MBFMONSTERMOVE, + tr("Monsters are affected by friction and pushers/pullers")); + section << DMFlag(COMPAT_CRUSHER_GIBS_BY_MORPHING_NOT_REPLACEMENT, COMPATF_CORPSEGIBS, + tr("Crushed monsters are turned into gibs, rather than replaced by gibs")); + section << DMFlag(COMPAT_BLOCK_MONSTER_LINES_IGNORE_FRIENDLY_MONSTERS, COMPATF_NOBLOCKFRIENDS, + tr("Friendly monsters aren't blocked by monster-blocking lines")); + section << DMFlag(COMPAT_SPRITE_SORT_ORDER_INVERTED, COMPATF_SPRITESORT, + tr("Invert sprite sorting order for sprites of equal distance")); + section << DMFlag(COMPAT_HITSCANS_ORIGINAL_BLOCKMAP, COMPATF_HITSCAN, + tr("Hitscans use original blockmap and hit check code")); + section << DMFlag(COMPAT_FIND_NEIGHBORING_LIGHT_LEVEL_LIKE_DOOM, COMPATF_LIGHT, + tr("Find neighboring light level like like Doom")); + section << DMFlag(COMPAT_DRAW_POLYOBJECTS_OLD, COMPATF_POLYOBJ, + tr("Draw polyobjects the old fashioned way")); + return section; +} + +DMFlagsSection Dmflags::zandronumqCompatFlags() +{ + using namespace ZandronumqGameSettingsNames; + + DMFlagsSection section("ZA Compat. flags"); + section << DMFlag(COMPAT_NETSCRIPTS_ARE_CLIENTSIDE, ZACOMPATF_NETSCRIPTS_ARE_CLIENTSIDE, + tr("Net scripts are client side")); + section << DMFlag(COMPAT_CLIENTS_SEND_FULL_BUTTON_INFO, ZACOMPATF_CLIENTS_SEND_FULL_BUTTON_INFO, + tr("Clients send full button info")); + section << DMFlag(NO_USE_LAND_CONSOLE_COMMAND, ZACOMPATF_NO_LAND, + tr("Players can't use 'land' CCMD")); + section << DMFlag(COMPAT_OLD_RANDOM_NUMBER_GENERATOR, + ZACOMPATF_OLD_RANDOM_GENERATOR, + tr("Use Doom's original random number generator")); + section << DMFlag(COMPAT_ADD_NOGRAVITYFLAG_TO_SPHERES, ZACOMPATF_NOGRAVITY_SPHERES, + tr("Spheres have NOGRAVITY flag")); + section << DMFlag(DONT_STOP_PLAYER_SCRIPTS_ON_DISCONNECT, + ZACOMPATF_DONT_STOP_PLAYER_SCRIPTS_ON_DISCONNECT, + tr("Don't stop player scripts on disconnect")); + section << DMFlag(OLD_ZDOOM_HORIZONTAL_THRUST, + ZACOMPATF_OLD_EXPLOSION_THRUST, + tr("Use horizontal explosion thrust of old ZDoom versions")); + section << DMFlag(OLD_ZDOOM_BRIDGE_DROPS, + ZACOMPATF_OLD_BRIDGE_DROPS, + tr("Non-SOLID things fall through invisible bridges")); + section << DMFlag(OLD_ZDOOM_JUMP_PHYSICS, ZACOMPATF_OLD_ZDOOM_ZMOVEMENT, + tr("Use old ZDoom jump physics")); + section << DMFlag(COMPAT_FULL_WEAPON_LOWER, + ZACOMPATF_FULL_WEAPON_LOWER, + tr("Disallow weapon change when in mid raise/lower")); + section << DMFlag(COMPAT_USE_VANILLA_AUTOAIM_TRACER_BEHAVIOR, ZACOMPATF_AUTOAIM, + tr("Use vanilla's autoaim tracer behavior")); + section << DMFlag(COMPAT_WEST_SPAWNS_ARE_SILENT, ZACOMPATF_SILENT_WEST_SPAWNS, + tr("West spawns are silent")); + section << DMFlag(COMPAT_LIMITED_MOVEMENT_IN_THE_AIR, ZACOMPATF_LIMITED_AIRMOVEMENT, + tr("Limited movement in the air")); + section << DMFlag(COMPAT_PLASMA_BUMP_BUG, ZACOMPATF_PLASMA_BUMP_BUG, + tr("Allow map01 \"plasma bump\" bug")); + section << DMFlag(COMPAT_ALLOW_INSTANT_RESPAWN, ZACOMPATF_INSTANTRESPAWN, + tr("Allow instant respawn after death")); + section << DMFlag(NO_TAUNT, ZACOMPATF_DISABLETAUNTS, + tr("Disable taunting")); + section << DMFlag(COMPAT_ORIGINAL_SOUND_CURVE, ZACOMPATF_ORIGINALSOUNDCURVE, + tr("Use doom2.exe's original sound curve")); + section << DMFlag(COMPAT_USE_OLD_INTERMISSION_SCREENS_MUSIC, ZACOMPATF_OLDINTERMISSION, + tr("Use original doom2 intermission music")); + section << DMFlag(COMPAT_DISABLE_STEALTH_MONSTERS, ZACOMPATF_DISABLESTEALTHMONSTERS, + tr("Disable stealth monsters")); + section << DMFlag(COMPAT_OLD_DAMAGE_RADIUS_INFINITE_HEIGHT, ZACOMPATF_OLDRADIUSDMG, + tr("Radius damage has infinite height")); + section << DMFlag(NO_USE_CROSSHAIRS, ZACOMPATF_NO_CROSSHAIR, + tr("Disable crosshair")); + section << DMFlag(COMPAT_ORIGINAL_WEAPON_SWITCH, ZACOMPATF_OLD_WEAPON_SWITCH, + tr("Force weapon switch")); + return section; +} + +DMFlagsSection Dmflags::dmflags() +{ + DMFlagsSection section("DMFlags"); + section << DMFlag("Do not spawn health items (DM)", DF_NO_HEALTH, + tr("Do not spawn health items (DM)")); + section << DMFlag("Do not spawn powerups (DM)", DF_NO_ITEMS, + tr("Do not spawn powerups (DM)")); + section << DMFlag("Weapons remain after pickup (DM)", DF_WEAPONS_STAY, + tr("Weapons remain after pickup (DM)")); + section << DMFlag("Falling damage (old ZDoom)", DF_FORCE_FALLINGZD, + tr("Falling damage (old ZDoom)")); + section << DMFlag("Falling damage (Hexen)", DF_FORCE_FALLINGHX, + tr("Falling damage (Hexen)")); + section << DMFlag("Falling damage (Strife)", DF_FORCE_FALLINGST, + tr("Falling damage (Strife)")); + section << DMFlag("Stay on same map when someone exits (DM)", DF_SAME_LEVEL, + tr("Stay on same map when someone exits (DM)")); + section << DMFlag("Spawn players as far as possible (DM)", DF_SPAWN_FARTHEST, + tr("Spawn players as far as possible (DM)")); + section << DMFlag("Automatically respawn dead players (DM)", DF_FORCE_RESPAWN, + tr("Automatically respawn dead players (DM)")); + section << DMFlag("Don't spawn armor (DM)", DF_NO_ARMOR, + tr("Don't spawn armor (DM)")); + section << DMFlag("Kill anyone who tries to exit the level (DM)", DF_NO_EXIT, + tr("Kill anyone who tries to exit the level (DM)")); + section << DMFlag("Infinite ammo", DF_INFINITE_AMMO, + tr("Infinite ammo")); + section << DMFlag("No monsters", DF_NO_MONSTERS, + tr("No monsters")); + section << DMFlag("Monsters respawn", DF_MONSTERS_RESPAWN, + tr("Monsters respawn")); + section << DMFlag("Items other than invuln. and invis. respawn", DF_ITEMS_RESPAWN, + tr("Items other than invuln. and invis. respawn")); + section << DMFlag("Fast monsters", DF_FAST_MONSTERS, + tr("Fast monsters")); + section << DMFlag("No jumping", DF_NO_JUMP, + tr("No jumping")); + section << DMFlag("No freelook", DF_NO_FREELOOK, + tr("No freelook")); + section << DMFlag("Respawn invulnerability and invisibility", DF_RESPAWN_SUPER, + tr("Respawn invulnerability and invisibility")); + section << DMFlag("Arbitrator FOV", DF_NO_FOV, + tr("Arbitrator FOV")); + section << DMFlag("No multiplayer weapons in cooperative", DF_NO_COOP_WEAPON_SPAWN, + tr("No multiplayer weapons in cooperative")); + section << DMFlag("No crouching", DF_NO_CROUCH, + tr("No crouching")); + section << DMFlag("Lose all old inventory on respawn (COOP)", DF_COOP_LOSE_INVENTORY, + tr("Lose all old inventory on respawn (COOP)")); + section << DMFlag("Lose keys on respawn (COOP)", DF_COOP_LOSE_KEYS, + tr("Lose keys on respawn (COOP)")); + section << DMFlag("Lose weapons on respawn (COOP)", DF_COOP_LOSE_WEAPONS, + tr("Lose weapons on respawn (COOP)")); + section << DMFlag("Lose armor on respawn (COOP)", DF_COOP_LOSE_ARMOR, + tr("Lose armor on respawn (COOP)")); + section << DMFlag("Lose powerups on respawn (COOP)", DF_COOP_LOSE_POWERUPS, + tr("Lose powerups on respawn (COOP)")); + section << DMFlag("Lose ammo on respawn (COOP)", DF_COOP_LOSE_AMMO, + tr("Lose ammo on respawn (COOP)")); + section << DMFlag("Lose half your ammo on respawn (COOP)", DF_COOP_HALVE_AMMO, + tr("Lose half your ammo on respawn (COOP)")); + // Why do these two exist anyway? + section << DMFlag("Jumping allowed", DF_YES_JUMP, + tr("Jumping allowed")); + section << DMFlag("Crouching allowed", DF_YES_CROUCH, + tr("Crouching allowed")); + return section; +} + +DMFlagsSection Dmflags::dmflags2() +{ + DMFlagsSection section("DMFlags2"); + section << DMFlag("Drop weapons upon death", DF2_YES_WEAPONDROP, + tr("Drop weapons upon death")); + section << DMFlag("Don't spawn runes", DF2_NO_RUNES, + tr("Don't spawn runes")); + section << DMFlag("Instantly return flags (ST/CTF)", DF2_INSTANT_RETURN, + tr("Instantly return flags (ST/CTF)")); + section << DMFlag("Don't allow players to switch teams", DF2_NO_TEAM_SWITCH, + tr("Don't allow players to switch teams")); + section << DMFlag("Players are automatically assigned teams", DF2_NO_TEAM_SELECT, + tr("Players are automatically assigned teams")); + section << DMFlag("Double the amount of ammo given", DF2_YES_DOUBLEAMMO, + tr("Double the amount of ammo given")); + section << DMFlag("Players slowly lose health over 100% like Quake", DF2_YES_DEGENERATION, + tr("Players slowly lose health over 100% like Quake")); + section << DMFlag("Allow BFG freeaiming", DF2_YES_FREEAIMBFG, + tr("Allow BFG freeaiming")); + section << DMFlag("Barrels respawn", DF2_BARRELS_RESPAWN, + tr("Barrels respawn")); + section << DMFlag("No respawn protection", DF2_NO_RESPAWN_INVUL, + tr("No respawn protection")); + section << DMFlag("All players start with a shotgun", DF2_COOP_SHOTGUNSTART, + tr("All players start with a shotgun")); + section << DMFlag("Players respawn where they died (COOP)", DF2_SAME_SPAWN_SPOT, + tr("Players respawn where they died (COOP)")); + section << DMFlag("Don't clear frags after each level", DF2_YES_KEEPFRAGS, + tr("Don't clear frags after each level")); + section << DMFlag("Player can't respawn", DF2_NO_RESPAWN, + tr("Player can't respawn")); + section << DMFlag("Lose a frag when killed", DF2_YES_LOSEFRAG, + tr("Lose a frag when killed")); + section << DMFlag("Infinite inventory", DF2_INFINITE_INVENTORY, + tr("Infinite inventory")); + section << DMFlag("All monsters must be killed before exiting", DF2_KILL_MONSTERS, + tr("All monsters must be killed before exiting")); + section << DMFlag("Players can't see the automap", DF2_NO_AUTOMAP, + tr("Players can't see the automap")); + section << DMFlag("Allies can't be seen on the automap", DF2_NO_AUTOMAP_ALLIES, + tr("Allies can't be seen on the automap")); + section << DMFlag("You can't spy allies", DF2_DISALLOW_SPYING, + tr("You can't spy allies")); + section << DMFlag("Players can use chase cam", DF2_CHASECAM, + tr("Players can use chase cam")); + section << DMFlag("Players can't suicide", DF2_NOSUICIDE, + tr("Players can't suicide")); + section << DMFlag("Players can't use autoaim", DF2_NOAUTOAIM, + tr("Players can't use autoaim")); + section << DMFlag("Don't check ammo when switching weapons", DF2_DONTCHECKAMMO, + tr("Don't check ammo when switching weapons")); + section << DMFlag("Kill all monsters spawned by a boss cube when the boss dies", DF2_KILLBOSSMONST, + tr("Kill all monsters spawned by a boss cube when the boss dies")); + return section; +} + +DMFlagsSection Dmflags::zandronumqDmflags() +{ + DMFlagsSection section("Zandronumq Flags"); + section << DMFlag("Clients can't identify targets", ZADF_NO_IDENTIFY_TARGET, + tr("Clients can't identify targets")); + section << DMFlag("lmsspectatorsettings applied in all game modes", + ZADF_ALWAYS_APPLY_LMS_SPECTATORSETTINGS, + tr("lmsspectatorsettings applied in all game modes")); + section << DMFlag("Clients can't draw coop info", ZADF_NO_COOP_INFO, + tr("Clients can't draw coop info")); + section << DMFlag("Unlagged is disabled", ZADF_NOUNLAGGED, + tr("Unlagged is disabled")); + section << DMFlag("Players don't block each other", ZADF_UNBLOCK_PLAYERS, + tr("Players don't block each other")); + section << DMFlag("Clients don't show medals", ZADF_NO_MEDALS, + tr("Clients don't show medals")); + section << DMFlag("Keys are shared between players", ZADF_SHARE_KEYS, + tr("Keys are shared between players")); + section << DMFlag("Player teams are preserved between maps", ZADF_YES_KEEP_TEAMS, + tr("Player teams are preserved between maps")); + section << DMFlag("Force OpenGL defaults", ZADF_FORCE_GL_DEFAULTS, + tr("Force OpenGL defaults")); + section << DMFlag("No rocket jumping", ZADF_NO_ROCKET_JUMPING, + tr("No rocket jumping")); + section << DMFlag("Award damage instead of kills", ZADF_AWARD_DAMAGE_INSTEAD_KILLS, + tr("Award damage instead of kills")); + section << DMFlag("Force drawing alpha", ZADF_FORCE_ALPHA, + tr("Force drawing alpha")); + section << DMFlag("Don't spawn multiplayer things", ZADF_COOP_SP_ACTOR_SPAWN, + tr("Don't spawn multiplayer things")); + section << DMFlag("Force blood screen brightness on clients to emulate vanilla", + ZADF_MAX_BLOOD_SCALAR, + tr("Force blood screen brightness on clients to emulate vanilla")); + section << DMFlag("Teammates don't block each other", ZADF_UNBLOCK_ALLIES, + tr("Teammates don't block each other")); + return section; +} + +QList Dmflags::flags() +{ + if (cachedFlags.isEmpty()) + { + cacheMutex.lock(); + if (cachedFlags.isEmpty()) + { + cachedFlags << dmflags(); + cachedFlags << dmflags2(); + cachedFlags << zandronumqDmflags(); + cachedFlags << compatFlags(); + cachedFlags << zandronumqCompatFlags(); + } + cacheMutex.unlock(); + } + return cachedFlags; +} +} diff --git a/src/plugins/zandronumq/zandronumq2dmflags.h b/src/plugins/zandronumq/zandronumq2dmflags.h new file mode 100644 index 00000000..249b7cc3 --- /dev/null +++ b/src/plugins/zandronumq/zandronumq2dmflags.h @@ -0,0 +1,284 @@ +//------------------------------------------------------------------------------ +// zandronumq2dmflags.h +//------------------------------------------------------------------------------ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301 USA +// +//------------------------------------------------------------------------------ +// Copyright (C) 2014 "Zalewa" +//------------------------------------------------------------------------------ +#ifndef id87B840A6_7A07_4EF7_BED7DE8ACD8DB8EB +#define id87B840A6_7A07_4EF7_BED7DE8ACD8DB8EB + +#include +#include + +class DMFlagsSection; + +namespace Zandronumq2 +{ +/** + * @brief Common dmflags. + */ +class Dmflags : public QObject +{ + Q_OBJECT + +public: + // DMFlag definitions as defined in "doomdef.h" of Zandronumq's + // source code. + + // [RH] dmflags bits (based on Q2's) + // [RC] NOTE: If adding a flag, be sure to add a stub in serverconsole_dmflags.cpp. + enum + { + DF_NO_HEALTH = 1 << 0, // Do not spawn health items (DM) + DF_NO_ITEMS = 1 << 1, // Do not spawn powerups (DM) - [RC] Currently not implemented (no easy way to find if it's an object, like AArtifact). + DF_WEAPONS_STAY = 1 << 2, // Leave weapons around after pickup (DM) + DF_FORCE_FALLINGZD = 1 << 3, // Falling too far hurts (old ZDoom style) + DF_FORCE_FALLINGHX = 2 << 3, // Falling too far hurts (Hexen style) + DF_FORCE_FALLINGST = 3 << 3, // Falling too far hurts (Strife style) + // 1 << 5 -- this space left blank -- + DF_SAME_LEVEL = 1 << 6, // Stay on the same map when someone exits (DM) + DF_SPAWN_FARTHEST = 1 << 7, // Spawn players as far as possible from other players (DM) + DF_FORCE_RESPAWN = 1 << 8, // Automatically respawn dead players after respawn_time is up (DM) + DF_NO_ARMOR = 1 << 9, // Do not spawn armor (DM) + DF_NO_EXIT = 1 << 10, // Kill anyone who tries to exit the level (DM) + DF_INFINITE_AMMO = 1 << 11, // Don't use up ammo when firing + DF_NO_MONSTERS = 1 << 12, // Don't spawn monsters (replaces -nomonsters parm) + DF_MONSTERS_RESPAWN = 1 << 13, // Monsters respawn sometime after their death (replaces -respawn parm) + DF_ITEMS_RESPAWN = 1 << 14, // Items other than invuln. and invis. respawn + DF_FAST_MONSTERS = 1 << 15, // Monsters are fast (replaces -fast parm) + DF_NO_JUMP = 1 << 16, // Don't allow jumping + // [BB] I don't want to change the dmflag numbers compared to 97D. + DF_YES_JUMP = 1 << 29, + DF_NO_FREELOOK = 1 << 17, // Don't allow freelook + DF_RESPAWN_SUPER = 1 << 18, // Respawn invulnerability and invisibility + DF_NO_FOV = 1 << 19, // Only let the arbitrator set FOV (for all players) + DF_NO_COOP_WEAPON_SPAWN = 1 << 20, // Don't spawn multiplayer weapons in coop games + DF_NO_CROUCH = 1 << 21, // Don't allow crouching + // [BB] I don't want to change the dmflag numbers compared to 97D. + DF_YES_CROUCH = 1 << 30, // + DF_COOP_LOSE_INVENTORY = 1 << 22, // Lose all your old inventory when respawning in coop + DF_COOP_LOSE_KEYS = 1 << 23, // Lose keys when respawning in coop + DF_COOP_LOSE_WEAPONS = 1 << 24, // Lose weapons when respawning in coop + DF_COOP_LOSE_ARMOR = 1 << 25, // Lose armor when respawning in coop + DF_COOP_LOSE_POWERUPS = 1 << 26, // Lose powerups when respawning in coop + DF_COOP_LOSE_AMMO = 1 << 27, // Lose ammo when respawning in coop + DF_COOP_HALVE_AMMO = 1 << 28, // Lose half your ammo when respawning in coop (but not less than the normal starting amount) + + }; + + // [BC] More dmflags. w00p! + // [RC] NOTE: If adding a flag, be sure to add a stub in serverconsole_dmflags.cpp. + enum + { + // DF2_YES_IMPALING = 1 << 0, // Player gets implaed on MF2_IMPALE items + DF2_YES_WEAPONDROP = 1 << 1, // Drop current weapon upon death + DF2_NO_RUNES = 1 << 2, // Don't spawn runes + DF2_INSTANT_RETURN = 1 << 3, // Instantly return flags and skulls when player carrying it dies (ST/CTF) + DF2_NO_TEAM_SWITCH = 1 << 4, // Do not allow players to switch teams in teamgames + DF2_NO_TEAM_SELECT = 1 << 5, // Player is automatically placed on a team. + DF2_YES_DOUBLEAMMO = 1 << 6, // Double amount of ammo that items give you like skill 1 and 5 do + DF2_YES_DEGENERATION = 1 << 7, // Player slowly loses health when over 100% (Quake-style) + DF2_YES_FREEAIMBFG = 1 << 8, // Allow BFG freeaiming in multiplayer games. + DF2_BARRELS_RESPAWN = 1 << 9, // Barrels respawn (duh) + DF2_NO_RESPAWN_INVUL = 1 << 10, // No respawn invulnerability. + DF2_COOP_SHOTGUNSTART = 1 << 11, // All playres start with a shotgun when they respawn + DF2_SAME_SPAWN_SPOT = 1 << 12, // Players respawn in the same place they died (co-op) + DF2_YES_KEEPFRAGS = 1 << 13, // Don't clear frags after each level + DF2_NO_RESPAWN = 1 << 14, // Player cannot respawn + DF2_YES_LOSEFRAG = 1 << 15, // Lose a frag when killed. More incentive to try to not get yerself killed + DF2_INFINITE_INVENTORY = 1 << 16, // Infinite inventory. + DF2_KILL_MONSTERS = 1 << 17, // All monsters must be killed before the level exits. + DF2_NO_AUTOMAP = 1 << 18, // Players are allowed to see the automap. + DF2_NO_AUTOMAP_ALLIES = 1 << 19, // Allies can been seen on the automap. + DF2_DISALLOW_SPYING = 1 << 20, // You can spy on your allies. + DF2_CHASECAM = 1 << 21, // Players can use the chasecam cheat. + DF2_NOSUICIDE = 1 << 22, // Players are not allowed to suicide. + DF2_NOAUTOAIM = 1 << 23, // Players cannot use autoaim. + DF2_DONTCHECKAMMO = 1 << 24, // Don't Check ammo when switching weapons. + DF2_KILLBOSSMONST = 1 << 25, // Kills all monsters spawned by a boss cube when the boss dies + }; + + // [BB] Zandronumq dmflags. + enum + { + // [BB] Enforces clients not to identify players, i.e. behave as if cl_identifytarget == 0. + ZADF_NO_IDENTIFY_TARGET = 1 << 0, + + // [BB] Apply lmsspectatorsettings in all game modes. + ZADF_ALWAYS_APPLY_LMS_SPECTATORSETTINGS = 1 << 1, + + // [BB] Enforces clients not to draw coop info, i.e. behave as if cl_drawcoopinfo == 0. + ZADF_NO_COOP_INFO = 1 << 2, + + // [Spleen] Don't use ping-based backwards reconciliation for player-fired hitscans and rails. + ZADF_NOUNLAGGED = 1 << 3, + + // [BB] Handle player bodies as if they had MF6_THRUSPECIES. + ZADF_UNBLOCK_PLAYERS = 1 << 4, + + // [BB] Enforces clients not to show medals, i.e. behave as if cl_medals == 0. + ZADF_NO_MEDALS = 1 << 5, + + // [Dusk] Share keys between all players + ZADF_SHARE_KEYS = 1 << 6, + + // [BB] Player keeps his team after a map change. + ZADF_YES_KEEP_TEAMS = 1 << 7, + + // [BB] Enforces some Gl rendering options to their default values. + ZADF_FORCE_GL_DEFAULTS = 1 << 8, + + // [BB] P_RadiusAttack doesn't give players any z-momentum if the attack was made by a player. This essentially disables rocket jumping. + ZADF_NO_ROCKET_JUMPING = 1 << 9, + + // [BB] Award actual damage dealt instead of kills. + ZADF_AWARD_DAMAGE_INSTEAD_KILLS = 1 << 10, + + // [BB] Enforces clients to display alpha, i.e. render as if r_drawtrans == 1. + ZADF_FORCE_ALPHA = 1 << 11, + + // [BB] Spawn map actors in coop as if the game was single player. + ZADF_COOP_SP_ACTOR_SPAWN = 1 << 12, + + // [CK] Force blood brightness to max scalar on clients to emulate vanilla screen damage + // [Dusk] Now a dmflag. + ZADF_MAX_BLOOD_SCALAR = 1 << 13, + + // [TP] Like ZADF_UNBLOCK_PLAYERS except only for teammates. + ZADF_UNBLOCK_ALLIES = 1 << 14, + }; + + // [RH] Compatibility flags. + // [RC] NOTE: If adding a flag, be sure to add a stub in serverconsole_dmflags.cpp. + enum + { + COMPATF_SHORTTEX = 1 << 0, // Use Doom's shortest texture around behavior? + COMPATF_STAIRINDEX = 1 << 1, // Don't fix loop index for stair building? + COMPATF_LIMITPAIN = 1 << 2, // Pain elemental is limited to 20 lost souls? + COMPATF_SILENTPICKUP = 1 << 3, // Pickups are only heard locally? + COMPATF_NO_PASSMOBJ = 1 << 4, // Pretend every actor is infinitely tall? + COMPATF_MAGICSILENCE = 1 << 5, // Limit actors to one sound at a time? + COMPATF_WALLRUN = 1 << 6, // Enable buggier wall clipping so players can wallrun? + COMPATF_NOTOSSDROPS = 1 << 7, // Spawn dropped items directly on the floor? + COMPATF_USEBLOCKING = 1 << 8, // Any special line can block a use line + COMPATF_NODOORLIGHT = 1 << 9, // Don't do the BOOM local door light effect + COMPATF_RAVENSCROLL = 1 << 10, // Raven's scrollers use their original carrying speed + COMPATF_SOUNDTARGET = 1 << 11, // Use sector based sound target code. + COMPATF_DEHHEALTH = 1 << 12, // Limit deh.MaxHealth to the health bonus (as in Doom2.exe) + COMPATF_TRACE = 1 << 13, // Trace ignores lines with the same sector on both sides + COMPATF_DROPOFF = 1 << 14, // Monsters cannot move when hanging over a dropoff + COMPATF_BOOMSCROLL = 1 << 15, // Scrolling sectors are additive like in Boom + COMPATF_INVISIBILITY = 1 << 16, // Monsters can see semi-invisible players + COMPATF_SILENT_INSTANT_FLOORS = 1<<17, // Instantly moving floors are not silent + COMPATF_SECTORSOUNDS = 1 << 18, // Sector sounds use original method for sound origin. + COMPATF_MISSILECLIP = 1 << 19, // Use original Doom heights for clipping against projectiles + COMPATF_CROSSDROPOFF = 1 << 20, // monsters can't be pushed over dropoffs + COMPATF_ANYBOSSDEATH = 1 << 21, // [GZ] Any monster which calls BOSSDEATH counts for level specials + COMPATF_MINOTAUR = 1 << 22, // Minotaur's floor flame is exploded immediately when feet are clipped + COMPATF_MUSHROOM = 1 << 23, // Force original velocity calculations for A_Mushroom in Dehacked mods. + COMPATF_MBFMONSTERMOVE = 1 << 24, // Monsters are affected by friction and pushers/pullers. + COMPATF_CORPSEGIBS = 1 << 25, // Crushed monsters are turned into gibs, rather than replaced by gibs. + COMPATF_NOBLOCKFRIENDS = 1 << 26, // Friendly monsters aren't blocked by monster-blocking lines. + COMPATF_SPRITESORT = 1 << 27, // Invert sprite sorting order for sprites of equal distance + COMPATF_HITSCAN = 1 << 28, // Hitscans use original blockmap anf hit check code. + COMPATF_LIGHT = 1 << 29, // Find neighboring light level like Doom + COMPATF_POLYOBJ = 1 << 30, // Draw polyobjects the old fashioned way + }; + + // [BB] Zandronumq compatibility flags. + enum + { + // [BB] Treat ACS scripts with the SCRIPTF_Net flag to be client side, i.e. + // executed on the clients, but not on the server. + ZACOMPATF_NETSCRIPTS_ARE_CLIENTSIDE = 1 << 0, + // [BB] Clients send ucmd.buttons as "long" instead of as "byte" in CLIENTCOMMANDS_ClientMove. + // So far this is only necessary if the ACS function GetPlayerInput is used in a server side + // script to check for buttons bigger than BT_ZOOM. Otherwise this information is completely + // useless for the server and the additional net traffic to send it should be avoided. + ZACOMPATF_CLIENTS_SEND_FULL_BUTTON_INFO = 1 << 1, + // [BB] Players are not allowed to use the land CCMD. Because of Skulltag's default amount + // of air control, flying players can get a huge speed boast with the land CCMD. Disallowing + // players to land, allows to keep the default air control most people are used to while not + // giving flying players too much of an advantage. + ZACOMPATF_NO_LAND = 1 << 2, + // [BB] Use Doom's random table instead of ZDoom's random number generator. + ZACOMPATF_OLD_RANDOM_GENERATOR = 1 << 3, + // [BB] Add NOGRAVITY to actors named InvulnerabilitySphere, Soulsphere, Megasphere and BlurSphere + // when spawned by the map. + ZACOMPATF_NOGRAVITY_SPHERES = 1 << 4, + // [BB] When a player leaves the game, don't stop any scripts of that player that are still running. + ZACOMPATF_DONT_STOP_PLAYER_SCRIPTS_ON_DISCONNECT = 1 << 5, + // [BB] Use the horizontal thrust of old ZDoom versions in P_RadiusAttack. + ZACOMPATF_OLD_EXPLOSION_THRUST = 1 << 6, + // [BB] Use the P_TestMobjZ approach of old ZDoom versions where non-SOLID things (like flags) fall + // through invisible bridges. + ZACOMPATF_OLD_BRIDGE_DROPS = 1 << 7, + // [CK] Uses old ZDoom jump physics, it's a minor bug in the gravity code that causes gravity application in the wrong place + ZACOMPATF_OLD_ZDOOM_ZMOVEMENT = 1 << 8, + // [CK] You can't change weapons mid raise/lower in vanilla + ZACOMPATF_FULL_WEAPON_LOWER = 1 << 9, + // [CK] We use more tracers to fill in the gaps, this reverts it to vanilla's 3 tracer behavior + ZACOMPATF_AUTOAIM = 1 << 10, + // [CK] Vanilla doom had silent west spawns + ZACOMPATF_SILENT_WEST_SPAWNS = 1 << 11, + + // Limited movement in the air. + ZACOMPATF_LIMITED_AIRMOVEMENT = 1 << 17, + + // Allow the map01 "plasma bump" bug. + ZACOMPATF_PLASMA_BUMP_BUG = 1 << 18, + + // Allow instant respawn after death. + ZACOMPATF_INSTANTRESPAWN = 1 << 19, + + // Taunting is disabled. + ZACOMPATF_DISABLETAUNTS = 1 << 20, + + // Use doom2.exe's original sound curve. + ZACOMPATF_ORIGINALSOUNDCURVE = 1 << 21, + + // Use doom2.exe's original intermission screens/music. + ZACOMPATF_OLDINTERMISSION = 1 << 22, + + // Disable stealth monsters, since doom2.exe didn't have them. + ZACOMPATF_DISABLESTEALTHMONSTERS = 1 << 23, + + // [BB] Always use the old radius damage code (infinite height) + ZACOMPATF_OLDRADIUSDMG = 1 << 24, + + // [BB] Clients are not allowed to use a crosshair. + ZACOMPATF_NO_CROSSHAIR = 1 << 25, + + // [BB] Clients use the vanilla Doom weapon on pickup behavior. + ZACOMPATF_OLD_WEAPON_SWITCH = 1 << 26, + }; + + QList flags(); + +private: + DMFlagsSection compatFlags(); + DMFlagsSection dmflags(); + DMFlagsSection dmflags2(); + DMFlagsSection zandronumqCompatFlags(); + DMFlagsSection zandronumqDmflags(); +}; + +} + +#endif diff --git a/src/plugins/zandronumq/zandronumq3dmflags.cpp b/src/plugins/zandronumq/zandronumq3dmflags.cpp new file mode 100644 index 00000000..31d1ad03 --- /dev/null +++ b/src/plugins/zandronumq/zandronumq3dmflags.cpp @@ -0,0 +1,362 @@ +//------------------------------------------------------------------------------ +// zandronumq3dmflags.cpp +//------------------------------------------------------------------------------ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301 USA +// +//------------------------------------------------------------------------------ +// Copyright (C) 2016 "Zalewa" +//------------------------------------------------------------------------------ +#include "zandronumq3dmflags.h" + +#include "zandronumqgamesettings.h" +#include +#include + +namespace Zandronumq3 +{ +static QList cachedFlags; +static QMutex cacheMutex; + +DMFlagsSection Dmflags::compatFlags() +{ + using namespace ZandronumqGameSettingsNames; + + DMFlagsSection section("Compat. flags"); + section << DMFlag(COMPAT_FIND_SHORTEST_TEXTURES_LIKE_DOOM, COMPATF_SHORTTEX, + tr("Use Doom's shortest texture behavior")); + section << DMFlag(COMPAT_USE_BUGGIER_STAIR_BUILDING, COMPATF_STAIRINDEX, + tr("Don't fix loop index for stair building")); + section << DMFlag(COMPAT_LIMIT_PAIN_ELEMENTALS, COMPATF_LIMITPAIN, + tr("Pain elemental is limited to 20 lost souls")); + section << DMFlag(COMPAT_DONT_LET_OTHERS_HEAR_PICKUPS, COMPATF_SILENTPICKUP, + tr("Pickups are only heard locally")); + section << DMFlag(COMPAT_ACTORS_ARE_INFINITELY_TALL, COMPATF_NO_PASSMOBJ, + tr("Infinitely tall actors")); + section << DMFlag(COMPAT_ALLOW_SILENT_BFGTRICK, COMPATF_MAGICSILENCE, + tr("Limit actors to only one sound")); + section << DMFlag(COMPAT_ENABLE_WALL_RUNNING, COMPATF_WALLRUN, + tr("Enable wallrunning")); + section << DMFlag(COMPAT_SPAWN_ITEM_DROPS_ON_THE_FLOOR, COMPATF_NOTOSSDROPS, + tr("Dropped items spawn on floor")); + section << DMFlag(COMPAT_ALL_SPECIAL_LINES_CAN_DROP_USE_LINES, COMPATF_USEBLOCKING, + tr("Special lines block use line")); + section << DMFlag(COMPAT_DISABLE_BOOM_DOOR_LIGHT_EFFECT, COMPATF_NODOORLIGHT, + tr("Disable BOOM local door light effect")); + section << DMFlag(COMPAT_RAVENS_SCROLLERS_USE_ORIGINAL_SPEED, COMPATF_RAVENSCROLL, + tr("Raven's scrollers use their original speed")); + section << DMFlag(COMPAT_USE_SECTOR_BASED_SOUND_TARGET_CODE, COMPATF_SOUNDTARGET, + tr("Use sector based sound target code")); + section << DMFlag(COMPAT_LIMIT_DEH_MAX_HEALTH_TO_HEALTH_BONUS, COMPATF_DEHHEALTH, + tr("Limit dehacked MaxHealth to health bonus")); + section << DMFlag(COMPAT_TRACE_IGNORE_LINES_WITHOUT_SAME_SECTOR_ON_BOTH_SIDES, COMPATF_TRACE, + tr("Trace ignores lines with the same sector on both sides")); + section << DMFlag(COMPAT_NO_MONSTERS_DROPOFF_MOVE, COMPATF_DROPOFF, + tr("Monsters can not move when hanging over a drop off")); + section << DMFlag(COMPAT_SCROLLING_SECTORS_ARE_ADDITIVE, COMPATF_BOOMSCROLL, + tr("Scrolling sectors are additive like Boom")); + section << DMFlag(COMPAT_MONSTERS_SEE_SEMI_INVISIBLE_PLAYERS, COMPATF_INVISIBILITY, + tr("Monsters can see semi-invisible players")); + section << DMFlag(COMPAT_INSTANTLY_MOVING_FLOORS_ARENT_SILENT, COMPATF_SILENT_INSTANT_FLOORS, + tr("Instantly moving floors are not silent")); + section << DMFlag(COMPAT_SECTOR_SOUNDS_USE_ORIGINAL_METHOD, COMPATF_SECTORSOUNDS, + tr("Sector sounds use original method for sound origin")); + section << DMFlag(COMPAT_USE_ORIGINAL_MISSILE_CLIPPING_HEIGHT, COMPATF_MISSILECLIP, + tr("Use original Doom heights for clipping against projectiles")); + section << DMFlag(COMPAT_MONSTERS_CANT_BE_PUSHED_OFF_CLIFFS, COMPATF_CROSSDROPOFF, + tr("Monsters can't be pushed over dropoffs")); + section << DMFlag(COMPAT_ANY_BOSS_DEATH_ACTIVATES_MAP_SPECIALS, COMPATF_ANYBOSSDEATH, + tr("Any monster which calls BOSSDEATH counts for level specials")); + section << DMFlag(COMPAT_MINOTAUR, COMPATF_MINOTAUR, + tr("Minotaur's floor flame is exploded immediately when feet are clipped")); + section << DMFlag(COMPAT_ORIGINAL_VELOCITY_CALC_FOR_MUSHROOM_IN_DEHACKED, COMPATF_MUSHROOM, + tr("Force original velocity calculations for A_Mushroom in Dehacked mods")); + section << DMFlag(COMPAT_FRICTION_PUSHERS_PULLERS_AFFECT_MONSTERS, COMPATF_MBFMONSTERMOVE, + tr("Monsters are affected by friction and pushers/pullers")); + section << DMFlag(COMPAT_CRUSHER_GIBS_BY_MORPHING_NOT_REPLACEMENT, COMPATF_CORPSEGIBS, + tr("Crushed monsters are turned into gibs, rather than replaced by gibs")); + section << DMFlag(COMPAT_BLOCK_MONSTER_LINES_IGNORE_FRIENDLY_MONSTERS, COMPATF_NOBLOCKFRIENDS, + tr("Friendly monsters aren't blocked by monster-blocking lines")); + section << DMFlag(COMPAT_SPRITE_SORT_ORDER_INVERTED, COMPATF_SPRITESORT, + tr("Invert sprite sorting order for sprites of equal distance")); + section << DMFlag(COMPAT_HITSCANS_ORIGINAL_BLOCKMAP, COMPATF_HITSCAN, + tr("Hitscans use original blockmap and hit check code")); + section << DMFlag(COMPAT_FIND_NEIGHBORING_LIGHT_LEVEL_LIKE_DOOM, COMPATF_LIGHT, + tr("Find neighboring light level like like Doom")); + section << DMFlag(COMPAT_DRAW_POLYOBJECTS_OLD, COMPATF_POLYOBJ, + tr("Draw polyobjects the old fashioned way")); + section << DMFlag("Ignore compositing when drawing masked midtextures", COMPATF_MASKEDMIDTEX, + tr("Ignore compositing when drawing masked midtextures")); + return section; +} + +DMFlagsSection Dmflags::compatFlags2() +{ + DMFlagsSection section("Compat. flags 2"); + section << DMFlag("It is impossible to directly face cardinal direction", COMPATF2_BADANGLES, + tr("It is impossible to directly face cardinal direction")); + section << DMFlag("Use the same floor motion behavior as Doom", COMPATF2_FLOORMOVE, + tr("Use the same floor motion behavior as Doom")); + return section; +} + +DMFlagsSection Dmflags::zandronumqCompatFlags() +{ + using namespace ZandronumqGameSettingsNames; + + DMFlagsSection section("ZA Compat. flags"); + section << DMFlag(COMPAT_NETSCRIPTS_ARE_CLIENTSIDE, ZACOMPATF_NETSCRIPTS_ARE_CLIENTSIDE, + tr("Net scripts are client side")); + section << DMFlag(COMPAT_CLIENTS_SEND_FULL_BUTTON_INFO, ZACOMPATF_CLIENTS_SEND_FULL_BUTTON_INFO, + tr("Clients send full button info")); + section << DMFlag(NO_USE_LAND_CONSOLE_COMMAND, ZACOMPATF_NO_LAND, + tr("Players can't use 'land' CCMD")); + section << DMFlag(COMPAT_OLD_RANDOM_NUMBER_GENERATOR, + ZACOMPATF_OLD_RANDOM_GENERATOR, + tr("Use Doom's original random number generator")); + section << DMFlag(COMPAT_ADD_NOGRAVITYFLAG_TO_SPHERES, ZACOMPATF_NOGRAVITY_SPHERES, + tr("Spheres have NOGRAVITY flag")); + section << DMFlag(DONT_STOP_PLAYER_SCRIPTS_ON_DISCONNECT, + ZACOMPATF_DONT_STOP_PLAYER_SCRIPTS_ON_DISCONNECT, + tr("Don't stop player scripts on disconnect")); + section << DMFlag(OLD_ZDOOM_HORIZONTAL_THRUST, + ZACOMPATF_OLD_EXPLOSION_THRUST, + tr("Use horizontal explosion thrust of old ZDoom versions")); + section << DMFlag(OLD_ZDOOM_BRIDGE_DROPS, + ZACOMPATF_OLD_BRIDGE_DROPS, + tr("Non-SOLID things fall through invisible bridges")); + section << DMFlag(OLD_ZDOOM_JUMP_PHYSICS, ZACOMPATF_OLD_ZDOOM_ZMOVEMENT, + tr("Use old ZDoom jump physics")); + section << DMFlag(COMPAT_FULL_WEAPON_LOWER, + ZACOMPATF_FULL_WEAPON_LOWER, + tr("Disallow weapon change when in mid raise/lower")); + section << DMFlag(COMPAT_USE_VANILLA_AUTOAIM_TRACER_BEHAVIOR, ZACOMPATF_AUTOAIM, + tr("Use vanilla's autoaim tracer behavior")); + section << DMFlag(COMPAT_WEST_SPAWNS_ARE_SILENT, ZACOMPATF_SILENT_WEST_SPAWNS, + tr("West spawns are silent")); + section << DMFlag(COMPAT_LIMITED_MOVEMENT_IN_THE_AIR, ZACOMPATF_LIMITED_AIRMOVEMENT, + tr("Limited movement in the air")); + section << DMFlag(COMPAT_PLASMA_BUMP_BUG, ZACOMPATF_PLASMA_BUMP_BUG, + tr("Allow map01 \"plasma bump\" bug")); + section << DMFlag(COMPAT_ALLOW_INSTANT_RESPAWN, ZACOMPATF_INSTANTRESPAWN, + tr("Allow instant respawn after death")); + section << DMFlag(NO_TAUNT, ZACOMPATF_DISABLETAUNTS, + tr("Disable taunting")); + section << DMFlag(COMPAT_ORIGINAL_SOUND_CURVE, ZACOMPATF_ORIGINALSOUNDCURVE, + tr("Use doom2.exe's original sound curve")); + section << DMFlag(COMPAT_USE_OLD_INTERMISSION_SCREENS_MUSIC, ZACOMPATF_OLDINTERMISSION, + tr("Use original doom2 intermission music")); + section << DMFlag(COMPAT_DISABLE_STEALTH_MONSTERS, ZACOMPATF_DISABLESTEALTHMONSTERS, + tr("Disable stealth monsters")); + section << DMFlag(COMPAT_OLD_DAMAGE_RADIUS_INFINITE_HEIGHT, ZACOMPATF_OLDRADIUSDMG, + tr("Radius damage has infinite height")); + section << DMFlag(NO_USE_CROSSHAIRS, ZACOMPATF_NO_CROSSHAIR, + tr("Disable crosshair")); + section << DMFlag(COMPAT_ORIGINAL_WEAPON_SWITCH, ZACOMPATF_OLD_WEAPON_SWITCH, + tr("Force weapon switch")); + return section; +} + +DMFlagsSection Dmflags::dmflags() +{ + DMFlagsSection section("DMFlags"); + section << DMFlag("Do not spawn health items (DM)", DF_NO_HEALTH, + tr("Do not spawn health items (DM)")); + section << DMFlag("Do not spawn powerups (DM)", DF_NO_ITEMS, + tr("Do not spawn powerups (DM)")); + section << DMFlag("Weapons remain after pickup (DM)", DF_WEAPONS_STAY, + tr("Weapons remain after pickup (DM)")); + section << DMFlag("Falling damage (old ZDoom)", DF_FORCE_FALLINGZD, + tr("Falling damage (old ZDoom)")); + section << DMFlag("Falling damage (Hexen)", DF_FORCE_FALLINGHX, + tr("Falling damage (Hexen)")); + section << DMFlag("Falling damage (Strife)", DF_FORCE_FALLINGST, + tr("Falling damage (Strife)")); + section << DMFlag("Stay on same map when someone exits (DM)", DF_SAME_LEVEL, + tr("Stay on same map when someone exits (DM)")); + section << DMFlag("Spawn players as far as possible (DM)", DF_SPAWN_FARTHEST, + tr("Spawn players as far as possible (DM)")); + section << DMFlag("Automatically respawn dead players (DM)", DF_FORCE_RESPAWN, + tr("Automatically respawn dead players (DM)")); + section << DMFlag("Don't spawn armor (DM)", DF_NO_ARMOR, + tr("Don't spawn armor (DM)")); + section << DMFlag("Kill anyone who tries to exit the level (DM)", DF_NO_EXIT, + tr("Kill anyone who tries to exit the level (DM)")); + section << DMFlag("Infinite ammo", DF_INFINITE_AMMO, + tr("Infinite ammo")); + section << DMFlag("No monsters", DF_NO_MONSTERS, + tr("No monsters")); + section << DMFlag("Monsters respawn", DF_MONSTERS_RESPAWN, + tr("Monsters respawn")); + section << DMFlag("Items other than invuln. and invis. respawn", DF_ITEMS_RESPAWN, + tr("Items other than invuln. and invis. respawn")); + section << DMFlag("Fast monsters", DF_FAST_MONSTERS, + tr("Fast monsters")); + section << DMFlag("No jumping", DF_NO_JUMP, + tr("No jumping")); + section << DMFlag("No freelook", DF_NO_FREELOOK, + tr("No freelook")); + section << DMFlag("Respawn invulnerability and invisibility", DF_RESPAWN_SUPER, + tr("Respawn invulnerability and invisibility")); + section << DMFlag("Arbitrator FOV", DF_NO_FOV, + tr("Arbitrator FOV")); + section << DMFlag("No multiplayer weapons in cooperative", DF_NO_COOP_WEAPON_SPAWN, + tr("No multiplayer weapons in cooperative")); + section << DMFlag("No crouching", DF_NO_CROUCH, + tr("No crouching")); + section << DMFlag("Lose all old inventory on respawn (COOP)", DF_COOP_LOSE_INVENTORY, + tr("Lose all old inventory on respawn (COOP)")); + section << DMFlag("Lose keys on respawn (COOP)", DF_COOP_LOSE_KEYS, + tr("Lose keys on respawn (COOP)")); + section << DMFlag("Lose weapons on respawn (COOP)", DF_COOP_LOSE_WEAPONS, + tr("Lose weapons on respawn (COOP)")); + section << DMFlag("Lose armor on respawn (COOP)", DF_COOP_LOSE_ARMOR, + tr("Lose armor on respawn (COOP)")); + section << DMFlag("Lose powerups on respawn (COOP)", DF_COOP_LOSE_POWERUPS, + tr("Lose powerups on respawn (COOP)")); + section << DMFlag("Lose ammo on respawn (COOP)", DF_COOP_LOSE_AMMO, + tr("Lose ammo on respawn (COOP)")); + section << DMFlag("Lose half your ammo on respawn (COOP)", DF_COOP_HALVE_AMMO, + tr("Lose half your ammo on respawn (COOP)")); + section << DMFlag("Jumping allowed", DF_YES_JUMP, + tr("Jumping allowed")); + section << DMFlag("Crouching allowed", DF_YES_CROUCH, + tr("Crouching allowed")); + return section; +} + +DMFlagsSection Dmflags::dmflags2() +{ + DMFlagsSection section("DMFlags2"); + section << DMFlag("Drop weapons upon death", DF2_YES_WEAPONDROP, + tr("Drop weapons upon death")); + section << DMFlag("Don't spawn runes", DF2_NO_RUNES, + tr("Don't spawn runes")); + section << DMFlag("Instantly return flags (ST/CTF)", DF2_INSTANT_RETURN, + tr("Instantly return flags (ST/CTF)")); + section << DMFlag("Don't allow players to switch teams", DF2_NO_TEAM_SWITCH, + tr("Don't allow players to switch teams")); + section << DMFlag("Players are automatically assigned teams", DF2_NO_TEAM_SELECT, + tr("Players are automatically assigned teams")); + section << DMFlag("Double the amount of ammo given", DF2_YES_DOUBLEAMMO, + tr("Double the amount of ammo given")); + section << DMFlag("Players slowly lose health over 100% like Quake", DF2_YES_DEGENERATION, + tr("Players slowly lose health over 100% like Quake")); + section << DMFlag("Allow BFG freeaiming", DF2_YES_FREEAIMBFG, + tr("Allow BFG freeaiming")); + section << DMFlag("Barrels respawn", DF2_BARRELS_RESPAWN, + tr("Barrels respawn")); + section << DMFlag("No respawn protection", DF2_NO_RESPAWN_INVUL, + tr("No respawn protection")); + section << DMFlag("All players start with a shotgun", DF2_COOP_SHOTGUNSTART, + tr("All players start with a shotgun")); + section << DMFlag("Players respawn where they died (COOP)", DF2_SAME_SPAWN_SPOT, + tr("Players respawn where they died (COOP)")); + section << DMFlag("Don't clear frags after each level", DF2_YES_KEEPFRAGS, + tr("Don't clear frags after each level")); + section << DMFlag("Player can't respawn", DF2_NO_RESPAWN, + tr("Player can't respawn")); + section << DMFlag("Lose a frag when killed", DF2_YES_LOSEFRAG, + tr("Lose a frag when killed")); + section << DMFlag("Infinite inventory", DF2_INFINITE_INVENTORY, + tr("Infinite inventory")); + section << DMFlag("All monsters must be killed before exiting", DF2_KILL_MONSTERS, + tr("All monsters must be killed before exiting")); + section << DMFlag("Players can't see the automap", DF2_NO_AUTOMAP, + tr("Players can't see the automap")); + section << DMFlag("Allies can't be seen on the automap", DF2_NO_AUTOMAP_ALLIES, + tr("Allies can't be seen on the automap")); + section << DMFlag("You can't spy allies", DF2_DISALLOW_SPYING, + tr("You can't spy allies")); + section << DMFlag("Players can use chase cam", DF2_CHASECAM, + tr("Players can use chase cam")); + section << DMFlag("Players can't suicide", DF2_NOSUICIDE, + tr("Players can't suicide")); + section << DMFlag("Players can't use autoaim", DF2_NOAUTOAIM, + tr("Players can't use autoaim")); + section << DMFlag("Don't check ammo when switching weapons", DF2_DONTCHECKAMMO, + tr("Don't check ammo when switching weapons")); + section << DMFlag("Kill all monsters spawned by a boss cube when the boss dies", DF2_KILLBOSSMONST, + tr("Kill all monsters spawned by a boss cube when the boss dies")); + section << DMFlag("Do not count monsters in 'end level when dying' sectors towards kill count", + DF2_NOCOUNTENDMONST, + tr("Do not count monsters in 'end level when dying' sectors towards kill count")); + return section; +} + +DMFlagsSection Dmflags::zandronumqDmflags() +{ + DMFlagsSection section("Zandronumq Flags"); + section << DMFlag("Clients can't identify targets", ZADF_NO_IDENTIFY_TARGET, + tr("Clients can't identify targets")); + section << DMFlag("lmsspectatorsettings applied in all game modes", + ZADF_ALWAYS_APPLY_LMS_SPECTATORSETTINGS, + tr("lmsspectatorsettings applied in all game modes")); + section << DMFlag("Clients can't draw coop info", ZADF_NO_COOP_INFO, + tr("Clients can't draw coop info")); + section << DMFlag("Unlagged is disabled", ZADF_NOUNLAGGED, + tr("Unlagged is disabled")); + section << DMFlag("Players don't block each other", ZADF_UNBLOCK_PLAYERS, + tr("Players don't block each other")); + section << DMFlag("Clients don't show medals", ZADF_NO_MEDALS, + tr("Clients don't show medals")); + section << DMFlag("Keys are shared between players", ZADF_SHARE_KEYS, + tr("Keys are shared between players")); + section << DMFlag("Player teams are preserved between maps", ZADF_YES_KEEP_TEAMS, + tr("Player teams are preserved between maps")); + section << DMFlag("Force OpenGL defaults", ZADF_FORCE_GL_DEFAULTS, + tr("Force OpenGL defaults")); + section << DMFlag("No rocket jumping", ZADF_NO_ROCKET_JUMPING, + tr("No rocket jumping")); + section << DMFlag("Award damage instead of kills", ZADF_AWARD_DAMAGE_INSTEAD_KILLS, + tr("Award damage instead of kills")); + section << DMFlag("Force drawing alpha", ZADF_FORCE_ALPHA, + tr("Force drawing alpha")); + section << DMFlag("Don't spawn multiplayer things", ZADF_COOP_SP_ACTOR_SPAWN, + tr("Don't spawn multiplayer things")); + section << DMFlag("Force blood screen brightness on clients to emulate vanilla", + ZADF_MAX_BLOOD_SCALAR, + tr("Force blood screen brightness on clients to emulate vanilla")); + section << DMFlag("Teammates don't block each other", ZADF_UNBLOCK_ALLIES, + tr("Teammates don't block each other")); + section << DMFlag("No dropping allowed", ZADF_NODROP, + tr("No dropping allowed")); + section << DMFlag("No map reset on death in survival", ZADF_SURVIVAL_NO_MAP_RESET_ON_DEATH, + tr("No map reset on death in survival")); + section << DMFlag("Dead players can keep inventory", ZADF_DEAD_PLAYERS_CAN_KEEP_INVENTORY, + tr("Dead players can keep inventory")); + return section; +} + +QList Dmflags::flags() +{ + if (cachedFlags.isEmpty()) + { + cacheMutex.lock(); + if (cachedFlags.isEmpty()) + { + cachedFlags << dmflags(); + cachedFlags << dmflags2(); + cachedFlags << zandronumqDmflags(); + cachedFlags << compatFlags(); + cachedFlags << zandronumqCompatFlags(); + cachedFlags << compatFlags2(); + } + cacheMutex.unlock(); + } + return cachedFlags; +} +} diff --git a/src/plugins/zandronumq/zandronumq3dmflags.h b/src/plugins/zandronumq/zandronumq3dmflags.h new file mode 100644 index 00000000..6fae2ac4 --- /dev/null +++ b/src/plugins/zandronumq/zandronumq3dmflags.h @@ -0,0 +1,304 @@ +//------------------------------------------------------------------------------ +// zandronumq3dmflags.h +//------------------------------------------------------------------------------ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301 USA +// +//------------------------------------------------------------------------------ +// Copyright (C) 2016 "Zalewa" +//------------------------------------------------------------------------------ +#ifndef id87B840A6_7A07_4EF7_BED7DE8ACD8DB8EC +#define id87B840A6_7A07_4EF7_BED7DE8ACD8DB8EC + +#include +#include + +class DMFlagsSection; + +namespace Zandronumq3 +{ +/** + * @brief Common dmflags. + */ +class Dmflags : public QObject +{ + Q_OBJECT + +public: + // DMFlag definitions as defined in "doomdef.h" of Zandronumq's + // source code. + + // [RH] dmflags bits (based on Q2's) + // [RC] NOTE: If adding a flag, be sure to add a stub in serverconsole_dmflags.cpp. + enum + { + DF_NO_HEALTH = 1 << 0, // Do not spawn health items (DM) + DF_NO_ITEMS = 1 << 1, // Do not spawn powerups (DM) - [RC] Currently not implemented (no easy way to find if it's an object, like AArtifact). + DF_WEAPONS_STAY = 1 << 2, // Leave weapons around after pickup (DM) + DF_FORCE_FALLINGZD = 1 << 3, // Falling too far hurts (old ZDoom style) + DF_FORCE_FALLINGHX = 2 << 3, // Falling too far hurts (Hexen style) + DF_FORCE_FALLINGST = 3 << 3, // Falling too far hurts (Strife style) + // 1 << 5 -- this space left blank -- + DF_SAME_LEVEL = 1 << 6, // Stay on the same map when someone exits (DM) + DF_SPAWN_FARTHEST = 1 << 7, // Spawn players as far as possible from other players (DM) + DF_FORCE_RESPAWN = 1 << 8, // Automatically respawn dead players after respawn_time is up (DM) + DF_NO_ARMOR = 1 << 9, // Do not spawn armor (DM) + DF_NO_EXIT = 1 << 10, // Kill anyone who tries to exit the level (DM) + DF_INFINITE_AMMO = 1 << 11, // Don't use up ammo when firing + DF_NO_MONSTERS = 1 << 12, // Don't spawn monsters (replaces -nomonsters parm) + DF_MONSTERS_RESPAWN = 1 << 13, // Monsters respawn sometime after their death (replaces -respawn parm) + DF_ITEMS_RESPAWN = 1 << 14, // Items other than invuln. and invis. respawn + DF_FAST_MONSTERS = 1 << 15, // Monsters are fast (replaces -fast parm) + DF_NO_JUMP = 1 << 16, // Don't allow jumping + DF_YES_JUMP = 2 << 16, + DF_NO_FREELOOK = 1 << 18, // Don't allow freelook + DF_RESPAWN_SUPER = 1 << 19, // Respawn invulnerability and invisibility + DF_NO_FOV = 1 << 20, // Only let the arbitrator set FOV (for all players) + DF_NO_COOP_WEAPON_SPAWN = 1 << 21, // Don't spawn multiplayer weapons in coop games + DF_NO_CROUCH = 1 << 22, // Don't allow crouching + DF_YES_CROUCH = 2 << 22, // + DF_COOP_LOSE_INVENTORY = 1 << 24, // Lose all your old inventory when respawning in coop + DF_COOP_LOSE_KEYS = 1 << 25, // Lose keys when respawning in coop + DF_COOP_LOSE_WEAPONS = 1 << 26, // Lose weapons when respawning in coop + DF_COOP_LOSE_ARMOR = 1 << 27, // Lose armor when respawning in coop + DF_COOP_LOSE_POWERUPS = 1 << 28, // Lose powerups when respawning in coop + DF_COOP_LOSE_AMMO = 1 << 29, // Lose ammo when respawning in coop + DF_COOP_HALVE_AMMO = 1 << 30, // Lose half your ammo when respawning in coop (but not less than the normal starting amount) + }; + + // [BC] More dmflags. w00p! + // [RC] NOTE: If adding a flag, be sure to add a stub in serverconsole_dmflags.cpp. + enum + { + // DF2_YES_IMPALING = 1 << 0, // Player gets implaed on MF2_IMPALE items + DF2_YES_WEAPONDROP = 1 << 1, // Drop current weapon upon death + DF2_NO_RUNES = 1 << 2, // Don't spawn runes + DF2_INSTANT_RETURN = 1 << 3, // Instantly return flags and skulls when player carrying it dies (ST/CTF) + DF2_NO_TEAM_SWITCH = 1 << 4, // Do not allow players to switch teams in teamgames + DF2_NO_TEAM_SELECT = 1 << 5, // Player is automatically placed on a team. + DF2_YES_DOUBLEAMMO = 1 << 6, // Double amount of ammo that items give you like skill 1 and 5 do + DF2_YES_DEGENERATION = 1 << 7, // Player slowly loses health when over 100% (Quake-style) + DF2_YES_FREEAIMBFG = 1 << 8, // Allow BFG freeaiming in multiplayer games. + DF2_BARRELS_RESPAWN = 1 << 9, // Barrels respawn (duh) + DF2_NO_RESPAWN_INVUL = 1 << 10, // No respawn invulnerability. + DF2_COOP_SHOTGUNSTART = 1 << 11, // All playres start with a shotgun when they respawn + DF2_SAME_SPAWN_SPOT = 1 << 12, // Players respawn in the same place they died (co-op) + DF2_YES_KEEPFRAGS = 1 << 13, // Don't clear frags after each level + DF2_NO_RESPAWN = 1 << 14, // Player cannot respawn + DF2_YES_LOSEFRAG = 1 << 15, // Lose a frag when killed. More incentive to try to not get yerself killed + DF2_INFINITE_INVENTORY = 1 << 16, // Infinite inventory. + DF2_KILL_MONSTERS = 1 << 17, // All monsters must be killed before the level exits. + DF2_NO_AUTOMAP = 1 << 18, // Players are allowed to see the automap. + DF2_NO_AUTOMAP_ALLIES = 1 << 19, // Allies can been seen on the automap. + DF2_DISALLOW_SPYING = 1 << 20, // You can spy on your allies. + DF2_CHASECAM = 1 << 21, // Players can use the chasecam cheat. + DF2_NOSUICIDE = 1 << 22, // Players are not allowed to suicide. + DF2_NOAUTOAIM = 1 << 23, // Players cannot use autoaim. + DF2_DONTCHECKAMMO = 1 << 24, // Don't Check ammo when switching weapons. + DF2_KILLBOSSMONST = 1 << 25, // Kills all monsters spawned by a boss cube when the boss dies + DF2_NOCOUNTENDMONST = 1 << 26, // Do not count monsters in 'end level when dying' sectors towards kill count + }; + + // [BB] Zandronumq dmflags. + enum + { + // [BB] Enforces clients not to identify players, i.e. behave as if cl_identifytarget == 0. + ZADF_NO_IDENTIFY_TARGET = 1 << 0, + + // [BB] Apply lmsspectatorsettings in all game modes. + ZADF_ALWAYS_APPLY_LMS_SPECTATORSETTINGS = 1 << 1, + + // [BB] Enforces clients not to draw coop info, i.e. behave as if cl_drawcoopinfo == 0. + ZADF_NO_COOP_INFO = 1 << 2, + + // [Spleen] Don't use ping-based backwards reconciliation for player-fired hitscans and rails. + ZADF_NOUNLAGGED = 1 << 3, + + // [BB] Handle player bodies as if they had MF6_THRUSPECIES. + ZADF_UNBLOCK_PLAYERS = 1 << 4, + + // [BB] Enforces clients not to show medals, i.e. behave as if cl_medals == 0. + ZADF_NO_MEDALS = 1 << 5, + + // [Dusk] Share keys between all players + ZADF_SHARE_KEYS = 1 << 6, + + // [BB] Player keeps his team after a map change. + ZADF_YES_KEEP_TEAMS = 1 << 7, + + // [BB] Enforces some Gl rendering options to their default values. + ZADF_FORCE_GL_DEFAULTS = 1 << 8, + + // [BB] P_RadiusAttack doesn't give players any z-velocity if the attack was made by a player. This essentially disables rocket jumping. + ZADF_NO_ROCKET_JUMPING = 1 << 9, + + // [BB] Award actual damage dealt instead of kills. + ZADF_AWARD_DAMAGE_INSTEAD_KILLS = 1 << 10, + + // [BB] Enforces clients to display alpha, i.e. render as if r_drawtrans == 1. + ZADF_FORCE_ALPHA = 1 << 11, + + // [BB] Spawn map actors in coop as if the game was single player. + ZADF_COOP_SP_ACTOR_SPAWN = 1 << 12, + + // [CK] Force blood brightness to max scalar on clients to emulate vanilla screen damage + // [Dusk] Now a dmflag. + ZADF_MAX_BLOOD_SCALAR = 1 << 13, + + // [TP] Like ZADF_UNBLOCK_PLAYERS except only for teammates. + ZADF_UNBLOCK_ALLIES = 1 << 14, + + // [TP] No dropping allowed. + ZADF_NODROP = 1 << 15, + + // [Zalewa] Don't reset map when all players die in survival. + // Just respawn the players with fresh set of lives and allow + // the ones in queue to join. + ZADF_SURVIVAL_NO_MAP_RESET_ON_DEATH = 1 << 16, + + // Affects game modes where sv_maxlives is honored by the game. + // If set, players who become dead spectators (run out of lives) will still + // keep inventory in accordance to DF_COOP_LOSE_* and DF_COOP_HALVE_AMMO flags. + // If unset, players who lose all lives will lose entire inventory + // regardless of the DF_COOP_* flags. + ZADF_DEAD_PLAYERS_CAN_KEEP_INVENTORY = 1 << 17, + }; + + // [RH] Compatibility flags. + // [RC] NOTE: If adding a flag, be sure to add a stub in serverconsole_dmflags.cpp. + enum + { + COMPATF_SHORTTEX = 1 << 0, // Use Doom's shortest texture around behavior? + COMPATF_STAIRINDEX = 1 << 1, // Don't fix loop index for stair building? + COMPATF_LIMITPAIN = 1 << 2, // Pain elemental is limited to 20 lost souls? + COMPATF_SILENTPICKUP = 1 << 3, // Pickups are only heard locally? + COMPATF_NO_PASSMOBJ = 1 << 4, // Pretend every actor is infinitely tall? + COMPATF_MAGICSILENCE = 1 << 5, // Limit actors to one sound at a time? + COMPATF_WALLRUN = 1 << 6, // Enable buggier wall clipping so players can wallrun? + COMPATF_NOTOSSDROPS = 1 << 7, // Spawn dropped items directly on the floor? + COMPATF_USEBLOCKING = 1 << 8, // Any special line can block a use line + COMPATF_NODOORLIGHT = 1 << 9, // Don't do the BOOM local door light effect + COMPATF_RAVENSCROLL = 1 << 10, // Raven's scrollers use their original carrying speed + COMPATF_SOUNDTARGET = 1 << 11, // Use sector based sound target code. + COMPATF_DEHHEALTH = 1 << 12, // Limit deh.MaxHealth to the health bonus (as in Doom2.exe) + COMPATF_TRACE = 1 << 13, // Trace ignores lines with the same sector on both sides + COMPATF_DROPOFF = 1 << 14, // Monsters cannot move when hanging over a dropoff + COMPATF_BOOMSCROLL = 1 << 15, // Scrolling sectors are additive like in Boom + COMPATF_INVISIBILITY = 1 << 16, // Monsters can see semi-invisible players + COMPATF_SILENT_INSTANT_FLOORS = 1<<17, // Instantly moving floors are not silent + COMPATF_SECTORSOUNDS = 1 << 18, // Sector sounds use original method for sound origin. + COMPATF_MISSILECLIP = 1 << 19, // Use original Doom heights for clipping against projectiles + COMPATF_CROSSDROPOFF = 1 << 20, // monsters can't be pushed over dropoffs + COMPATF_ANYBOSSDEATH = 1 << 21, // [GZ] Any monster which calls BOSSDEATH counts for level specials + COMPATF_MINOTAUR = 1 << 22, // Minotaur's floor flame is exploded immediately when feet are clipped + COMPATF_MUSHROOM = 1 << 23, // Force original velocity calculations for A_Mushroom in Dehacked mods. + COMPATF_MBFMONSTERMOVE = 1 << 24, // Monsters are affected by friction and pushers/pullers. + COMPATF_CORPSEGIBS = 1 << 25, // Crushed monsters are turned into gibs, rather than replaced by gibs. + COMPATF_NOBLOCKFRIENDS = 1 << 26, // Friendly monsters aren't blocked by monster-blocking lines. + COMPATF_SPRITESORT = 1 << 27, // Invert sprite sorting order for sprites of equal distance + COMPATF_HITSCAN = 1 << 28, // Hitscans use original blockmap anf hit check code. + COMPATF_LIGHT = 1 << 29, // Find neighboring light level like Doom + COMPATF_POLYOBJ = 1 << 30, // Draw polyobjects the old fashioned way + COMPATF_MASKEDMIDTEX = 1u << 31, // Ignore compositing when drawing masked midtextures + + COMPATF2_BADANGLES = 1 << 0, // It is impossible to face directly NSEW. + COMPATF2_FLOORMOVE = 1 << 1, // Use the same floor motion behavior as Doom. + }; + + // [BB] Zandronumq compatibility flags. + enum + { + // [BB] Treat ACS scripts with the SCRIPTF_Net flag to be client side, i.e. + // executed on the clients, but not on the server. + ZACOMPATF_NETSCRIPTS_ARE_CLIENTSIDE = 1 << 0, + // [BB] Clients send ucmd.buttons as "long" instead of as "byte" in CLIENTCOMMANDS_ClientMove. + // So far this is only necessary if the ACS function GetPlayerInput is used in a server side + // script to check for buttons bigger than BT_ZOOM. Otherwise this information is completely + // useless for the server and the additional net traffic to send it should be avoided. + ZACOMPATF_CLIENTS_SEND_FULL_BUTTON_INFO = 1 << 1, + // [BB] Players are not allowed to use the land CCMD. Because of Skulltag's default amount + // of air control, flying players can get a huge speed boast with the land CCMD. Disallowing + // players to land, allows to keep the default air control most people are used to while not + // giving flying players too much of an advantage. + ZACOMPATF_NO_LAND = 1 << 2, + // [BB] Use Doom's random table instead of ZDoom's random number generator. + ZACOMPATF_OLD_RANDOM_GENERATOR = 1 << 3, + // [BB] Add NOGRAVITY to actors named InvulnerabilitySphere, Soulsphere, Megasphere and BlurSphere + // when spawned by the map. + ZACOMPATF_NOGRAVITY_SPHERES = 1 << 4, + // [BB] When a player leaves the game, don't stop any scripts of that player that are still running. + ZACOMPATF_DONT_STOP_PLAYER_SCRIPTS_ON_DISCONNECT = 1 << 5, + // [BB] Use the horizontal thrust of old ZDoom versions in P_RadiusAttack. + ZACOMPATF_OLD_EXPLOSION_THRUST = 1 << 6, + // [BB] Use the P_TestMobjZ approach of old ZDoom versions where non-SOLID things (like flags) fall + // through invisible bridges. + ZACOMPATF_OLD_BRIDGE_DROPS = 1 << 7, + // [CK] Uses old ZDoom jump physics, it's a minor bug in the gravity code that causes gravity application in the wrong place + ZACOMPATF_OLD_ZDOOM_ZMOVEMENT = 1 << 8, + // [CK] You can't change weapons mid raise/lower in vanilla + ZACOMPATF_FULL_WEAPON_LOWER = 1 << 9, + // [CK] We use more tracers to fill in the gaps, this reverts it to vanilla's 3 tracer behavior + ZACOMPATF_AUTOAIM = 1 << 10, + // [CK] Vanilla doom had silent west spawns + ZACOMPATF_SILENT_WEST_SPAWNS = 1 << 11, + // [BB] Restore the jumping behavior known from Skulltag. This reverts the jumping change from ZDoom SVN revision 2970. + ZACOMPATF_SKULLTAG_JUMPING = 1 << 12, + + // Limited movement in the air. + ZACOMPATF_LIMITED_AIRMOVEMENT = 1 << 17, + + // Allow the map01 "plasma bump" bug. + ZACOMPATF_PLASMA_BUMP_BUG = 1 << 18, + + // Allow instant respawn after death. + ZACOMPATF_INSTANTRESPAWN = 1 << 19, + + // Taunting is disabled. + ZACOMPATF_DISABLETAUNTS = 1 << 20, + + // Use doom2.exe's original sound curve. + ZACOMPATF_ORIGINALSOUNDCURVE = 1 << 21, + + // Use doom2.exe's original intermission screens/music. + ZACOMPATF_OLDINTERMISSION = 1 << 22, + + // Disable stealth monsters, since doom2.exe didn't have them. + ZACOMPATF_DISABLESTEALTHMONSTERS = 1 << 23, + + // [BB] Always use the old radius damage code (infinite height) + ZACOMPATF_OLDRADIUSDMG = 1 << 24, + + // [BB] Clients are not allowed to use a crosshair. + ZACOMPATF_NO_CROSSHAIR = 1 << 25, + + // [BB] Clients use the vanilla Doom weapon on pickup behavior. + ZACOMPATF_OLD_WEAPON_SWITCH = 1 << 26, + }; + + QList flags(); + +private: + DMFlagsSection compatFlags(); + DMFlagsSection compatFlags2(); + DMFlagsSection dmflags(); + DMFlagsSection dmflags2(); + DMFlagsSection zandronumqCompatFlags(); + DMFlagsSection zandronumqDmflags(); +}; + +} + +#endif diff --git a/src/plugins/zandronumq/zandronumqbinaries.cpp b/src/plugins/zandronumq/zandronumqbinaries.cpp new file mode 100644 index 00000000..93bf6426 --- /dev/null +++ b/src/plugins/zandronumq/zandronumqbinaries.cpp @@ -0,0 +1,524 @@ +//------------------------------------------------------------------------------ +// zandronumqbinaries.cpp +//------------------------------------------------------------------------------ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301 USA +// +//------------------------------------------------------------------------------ +// Copyright (C) 2012 "Zalewa" +//------------------------------------------------------------------------------ +#include "log.h" + +#include "../wadseeker/zip/unarchive.h" +#include "application.h" +#include "plugins/engineplugin.h" +#include "serverapi/message.h" +#include "version.h" +#include "zandronumqbinaries.h" +#include "zandronumqengineplugin.h" +#include "zandronumqserver.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TESTING_BINARY_URL_BASE "https://qzandronum.com/downloads/testing/%1/ZandroDev%1-%2" + +#ifdef Q_OS_WIN32 +#define TESTING_BINARY_URL TESTING_BINARY_URL_BASE "windows.zip" +#define ZANDRONUMQ_BINARY_NAME "q-zandronum.exe" +#define SCRIPT_FILE_EXTENSION ".bat" +#else + +#ifndef __x86_64__ +#define TESTING_BINARY_URL TESTING_BINARY_URL_BASE "linux-x86.tar.bz2" +#else +#define TESTING_BINARY_URL TESTING_BINARY_URL_BASE "linux-x86_64.tar.bz2" +#endif + +#ifndef Q_OS_DARWIN +#define ZANDRONUMQ_BINARY_NAME "q-zandronum" +#else +#define ZANDRONUMQ_BINARY_NAME "Q-Zandronum.app" +#define ZANDRONUMQ_APP_BUNDLE_BIN "/Contents/MacOS/q-zandronum" +#endif +#define SCRIPT_FILE_EXTENSION ".sh" +#endif + +class ZandronumqClientExeFile::PrivData +{ +public: + QSharedPointer server; + + bool isEmptyDir(const QString &path) const + { + QDir dir(path); + return dir.exists() && dir.entryList( + QDir::NoDotAndDotDot | QDir::AllEntries).isEmpty(); + } + + bool isNonEmptyDir(const QString &path) const + { + QDir dir(path); + return dir.exists() && !dir.entryList( + QDir::NoDotAndDotDot | QDir::AllEntries).isEmpty(); + } +}; + +ZandronumqClientExeFile::ZandronumqClientExeFile(const QSharedPointer &server) +{ + d = new PrivData(); + d->server = server; + setProgramName(server->plugin()->data()->name); + setExeTypeName(tr("client")); + setConfigKey("BinaryPath"); +} + +ZandronumqClientExeFile::~ZandronumqClientExeFile() +{ + delete d; +} + +IniSection &ZandronumqClientExeFile::config() +{ + return *ZandronumqEnginePlugin::staticInstance()->data()->pConfig; +} + +Message ZandronumqClientExeFile::install(QWidget *parent) +{ + if (askToInstallTestingVersion(parent)) + { + QString path = config()["TestingPath"]; + if (path.isEmpty()) + { + return Message::customError(tr("No testing directory specified for Zandronumq")); + } + + QDir dir(path); + if (!dir.mkpath(".")) + { + return Message::customError(tr("Unable to create directory:\n%1").arg(path)); + } + if (!dir.mkpath(testingVersion())) + { + return Message::customError(tr("Unable to create directory:\n%1/%2").arg( + path, testingVersion())); + } + + QString finalDestinationPath = path + '/' + testingVersion(); + + // Now copy all .ini's. On Linux .ini's are kept in ~/.zandronumq so this will + // do nothing, but on Windows this should work like magic. + Message message; + QDir baseBinaryDir(workingDirectory(message)); + QStringList nameFilters; + nameFilters << "*.ini"; + QStringList iniFiles = baseBinaryDir.entryList(nameFilters, QDir::Files); + for (QString str : iniFiles) + { + QString sourcePath = baseBinaryDir.absolutePath() + '/' + str; + QString targetPath = finalDestinationPath + '/' + str; + QFile file(sourcePath); + file.copy(targetPath); + } + + if (!downloadTestingBinaries(finalDestinationPath, parent)) + { + QMessageBox::information(parent, tr("Doomseeker"), + tr("Please install now version \"%1\" into:\n%2").arg(testingVersion(), path)); + } + + return Message(Message::Type::SUCCESSFUL); + } + return Message(Message::Type::CANCELLED); +} + +bool ZandronumqClientExeFile::askToInstallTestingVersion(QWidget *parent) const +{ + QString question; + QMessageBox::Icon icon = QMessageBox::NoIcon; + if (d->isNonEmptyDir(testingVersionInstallPath())) + { + question = tr("

Installation of testing binaries for version %1 " + "can potentially overwrite your files.

" + "

Game will be installed to:
%2

" + "

Do you want Doomseeker to extract Zandronumq files, potentially " + "overwriting existing ones, and to copy all your configuration " + "files from your base directory?

").arg( + testingVersion(), testingVersionInstallPath()); + icon = QMessageBox::Warning; + } + else + { + question = tr("Zandronumq testing version %1 can be installed.\n\n" + "Game will be installed to:\n%2\n\n" + "Do you want Doomseeker to install that version and copy all " + "your configuration files from your base directory?").arg( + testingVersion(), testingVersionInstallPath()); + icon = QMessageBox::Question; + } + QMessageBox box(icon, tr("Doomseeker - install Zandronumq testing version"), question, + QMessageBox::Yes | QMessageBox::No, parent); + + // Gross hack to enable text copying from a QMessageBox. + // http://stackoverflow.com/a/32595502/1089357 + box.setStyleSheet("QMessageBox { messagebox-text-interaction-flags: 5; }"); + + return box.exec() == QMessageBox::Yes; +} + +QString ZandronumqClientExeFile::pathToExe(Message &message) +{ + IniSection &config = *ZandronumqEnginePlugin::staticInstance()->data()->pConfig; + + if (!d->server->isTestingServer() || !config["EnableTesting"]) + { + return ExeFile::pathToExe(message); + } + else + { + message = Message(); + QString error; + + QString testingPathRoot = config["TestingPath"]; + if (testingPathRoot.isEmpty()) + { + error = tr("No testing directory specified for Zandronumq"); + message = Message::customError(error); + return QString(); + } + + QString path = testingVersionInstallPath(); + + QFileInfo fi(path); + if (!fi.exists() || d->isEmptyDir(path)) + { + error = tr("%1\ndoesn't exist.\nYou need to install new testing binaries.").arg(path); + message = Message(Message::Type::GAME_NOT_FOUND_BUT_CAN_BE_INSTALLED, error); + return QString(); + } + + if (!fi.isDir()) + { + error = tr("%1\nexists but is NOT a directory.\nCannot proceed.").arg(path); + message = Message::customError(error); + return QString(); + } + + QString binPath = path + '/' + ZANDRONUMQ_BINARY_NAME; + fi = QFileInfo(binPath); + if (!fi.exists() || (fi.isDir() && !fi.isBundle())) + { + error = tr("%1\nexists but doesn't contain Zandronumq executable.\n\n" + "Doomseeker can still install the game there if you want.").arg(path); + message = Message(Message::Type::GAME_NOT_FOUND_BUT_CAN_BE_INSTALLED, error); + return QString(); + } + + // Everything checked out, so proceed to create (if necessary) and return path to the script file. + QString retPath; + if (!spawnTestingBatchFile(path, retPath, message)) + { + // message is already specified inside spawnTestingBatchFile() + return QString(); + } + + return retPath; + } +} + +QString ZandronumqClientExeFile::testingVersion() const +{ + QString testingVersion = d->server->gameVersion(); + // Strip out extraneous data in the version number. + return testingVersion.left(testingVersion.indexOf(' ')); +} + +QString ZandronumqClientExeFile::testingVersionInstallPath() const +{ + IniSection &config = *ZandronumqEnginePlugin::staticInstance()->data()->pConfig; + QString path = config["TestingPath"]; + return Strings::combinePaths(path, testingVersion()); +} + +QString ZandronumqClientExeFile::workingDirectory(Message &message) +{ + Q_UNUSED(message); + IniSection &config = *ZandronumqEnginePlugin::staticInstance()->data()->pConfig; + + QFileInfo fi((QString)config["BinaryPath"]); + return fi.absolutePath(); +} + +bool ZandronumqClientExeFile::downloadTestingBinaries(const QDir &destination, QWidget *parent) +{ + #ifdef Q_OS_DARWIN + // Can't do anything for Mac OS X at this time. :/ + return false; + #else + // Download testing binaries + ZandronumqVersion version(d->server->gameVersion()); + + // Find the hg revision string + QString hgVersion; + if (version.hgVersionDate() < 4000) // Arbitrary number here to determine between old and new format + hgVersion = QString("%1").arg(version.hgVersionDate()); + else + hgVersion = QString("%1-%2").arg(version.hgVersionDate()).arg(version.hgVersionTime(), 4, 10, QChar('0')); + + // Get URL + QString versionPrefix; + if (version.revisionVersion() != 0) + { + versionPrefix = QString("%1.%2.%3").arg(version.majorVersion()) + .arg(version.minorVersion()).arg(version.revisionVersion()); + } + else + { + versionPrefix = QString("%1.%2").arg(version.majorVersion()) + .arg(version.minorVersion()); + } + + QUrl url(QString(TESTING_BINARY_URL).arg(versionPrefix).arg(hgVersion)); + gLog << tr("Downloading Zandronumq testing binary from URL: %1").arg(url.toString()); + TestingProgressDialog dialog(url, parent); + int ret = dialog.exec(); + if (!dialog.error().isEmpty()) + { + QMessageBox::critical(parent, tr("Doomseeker - download failed"), + tr("Failed to download testing binary.\n\n%1").arg(dialog.error())); + return false; + } + else if (ret == QDialog::Accepted) + { + // Extract the needed files. + QString filename; + QFileInfo fi(dialog.filename()); + QByteArray data = dialog.data(); + QBuffer dataBuffer(&data); + QScopedPointer archive(UnArchive::openArchive(fi, &dataBuffer)); + + if (!archive.isNull()) + { + for (int i = 0;; ++i) + { + filename = archive->fileNameFromIndex(i); + + if (filename.isNull()) + { + break; + } + + QString fileTargetPath = destination.path() + QDir::separator() + filename; + gLog << tr("Unpacking file: %1").arg(fileTargetPath); + if (archive->extract(i, fileTargetPath)) + { + // Make sure we can execute the binary. + if (filename == ZANDRONUMQ_BINARY_NAME) + { + QFile binaryFile(fileTargetPath); + binaryFile.setPermissions(binaryFile.permissions() | QFile::ExeUser); + } + } + else + { + QMessageBox::critical(parent, tr("Doomseeker - unpack failed"), + tr("Failed to unpack: %1").arg(filename)); + return false; + } + } + return true; + } + } + + return false; + #endif +} + +QString ZandronumqClientExeFile::scriptFileExtension() +{ + return SCRIPT_FILE_EXTENSION; +} + +bool ZandronumqClientExeFile::spawnTestingBatchFile(const QString &versionDir, QString &fullPathToFile, Message &message) +{ + QString binaryPath = versionDir + '/' + ZANDRONUMQ_BINARY_NAME; + // This will create an actual path to file, because there is no '/' at the end + // of scriptFilepath. + fullPathToFile = versionDir + SCRIPT_FILE_EXTENSION; + QFileInfo fi(fullPathToFile); + QFile file(fullPathToFile); + if (fi.isDir()) + { + QString error = tr("%1\n should be a script file but is a directory!").arg(fullPathToFile); + message = Message::customError(error); + return false; + } + + if (fi.exists()) + { + if ((file.permissions() & QFile::ExeUser) == 0) + { + QString error = tr("You don't have permissions to execute file: %1\n").arg(fullPathToFile); + message = Message::customError(error); + return false; + } + return true; + } + + QString content; + #ifdef Q_OS_WIN32 + // Create Windows batch file + // Extract drive letter: + QString driveLetter; + QString workDir = workingDirectory(message); + for (int i = 0; i < workDir.length(); ++i) + { + if (workDir[i] == ':') + { + driveLetter = workDir.left(i); + } + } + + if (!driveLetter.isEmpty()) + { + content += driveLetter + ":\r\n"; + } + + QString cdDir = workingDirectory(message).replace('/', '\\'); + QString exePath = binaryPath.replace('/', '\\'); + + content += "cd \"" + cdDir + "\"\r\n"; + content += "\"" + exePath + "\" %*"; // %* deals with all the parameters + #else + QString cdDir = workingDirectory(message); + + // Create Unix script file + content = "#!/bin/sh\n"; + content += "cd \"" + cdDir + "\" \n"; + content += "export LANG=C\n"; + #ifdef Q_OS_DARWIN + content += "\"" + binaryPath + ZANDRONUMQ_APP_BUNDLE_BIN "\" \"$@\"\n"; + #else + content += "\"" + binaryPath + "\" \"$@\"\n"; // "$@" deals with all the parameters + #endif + #endif + + if (!file.open(QIODevice::WriteOnly)) + { + QString error = tr("Couldn't open batch file \"%1\" for writing").arg(fullPathToFile); + message = Message::customError(error); + return false; + } + + if (file.write(content.toUtf8()) < 0) + { + QString error = tr("Error while writing batch file \"%1\"").arg(fullPathToFile); + message = Message::customError(error); + file.close(); + return false; + } + + file.close(); + + if (!file.setPermissions(file.permissions() | QFile::ExeUser)) + { + QString error = tr("Cannot set permissions for file:\n%1").arg(fullPathToFile); + message = Message::customError(error); + return false; + } + + return true; +} + +//////////////////////////////////////////////////////////////////////////////// + +TestingProgressDialog::TestingProgressDialog(const QUrl &url, QWidget *parent) + : QProgressDialog(tr("Downloading testing binaries..."), tr("Cancel"), 0, 0, parent) +{ + connect(this, SIGNAL(canceled()), this, SLOT(abort())); + + getUrl(url); + + setAutoClose(false); + setAutoReset(false); + setMinimumDuration(0); +} + +void TestingProgressDialog::abort() +{ + pNetworkReply->abort(); +} + +void TestingProgressDialog::downloadProgress(qint64 value, qint64 max) +{ + setValue(value); + setMaximum(max); +} + +void TestingProgressDialog::downloadFinished() +{ + QUrl possibleRedirectUrl = pNetworkReply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl(); + QUrl url = pNetworkReply->request().url(); + if (!possibleRedirectUrl.isEmpty() + && possibleRedirectUrl != url) + { + // Redirect. + if (possibleRedirectUrl.isRelative()) + { + possibleRedirectUrl = url.resolved(possibleRedirectUrl); + } + + pNetworkReply->deleteLater(); + getUrl(possibleRedirectUrl); + } + else + { + QUrl url = pNetworkReply->request().url(); + QFileInfo fi(url.path()); + QString filename = fi.fileName(); + + downloadedFilename = filename; + downloadedFileData = pNetworkReply->readAll(); + + accept(); + } +} + +void TestingProgressDialog::errorReceived(QNetworkReply::NetworkError code) +{ + Q_UNUSED(code); + networkError = pNetworkReply->errorString(); +} + +void TestingProgressDialog::getUrl(const QUrl &url) +{ + QNetworkRequest request; + request.setUrl(url); + request.setRawHeader("User-Agent", Version::userAgent().toUtf8()); + + this->pNetworkReply = networkAccessManager.get(request); + + connect(pNetworkReply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(downloadProgress(qint64,qint64))); + connect(pNetworkReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(errorReceived(QNetworkReply::NetworkError))); + connect(pNetworkReply, SIGNAL(finished()), this, SLOT(downloadFinished())); +} diff --git a/src/plugins/zandronumq/zandronumqbinaries.h b/src/plugins/zandronumq/zandronumqbinaries.h new file mode 100644 index 00000000..43eac4ce --- /dev/null +++ b/src/plugins/zandronumq/zandronumqbinaries.h @@ -0,0 +1,112 @@ +//------------------------------------------------------------------------------ +// zandronumqbinaries.h +//------------------------------------------------------------------------------ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301 USA +// +//------------------------------------------------------------------------------ +// Copyright (C) 2012 "Zalewa" +//------------------------------------------------------------------------------ +#ifndef DOOMSEEKER_PLUGIN_ZANDRONUMQ_BINARIES_H +#define DOOMSEEKER_PLUGIN_ZANDRONUMQ_BINARIES_H + +#include +#include + +#include + +class EnginePlugin; +class IniSection; +class ZandronumqServer; +class QDir; + +class ZandronumqClientExeFile : public ExeFile +{ + Q_OBJECT + +public: + static QString scriptFileExtension(); + + ZandronumqClientExeFile(const QSharedPointer &server); + ~ZandronumqClientExeFile() override; + + Message install(QWidget *parent) override; + + /** + * If the parent Server is a normal server simple path to executable + * file is returned. If this is a testing server, a shell script is + * created if necessary and a path to this shell script s returned. + */ + QString pathToExe(Message &message) override; + QString workingDirectory(Message &message) override; + +protected: + bool downloadTestingBinaries(const QDir &destination, QWidget *parent); + /** + * Creates Unix .sh file or Windows .bat file to + * launch client for parent server. Returns true if the file + * already exists. + * @param versionDir - convenience parameter. This is the directory + * where testing package was unpacked. This path was + * already created in clientBinary() method so let's reuse it. + * @param [out] fullPathToFile - path to created script file + * @param [out] error - error if return == false + * @return false if fail + */ + bool spawnTestingBatchFile(const QString &versionDir, QString &fullPathToFile, Message &message); + +private: + class PrivData; + PrivData *d; + + IniSection &config(); + /** + * @return true - user accepts installation; false - user refuses. + */ + bool askToInstallTestingVersion(QWidget *parent) const; + QString testingVersion() const; + QString testingVersionInstallPath() const; +}; + +class TestingProgressDialog : public QProgressDialog +{ + Q_OBJECT + +public: + TestingProgressDialog(const QUrl &url, QWidget *parent); + + const QByteArray &data() const { return downloadedFileData; } + QString error() const { return networkError; } + const QString &filename() const { return downloadedFilename; } + +private slots: + void abort(); + void errorReceived(QNetworkReply::NetworkError); + void downloadFinished(); + void downloadProgress(qint64 value, qint64 max); + + +private: + QByteArray downloadedFileData; + QString downloadedFilename; + QNetworkAccessManager networkAccessManager; + QNetworkReply *pNetworkReply; + QString networkError; + + void getUrl(const QUrl &url); +}; + +#endif diff --git a/src/plugins/zandronumq/zandronumqbroadcast.cpp b/src/plugins/zandronumq/zandronumqbroadcast.cpp new file mode 100644 index 00000000..a24959e7 --- /dev/null +++ b/src/plugins/zandronumq/zandronumqbroadcast.cpp @@ -0,0 +1,182 @@ +//------------------------------------------------------------------------------ +// zandronumqbroadcast.cpp +//------------------------------------------------------------------------------ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301 USA +// +//------------------------------------------------------------------------------ +// Copyright (C) 2015 "Zalewa" +//------------------------------------------------------------------------------ +#include "zandronumqbroadcast.h" + +#include "zandronumqengineplugin.h" +#include "zandronumqserver.h" +#include +#include +#include +#include +#include + +DClass +{ +public: + class HostPort + { + public: + QHostAddress host; + unsigned short port; + + HostPort(const QHostAddress &host, unsigned short port) + { + this->host = host; + this->port = port; + } + + bool operator<(const HostPort &other) const + { + return host != other.host ? host.toString() < other.host.toString() : port < other.port; + } + }; + + class LanServer + { + public: + ServerPtr server; + QElapsedTimer lastActivityTime; + + LanServer() + { + lastActivityTime.start(); + } + + LanServer(ServerPtr server) + { + this->server = server; + lastActivityTime.start(); + } + }; + + static const int BROADCAST_LISTEN_PORT = 15101; + static const int TERMINATE_OLD_AGE_MS = 10000; + + bool bindFailureLogged; + QUdpSocket *socket; + QMap servers; + QTimer activityTimer; +}; +DPointeredNoCopy(ZandronumqBroadcast) + +ZandronumqBroadcast::ZandronumqBroadcast() +{ + d->bindFailureLogged = false; + d->socket = nullptr; +} + +ZandronumqBroadcast::~ZandronumqBroadcast() +{ +} + +EnginePlugin *ZandronumqBroadcast::plugin() const +{ + return ZandronumqEnginePlugin::staticInstance(); +} + +void ZandronumqBroadcast::start() +{ + d->socket = new QUdpSocket(this); + this->connect(d->socket, SIGNAL(readyRead()), SLOT(readAllPendingDatagrams())); + bindSocket(); + + this->connect(&d->activityTimer, SIGNAL(timeout()), SLOT(terminateOldServers())); + this->connect(&d->activityTimer, SIGNAL(timeout()), SLOT(readAllPendingDatagrams())); + d->activityTimer.start(PrivData::TERMINATE_OLD_AGE_MS); +} + +void ZandronumqBroadcast::bindSocket() +{ + const int port = PrivData::BROADCAST_LISTEN_PORT; + bool bound = d->socket->bind(QHostAddress::Any, port, + QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint); + if (bound) + { + gLog << tr("Listening to Zandronumq's LAN servers broadcasts on port %1.").arg(port); + } + else + { + if (!d->bindFailureLogged) + { + gLog << tr("Failed to bind Zandronumq's LAN broadcasts listening socket on port %1. " + "Will keep retrying silently.").arg(port); + d->bindFailureLogged = true; + } + QTimer::singleShot(10000, this, SLOT(bindSocket())); + } +} + +void ZandronumqBroadcast::readAllPendingDatagrams() +{ + while (d->socket->hasPendingDatagrams()) + { + QByteArray datagram; + datagram.resize(d->socket->pendingDatagramSize()); + QHostAddress sender; + unsigned short senderPort; + + d->socket->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort); + if (!isEnabled()) + { + // just drop the packets + continue; + } + + ServerPtr server = ZandronumqEnginePlugin::staticInstance()->server(sender, senderPort); + if (server->readRefreshQueryResponse(datagram) == Server::RESPONSE_GOOD) + { + PrivData::HostPort addr(sender, senderPort); + if (d->servers.contains(addr)) + { + PrivData::LanServer &lanserver = d->servers[addr]; + lanserver.lastActivityTime.start(); + emit serverDetected(lanserver.server, false); + } + else + { + // Rebuild server instance as we need to refresh it + // anyway and we don't want whatever was intepreted + // from broadcast to pollute the status. + server = ZandronumqEnginePlugin::staticInstance()->server(sender, senderPort); + d->servers[addr] = server; + emit serverDetected(server, true); + } + } + } +} + +void ZandronumqBroadcast::terminateOldServers() +{ + QMutableMapIterator::HostPort, + PrivData::LanServer> it(d->servers); + while (it.hasNext()) + { + it.next(); + PrivData::LanServer &server = it.value(); + if (server.lastActivityTime.elapsed() > PrivData::TERMINATE_OLD_AGE_MS) + { + emit serverLost(server.server); + it.remove(); + } + } +} diff --git a/src/plugins/zandronumq/zandronumqbroadcast.h b/src/plugins/zandronumq/zandronumqbroadcast.h new file mode 100644 index 00000000..e3e729c2 --- /dev/null +++ b/src/plugins/zandronumq/zandronumqbroadcast.h @@ -0,0 +1,51 @@ +//------------------------------------------------------------------------------ +// zandronumqbroadcast.h +//------------------------------------------------------------------------------ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301 USA +// +//------------------------------------------------------------------------------ +// Copyright (C) 2015 "Zalewa" +//------------------------------------------------------------------------------ +#ifndef ide4ecbce5_6700_4d65_8e47_160a349b2211 +#define ide4ecbce5_6700_4d65_8e47_160a349b2211 + +#include +#include +#include +#include + +class ZandronumqBroadcast : public Broadcast +{ + Q_OBJECT + +public: + ZandronumqBroadcast(); + ~ZandronumqBroadcast() override; + + EnginePlugin *plugin() const override; + void start(); + +private: + DPtr d; + +private slots: + void bindSocket(); + void readAllPendingDatagrams(); + void terminateOldServers(); +}; + +#endif diff --git a/src/plugins/zandronumq/zandronumqengineplugin.cpp b/src/plugins/zandronumq/zandronumqengineplugin.cpp new file mode 100644 index 00000000..581cb015 --- /dev/null +++ b/src/plugins/zandronumq/zandronumqengineplugin.cpp @@ -0,0 +1,190 @@ +//------------------------------------------------------------------------------ +// zandronumqengineplugin.cpp +//------------------------------------------------------------------------------ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301 USA +// +//------------------------------------------------------------------------------ +// Copyright (C) 2009 Braden "Blzut3" Obrzut (skulltagengineplugin.cpp) +// Copyright (C) 2012 "Zalewa" +//------------------------------------------------------------------------------ + +#include +#include +#include +#include +#include + +#include "createserverdialogpages/flagspage.h" +#include "enginezandronumqconfigbox.h" +#include "huffman/huffman.h" +#include "zandronumqbinaries.h" +#include "zandronumqbroadcast.h" +#include "zandronumqengineplugin.h" +#include "zandronumqgameexefactory.h" +#include "zandronumqgamehost.h" +#include "zandronumqgameinfo.h" +#include "zandronumqmasterclient.h" +#include "zandronumqserver.h" + +DClass +{ +public: + ZandronumqBroadcast *broadcast; +}; +DPointered(ZandronumqEnginePlugin) + +INSTALL_PLUGIN(ZandronumqEnginePlugin) + +ZandronumqEnginePlugin::ZandronumqEnginePlugin() +{ + HUFFMAN_Construct(); + d->broadcast = new ZandronumqBroadcast(); + + const // clear warnings + #include "zandronumq.xpm" + + init("Q-Zandronum", zandronumq_xpm, + EP_Author, "The Doomseeker Team", + EP_Version, PLUGIN_VERSION, + EP_AboutProvider, new ZandronumqAboutProvider, + + EP_AllowsURL, + EP_AllowsEmail, + EP_AllowsConnectPassword, + EP_AllowsJoinPassword, + EP_AllowsLogging, + EP_AllowsRConPassword, + EP_AllowsMOTD, + EP_AllowsUpnp, + EP_AllowsUpnpPort, + #if defined(Q_OS_WIN32) || defined(Q_OS_DARWIN) + EP_ClientOnly, + #endif + EP_ClientExeName, "q-zandronum", + EP_ServerExeName, "q-zandronum-server", + EP_GameFileSearchSuffixes, "zandronumq", + EP_DontCreateDMFlagsPagesAutomatic, + EP_DefaultServerPort, 10666, + EP_DefaultMaster, "master.qzandronum.com:15300", + EP_SupportsRandomMapRotation, + EP_IRCChannel, "Q-Zandronum", "irc.qzandronum.com", "#qzandronum", + EP_RefreshThreshold, 10, + EP_DemoExtension, false, "cld", + EP_URLScheme, "zan", + EP_Broadcast, d->broadcast, + EP_MasterClient, new ZandronumqMasterClient(), + EP_Done + ); +} + +void ZandronumqEnginePlugin::setupConfig(IniSection &config) +{ + config.createSetting("Masterserver", data()->defaultMaster); + config.createSetting("EnableTesting", true); + config.createSetting("TestingPath", + DataPaths::defaultInstance()->pluginLocalDataLocationPath(*this)); +} + +ConfigPage *ZandronumqEnginePlugin::configuration(QWidget *parent) +{ + return new EngineZandronumqConfigBox(staticInstance(), *data()->pConfig, parent); +} + +QList ZandronumqEnginePlugin::createServerDialogPages(CreateServerDialog *pDialog) +{ + QList pages; + + pages << new FlagsPage(pDialog); + + return pages; +} + +GameHost *ZandronumqEnginePlugin::gameHost() +{ + return new ZandronumqGameHost(); +} + +QList ZandronumqEnginePlugin::gameModes() const +{ + return ZandronumqGameInfo::gameModes(); +} + +QList ZandronumqEnginePlugin::gameModifiers() const +{ + return ZandronumqGameInfo::gameModifiers(); +} + +QList ZandronumqEnginePlugin::limits(const GameMode &gm) const +{ + QList gl; + + int m = gm.index(); + + if (m != GameMode::SGM_Cooperative + && m != ZandronumqGameInfo::GAMEMODE_INVASION + && m != ZandronumqGameInfo::GAMEMODE_SURVIVAL) + { + gl << GameCVar(QObject::tr("Time limit:"), "+timelimit"); + } + + if (m == GameMode::SGM_Deathmatch + || m == ZandronumqGameInfo::GAMEMODE_DUEL + || m == GameMode::SGM_TeamDeathmatch + || m == ZandronumqGameInfo::GAMEMODE_TERMINATOR) + { + gl << GameCVar(QObject::tr("Frag limit:"), "+fraglimit"); + } + + if (m == GameMode::SGM_CTF + || m == ZandronumqGameInfo::GAMEMODE_DOMINATION + || m == ZandronumqGameInfo::GAMEMODE_ONEFLAGCTF + || m == ZandronumqGameInfo::GAMEMODE_POSSESSION + || m == ZandronumqGameInfo::GAMEMODE_SKULLTAG + || m == ZandronumqGameInfo::GAMEMODE_TEAMGAME + || m == ZandronumqGameInfo::GAMEMODE_TEAMPOSSESSION) + { + gl << GameCVar(QObject::tr("Point limit:"), "+pointlimit"); + } + + if (m == ZandronumqGameInfo::GAMEMODE_DUEL + || m == ZandronumqGameInfo::GAMEMODE_LASTMANSTANDING + || m == ZandronumqGameInfo::GAMEMODE_TEAMLMS) + { + gl << GameCVar(QObject::tr("Win limit:"), "+winlimit"); + } + + if (m == ZandronumqGameInfo::GAMEMODE_DUEL) + { + gl << GameCVar(QObject::tr("Duel limit:"), "+duellimit"); + } + + gl << GameCVar(QObject::tr("Max. lives:"), "+sv_maxlives"); + + return gl; +} + +ServerPtr ZandronumqEnginePlugin::mkServer(const QHostAddress &address, unsigned short port) const +{ + return ServerPtr(new ZandronumqServer(address, port)); +} + +void ZandronumqEnginePlugin::start() +{ + EnginePlugin::start(); + setGameExeFactory(QSharedPointer(new ZandronumqGameExeFactory(this))); + d->broadcast->start(); +} diff --git a/src/plugins/zandronumq/zandronumqengineplugin.h b/src/plugins/zandronumq/zandronumqengineplugin.h new file mode 100644 index 00000000..c645c966 --- /dev/null +++ b/src/plugins/zandronumq/zandronumqengineplugin.h @@ -0,0 +1,55 @@ +//------------------------------------------------------------------------------ +// zandronumqengineplugin.h +//------------------------------------------------------------------------------ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301 USA +// +//------------------------------------------------------------------------------ +// Copyright (C) 2012 "Zalewa" +//------------------------------------------------------------------------------ +#ifndef DOOMSEEKER_PLUGIN_ZANDRONUMQ_ENGINEPLUGIN_H +#define DOOMSEEKER_PLUGIN_ZANDRONUMQ_ENGINEPLUGIN_H + +#include +#include + +class ZandronumqEnginePlugin : public EnginePlugin +{ + DECLARE_PLUGIN(ZandronumqEnginePlugin) +public: + ZandronumqEnginePlugin(); + + QList createServerDialogPages(CreateServerDialog *pDialog) override; + + void setupConfig(IniSection &config) override; + + ConfigPage *configuration(QWidget *parent) override; + GameHost *gameHost() override; + QList gameModes() const override; + QList gameModifiers() const override; + QList limits(const GameMode &gm) const override; + + MasterClient *masterClient() const; + + ServerPtr mkServer(const QHostAddress &address, unsigned short port) const override; + + void start() override; + +private: + DPtr d; +}; + +#endif diff --git a/src/plugins/zandronumq/zandronumqgameexefactory.cpp b/src/plugins/zandronumq/zandronumqgameexefactory.cpp new file mode 100644 index 00000000..8de131a5 --- /dev/null +++ b/src/plugins/zandronumq/zandronumqgameexefactory.cpp @@ -0,0 +1,109 @@ +//------------------------------------------------------------------------------ +// zandronumqgameexefactory.cpp +//------------------------------------------------------------------------------ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301 USA +// +//------------------------------------------------------------------------------ +// Copyright (C) 2015 "Zalewa" +//------------------------------------------------------------------------------ +#include "zandronumqgameexefactory.h" + +#include "zandronumqbinaries.h" +#include +#include +#include +#include +#include + +DClass +{ +public: +}; +DPointered(ZandronumqGameExeFactory) + +ZandronumqGameExeFactory::ZandronumqGameExeFactory(EnginePlugin *plugin) + : GameExeFactory(plugin) +{ + set_additionalExecutables(&ZandronumqGameExeFactory::additionalExecutables); +} + +ZandronumqGameExeFactory::~ZandronumqGameExeFactory() +{ +} + +QList ZandronumqGameExeFactory::additionalExecutables(int execType) const +{ + QList testingExecutables; + IniSection *cfg = plugin()->data()->pConfig; + if (cfg != nullptr) + { + QDir directory(cfg->value("TestingPath").toString()); + QStringList subdirs = directory.entryList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name | QDir::Reversed); + for (const QString &subdirName : subdirs) + { + testingExecutables << scanSubdir(directory, subdirName, execType); + } + } + return testingExecutables; +} + +QList ZandronumqGameExeFactory::scanSubdir(const QDir &mainDir, + const QString &subdirName, int execType) const +{ + QList paths; + QDir subdir = mainDir; + subdir.cd(subdirName); + if (execType & GameFile::Client || execType & GameFile::Offline) + { + if (!subdir.entryList(QStringList(execName()), QDir::Files).isEmpty()) + { + paths << mainDir.absoluteFilePath( + subdirName + ZandronumqClientExeFile::scriptFileExtension()); + } + } + if (execType & GameFile::Server) + { + if (!subdir.entryList(QStringList(serverExecName()), QDir::Files).isEmpty()) + { + #ifdef Q_OS_WIN32 + paths << mainDir.absoluteFilePath( + subdirName + ZandronumqClientExeFile::scriptFileExtension()); + #else + paths << mainDir.absoluteFilePath(subdirName + "/zandronumq-server"); + #endif + } + } + return paths; +} + +QString ZandronumqGameExeFactory::execName() const +{ + #ifdef Q_OS_WIN32 + return "zandronumq.exe"; + #else + return "zandronumq"; + #endif +} + +QString ZandronumqGameExeFactory::serverExecName() const +{ + #ifdef Q_OS_WIN32 + return "zandronumq.exe"; + #else + return "zandronumq-server"; + #endif +} diff --git a/src/plugins/zandronumq/zandronumqgameexefactory.h b/src/plugins/zandronumq/zandronumqgameexefactory.h new file mode 100644 index 00000000..a0ec7e73 --- /dev/null +++ b/src/plugins/zandronumq/zandronumqgameexefactory.h @@ -0,0 +1,49 @@ +//------------------------------------------------------------------------------ +// zandronumqgameexefactory.h +//------------------------------------------------------------------------------ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301 USA +// +//------------------------------------------------------------------------------ +// Copyright (C) 2015 "Zalewa" +//------------------------------------------------------------------------------ +#ifndef id11524123_87af_4cee_82b2_c7f39783c02c +#define id11524123_87af_4cee_82b2_c7f39783c02c + +#include "dptr.h" +#include +#include +#include +#include + +class ExeFilePath; + +class ZandronumqGameExeFactory : public GameExeFactory +{ +public: + ZandronumqGameExeFactory(EnginePlugin *plugin); + ~ZandronumqGameExeFactory() override; + +private: + DPtr d; + + QList additionalExecutables(int execType) const; + QString execName() const; + QList scanSubdir(const QDir &mainDir, const QString &subdirName, int execType) const; + QString serverExecName() const; +}; + +#endif diff --git a/src/plugins/zandronumq/zandronumqgamehost.cpp b/src/plugins/zandronumq/zandronumqgamehost.cpp new file mode 100644 index 00000000..4bdda693 --- /dev/null +++ b/src/plugins/zandronumq/zandronumqgamehost.cpp @@ -0,0 +1,173 @@ +//------------------------------------------------------------------------------ +// zandronumqgamehost.cpp +//------------------------------------------------------------------------------ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301 USA +// +//------------------------------------------------------------------------------ +// Copyright (C) 2013 "Zalewa" +//------------------------------------------------------------------------------ +#include "zandronumqengineplugin.h" +#include "zandronumqgamehost.h" +#include "zandronumqgameinfo.h" +#include "zandronumqgamerunner.h" +#include "zandronumqserver.h" +#include + +ZandronumqGameHost::ZandronumqGameHost() + : GameHost(ZandronumqEnginePlugin::staticInstance()) +{ + setArgForServerLaunch("-host"); + setArgForOptionalWadLoading("-optfile"); + + set_addDMFlags(&ZandronumqGameHost::addDMFlags); +} + +void ZandronumqGameHost::addDMFlags() +{ + const QList &dmFlags = params().dmFlags(); + const QString argNames[] = { "+dmflags", "+dmflags2", "+compatflags" }; + for (int i = 0; i < qMin(dmFlags.size(), 3); ++i) + { + unsigned flagsValue = 0; + const DMFlagsSection §ion = dmFlags[i]; + + for (int j = 0; j < section.count(); ++j) + { + flagsValue |= section[i].value(); + } + + args() << argNames[i] << QString::number(flagsValue); + } +} + +void ZandronumqGameHost::addExtra() +{ + args() << "+alwaysapplydmflags" << QString::number(1); + + if (params().skill() != Skill::UNDEFINED) + args() << "-skill" << QString::number(params().skill() + 1); // from 1 to 5 + + if (!params().loggingPath().isEmpty()) + { + // Zandronumq suffixes a date plus a ".log" extension. We'll add a prefix. + args() << "+logfile" << params().loggingPath() + "/Zandronumq"; + } + + QString gameModeStr; + switch (params().gameMode().index()) + { + case GameMode::SGM_Cooperative: gameModeStr = "+cooperative"; break; + case GameMode::SGM_CTF: gameModeStr = "+ctf"; break; + case GameMode::SGM_Deathmatch: gameModeStr = "+deathmatch"; break; + case GameMode::SGM_TeamDeathmatch: gameModeStr = "+teamplay"; break; + case ZandronumqGameInfo::GAMEMODE_DOMINATION: gameModeStr = "+domination"; break; + case ZandronumqGameInfo::GAMEMODE_DUEL: gameModeStr = "+duel"; break; + case ZandronumqGameInfo::GAMEMODE_INVASION: gameModeStr = "+invasion"; break; + case ZandronumqGameInfo::GAMEMODE_LASTMANSTANDING: gameModeStr = "+lastmanstanding"; break; + case ZandronumqGameInfo::GAMEMODE_ONEFLAGCTF: gameModeStr = "+oneflagctf"; break; + case ZandronumqGameInfo::GAMEMODE_POSSESSION: gameModeStr = "+possession"; break; + case ZandronumqGameInfo::GAMEMODE_SKULLTAG: gameModeStr = "+skulltag"; break; + case ZandronumqGameInfo::GAMEMODE_SURVIVAL: gameModeStr = "+survival"; break; + case ZandronumqGameInfo::GAMEMODE_TEAMGAME: gameModeStr = "+teamgame"; break; + case ZandronumqGameInfo::GAMEMODE_TEAMLMS: gameModeStr = "+teamlms"; break; + case ZandronumqGameInfo::GAMEMODE_TEAMPOSSESSION: gameModeStr = "+teampossession"; break; + case ZandronumqGameInfo::GAMEMODE_TERMINATOR: gameModeStr = "+terminator"; break; + } + if (!gameModeStr.isEmpty()) + args() << gameModeStr << "1"; + + if (!params().map().isEmpty()) + { + args() << "+map" << strArg(params().map()); + } + + for (const QString &map : params().mapList()) + { + args() << "+addmap" << strArg(map); + } + + args() << "+sv_maprotation" << QString::number( + static_cast(!params().mapList().isEmpty())); + args() << "+sv_randommaprotation" << QString::number( + static_cast(params().isRandomMapRotation())); + + if (params().hostMode() == GameCreateParams::Host) + addHostModeParams(); +} + +void ZandronumqGameHost::addHostModeParams() +{ + QString motd = params().motd(); + args() << "+sv_motd" << strArg(motd.replace("\n", "\\n")); + args() << "+sv_hostemail" << strArg(params().email()); + args() << "+sv_hostname" << strArg(params().name()); + args() << "+sv_website" << strArg(params().url()); + + { + QString password = params().connectPassword(); + args() << "+sv_password" << strArg(password); + args() << "+sv_forcepassword" << QString::number(static_cast(!password.isEmpty())); + } + + { + QString password = params().ingamePassword(); + args() << "+sv_joinpassword" << strArg(password); + args() << "+sv_forcejoinpassword" << QString::number(static_cast(!password.isEmpty())); + } + + args() << "+sv_rconpassword" << strArg(params().rconPassword()); + + args() << "+sv_broadcast" << QString::number(static_cast(params().isBroadcastToLan())); + args() << "+sv_updatemaster" << QString::number(static_cast(params().isBroadcastToMaster())); + args() << "+sv_maxclients" << QString::number(params().maxTotalClientSlots()); + args() << "+sv_maxplayers" << QString::number(params().maxPlayers()); + + if (params().upnp()) + { + args() << "-upnp"; + if (params().upnpPort() > 0) + { + args() << QString::number(params().upnpPort()); + } + } +} + +ZandronumqGameInfo::GameVersion ZandronumqGameHost::gameVersion() const +{ + return static_cast( + params().option(ZandronumqGameInfo::OPTION_GAMEVERSION).toInt()); +} + +QString ZandronumqGameHost::strArg(const QString &val) +{ + if (val.isEmpty()) + { + // This will reset the value to nothing. + if (gameVersion() == ZandronumqGameInfo::GV_Zandronumq2) + { + return "\"\""; + } + else + { + return ""; + } + } + else + { + return val; + } +} diff --git a/src/plugins/zandronumq/zandronumqgamehost.h b/src/plugins/zandronumq/zandronumqgamehost.h new file mode 100644 index 00000000..f4590df5 --- /dev/null +++ b/src/plugins/zandronumq/zandronumqgamehost.h @@ -0,0 +1,49 @@ +//------------------------------------------------------------------------------ +// zandronumqgamehost.h +//------------------------------------------------------------------------------ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301 USA +// +//------------------------------------------------------------------------------ +// Copyright (C) 2013 "Zalewa" +//------------------------------------------------------------------------------ +#ifndef id7CCF5C41_0664_487D_926B2383C451D847 +#define id7CCF5C41_0664_487D_926B2383C451D847 + +#include "zandronumqgameinfo.h" +#include + +class ZandronumqGameHost : public GameHost +{ + Q_OBJECT + +public: + ZandronumqGameHost(); + +protected: + void addExtra() override; + +private: + Q_DISABLE_COPY(ZandronumqGameHost) + + void addDMFlags(); + void addHostModeParams(); + + QString strArg(const QString &val); + ZandronumqGameInfo::GameVersion gameVersion() const; +}; + +#endif // header diff --git a/src/plugins/zandronumq/zandronumqgameinfo.cpp b/src/plugins/zandronumq/zandronumqgameinfo.cpp new file mode 100644 index 00000000..7f230731 --- /dev/null +++ b/src/plugins/zandronumq/zandronumqgameinfo.cpp @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// zandronumqgameinfo.cpp +//------------------------------------------------------------------------------ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301 USA +// +//------------------------------------------------------------------------------ +// Copyright (C) 2012 "Zalewa" +//------------------------------------------------------------------------------ +#include "zandronumqgameinfo.h" + +const QString ZandronumqGameInfo::OPTION_GAMEVERSION = "GameVersion"; + +QList ZandronumqGameInfo::gameModes() +{ + QList gameModesList; + gameModesList << GameMode::mkCooperative(); + gameModesList << GameMode::ffaGame(GAMEMODE_SURVIVAL, tr("Survival")); + gameModesList << GameMode::ffaGame(GAMEMODE_INVASION, tr("Invasion")); + gameModesList << GameMode::mkDeathmatch(); + gameModesList << GameMode::mkTeamDeathmatch(); + gameModesList << GameMode::ffaGame(GAMEMODE_DUEL, tr("Duel")); + gameModesList << GameMode::ffaGame(GAMEMODE_TERMINATOR, tr("Terminator")); + gameModesList << GameMode::ffaGame(GAMEMODE_LASTMANSTANDING, tr("LMS")); + gameModesList << GameMode::teamGame(GAMEMODE_TEAMLMS, tr("Team LMS")); + gameModesList << GameMode::ffaGame(GAMEMODE_POSSESSION, tr("Possession")); + gameModesList << GameMode::teamGame(GAMEMODE_TEAMPOSSESSION, tr("Team Poss")); + gameModesList << GameMode::teamGame(GAMEMODE_TEAMGAME, tr("Team Game")); + gameModesList << GameMode::mkCaptureTheFlag(); + gameModesList << GameMode::teamGame(GAMEMODE_ONEFLAGCTF, tr("One Flag CTF")); + gameModesList << GameMode::teamGame(GAMEMODE_SKULLTAG, tr("Skulltag")); + gameModesList << GameMode::teamGame(GAMEMODE_DOMINATION, tr("Domination")); + gameModesList << GameMode::mkUnknown(); + return gameModesList; +} + +QList ZandronumqGameInfo::gameModifiers() +{ + QList gameModifiersList; + gameModifiersList << GameCVar("Buckshot", "+buckshot"); + gameModifiersList << GameCVar("Instagib", "+instagib"); + return gameModifiersList; +} + +QString ZandronumqAboutProvider::provide() +{ + QString aboutDescription = "Q-Zandronum (https://qzandronum.com/)\n\n"; + aboutDescription += tr("This plugin is distributed under the terms of the LGPL v2.1 or later.\n\n"); + return aboutDescription; +} \ No newline at end of file diff --git a/src/plugins/zandronumq/zandronumqgameinfo.h b/src/plugins/zandronumq/zandronumqgameinfo.h new file mode 100644 index 00000000..95fead63 --- /dev/null +++ b/src/plugins/zandronumq/zandronumqgameinfo.h @@ -0,0 +1,101 @@ +//------------------------------------------------------------------------------ +// zandronumqgameinfo.h +//------------------------------------------------------------------------------ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301 USA +// +//------------------------------------------------------------------------------ +// Copyright (C) 2012 "Zalewa" +//------------------------------------------------------------------------------ +#ifndef DOOMSEEKER_PLUGIN_ZANDRONUMQGAMEINFO_H +#define DOOMSEEKER_PLUGIN_ZANDRONUMQGAMEINFO_H + +#include "serverapi/serverstructs.h" +#include "serverapi/textprovider.h" +#include + +class ZandronumqGameInfo : public QObject +{ + Q_OBJECT + +public: + enum LMSAllowedWeapons + { + LMSAW_Pistol = 1 << 0, + LMSAW_Shotgun = 1 << 1, + LMSAW_SuperShotgun = 1 << 2, + LMSAW_Chaingun = 1 << 3, + LMSAW_Minigun = 1 << 4, + LMSAW_RocketLauncher = 1 << 5, + LMSAW_GrenadeLauncher = 1 << 6, + LMSAW_PlasmaRifle = 1 << 7, + LMSAW_Railgun = 1 << 8, + LMSAW_Chainsaw = 1 << 9, + }; + + enum LMSSpectatorSettings + { + LMSSS_TalkToActivePlayers = 1 << 0, + LMSSS_ViewTheGame = 1 << 1, + }; + + enum ZandronumqGameMode + { + GAMEMODE_COOPERATIVE, + GAMEMODE_SURVIVAL, + GAMEMODE_INVASION, + GAMEMODE_DEATHMATCH, + GAMEMODE_TEAMPLAY, + GAMEMODE_DUEL, + GAMEMODE_TERMINATOR, + GAMEMODE_LASTMANSTANDING, + GAMEMODE_TEAMLMS, + GAMEMODE_POSSESSION, + GAMEMODE_TEAMPOSSESSION, + GAMEMODE_TEAMGAME, + GAMEMODE_CTF, + GAMEMODE_ONEFLAGCTF, + GAMEMODE_SKULLTAG, + GAMEMODE_DOMINATION + }; + + /** + * This is stored in config and indexing cannot change between versions. + */ + enum GameVersion + { + GV_Zandronumq2 = 1, + GV_Zandronumq3 = 2 + }; + + static const QString OPTION_GAMEVERSION; + + static QList gameModes(); + static QList gameModifiers(); +}; + +/** + * @brief Provides a (translated) About text for Zandronumq. + */ +class ZandronumqAboutProvider : public TextProvider +{ + Q_OBJECT + +public: + QString provide() override; +}; + +#endif diff --git a/src/plugins/zandronumq/zandronumqgamerunner.cpp b/src/plugins/zandronumq/zandronumqgamerunner.cpp new file mode 100644 index 00000000..86bbf877 --- /dev/null +++ b/src/plugins/zandronumq/zandronumqgamerunner.cpp @@ -0,0 +1,37 @@ +//------------------------------------------------------------------------------ +// zandronumqgamerunner.cpp +//------------------------------------------------------------------------------ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301 USA +// +//------------------------------------------------------------------------------ +// Copyright (C) 2012 "Zalewa" +//------------------------------------------------------------------------------ +#include "zandronumqengineplugin.h" +#include "zandronumqgameinfo.h" +#include "zandronumqgamerunner.h" +#include "zandronumqserver.h" + +#include +#include + +ZandronumqGameClientRunner::ZandronumqGameClientRunner(ServerPtr server) + : GameClientRunner(server) +{ + setArgForConnectPassword("+cl_password"); + setArgForInGamePassword("+cl_joinpassword"); + setArgForOptionalWadLoading("-optfile"); +} \ No newline at end of file diff --git a/src/plugins/zandronumq/zandronumqgamerunner.h b/src/plugins/zandronumq/zandronumqgamerunner.h new file mode 100644 index 00000000..f90df8c8 --- /dev/null +++ b/src/plugins/zandronumq/zandronumqgamerunner.h @@ -0,0 +1,43 @@ +//------------------------------------------------------------------------------ +// zandronumqgamerunner.h +//------------------------------------------------------------------------------ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301 USA +// +//------------------------------------------------------------------------------ +// Copyright (C) 2012 "Zalewa" +//------------------------------------------------------------------------------ +#ifndef DOOMSEEKER_PLUGIN_ZANDRONUMQGAMERUNNER_H +#define DOOMSEEKER_PLUGIN_ZANDRONUMQGAMERUNNER_H + +#include "zandronumqengineplugin.h" +#include +#include + +class ZandronumqServer; + +class ZandronumqGameClientRunner : public GameClientRunner +{ +public: + ZandronumqGameClientRunner(ServerPtr server); + + const EnginePlugin *plugin() const + { + return ZandronumqEnginePlugin::staticInstance(); + } +}; + +#endif diff --git a/src/plugins/zandronumq/zandronumqgamesettings.cpp b/src/plugins/zandronumq/zandronumqgamesettings.cpp new file mode 100644 index 00000000..9c12fcc6 --- /dev/null +++ b/src/plugins/zandronumq/zandronumqgamesettings.cpp @@ -0,0 +1,171 @@ +//------------------------------------------------------------------------------ +// zandronumqgamesettings.cpp +//------------------------------------------------------------------------------ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301 USA +// +//------------------------------------------------------------------------------ +// Copyright (C) 2016 "Zalewa" +//------------------------------------------------------------------------------ +#include "zandronumqgamesettings.h" + +namespace ZandronumqGameSettingsNames +{ +const QString COMPAT_ALLOW_SILENT_BFGTRICK = "CompatAllowSilentBFGTrick"; +const QString COMPAT_ENABLE_WALL_RUNNING = "CompatEnableWallRunning"; +const QString COMPAT_DONT_LET_OTHERS_HEAR_PICKUPS = "CompatDontLetOthersHearPickups"; +const QString COMPAT_MONSTERS_SEE_SEMI_INVISIBLE_PLAYERS = "CompatMonstersSeeSemiInvisiblePlayers"; +const QString COMPAT_NO_MONSTERS_DROPOFF_MOVE = "CompatNoMonstersDropoffMove"; +const QString COMPAT_SCROLLING_SECTORS_ARE_ADDITIVE = "CompatScrollingSectorsAreAdditive"; +const QString COMPAT_INSTANTLY_MOVING_FLOORS_ARENT_SILENT = "CompatInstantlyMovingFloorsArentSilent"; +const QString COMPAT_SECTOR_SOUNDS_USE_ORIGINAL_METHOD = "CompatSectorSoundsUseOriginalMethod"; +const QString COMPAT_ANY_BOSS_DEATH_ACTIVATES_MAP_SPECIALS = "CompatAnyBossDeathActivatesMapSpecials"; +const QString COMPAT_FRICTION_PUSHERS_PULLERS_AFFECT_MONSTERS = "CompatFrictionPushersPullersAffectMonsters"; +const QString COMPAT_CRUSHER_GIBS_BY_MORPHING_NOT_REPLACEMENT = "CompatCrusherGibsByMorphingNotReplacement"; +const QString COMPAT_BLOCK_MONSTER_LINES_IGNORE_FRIENDLY_MONSTERS = "CompatBlockMonsterLinesIgnoreFriendlyMonsters"; +const QString COMPAT_FIND_NEIGHBORING_LIGHT_LEVEL_LIKE_DOOM = "CompatFindNeighboringLightLevelLikeDoom"; +const QString COMPAT_FIND_SHORTEST_TEXTURES_LIKE_DOOM = "CompatFindShortestTexturesLikeDoom"; +const QString COMPAT_USE_BUGGIER_STAIR_BUILDING = "CompatUseBuggierStairBuilding"; +const QString COMPAT_LIMIT_PAIN_ELEMENTALS = "CompatLimitPainElementals"; +const QString COMPAT_ACTORS_ARE_INFINITELY_TALL = "CompatActorsAreInfinitelyTall"; +const QString COMPAT_SPAWN_ITEM_DROPS_ON_THE_FLOOR = "CompatSpawnItemDropsOnTheFloor"; +const QString COMPAT_ALL_SPECIAL_LINES_CAN_DROP_USE_LINES = "CompatAllSpecialLinesCanDropUseLines"; +const QString COMPAT_DISABLE_BOOM_DOOR_LIGHT_EFFECT = "CompatDisableBoomDoorLightEffect"; +const QString COMPAT_RAVENS_SCROLLERS_USE_ORIGINAL_SPEED = "CompatRavensScrollersUseOriginalSpeed"; +const QString COMPAT_USE_SECTOR_BASED_SOUND_TARGET_CODE = "CompatUseSectorBasedSoundTargetCode"; +const QString COMPAT_LIMIT_DEH_MAX_HEALTH_TO_HEALTH_BONUS = "CompatLimitDehMaxHealthToHealthBonus"; +const QString COMPAT_TRACE_IGNORE_LINES_WITHOUT_SAME_SECTOR_ON_BOTH_SIDES = "CompatTraceIgnoreLinesWithoutSameSectorOnBothSides"; +const QString COMPAT_MONSTERS_CANT_BE_PUSHED_OFF_CLIFFS = "CompatMonstersCantBePushedOffCliffs"; +const QString COMPAT_USE_ORIGINAL_MISSILE_CLIPPING_HEIGHT = "CompatUseOriginalMissileClippingHeight"; +const QString COMPAT_MINOTAUR = "CompatMinotaur"; +const QString COMPAT_ORIGINAL_VELOCITY_CALC_FOR_MUSHROOM_IN_DEHACKED = "CompatOriginalVelocityCalcForMushroomInDehacked"; +const QString COMPAT_SPRITE_SORT_ORDER_INVERTED = "CompatSpriteSortOrderInverted"; +const QString COMPAT_HITSCANS_ORIGINAL_BLOCKMAP = "CompatHitscansOriginalBlockmap"; +const QString COMPAT_DRAW_POLYOBJECTS_OLD = "CompatDrawPolyobjectsOld"; +const QString NO_TAUNT = "NoTaunt"; +const QString NO_USE_CROSSHAIRS = "NoUseCrosshairs"; +const QString NO_USE_LAND_CONSOLE_COMMAND = "NoUseLandConsoleCommand"; +const QString COMPAT_PLASMA_BUMP_BUG = "CompatPlasmaBumpBug"; +const QString COMPAT_ORIGINAL_WEAPON_SWITCH = "CompatOriginalWeaponSwitch"; +const QString COMPAT_LIMITED_MOVEMENT_IN_THE_AIR = "CompatLimitedMovementInTheAir"; +const QString COMPAT_ALLOW_INSTANT_RESPAWN = "CompatAllowInstantRespawn"; +const QString COMPAT_USE_OLD_INTERMISSION_SCREENS_MUSIC = "CompatUseOldIntermissionScreensMusic"; +const QString COMPAT_DISABLE_STEALTH_MONSTERS = "CompatDisableStealthMonsters"; +const QString COMPAT_OLD_DAMAGE_RADIUS_INFINITE_HEIGHT = "CompatOldDamageRadiusInfiniteHeight"; +const QString COMPAT_CLIENTS_SEND_FULL_BUTTON_INFO = "CompatClientsSendFullButtonInfo"; +const QString COMPAT_OLD_RANDOM_NUMBER_GENERATOR = "CompatOldRandomNumberGenerator"; +const QString COMPAT_NETSCRIPTS_ARE_CLIENTSIDE = "CompatNETScriptsAreClientside"; +const QString COMPAT_ADD_NOGRAVITYFLAG_TO_SPHERES = "CompatAddNOGRAVITYFlagToSpheres"; +const QString DONT_STOP_PLAYER_SCRIPTS_ON_DISCONNECT = "DontStopPlayerScriptsOnDisconnect"; +const QString OLD_ZDOOM_HORIZONTAL_THRUST = "OldZDoomHorizontalThrust"; +const QString OLD_ZDOOM_BRIDGE_DROPS = "OldZDoomBridgeDrops"; +const QString OLD_ZDOOM_JUMP_PHYSICS = "OldZDoomJumpPhysics"; +const QString COMPAT_FULL_WEAPON_LOWER = "CompatFullWeaponLower"; +const QString COMPAT_ORIGINAL_SOUND_CURVE = "CompatOriginalSoundCurve"; +const QString COMPAT_USE_VANILLA_AUTOAIM_TRACER_BEHAVIOR = "CompatUseVanillaAutoaimTracerBehavior"; +const QString COMPAT_WEST_SPAWNS_ARE_SILENT = "CompatWestSpawnsAreSilent"; +const QString COMPAT_MASKED_MIDTEX = "CompatMaskedMidtex"; +const QString COMPAT_BAD_ANGLES = "CompatBadAngles"; +const QString COMPAT_FLOOR_MOVE = "CompatFloorMove"; +const QString NO_MONSTERS = "NoMonsters"; +const QString ITEMS_RESPAWN = "ItemsRespawn"; +const QString MEGA_POWERUPS_RESPAWN = "MegaPowerupsRespawn"; +const QString NO_USE_FOV = "NoUseFOV"; +const QString NO_USE_FREELOOK = "NoUseFreelook"; +const QString INFINITE_AMMO = "InfiniteAmmo"; +const QString DONT_SPAWN_DEATHMATCH_WEAPONS = "DontSpawnDeathmatchWeapons"; +const QString MONSTERS_ARE_FAST = "MonstersAreFast"; +const QString MONSTERS_RESPAWN = "MonstersRespawn"; +const QString LOSE_ALL_INVENTORY = "LoseAllInventory"; +const QString LOSE_ARMOR = "LoseArmor"; +const QString LOSE_KEYS = "LoseKeys"; +const QString LOSE_POWERUPS = "LosePowerups"; +const QString LOSE_WEAPONS = "LoseWeapons"; +const QString LOSE_ALL_AMMO = "LoseAllAmmo"; +const QString LOSE_HALF_AMMO = "LoseHalfAmmo"; +const QString RESPAWN_AUTOMATICALLY = "RespawnAutomatically"; +const QString RESPAWN_FARTHEST_AWAY_FROM_OTHERS = "RespawnFarthestAwayFromOthers"; +const QString WEAPONS_STAY_AFTER_PICKUP = "WeaponsStayAfterPickup"; +const QString DONT_SPAWN_HEALTH = "DontSpawnHealth"; +const QString DONT_SPAWN_ARMOR = "DontSpawnArmor"; +const QString BARRELS_RESPAWN = "BarrelsRespawn"; +const QString SERVER_PICKS_TEAMS = "ServerPicksTeams"; +const QString PLAYERS_CANT_SWITCH_TEAMS = "PlayersCantSwitchTeams"; +const QString KEEP_TEAMS_AFTER_AMAP_CHANGE = "KeepTeamsAfterAMapChange"; +const QString HIDE_ALLIES_ON_THE_AUTOMAP = "HideAlliesOnTheAutomap"; +const QString DONT_LET_PLAYERS_SPY_ON_ALLIES = "DontLetPlayersSpyOnAllies"; +const QString INSTANT_FLAG_SKULL_RETURN = "InstantFlagSkullReturn"; +const QString NO_SUICIDE = "NoSuicide"; +const QString NO_RESPAWN = "NoRespawn"; +const QString NO_USE_AUTOMAP = "NoUseAutomap"; +const QString NO_USE_AUTOAIM = "NoUseAutoaim"; +const QString INFINITE_INVENTORY = "InfiniteInventory"; +const QString SLOWLY_LOSE_HEALTH_WHEN_OVER100 = "SlowlyLoseHealthWhenOver100"; +const QString CAN_USE_CHASECAM = "CanUseChasecam"; +const QString ALLOW_BFGFREEAIMING = "AllowBFGFreeaiming"; +const QString DONT_CHECK_AMMO_WHEN_SWITCHING_WEAPONS = "DontCheckAmmoWhenSwitchingWeapons"; +const QString MONSTERS_MUST_BE_KILLED_TO_EXIT = "MonstersMustBeKilledToExit"; +const QString KILL_BOSS_MONSTERS = "KillBossMonsters"; +const QString RESPAWN_WHERE_DIED = "RespawnWhereDied"; +const QString RESPAWN_WITH_ASHOTGUN = "RespawnWithAShotgun"; +const QString DROP_WEAPON_ON_DEATH = "DropWeaponOnDeath"; +const QString LOSE_AFRAG_ON_DEATH = "LoseAFragOnDeath"; +const QString NO_RESPAWN_PROTECTION = "NoRespawnProtection"; +const QString KEEP_FRAGS_AFTER_MAP_CHANGE = "KeepFragsAfterMapChange"; +const QString DOUBLE_AMMO = "DoubleAmmo"; +const QString DONT_SPAWN_RUNES = "DontSpawnRunes"; +const QString NO_UNLAGGED = "NoUnlagged"; +const QString ALWAYS_APPLY_LMSSPECTATOR_SETTINGS = "AlwaysApplyLMSSpectatorSettings"; +const QString NO_MEDALS = "NoMedals"; +const QString SCORE_DAMAGE_NOT_KILLS = "ScoreDamageNotKills"; +const QString DONT_SPAWN_ANY_MULTIPLAYER_ITEM = "DontSpawnAnyMultiplayerItem"; +const QString NO_TARGET_IDENTIFY = "NoTargetIdentify"; +const QString NO_DISPLAY_COOP_INFO = "NoDisplayCoopInfo"; +const QString NO_MAX_BLOOD_SCALAR = "NoMaxBloodScalar"; +const QString NO_ITEM_DROP = "NoItemDrop"; +const QString NO_ROCKET_JUMP = "NoRocketJump"; +const QString NO_USE_CUSTOM_GLLIGHTING_SETTINGS = "NoUseCustomGLLightingSettings"; +const QString NO_TURN_OFF_TRANSLUCENCY = "NoTurnOffTranslucency"; +const QString SHARE_KEYS = "ShareKeys"; +const QString SURVIVAL_NO_MAP_RESET_ON_DEATH = "SurvivalNoMapResetOnDeath"; +const QString DEAD_PLAYERS_CAN_KEEP_INVENTORY = "DeadPlayersCanKeepInventory"; +const QString LMSCHAINSAW = "LMSChainsaw"; +const QString LMSPISTOL = "LMSPistol"; +const QString LMSSHOTGUN = "LMSShotgun"; +const QString LMSSUPER_SHOTGUN = "LMSSuperShotgun"; +const QString LMSCHAINGUN = "LMSChaingun"; +const QString LMSMINIGUN = "LMSMinigun"; +const QString LMSROCKET_LAUNCHER = "LMSRocketLauncher"; +const QString LMSGRENADE_LAUNCHER = "LMSGrenadeLauncher"; +const QString LMSPLASMA_RIFLE = "LMSPlasmaRifle"; +const QString LMSRAILGUN = "LMSRailgun"; +const QString LMSSPECTATORS_CAN_TALK_TO_ACTIVE_PLAYERS = "LMSSpectatorsCanTalkToActivePlayers"; +const QString LMSSPECTATORS_CAN_VIEW_THE_GAME = "LMSSpectatorsCanViewTheGame"; +} + +DClass +{ +public: +}; +DPointered(ZandronumqGameSettings) + +ZandronumqGameSettings::ZandronumqGameSettings() +{ +} + +ZandronumqGameSettings::~ZandronumqGameSettings() +{ +} diff --git a/src/plugins/zandronumq/zandronumqgamesettings.h b/src/plugins/zandronumq/zandronumqgamesettings.h new file mode 100644 index 00000000..9cdd9bd1 --- /dev/null +++ b/src/plugins/zandronumq/zandronumqgamesettings.h @@ -0,0 +1,175 @@ +//------------------------------------------------------------------------------ +// zandronumqgamesettings.h +//------------------------------------------------------------------------------ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301 USA +// +//------------------------------------------------------------------------------ +// Copyright (C) 2016 "Zalewa" +//------------------------------------------------------------------------------ +#ifndef id50f6b4ec_858f_41ef_bb82_4892db6d51b3 +#define id50f6b4ec_858f_41ef_bb82_4892db6d51b3 + +#include + +#include + +namespace ZandronumqGameSettingsNames +{ +extern const QString COMPAT_ALLOW_SILENT_BFGTRICK; +extern const QString COMPAT_ENABLE_WALL_RUNNING; +extern const QString COMPAT_DONT_LET_OTHERS_HEAR_PICKUPS; +extern const QString COMPAT_MONSTERS_SEE_SEMI_INVISIBLE_PLAYERS; +extern const QString COMPAT_NO_MONSTERS_DROPOFF_MOVE; +extern const QString COMPAT_SCROLLING_SECTORS_ARE_ADDITIVE; +extern const QString COMPAT_INSTANTLY_MOVING_FLOORS_ARENT_SILENT; +extern const QString COMPAT_SECTOR_SOUNDS_USE_ORIGINAL_METHOD; +extern const QString COMPAT_ANY_BOSS_DEATH_ACTIVATES_MAP_SPECIALS; +extern const QString COMPAT_FRICTION_PUSHERS_PULLERS_AFFECT_MONSTERS; +extern const QString COMPAT_CRUSHER_GIBS_BY_MORPHING_NOT_REPLACEMENT; +extern const QString COMPAT_BLOCK_MONSTER_LINES_IGNORE_FRIENDLY_MONSTERS; +extern const QString COMPAT_FIND_NEIGHBORING_LIGHT_LEVEL_LIKE_DOOM; +extern const QString COMPAT_FIND_SHORTEST_TEXTURES_LIKE_DOOM; +extern const QString COMPAT_USE_BUGGIER_STAIR_BUILDING; +extern const QString COMPAT_LIMIT_PAIN_ELEMENTALS; +extern const QString COMPAT_ACTORS_ARE_INFINITELY_TALL; +extern const QString COMPAT_SPAWN_ITEM_DROPS_ON_THE_FLOOR; +extern const QString COMPAT_ALL_SPECIAL_LINES_CAN_DROP_USE_LINES; +extern const QString COMPAT_DISABLE_BOOM_DOOR_LIGHT_EFFECT; +extern const QString COMPAT_RAVENS_SCROLLERS_USE_ORIGINAL_SPEED; +extern const QString COMPAT_USE_SECTOR_BASED_SOUND_TARGET_CODE; +extern const QString COMPAT_LIMIT_DEH_MAX_HEALTH_TO_HEALTH_BONUS; +extern const QString COMPAT_TRACE_IGNORE_LINES_WITHOUT_SAME_SECTOR_ON_BOTH_SIDES; +extern const QString COMPAT_MONSTERS_CANT_BE_PUSHED_OFF_CLIFFS; +extern const QString COMPAT_USE_ORIGINAL_MISSILE_CLIPPING_HEIGHT; +extern const QString COMPAT_MINOTAUR; +extern const QString COMPAT_ORIGINAL_VELOCITY_CALC_FOR_MUSHROOM_IN_DEHACKED; +extern const QString COMPAT_SPRITE_SORT_ORDER_INVERTED; +extern const QString COMPAT_HITSCANS_ORIGINAL_BLOCKMAP; +extern const QString COMPAT_DRAW_POLYOBJECTS_OLD; +extern const QString NO_TAUNT; +extern const QString NO_USE_CROSSHAIRS; +extern const QString NO_USE_LAND_CONSOLE_COMMAND; +extern const QString COMPAT_PLASMA_BUMP_BUG; +extern const QString COMPAT_ORIGINAL_WEAPON_SWITCH; +extern const QString COMPAT_LIMITED_MOVEMENT_IN_THE_AIR; +extern const QString COMPAT_ALLOW_INSTANT_RESPAWN; +extern const QString COMPAT_USE_OLD_INTERMISSION_SCREENS_MUSIC; +extern const QString COMPAT_DISABLE_STEALTH_MONSTERS; +extern const QString COMPAT_OLD_DAMAGE_RADIUS_INFINITE_HEIGHT; +extern const QString COMPAT_CLIENTS_SEND_FULL_BUTTON_INFO; +extern const QString COMPAT_OLD_RANDOM_NUMBER_GENERATOR; +extern const QString COMPAT_NETSCRIPTS_ARE_CLIENTSIDE; +extern const QString COMPAT_ADD_NOGRAVITYFLAG_TO_SPHERES; +extern const QString DONT_STOP_PLAYER_SCRIPTS_ON_DISCONNECT; +extern const QString OLD_ZDOOM_HORIZONTAL_THRUST; +extern const QString OLD_ZDOOM_BRIDGE_DROPS; +extern const QString OLD_ZDOOM_JUMP_PHYSICS; +extern const QString COMPAT_FULL_WEAPON_LOWER; +extern const QString COMPAT_ORIGINAL_SOUND_CURVE; +extern const QString COMPAT_USE_VANILLA_AUTOAIM_TRACER_BEHAVIOR; +extern const QString COMPAT_WEST_SPAWNS_ARE_SILENT; +extern const QString COMPAT_MASKED_MIDTEX; +extern const QString COMPAT_BAD_ANGLES; +extern const QString COMPAT_FLOOR_MOVE; +extern const QString NO_MONSTERS; +extern const QString ITEMS_RESPAWN; +extern const QString MEGA_POWERUPS_RESPAWN; +extern const QString NO_USE_FOV; +extern const QString NO_USE_FREELOOK; +extern const QString INFINITE_AMMO; +extern const QString DONT_SPAWN_DEATHMATCH_WEAPONS; +extern const QString MONSTERS_ARE_FAST; +extern const QString MONSTERS_RESPAWN; +extern const QString LOSE_ALL_INVENTORY; +extern const QString LOSE_ARMOR; +extern const QString LOSE_KEYS; +extern const QString LOSE_POWERUPS; +extern const QString LOSE_WEAPONS; +extern const QString LOSE_ALL_AMMO; +extern const QString LOSE_HALF_AMMO; +extern const QString RESPAWN_AUTOMATICALLY; +extern const QString RESPAWN_FARTHEST_AWAY_FROM_OTHERS; +extern const QString WEAPONS_STAY_AFTER_PICKUP; +extern const QString DONT_SPAWN_HEALTH; +extern const QString DONT_SPAWN_ARMOR; +extern const QString BARRELS_RESPAWN; +extern const QString SERVER_PICKS_TEAMS; +extern const QString PLAYERS_CANT_SWITCH_TEAMS; +extern const QString KEEP_TEAMS_AFTER_AMAP_CHANGE; +extern const QString HIDE_ALLIES_ON_THE_AUTOMAP; +extern const QString DONT_LET_PLAYERS_SPY_ON_ALLIES; +extern const QString INSTANT_FLAG_SKULL_RETURN; +extern const QString NO_SUICIDE; +extern const QString NO_RESPAWN; +extern const QString NO_USE_AUTOMAP; +extern const QString NO_USE_AUTOAIM; +extern const QString INFINITE_INVENTORY; +extern const QString SLOWLY_LOSE_HEALTH_WHEN_OVER100; +extern const QString CAN_USE_CHASECAM; +extern const QString ALLOW_BFGFREEAIMING; +extern const QString DONT_CHECK_AMMO_WHEN_SWITCHING_WEAPONS; +extern const QString MONSTERS_MUST_BE_KILLED_TO_EXIT; +extern const QString KILL_BOSS_MONSTERS; +extern const QString RESPAWN_WHERE_DIED; +extern const QString RESPAWN_WITH_ASHOTGUN; +extern const QString DROP_WEAPON_ON_DEATH; +extern const QString LOSE_AFRAG_ON_DEATH; +extern const QString NO_RESPAWN_PROTECTION; +extern const QString KEEP_FRAGS_AFTER_MAP_CHANGE; +extern const QString DOUBLE_AMMO; +extern const QString DONT_SPAWN_RUNES; +extern const QString NO_UNLAGGED; +extern const QString ALWAYS_APPLY_LMSSPECTATOR_SETTINGS; +extern const QString NO_MEDALS; +extern const QString SCORE_DAMAGE_NOT_KILLS; +extern const QString DONT_SPAWN_ANY_MULTIPLAYER_ITEM; +extern const QString NO_TARGET_IDENTIFY; +extern const QString NO_DISPLAY_COOP_INFO; +extern const QString NO_MAX_BLOOD_SCALAR; +extern const QString NO_ITEM_DROP; +extern const QString NO_ROCKET_JUMP; +extern const QString NO_USE_CUSTOM_GLLIGHTING_SETTINGS; +extern const QString NO_TURN_OFF_TRANSLUCENCY; +extern const QString SHARE_KEYS; +extern const QString SURVIVAL_NO_MAP_RESET_ON_DEATH; +extern const QString DEAD_PLAYERS_CAN_KEEP_INVENTORY; +extern const QString LMSCHAINSAW; +extern const QString LMSPISTOL; +extern const QString LMSSHOTGUN; +extern const QString LMSSUPER_SHOTGUN; +extern const QString LMSCHAINGUN; +extern const QString LMSMINIGUN; +extern const QString LMSROCKET_LAUNCHER; +extern const QString LMSGRENADE_LAUNCHER; +extern const QString LMSPLASMA_RIFLE; +extern const QString LMSRAILGUN; +extern const QString LMSSPECTATORS_CAN_TALK_TO_ACTIVE_PLAYERS; +extern const QString LMSSPECTATORS_CAN_VIEW_THE_GAME; +} + + +class ZandronumqGameSettings +{ +public: + ZandronumqGameSettings(); + ~ZandronumqGameSettings(); + +private: + DPtr d; +}; + +#endif diff --git a/src/plugins/zandronumq/zandronumqmasterclient.cpp b/src/plugins/zandronumq/zandronumqmasterclient.cpp new file mode 100644 index 00000000..5c628d89 --- /dev/null +++ b/src/plugins/zandronumq/zandronumqmasterclient.cpp @@ -0,0 +1,187 @@ +//------------------------------------------------------------------------------ +// zandronumqmasterclient.cpp +//------------------------------------------------------------------------------ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301 USA +// +//------------------------------------------------------------------------------ +// Copyright (C) 2009 Braden "Blzut3" Obrzut (skulltagmasterclient.cpp) +// Copyright (C) 2012 "Zalewa" +//------------------------------------------------------------------------------ +#include +#include +#include +#include + +#include "datastreamoperatorwrapper.h" +#include "global.h" +#include "huffman/huffman.h" +#include "zandronumqengineplugin.h" +#include "zandronumqmasterclient.h" +#include "zandronumqserver.h" + +#define MASTER_CHALLENGE 5660028 +#define MASTER_PROTOCOL_VERSION 2 +#define MASTER_RESPONSE_GOOD 0 +#define MASTER_RESPONSE_BANNED 3 +#define MASTER_RESPONSE_BAD 4 +#define MASTER_RESPONSE_WRONGVERSION 5 +#define MASTER_RESPONSE_SERVER 1 +#define MASTER_RESPONSE_END 2 +#define MASTER_RESPONSE_BEGINPART 6 +#define MASTER_RESPONSE_ENDPART 7 +#define MASTER_RESPONSE_SERVERBLOCK 8 + +#define RETURN_BAD_IF_NOT_ENOUGH_DATA(min_amount_of_data_required) \ + { \ + if (in.remaining() < (min_amount_of_data_required)) \ + return RESPONSE_BAD; \ + } + +ZandronumqMasterClient::ZandronumqMasterClient() : MasterClient() +{ + set_masterBanHelp(&ZandronumqMasterClient::masterBanHelp); +} + +QByteArray ZandronumqMasterClient::createServerListRequest() +{ + const unsigned char challenge[6] = {WRITEINT32_DIRECT(unsigned char, MASTER_CHALLENGE), WRITEINT16_DIRECT(unsigned char, MASTER_PROTOCOL_VERSION)}; + unsigned char challengeOut[12]; + int out = 12; + HUFFMAN_Encode(challenge, challengeOut, 6, &out); + return QByteArray(reinterpret_cast(challengeOut), out); +} + +QString ZandronumqMasterClient::masterBanHelp() const +{ + return tr("You may contact Q-Zandronum staff about this through " + "IRC: irc.qzandronum.com #zandronumq or on " + "the forum: https://qzandronum.com/forum."); +} + +const EnginePlugin *ZandronumqMasterClient::plugin() const +{ + return ZandronumqEnginePlugin::staticInstance(); +} + +MasterClient::Response ZandronumqMasterClient::readMasterResponse(const QByteArray &data) +{ + const char *packetEncoded = data.data(); + int packetDecodedSize = 2000 + data.size(); + char *packetDecoded = new char[packetDecodedSize]; + + HUFFMAN_Decode(reinterpret_cast(packetEncoded), + reinterpret_cast(packetDecoded), + data.size(), &packetDecodedSize); + + if (packetDecodedSize <= 0) + { + delete[] packetDecoded; + return RESPONSE_BAD; + } + + QByteArray packetDecodedByteArray(packetDecoded, packetDecodedSize); + delete[] packetDecoded; + + QBuffer ioBuffer(&packetDecodedByteArray); + ioBuffer.open(QIODevice::ReadOnly); + QDataStream inStream(&ioBuffer); + inStream.setByteOrder(QDataStream::LittleEndian); + DataStreamOperatorWrapper in(&inStream); + + // Check the response code + RETURN_BAD_IF_NOT_ENOUGH_DATA(4); + int response = in.readQInt32(); + if (response == MASTER_RESPONSE_BANNED) + return RESPONSE_BANNED; + else if (response == MASTER_RESPONSE_BAD) + return RESPONSE_WAIT; + else if (response == MASTER_RESPONSE_WRONGVERSION) + return RESPONSE_OLD; + else if (response != MASTER_RESPONSE_BEGINPART) + return RESPONSE_PENDING; + + RETURN_BAD_IF_NOT_ENOUGH_DATA(1); + int packetNum = in.readQUInt8(); + if (!(packetsRead & (1 << packetNum))) // Set flag if we haven't read this packet + packetsRead |= 1 << packetNum; + else // Already read packet so ignore it. + return RESPONSE_PENDING; + if (packetNum + 1 > numPackets) // Packet numbers start at 0 + numPackets = packetNum + 1; + + RETURN_BAD_IF_NOT_ENOUGH_DATA(1); + quint8 firstByte = in.readQUInt8(); + if (firstByte != MASTER_RESPONSE_ENDPART && firstByte != MASTER_RESPONSE_END) + { + unsigned int numServersInBlock = in.readQUInt8(); + while (numServersInBlock != 0) + { + RETURN_BAD_IF_NOT_ENOUGH_DATA(4 + 2); // ip + port + + // [Zalewa] Remember: it's a very bad idea to pass reads + // directly to function calls because function calls are + // resolved in reverse order (in MSVC at least). + quint8 ip1 = in.readQUInt8(); + quint8 ip2 = in.readQUInt8(); + quint8 ip3 = in.readQUInt8(); + quint8 ip4 = in.readQUInt8(); + + QString ip = QString("%1.%2.%3.%4"). + arg(ip1, 1, 10, QChar('0')). + arg(ip2, 1, 10, QChar('0')). + arg(ip3, 1, 10, QChar('0')). + arg(ip4, 1, 10, QChar('0')); + + for (unsigned int i = 0; i < numServersInBlock; i++) + { + quint16 port = in.readQUInt16(); + ZandronumqServer *server = new ZandronumqServer(QHostAddress(ip), + port); + registerNewServer(ServerPtr(server)); + } + + RETURN_BAD_IF_NOT_ENOUGH_DATA(1); + numServersInBlock = in.readQUInt8(); + } + RETURN_BAD_IF_NOT_ENOUGH_DATA(1); + firstByte = in.readQUInt8(); + } + + if (firstByte == MASTER_RESPONSE_END) + readLastPacket = true; + if (readLastPacket) // See if we read every packet. + { + if (packetsRead == static_cast((1 << numPackets) - 1)) + { + emit listUpdated(); + return RESPONSE_GOOD; + } + } + + return RESPONSE_PENDING; +} + +void ZandronumqMasterClient::refreshStarts() +{ + // Make sure we have an empty list. + emptyServerList(); + readLastPacket = false; + numPackets = 0; + packetsRead = 0; + + MasterClient::refreshStarts(); +} diff --git a/src/plugins/zandronumq/zandronumqmasterclient.h b/src/plugins/zandronumq/zandronumqmasterclient.h new file mode 100644 index 00000000..85e59b04 --- /dev/null +++ b/src/plugins/zandronumq/zandronumqmasterclient.h @@ -0,0 +1,56 @@ +//------------------------------------------------------------------------------ +// zandronumqmasterclient.h +//------------------------------------------------------------------------------ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301 USA +// +//------------------------------------------------------------------------------ +// Copyright (C) 2009 Braden "Blzut3" Obrzut (skulltagmasterclient.h) +// Copyright (C) 2012 "Zalewa" +//------------------------------------------------------------------------------ +#ifndef DOOMSEEKER_PLUGIN_ZANDRONUMQMASTERCLIENT_H +#define DOOMSEEKER_PLUGIN_ZANDRONUMQMASTERCLIENT_H + +#include + +class EnginePlugin; + +class ZandronumqMasterClient : public MasterClient +{ + Q_OBJECT + +public: + ZandronumqMasterClient(); + + const EnginePlugin *plugin() const override; + +public slots: + void refreshStarts() override; + +protected: + QByteArray createServerListRequest() override; + Response readMasterResponse(const QByteArray &data) override; + + /// This is used as a marker to determine if we have an accurate reading for numPackets. + bool readLastPacket; + int numPackets; + unsigned int packetsRead; + +private: + QString masterBanHelp() const; +}; + +#endif diff --git a/src/plugins/zandronumq/zandronumqrconprotocol.cpp b/src/plugins/zandronumq/zandronumqrconprotocol.cpp new file mode 100644 index 00000000..74eef422 --- /dev/null +++ b/src/plugins/zandronumq/zandronumqrconprotocol.cpp @@ -0,0 +1,352 @@ +//------------------------------------------------------------------------------ +// zandronumqrconprotocol.cpp +//------------------------------------------------------------------------------ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301 USA +// +//------------------------------------------------------------------------------ +// Copyright (C) 2009 Braden "Blzut3" Obrzut +// Copyright (C) 2014 "Zalewa" +//------------------------------------------------------------------------------ +#include "zandronumqrconprotocol.h" + +#include "huffman/huffman.h" +#include "zandronumqserver.h" +#include +#include +#include +#include +#include + +#define RCON_PROTOCOL_VERSION 3 + +ZandronumqRConProtocol::ZandronumqRConProtocol(ServerPtr server) + : RConProtocol(server) +{ + set_disconnectFromServer(&ZandronumqRConProtocol::disconnectFromServer); + set_sendCommand(&ZandronumqRConProtocol::sendCommand); + set_sendPassword(&ZandronumqRConProtocol::sendPassword); + + connectStage = Disconnected; + connectionAttempts = 0; + passwordAttempts = 0; + authTime.invalidate(); + + huffmanSocket.setSocket(&socket()); + connect(&socket(), SIGNAL(readyRead()), this, SLOT(readAllPendingDatagrams())); + + // Note: the original rcon utility did TIMEOUT/4. + // Try to get at least 4 packets in before timing out, + pingTimer.setInterval(2500); + connect(&pingTimer, SIGNAL(timeout()), this, SLOT(sendPong())); + connect(&pingTimer, SIGNAL(timeout()), this, SLOT(readAllPendingDatagrams())); + + timeoutTimer.setSingleShot(true); + this->connect(&timeoutTimer, SIGNAL(timeout()), SLOT(packetTimeout())); +} + +void ZandronumqRConProtocol::connectToServer() +{ + const char beginConnection[2] = { CLRC_BEGINCONNECTION, RCON_PROTOCOL_VERSION }; + + if (connectionAttempts < MAX_CONNECTIONT_ATTEMPTS) + { + ++connectionAttempts; + emit messageReceived(tr("Connection attempt ...")); + setConnected(false); + huffmanSocket.writeDatagram(beginConnection, 2, address(), port()); + timeoutTimer.start(3000); + } + else + { + setDisconnectedState(); + emit messageReceived(tr("Too many failed connection attempts. Aborting.")); + } +} + +void ZandronumqRConProtocol::disconnectFromServer() +{ + if (isConnected()) + { + const char disconnectPacket[1] = { CLRC_DISCONNECT }; + huffmanSocket.writeDatagram(disconnectPacket, 1, address(), port()); + } + setDisconnectedState(); + emit disconnected(); +} + +void ZandronumqRConProtocol::sendCommand(const QString &cmd) +{ + char packet[4096]; + packet[0] = CLRC_COMMAND; + packet[cmd.length() + 1] = 0; + memcpy(packet + 1, cmd.toUtf8().constData(), cmd.length()); + huffmanSocket.writeDatagram(packet, 4096, address(), port()); +} + +void ZandronumqRConProtocol::sendPassword(const QString &password) +{ + this->password = password; + stepConnect(); +} + +void ZandronumqRConProtocol::sendMemorizedPassword() +{ + if (passwordAttempts < MAX_PASSWORD_ATTEMPTS) + { + ++passwordAttempts; + emit messageReceived(tr("Authenticating ...")); + // Calculate the MD5 of the salt + password + QString hashPassword = salt + password; + QCryptographicHash hash(QCryptographicHash::Md5); + hash.addData(hashPassword.toUtf8()); + QByteArray md5 = hash.result().toHex(); + + // Create the packet + char passwordPacket[34]; + passwordPacket[0] = CLRC_PASSWORD; + memcpy(passwordPacket + 1, md5.data(), md5.size()); + passwordPacket[33] = 0; + + huffmanSocket.writeDatagram(passwordPacket, 34, address(), port()); + timeoutTimer.start(3000); + } + else + { + setDisconnectedState(); + emit messageReceived(tr("Too many failed authentication attempts. Aborting.")); + } +} + +void ZandronumqRConProtocol::setDisconnectedState() +{ + pingTimer.stop(); + setConnected(false); + authTime.invalidate(); + connectStage = Disconnected; +} + +void ZandronumqRConProtocol::setReconnectState() +{ + setDisconnectedState(); + connectStage = ConnectEstablishing; +} + +void ZandronumqRConProtocol::stepConnect() +{ + switch (connectStage) + { + case Disconnected: + connectionAttempts = 0; + passwordAttempts = 0; + connectStage = ConnectEstablishing; + stepConnect(); + break; + case ConnectEstablishing: + connectToServer(); + break; + case ConnectPassword: + if (!authTime.isValid()) + { + sendMemorizedPassword(); + } + else + { + int delta = qMax(0, AUTH_FLOOD_PREVENTION_PERIOD - static_cast(authTime.elapsed())); + if (delta > 0) + { + emit messageReceived( + tr("Delaying for about %n seconds before next authentication attempt.", + nullptr, qMax(1, delta / 1000))); + } + setReconnectState(); + QTimer::singleShot(delta, this, SLOT(stepConnect())); + } + break; + default: + break; + } +} + +void ZandronumqRConProtocol::sendPong() +{ + // create a "PONG" packet + const char pong[1] = { CLRC_PONG }; + huffmanSocket.writeDatagram(pong, 1, address(), port()); +} + +void ZandronumqRConProtocol::readAllPendingDatagrams() +{ + while (socket().hasPendingDatagrams()) + { + timeoutTimer.stop(); + QByteArray packet = huffmanSocket.readDatagram(); + QBuffer stream(&packet); + stream.open(QIODevice::ReadOnly); + switch (connectStage) + { + case ConnectEstablishing: + processEstablishingPacket(stream); + break; + case ConnectPassword: + case ConnectEstablished: + processPacket(&stream); + break; + case Disconnected: + break; + } + } +} + +void ZandronumqRConProtocol::packetTimeout() +{ + switch (connectStage) + { + case ConnectEstablishing: + emit messageReceived(tr("Failed to establish connection.")); + break; + case ConnectPassword: + emit messageReceived(tr("Timeout on authentication.")); + break; + default: + return; + } + stepConnect(); +} + +void ZandronumqRConProtocol::processEstablishingPacket(QIODevice &ioDevice) +{ + QDataStream dataStream(&ioDevice); + dataStream.setByteOrder(QDataStream::LittleEndian); + DataStreamOperatorWrapper in(&dataStream); + + qint8 code = in.readQInt8(); + switch (code) + { + case SVRC_BANNED: + emit messageReceived(tr("You have been banned from this server.")); + setDisconnectedState(); + break; + default: + case SVRC_OLDPROTOCOL: + emit messageReceived(tr("The protocol appears to be outdated.")); + setDisconnectedState(); + break; + case SVRC_SALT: + setConnected(true); + salt = QString(in.readRawUntilByte('\0')); + pingTimer.start(); + connectStage = ConnectPassword; + stepConnect(); + break; + } +} + +void ZandronumqRConProtocol::processPacket(QIODevice *ioDevice, bool initial, int maxUpdates) +{ + static const QRegExp colorCode(R"(\\c(\[[a-zA-Z0-9]*\]|[a-v+\-!*]))"); + + // QIODevice is assumed to be already opened at this point. + QDataStream dataStream(ioDevice); + dataStream.setByteOrder(QDataStream::LittleEndian); + DataStreamOperatorWrapper in(&dataStream); + + while (in.hasRemaining() && maxUpdates-- != 0) + { + // Determine how we get to the update. + int update = 0; + if (initial) + update = SVRC_UPDATE; + else + update = in.readQUInt8(); + + switch (update) + { + default: + qDebug() << "Unknown update (" << update << ")"; + return; + case SVRC_INVALIDPASSWORD: + authTime.start(); + emit messageReceived(tr("Authentication failure.")); + emit invalidPassword(); + break; + case SVRC_LOGGEDIN: + { + emit messageReceived(tr("Remote console connection established.")); + emit messageReceived(tr("-----")); // Just a delimiter. + connectStage = ConnectEstablished; + serverProtocolVersion = in.readQUInt8(); + hostName = in.readRawUntilByte('\0'); + emit serverNameChanged(hostName); + + int numUpdates = in.readQUInt8(); + + processPacket(ioDevice, true, numUpdates); + + int numStrings = in.readQUInt8(); + while (numStrings-- > 0) + { + QString message = in.readRawUntilByte('\0'); + message.replace(colorCode, "\034\\1"); + emit messageReceived(message.trimmed()); + } + break; + } + case SVRC_MESSAGE: + { + QString message = QDateTime::currentDateTime().toString("[hh:mm:ss ap] ") + in.readRawUntilByte('\0'); + message.replace(colorCode, "\034\\1"); + emit messageReceived(message); + break; + } + case SVRC_UPDATE: + int updateType = in.readQUInt8(); + switch (updateType) + { + default: + qDebug() << "Uknown streamlined update (" << update << ")"; + return; + case SVRCU_MAP: + { + QString map = in.readRawUntilByte('\0'); + break; + } + case SVRCU_ADMINCOUNT: + { + // Unused: + // int admins = in.readQUint8(); + // !!! MAKE SURE to remove the line below if line above + // is uncommented! + in.skipRawData(1); + break; + } + case SVRCU_PLAYERDATA: + { + int players = in.readQUInt8(); + this->playersMutable().clear(); + while (players-- > 0) + { + QString player = in.readRawUntilByte('\0'); + this->playersMutable().append(Player(player, 0, 0)); + } + emit playerListUpdated(); + break; + } + } + break; + } + } +} diff --git a/src/plugins/zandronumq/zandronumqrconprotocol.h b/src/plugins/zandronumq/zandronumqrconprotocol.h new file mode 100644 index 00000000..942e6c8d --- /dev/null +++ b/src/plugins/zandronumq/zandronumqrconprotocol.h @@ -0,0 +1,109 @@ +//------------------------------------------------------------------------------ +// zandronumqrconprotocol.h +//------------------------------------------------------------------------------ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301 USA +// +//------------------------------------------------------------------------------ +// Copyright (C) 2009 Braden "Blzut3" Obrzut +// Copyright (C) 2014 "Zalewa" +//------------------------------------------------------------------------------ +#ifndef idd10651d2_c61d_498e_8ff6_88a782a8fa1c +#define idd10651d2_c61d_498e_8ff6_88a782a8fa1c + +#include "huffmanudpsocket.h" +#include +#include +#include + +class ZandronumqRConProtocol : public RConProtocol +{ + Q_OBJECT + +private: + enum + { + SVRCU_PLAYERDATA = 0, + SVRCU_ADMINCOUNT, + SVRCU_MAP, + + SVRC_OLDPROTOCOL = 32, + SVRC_BANNED, + SVRC_SALT, + SVRC_LOGGEDIN, + SVRC_INVALIDPASSWORD, + SVRC_MESSAGE, + SVRC_UPDATE, + + CLRC_BEGINCONNECTION = 52, + CLRC_PASSWORD, + CLRC_COMMAND, + CLRC_PONG, + CLRC_DISCONNECT + }; + +public: + ZandronumqRConProtocol(ServerPtr server); + void connectToServer(); + +public slots: + void disconnectFromServer(); + void sendCommand(const QString &cmd); + void sendPassword(const QString &password); + void sendPong(); + +private: + static const int MAX_CONNECTIONT_ATTEMPTS = 3; + static const int MAX_PASSWORD_ATTEMPTS = 3; + static const int AUTH_FLOOD_PREVENTION_PERIOD = 11 * 1000; + + enum ConnectStage + { + ConnectEstablishing, + ConnectPassword, + ConnectEstablished, + Disconnected, + }; + + void processEstablishingPacket(QIODevice &ioDevice); + void processPacket(QIODevice *ioDevice, bool initial = false, int maxUpdates = 1); + void sendMemorizedPassword(); + void setDisconnectedState(); + /** + * @brief Reconnect state is similar to disconnect state, but + * doesn't clear failed attempts counters. + */ + void setReconnectState(); + + QElapsedTimer authTime; + ConnectStage connectStage; + int connectionAttempts; + int passwordAttempts; + HuffmanUdpSocket huffmanSocket; + QTimer pingTimer; + QString hostName; + QString password; + QString salt; + int serverProtocolVersion; + QTimer timeoutTimer; + +private slots: + void readAllPendingDatagrams(); + void packetTimeout(); + void stepConnect(); +}; + +#endif diff --git a/src/plugins/zandronumq/zandronumqserver.cpp b/src/plugins/zandronumq/zandronumqserver.cpp new file mode 100644 index 00000000..d011c58e --- /dev/null +++ b/src/plugins/zandronumq/zandronumqserver.cpp @@ -0,0 +1,762 @@ +//------------------------------------------------------------------------------ +// zandronumqserver.cpp +//------------------------------------------------------------------------------ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301 USA +// +//------------------------------------------------------------------------------ +// Copyright (C) 2009 Braden "Blzut3" Obrzut +// Copyright (C) 2012 "Zalewa" +//------------------------------------------------------------------------------ +#include "zandronumqserver.h" + +#include "datastreamoperatorwrapper.h" +#include "global.h" +#include "huffman/huffman.h" +#include "log.h" +#include "zandronumqbinaries.h" +#include "zandronumqengineplugin.h" +#include "zandronumqgamehost.h" +#include "zandronumqgameinfo.h" +#include "zandronumqgamerunner.h" +#include "zandronumqrconprotocol.h" +#include "zandronumqserverdmflagsparser.h" +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define SERVER_CHALLENGE 0xC7, 0x00, 0x00, 0x00 +#define SERVER_GOOD 5660023 +#define SERVER_BANNED 5660025 +#define SERVER_WAIT 5660024 + +#define RETURN_BAD_IF_NOT_ENOUGH_DATA(min_amout_of_data_required) \ + { \ + /* qDebug() << "pos/size" << in.device()->pos() << "/" << in.device()->size(); */ \ + if (in.remaining() < (min_amout_of_data_required)) \ + { \ + return RESPONSE_BAD; \ + } \ + } + +/** + * Compares versions of Zandronumq. + */ +ZandronumqVersion::ZandronumqVersion(QString version) : version(version) +{ + versionExpression.exactMatch(version); + QStringList parts = versionExpression.capturedTexts(); + major = parts[1].toUShort(); + minor = parts[2].toUShort(); + revision = parts[3].toUShort(); + build = parts[4].toUShort(); + tag = parts[5]; + hgRevisionDate = parts[6].toUInt(); + hgRevisionTime = parts[7].toUShort(); +} + +bool ZandronumqVersion::operator> (const ZandronumqVersion &other) const +{ + if (major > other.major || + (major == other.major && (minor > other.minor || + (minor == other.minor && (revision > other.revision || + (revision == other.revision && build > other.build)))))) + return true; + if ((tag.isEmpty() && !other.tag.isEmpty()) || (tag > other.tag)) + return true; + if (hgRevisionDate > other.hgRevisionDate) + return true; + if (hgRevisionTime > other.hgRevisionTime) + return true; + return false; +} + +const QRegExp ZandronumqVersion::versionExpression(R"((\d+).(\d+)(?:.(\d+)(?:.(\d+))?)?(?:-([a-zA-Z]*)?)?(?:-r(\d+)(?:-(\d+))?)?)"); + +//////////////////////////////////////////////////////////////////////////////// + +TeamInfo::TeamInfo(QString name, QColor color, unsigned int score) : + teamName(std::move(name)), teamColor(std::move(color)), teamScore(score) +{ +} + +//////////////////////////////////////////////////////////////////////////////// + +ZandronumqServer::ZandronumqServer(const QHostAddress &address, unsigned short port) + : Server(address, port), + buckshot(false), instagib(false), teamDamage(0.0f), + botSkill(0), duelLimit(0), fragLimit(0), pointLimit(0), winLimit(0), + numTeams(2) +{ + teamInfo[0] = TeamInfo(tr("Blue"), QColor(0, 0, 255), 0); + teamInfo[1] = TeamInfo(tr("Red"), QColor(255, 0, 0), 0); + teamInfo[2] = TeamInfo(tr("Green"), QColor(0, 255, 0), 0); + teamInfo[3] = TeamInfo(tr("Gold"), QColor(255, 255, 0), 0); + + set_createSendRequest(&ZandronumqServer::createSendRequest); + set_readRequest(&ZandronumqServer::readRequest); + + connect(this, SIGNAL(updated(ServerPtr,int)), this, SLOT(updatedSlot(ServerPtr,int))); +} + +ExeFile *ZandronumqServer::clientExe() +{ + return new ZandronumqClientExeFile(self().toStrongRef().staticCast()); +} + +GameClientRunner *ZandronumqServer::gameRunner() +{ + return new ZandronumqGameClientRunner(self()); +} + +unsigned int ZandronumqServer::millisecondTime() +{ + const QTime time = QTime::currentTime(); + return time.hour() * 360000 + time.minute() * 60000 + time.second() * 1000 + time.msec(); +} + +QList ZandronumqServer::modifiers() const +{ + QList result; + if (instagib) + result << ZandronumqGameInfo::gameModifiers()[1]; + else if (buckshot) + result << ZandronumqGameInfo::gameModifiers()[0]; + return result; +} + +EnginePlugin *ZandronumqServer::plugin() const +{ + return ZandronumqEnginePlugin::staticInstance(); +} + +Server::Response ZandronumqServer::readRequest(const QByteArray &data) +{ + const int BUFFER_SIZE = 6000; + QByteArray rawReadBuffer; + + // Decompress the response. + const char *huffmanPacket = data.data(); + + int decodedSize = BUFFER_SIZE + data.size(); + char *packetDecodedBuffer = new char[decodedSize]; + + HUFFMAN_Decode(reinterpret_cast(huffmanPacket), + reinterpret_cast(packetDecodedBuffer), data.size(), + &decodedSize); + + if (decodedSize <= 0) + { + delete [] packetDecodedBuffer; + return RESPONSE_BAD; + } + + // Prepare reading interface. + QByteArray packetDecoded(packetDecodedBuffer, decodedSize); + lastReadRequest = packetDecoded; + + delete [] packetDecodedBuffer; + + QBuffer packetDecodedIo(&packetDecoded); + + packetDecodedIo.open(QIODevice::ReadOnly); + packetDecodedIo.seek(0); + + QDataStream inStream(&packetDecodedIo); + inStream.setByteOrder(QDataStream::LittleEndian); + + DataStreamOperatorWrapper in(&inStream); + + // Read and parse. + + // Do the initial sanity check. All packets must be at least 8 bytes big. + if (decodedSize < 8) + { + fprintf(stderr, "Data size error when reading server %s:%u." + " Data size encoded: %u, decoded %u\n", + address().toString().toUtf8().constData(), port(), + data.size(), decodedSize); + return RESPONSE_BAD; + } + + // Check the response code + qint32 response = in.readQInt32(); + + // Determine ping. Time is sent no matter what the response is, still we + // should check if there's enough data to read from. + qint32 responseTimestamp = in.readQInt32(); + setPing(millisecondTime() - responseTimestamp); + setPingIsSet(true); + + // Act according to the response + switch (response) + { + case SERVER_BANNED: + return RESPONSE_BANNED; + + case SERVER_WAIT: + return RESPONSE_WAIT; + + case SERVER_GOOD: + // Do nothing, continue + break; + + default: + return RESPONSE_BAD; + } + + // If response was equal to SERVER_GOOD, proceed to read data. + RETURN_BAD_IF_NOT_ENOUGH_DATA(1); + setGameVersion(in.readRawUntilByte('\0')); + + ZandronumqGameInfo::ZandronumqGameMode mode = ZandronumqGameInfo::GAMEMODE_COOPERATIVE; + + // Flags - set of flags returned by the server. This is compared + // with known set of flags and the data is read from the packet + // accordingly. Every flag is removed from this variable after such check. + // See "if SQF_NAME" for an example. + RETURN_BAD_IF_NOT_ENOUGH_DATA(4); + quint32 flags = in.readQUInt32(); + if ((flags & SQF_NAME) == SQF_NAME) // Check if SQF_NAME is inside flags var. + { + RETURN_BAD_IF_NOT_ENOUGH_DATA(1); + setName(in.readRawUntilByte('\0')); + flags ^= SQF_NAME; // Remove SQF_NAME flag from the variable. + } + + if ((flags & SQF_URL) == SQF_URL) + { + RETURN_BAD_IF_NOT_ENOUGH_DATA(1); + setWebSite(in.readRawUntilByte('\0')); + flags ^= SQF_URL; + } + if ((flags & SQF_EMAIL) == SQF_EMAIL) + { + RETURN_BAD_IF_NOT_ENOUGH_DATA(1); + setEmail(in.readRawUntilByte('\0')); + flags ^= SQF_EMAIL; + } + if ((flags & SQF_MAPNAME) == SQF_MAPNAME) + { + RETURN_BAD_IF_NOT_ENOUGH_DATA(1); + setMap(in.readRawUntilByte('\0')); + flags ^= SQF_MAPNAME; + } + + if ((flags & SQF_MAXCLIENTS) == SQF_MAXCLIENTS) + { + RETURN_BAD_IF_NOT_ENOUGH_DATA(1); + setMaxClients(in.readQUInt8()); + flags ^= SQF_MAXCLIENTS; + } + else + { + setMaxClients(0); + } + + if ((flags & SQF_MAXPLAYERS) == SQF_MAXPLAYERS) + { + RETURN_BAD_IF_NOT_ENOUGH_DATA(1); + setMaxPlayers(in.readQUInt8()); + flags ^= SQF_MAXPLAYERS; + } + else + { + setMaxPlayers(0); + } + + if ((flags & SQF_PWADS) == SQF_PWADS) + { + RETURN_BAD_IF_NOT_ENOUGH_DATA(1); + qint8 numPwads = in.readQInt8(); + clearWads(); + flags ^= SQF_PWADS; + for (int i = 0; i < numPwads; i++) + { + RETURN_BAD_IF_NOT_ENOUGH_DATA(1); + QString wad = in.readRawUntilByte('\0'); + if (!wad.isEmpty()) + addWad(wad); + } + } + + if ((flags & SQF_GAMETYPE) == SQF_GAMETYPE) + { + RETURN_BAD_IF_NOT_ENOUGH_DATA(1); + qint8 modeCode = in.readQInt8(); + + if (modeCode > NUM_ZANDRONUMQ_GAME_MODES) + { + modeCode = NUM_ZANDRONUMQ_GAME_MODES; // this will set game mode to unknown + } + + mode = static_cast(modeCode); + setGameMode(ZandronumqGameInfo::gameModes()[mode]); + + RETURN_BAD_IF_NOT_ENOUGH_DATA(2); + instagib = in.readQInt8() != 0; + buckshot = in.readQInt8() != 0; + + flags ^= SQF_GAMETYPE; + } + + if ((flags & SQF_GAMENAME) == SQF_GAMENAME) + { + //Useless String + RETURN_BAD_IF_NOT_ENOUGH_DATA(1); + in.readRawUntilByte('\0'); + } + + if ((flags & SQF_IWAD) == SQF_IWAD) + { + RETURN_BAD_IF_NOT_ENOUGH_DATA(1); + setIwad(in.readRawUntilByte('\0')); + flags ^= SQF_IWAD; + } + + if ((flags & SQF_FORCEPASSWORD) == SQF_FORCEPASSWORD) + { + RETURN_BAD_IF_NOT_ENOUGH_DATA(1); + setLocked(in.readQInt8() != 0); + flags ^= SQF_FORCEPASSWORD; + } + else + { + setLocked(false); + } + + if ((flags & SQF_FORCEJOINPASSWORD) == SQF_FORCEJOINPASSWORD) + { + RETURN_BAD_IF_NOT_ENOUGH_DATA(1); + setLockedInGame(in.readQInt8() != 0); + flags ^= SQF_FORCEJOINPASSWORD; + } + else + { + setLockedInGame(false); + } + + if ((flags & SQF_GAMESKILL) == SQF_GAMESKILL) + { + RETURN_BAD_IF_NOT_ENOUGH_DATA(1); + setSkill(in.readQInt8()); + flags ^= SQF_GAMESKILL; + } + + if ((flags & SQF_BOTSKILL) == SQF_BOTSKILL) + { + RETURN_BAD_IF_NOT_ENOUGH_DATA(1); + botSkill = in.readQInt8(); + flags ^= SQF_BOTSKILL; + } + + if ((flags & SQF_LIMITS) == SQF_LIMITS) + { + flags ^= SQF_LIMITS; + + RETURN_BAD_IF_NOT_ENOUGH_DATA(2); + fragLimit = in.readQUInt16(); + + // Read timelimit and timeleft, + // note that if timelimit == 0 then no info + // about timeleft is sent + RETURN_BAD_IF_NOT_ENOUGH_DATA(2); + setTimeLimit(in.readQUInt16()); + if (timeLimit() != 0) + { + RETURN_BAD_IF_NOT_ENOUGH_DATA(2); + setTimeLeft(in.readQUInt16()); + } + + RETURN_BAD_IF_NOT_ENOUGH_DATA(2 + 2 + 2); + duelLimit = in.readQUInt16(); + pointLimit = in.readQUInt16(); + winLimit = in.readQUInt16(); + switch (mode) + { + default: + setScoreLimit(fragLimit); + break; + case ZandronumqGameInfo::GAMEMODE_LASTMANSTANDING: + case ZandronumqGameInfo::GAMEMODE_TEAMLMS: + setScoreLimit(winLimit); + break; + case ZandronumqGameInfo::GAMEMODE_POSSESSION: + case ZandronumqGameInfo::GAMEMODE_TEAMPOSSESSION: + case ZandronumqGameInfo::GAMEMODE_TEAMGAME: + case ZandronumqGameInfo::GAMEMODE_CTF: + case ZandronumqGameInfo::GAMEMODE_ONEFLAGCTF: + case ZandronumqGameInfo::GAMEMODE_SKULLTAG: + case ZandronumqGameInfo::GAMEMODE_DOMINATION: + setScoreLimit(pointLimit); + break; + } + } + else + { + // Nullify vars if there is no info + fragLimit = 0; + setTimeLimit(0); + duelLimit = 0; + pointLimit = 0; + winLimit = 0; + setScoreLimit(0); + } + + if ((flags & SQF_TEAMDAMAGE) == SQF_TEAMDAMAGE) + { + RETURN_BAD_IF_NOT_ENOUGH_DATA(4); + teamDamage = in.readFloat(); + flags ^= SQF_TEAMDAMAGE; + } + if ((flags & SQF_TEAMSCORES) == SQF_TEAMSCORES) + { + // DEPRECATED flag + for (int i = 0; i < 2; i++) + { + RETURN_BAD_IF_NOT_ENOUGH_DATA(2); + scoresMutable()[i] = in.readQInt16(); + } + flags ^= SQF_TEAMSCORES; + } + if ((flags & SQF_NUMPLAYERS) == SQF_NUMPLAYERS) + { + RETURN_BAD_IF_NOT_ENOUGH_DATA(1); + int numPlayers = in.readQUInt8(); + flags ^= SQF_NUMPLAYERS; + + if ((flags & SQF_PLAYERDATA) == SQF_PLAYERDATA) + { + flags ^= SQF_PLAYERDATA; + clearPlayersList(); // Erase previous players (if any) + for (int i = 0; i < numPlayers; i++) + { + // team isn't sent in non team modes. + bool teammode = gameMode().isTeamGame(); + + RETURN_BAD_IF_NOT_ENOUGH_DATA(1); + QString name = in.readRawUntilByte('\0'); + + RETURN_BAD_IF_NOT_ENOUGH_DATA(2 + 2 + 1 + 1); + int score = in.readQInt16(); + int ping = in.readQUInt16(); + bool spectating = in.readQUInt8() != 0; + bool bot = in.readQUInt8() != 0; + + int team; + if (teammode) + { + RETURN_BAD_IF_NOT_ENOUGH_DATA(1); + team = in.readQUInt8(); + } + else + { + team = Player::TEAM_NONE; + } + // Now there is info on time that the player is + // on the server. We'll skip it. + RETURN_BAD_IF_NOT_ENOUGH_DATA(1); + in.skipRawData(1); + + Player player(name, score, ping, static_cast(team), spectating, bot); + addPlayer(player); + } + } + } + + if ((flags & SQF_TEAMINFO_NUMBER) == SQF_TEAMINFO_NUMBER) + { + RETURN_BAD_IF_NOT_ENOUGH_DATA(1); + numTeams = in.readQUInt8(); + flags ^= SQF_TEAMINFO_NUMBER; + } + + if ((flags & SQF_TEAMINFO_NAME) == SQF_TEAMINFO_NAME) + { + flags ^= SQF_TEAMINFO_NAME; + for (unsigned i = 0; i < numTeams && i < ST_MAX_TEAMS; ++i) + { + RETURN_BAD_IF_NOT_ENOUGH_DATA(1); + QString name = in.readRawUntilByte('\0'); + teamInfo[i].setName(tr(name.toUtf8().constData())); + } + } + if ((flags & SQF_TEAMINFO_COLOR) == SQF_TEAMINFO_COLOR) + { + flags ^= SQF_TEAMINFO_COLOR; + // NOTE: This may not be correct + unsigned forLimit = qMin(numTeams, ST_MAX_TEAMS); + + for (unsigned i = 0; i < forLimit; i++) + { + RETURN_BAD_IF_NOT_ENOUGH_DATA(4); + quint32 colorRgb = in.readQUInt32(); + teamInfo[i].setColor(QColor(colorRgb)); + } + } + if ((flags & SQF_TEAMINFO_SCORE) == SQF_TEAMINFO_SCORE) + { + flags ^= SQF_TEAMINFO_SCORE; + unsigned forLimit = qMin(numTeams, ST_MAX_TEAMS); + + for (unsigned i = 0; i < forLimit; i++) + { + RETURN_BAD_IF_NOT_ENOUGH_DATA(2); + qint16 score = in.readQInt16(); + teamInfo[i].setScore(score); + if (i < MAX_TEAMS) // Transfer to super class score array if possible. + { + scoresMutable()[i] = teamInfo[i].score(); + } + } + } + + if (in.remaining() != 0 && (flags & SQF_TESTING_SERVER) == SQF_TESTING_SERVER) + { + flags ^= SQF_TESTING_SERVER; + + RETURN_BAD_IF_NOT_ENOUGH_DATA(1); + setTestingServer(in.readQInt8() != 0); + + // '\0' is read if testingServer == false + RETURN_BAD_IF_NOT_ENOUGH_DATA(1); + testingArchive = in.readRawUntilByte('\0'); + } + else + { + setTestingServer(false); + testingArchive = QString(); + } + + setDmFlags(QList()); // Basically, clear. + if ((flags & SQF_ALL_DMFLAGS) == SQF_ALL_DMFLAGS) + { + flags ^= SQF_ALL_DMFLAGS; + ZandronumqServerDmflagsParser *parser = ZandronumqServerDmflagsParser::mkParser(this, &inStream); + if (parser != nullptr) + { + setDmFlags(parser->parse()); + delete parser; + } + } + + if ((flags & SQF_SECURITY_SETTINGS) == SQF_SECURITY_SETTINGS) + { + flags ^= SQF_SECURITY_SETTINGS; + + setSecure(in.readQUInt8() != 0); + } + + if ((flags & SQF_OPTIONAL_WADS) == SQF_OPTIONAL_WADS) + { + flags ^= SQF_OPTIONAL_WADS; + + RETURN_BAD_IF_NOT_ENOUGH_DATA(1); + unsigned int numOpts = in.readQUInt8(); + RETURN_BAD_IF_NOT_ENOUGH_DATA(numOpts); + + QList pwads = wads(); + while (numOpts--) + { + unsigned int index = in.readQInt8(); + if (index < static_cast(pwads.size())) + pwads.replace(index, PWad(pwads[index].name(), true)); + } + + resetPwadsList(pwads); + } + + if ((flags & SQF_DEH) == SQF_DEH) + { + flags ^= SQF_DEH; + + RETURN_BAD_IF_NOT_ENOUGH_DATA(1); + unsigned int numDehs = in.readQUInt8(); + + QList pwads = wads(); + while (numDehs--) + { + RETURN_BAD_IF_NOT_ENOUGH_DATA(1); + QString deh = in.readRawUntilByte('\0'); + pwads << deh; + } + resetPwadsList(pwads); + } + + //Extended flags + if ((flags & SQF_EXTENDED_INFO) == SQF_EXTENDED_INFO) + { + RETURN_BAD_IF_NOT_ENOUGH_DATA(1); + quint32 flags2 = in.readQInt32(); + + if ((flags2 & SQF2_PWAD_HASHES) == SQF2_PWAD_HASHES) + { + QList pwads = wads(); + flags2 ^= SQF2_PWAD_HASHES; + + RETURN_BAD_IF_NOT_ENOUGH_DATA(1); + unsigned int numHashes = in.readQInt8(); + RETURN_BAD_IF_NOT_ENOUGH_DATA(numHashes); + + for (unsigned int index = 0; index < numHashes; index++) + { + PWad pwad(pwads[index].name(), + pwads[index].isOptional()); + pwad.addChecksum(QByteArray::fromHex(in.readRawUntilByte('\0')), + QCryptographicHash::Md5); + pwads.replace(index, pwad); + } + resetPwadsList(pwads); + } + } + return RESPONSE_GOOD; +} + +void ZandronumqServer::resetPwadsList(const QList &wads) +{ + clearWads(); + for (const PWad &wad : wads) + addWad(wad); +} + +QByteArray ZandronumqServer::createSendRequest() +{ + // Prepare launcher challenge. + unsigned int standard_query = SQF_STANDARDQUERY; + unsigned int extended_query = SQF2_STANDARDQUERY; + const unsigned char challenge[18] = { + SERVER_CHALLENGE, + WRITEINT32_DIRECT(unsigned char, standard_query), + WRITEINT32_DIRECT(unsigned char, millisecondTime()), + WRITEINT32_DIRECT(unsigned char, extended_query) + }; + char challengeOut[16]; + int out = 16; + HUFFMAN_Encode(challenge, reinterpret_cast(challengeOut), 12, &out); + QByteArray data(challengeOut, out); + return data; +} + +QRgb ZandronumqServer::teamColor(unsigned team) const +{ + if (team >= ST_MAX_TEAMS) + return Server::teamColor(team); + + return teamInfo[team].color().rgb(); +} + +QString ZandronumqServer::teamName(unsigned team) const +{ + if (team == 255) + return "NO TEAM"; + + return team < ST_MAX_TEAMS ? teamInfo[team].name() : ""; +} + +void ZandronumqServer::updatedSlot(ServerPtr server, int response) +{ + if (response == RESPONSE_BAD) + { + // If response is bad we will print the read request to stderr, + // for debug purposes of course. + QSharedPointer s = server.staticCast(); + QByteArray &req = s->lastReadRequest; + + fprintf(stderr, "Bad response from server: %s:%u\n", address().toString().toUtf8().constData(), port()); + fprintf(stderr, "Response size: %u\n", req.size()); + fprintf(stderr, "Data (all non-printable characters are replaced with '?'):\n"); + + + for (int x = 0; x < req.size(); ++x) + { + if (req[x] < (char)0x20 || req[x] > (char)0x7e) + { + fprintf(stderr, "?"); + } + else + { + fprintf(stderr, "%c", (char)req[x]); + } + fprintf(stderr, "[%02X] ", (unsigned char)req[x]); + + if ((x + 1) % 20 == 0) + { + fprintf(stderr, "\n"); + } + } + + fprintf(stderr, "\n\n"); + + fprintf(stderr, "Data as text (all non-printable characters are replaced with '?'):\n"); + for (int x = 0; x < req.size(); ++x) + { + if (req[x] < (char)0x20 || req[x] > (char)0x7e) + { + fprintf(stderr, "?"); + } + else + { + fprintf(stderr, "%c", (char)req[x]); + } + + if ((x + 1) % 70 == 0) + { + fprintf(stderr, "\n"); + } + } + + fprintf(stderr, "\n-- End of response --\n\n"); + } +} + +PathFinder ZandronumqServer::wadPathFinder() +{ + PathFinder pathFinder = Server::wadPathFinder(); + if (isTestingServer()) + { + QScopedPointer exe(clientExe()); + Message message; + QString exePath = exe->pathToExe(message); + if (!exePath.isNull()) + { + // exePath is path to a .bat/.sh file that resides in + // directory above the directory of actual deployment of + // the testing client. Fortunately, name of the .bat/.sh + // file is the same as the name of the directory that + // interests us. So, we cut out the file extension and + // thus we receive a proper path that we can add to + // PathFinder. + QFileInfo fileInfo(exePath); + QString dirPath = Strings::combinePaths(fileInfo.absolutePath(), + fileInfo.completeBaseName()); + pathFinder.addPrioritySearchDir(dirPath); + } + } + return pathFinder; +} + +RConProtocol *ZandronumqServer::rcon() +{ + return new ZandronumqRConProtocol(self()); +} diff --git a/src/plugins/zandronumq/zandronumqserver.h b/src/plugins/zandronumq/zandronumqserver.h new file mode 100644 index 00000000..3a2a9991 --- /dev/null +++ b/src/plugins/zandronumq/zandronumqserver.h @@ -0,0 +1,196 @@ +//------------------------------------------------------------------------------ +// zandronumqserver.h +//------------------------------------------------------------------------------ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301 USA +// +//------------------------------------------------------------------------------ +// Copyright (C) 2009 Braden "Blzut3" Obrzut (skulltagserver.h) +// Copyright (C) 2012 "Zalewa" +//------------------------------------------------------------------------------ +#ifndef DOOMSEEKER_PLUGIN_ZANDRONUMQSERVER_H +#define DOOMSEEKER_PLUGIN_ZANDRONUMQSERVER_H + +#include +#include + +#include "serverapi/server.h" + +#define NUM_ZANDRONUMQ_GAME_MODES 16 +#define NUM_ZANDRONUMQ_GAME_MODIFIERS 2 +#define ST_MAX_TEAMS 4U + +class GameClientRunner; +class RConProtocol; +class ZandronumqServer; + +/** + * Compares versions of Zandronumq. + */ +class ZandronumqVersion +{ +public: + ZandronumqVersion(QString version); + + unsigned short int majorVersion() const { return major; } + unsigned short int minorVersion() const { return minor; } + unsigned short int revisionVersion() const { return revision; } + unsigned int hgVersionDate() const { return hgRevisionDate; } + unsigned short int hgVersionTime() const { return hgRevisionTime; } + + bool operator> (const ZandronumqVersion &other) const; + +protected: + static const QRegExp versionExpression; + QString version; + + unsigned short int major; + unsigned short int minor; + unsigned short int revision; + unsigned short int build; + QString tag; + unsigned int hgRevisionDate; + unsigned short int hgRevisionTime; +}; + +class TeamInfo +{ +public: + TeamInfo(QString name = QObject::tr("<< Unknown >>"), QColor color = QColor(0, 0, 0), unsigned int score = 0); + + const QString &name() const { return teamName; } + const QColor &color() const { return teamColor; } + unsigned int score() const { return teamScore; } + +protected: + void setName(const QString &name) { teamName = name; } + void setColor(const QColor &color) { teamColor = color; } + void setScore(int score) { teamScore = score; } + + friend class ZandronumqServer; + +private: + QString teamName; + QColor teamColor; + unsigned int teamScore; +}; + +class ZandronumqServer : public Server +{ + Q_OBJECT + +public: + + + enum ZandronumqQueryFlags + { + SQF_NAME = 0x00000001, + SQF_URL = 0x00000002, + SQF_EMAIL = 0x00000004, + SQF_MAPNAME = 0x00000008, + SQF_MAXCLIENTS = 0x00000010, + SQF_MAXPLAYERS = 0x00000020, + SQF_PWADS = 0x00000040, + SQF_GAMETYPE = 0x00000080, + SQF_GAMENAME = 0x00000100, + SQF_IWAD = 0x00000200, + SQF_FORCEPASSWORD = 0x00000400, + SQF_FORCEJOINPASSWORD = 0x00000800, + SQF_GAMESKILL = 0x00001000, + SQF_BOTSKILL = 0x00002000, + SQF_DMFLAGS = 0x00004000, // Deprecated + SQF_LIMITS = 0x00010000, + SQF_TEAMDAMAGE = 0x00020000, + SQF_TEAMSCORES = 0x00040000, + SQF_NUMPLAYERS = 0x00080000, + SQF_PLAYERDATA = 0x00100000, + SQF_TEAMINFO_NUMBER = 0x00200000, + SQF_TEAMINFO_NAME = 0x00400000, + SQF_TEAMINFO_COLOR = 0x00800000, + SQF_TEAMINFO_SCORE = 0x01000000, + SQF_TESTING_SERVER = 0x02000000, + SQF_DATA_MD5SUM = 0x04000000, + SQF_ALL_DMFLAGS = 0x08000000, + SQF_SECURITY_SETTINGS = 0x10000000, + SQF_OPTIONAL_WADS = 0x20000000, + SQF_DEH = 0x40000000, + SQF_EXTENDED_INFO = 0x80000000, + + SQF_STANDARDQUERY = + SQF_NAME | SQF_URL | SQF_EMAIL | SQF_MAPNAME | SQF_MAXCLIENTS | + SQF_MAXPLAYERS | SQF_PWADS | SQF_GAMETYPE | SQF_IWAD | + SQF_FORCEPASSWORD | SQF_FORCEJOINPASSWORD | SQF_LIMITS | + SQF_NUMPLAYERS | SQF_PLAYERDATA | SQF_TEAMINFO_NUMBER | + SQF_TEAMINFO_NAME | SQF_TEAMINFO_SCORE | SQF_GAMESKILL | + SQF_TESTING_SERVER | SQF_ALL_DMFLAGS | SQF_SECURITY_SETTINGS | + SQF_OPTIONAL_WADS | SQF_DEH | SQF_EXTENDED_INFO, + + SQF2_PWAD_HASHES = 0x00000001, + + SQF2_STANDARDQUERY = SQF2_PWAD_HASHES + }; + + ZandronumqServer(const QHostAddress &address, unsigned short port); + + ExeFile *clientExe() override; + + GameHost *gameHost(); + GameClientRunner *gameRunner() override; + + bool hasRcon() const override { return true; } + + QList modifiers() const override; + EnginePlugin *plugin() const override; + + RConProtocol *rcon() override; + + QRgb teamColor(unsigned team) const; + QString teamName(unsigned team) const; + + PathFinder wadPathFinder() override; + +protected slots: + void updatedSlot(ServerPtr server, int response); + +protected: + bool buckshot; + bool instagib; + + float teamDamage; + + unsigned short botSkill; + + QByteArray lastReadRequest; + + unsigned short duelLimit; + unsigned short fragLimit; + unsigned short pointLimit; + unsigned short winLimit; + + unsigned int numTeams; + TeamInfo teamInfo[ST_MAX_TEAMS]; + + QString testingArchive; + + QByteArray createSendRequest(); + static unsigned int millisecondTime(); + Response readRequest(const QByteArray &data); + +private: + void resetPwadsList(const QList &wads); +}; + +#endif diff --git a/src/plugins/zandronumq/zandronumqserverdmflagsparser.cpp b/src/plugins/zandronumq/zandronumqserverdmflagsparser.cpp new file mode 100644 index 00000000..957fe13a --- /dev/null +++ b/src/plugins/zandronumq/zandronumqserverdmflagsparser.cpp @@ -0,0 +1,105 @@ +//------------------------------------------------------------------------------ +// zandronumqserverdmflagsparser.cpp +//------------------------------------------------------------------------------ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301 USA +// +//------------------------------------------------------------------------------ +// Copyright (C) 2014 "Zalewa" +//------------------------------------------------------------------------------ +#include "zandronumqserverdmflagsparser.h" + +#include "zandronumq2dmflags.h" +#include "zandronumq3dmflags.h" +#include "zandronumqgameinfo.h" +#include "zandronumqserver.h" +#include +#include + +ZandronumqServerDmflagsParser *ZandronumqServerDmflagsParser::mkParser( + ZandronumqServer *server, QDataStream *in) +{ + ZandronumqVersion version(server->gameVersion()); + if (version.majorVersion() >= 3) + return new ZandronumqServer3DmflagsParser(server, in); + return new ZandronumqServer2DmflagsParser(server, in); +} + +ZandronumqServerDmflagsParser::ZandronumqServerDmflagsParser( + ZandronumqServer *server, QDataStream *in) +{ + this->server = server; + this->inStream = in; +} + +QList ZandronumqServerDmflagsParser::sequential32Parse(const QList &knownFlags) +{ + DataStreamOperatorWrapper in(inStream); + int numSections = in.readQInt8(); + + QList result; + // Read each dmflags section separately. + for (int i = 0; i < knownFlags.count() && i < numSections; ++i) + { + quint32 dmflags = in.readQUInt32(); + + const DMFlagsSection &knownSection = knownFlags[i]; + DMFlagsSection detectedSection = knownSection.copyEmpty(); + + // Iterate through every known flag to check whether it should be + // inserted into the structure of this server. + for (int j = 0; j < knownSection.count(); ++j) + { + if ((dmflags & knownSection[j].value()) != 0) + { + detectedSection << knownSection[j]; + } + } + + result << detectedSection; + } + if (knownFlags.count() < numSections) + { + // Skip all sections we didn't read. + int remaining = numSections - knownFlags.count(); + in.skipRawData(remaining * 4); + } + return result; +} + +/////////////////////////////////////////////////////////////////////////////// + +QList ZandronumqServerNullParser::parse() +{ + DataStreamOperatorWrapper in(inStream); + int numSections = in.readQInt8(); + in.skipRawData(numSections * 4); + return QList(); +} + +/////////////////////////////////////////////////////////////////////////////// + +QList ZandronumqServer2DmflagsParser::parse() +{ + return sequential32Parse(Zandronumq2::Dmflags().flags()); +} + +/////////////////////////////////////////////////////////////////////////////// + +QList ZandronumqServer3DmflagsParser::parse() +{ + return sequential32Parse(Zandronumq3::Dmflags().flags()); +} diff --git a/src/plugins/zandronumq/zandronumqserverdmflagsparser.h b/src/plugins/zandronumq/zandronumqserverdmflagsparser.h new file mode 100644 index 00000000..c32ca89d --- /dev/null +++ b/src/plugins/zandronumq/zandronumqserverdmflagsparser.h @@ -0,0 +1,83 @@ +//------------------------------------------------------------------------------ +// zandronumqserverdmflagsparser.h +//------------------------------------------------------------------------------ +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301 USA +// +//------------------------------------------------------------------------------ +// Copyright (C) 2014 "Zalewa" +//------------------------------------------------------------------------------ +#ifndef id86E9EA04_C69C_43C1_877B45D653F448FA +#define id86E9EA04_C69C_43C1_877B45D653F448FA + +#include +#include + +class DMFlagsSection; +class ZandronumqServer; + +/** + * @brief SQF_ALL_DMFLAGS parser family. + */ +class ZandronumqServerDmflagsParser +{ +public: + static ZandronumqServerDmflagsParser *mkParser(ZandronumqServer * server, QDataStream *in); + + ZandronumqServerDmflagsParser(ZandronumqServer *server, QDataStream *in); + virtual ~ZandronumqServerDmflagsParser() + {} + + virtual QList parse() = 0; + +protected: + QDataStream *inStream; + ZandronumqServer *server; + + QList sequential32Parse(const QList &knownFlags); +}; + +class ZandronumqServerNullParser : public ZandronumqServerDmflagsParser +{ +public: + ZandronumqServerNullParser(ZandronumqServer *server, QDataStream *in) + : ZandronumqServerDmflagsParser(server, in) + {} + + QList parse() override; +}; + +class ZandronumqServer2DmflagsParser : public ZandronumqServerDmflagsParser +{ +public: + ZandronumqServer2DmflagsParser(ZandronumqServer *server, QDataStream *in) + : ZandronumqServerDmflagsParser(server, in) + {} + + QList parse() override; +}; + +class ZandronumqServer3DmflagsParser : public ZandronumqServerDmflagsParser +{ +public: + ZandronumqServer3DmflagsParser(ZandronumqServer *server, QDataStream *in) + : ZandronumqServerDmflagsParser(server, in) + {} + + QList parse() override; +}; + +#endif -- 2.25.1.windows.1