Giter Club home page Giter Club logo

gamecode's Introduction

OpenArena gamecode

Build status Codacy Badge

Description

This is the game code part of OpenArena. In mod form it is referred as OpenArenaExpanded (OAX).

Building

You need a C-compiler (tested with gcc and clang) and GNU make then just type

make

and the qvm-files will be build. Ready to be packed into a pk3-file.

See https://github.com/OpenArena/gamecode/wiki/Build-instruction for more details.

See http://openarena.wikia.com/wiki/OpenArena_eXpanded for alternative build options

Extracting entities

It is possible to extract entity definition for use with GtkRadiant and NetRadiant like this:

cd code/game
./extract_entities.sh > openarena.def

Links

Development documentation is located here: https://github.com/OpenArena/gamecode/wiki

The development board on the OpenArena forum: http://openarena.ws/board/index.php?board=30.0

In particular the Open Arena Expanded topic: http://openarena.ws/board/index.php?topic=1908.0

License

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

gamecode's People

Contributors

bishop-333 avatar devnexen avatar garux avatar guilddio avatar ldrone avatar leilei- avatar neonknightoa avatar noisebynorthwest avatar protovision avatar sago007 avatar smcv avatar technologyclassroom avatar the-gig avatar trashmacnugget avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gamecode's Issues

[Feature] UGC management system

DISCLAIMER: I personally don't think I have what it takes to actually pull this off. I need knowledge of certain areas and be more familiarized with the game's code beforehand. And it may possibly involve changes to engine as well.

A simple system to install/uninstall gamepacks from inside the game. A protected cvar would take care of the repository.

In-game you would enter to a menu, select a mod from a list of mods, click "Install", and the mod would be installed in the right folder. Likewise, with the mod installed, a simple "Uninstall" button would safely remove the mod.

My idea is closer to the "Addons" menu in the 2021 Remastered edition of Quake:

how-to-play-Quake-64

The retrieval URL would be either hard-coded into the game or cvar-controlled but in such a way that it shouldn't be easily manipulable, leading to malicious URLs downloading and installing rogue packages.

[Post-0.8.8 bug] Invisible Lightning from LG

One day, doing a run on the SP, I noticed that the Lightning Gun wasn't shooting anything but the ammo count still lowered and the marks on the walls and floors still kept being displayed.

I tested the last 2023 nightly and it still showed up.
I tested the very first nightly, it still showed up.
I tested with b52 and it still showed up.
I tested 0.8.8 and the LG behaved as normal.

So the bug may have been introduced between version 0.8.8 and one of the post-0.8.8 releases. Or perhaps it's a problem with my old config. I reset the config and the bug was gone. Still it's not a scenario that should be reproduced.

// generated by quake, do not modify
unbindall
bind TAB "+scores"
bind ENTER "+button2"
bind ESCAPE "togglemenu"
bind SPACE "+moveup"
bind + "sizeup"
bind - "sizedown"
bind 0 "weapon 10"
bind 1 "weapon 1"
bind 2 "weapon 2"
bind 3 "weapon 3"
bind 4 "weapon 4"
bind 5 "weapon 5"
bind 6 "weapon 6"
bind 7 "weapon 7"
bind 8 "weapon 8"
bind 9 "weapon 9"
bind = "sizeup"
bind _ "sizedown"
bind ` "toggleconsole"
bind a "weapon 8"
bind d "+back"
bind e "+forward"
bind f "+moveright"
bind g "weapon 5"
bind i "messagemode"
bind o "messagemode2"
bind q "weapon 10"
bind r "weapon 6"
bind s "+moveleft"
bind t "weapon 7"
bind w "weapon 11"
bind ~ "toggleconsole"
bind BACKSPACE "dropweapon"
bind PAUSE "pause"
bind CTRL "+movedown"
bind F1 "vote yes"
bind F2 "vote no"
bind F3 "ui_teamorders"
bind F11 "screenshot"
bind F12 "screenshotJPEG"
bind MOUSE1 "+attack"
bind MOUSE2 "+zoom"
bind MWHEELDOWN "weapnext"
bind MWHEELUP "weapprev"
seta cg_leiDebug "0"
seta com_pipefile ""
seta s_alInputDevice ""
seta joy_threshold "0.150000"
seta r_motionblur "0"
seta r_tvFilter "1"
seta r_tvModeForceAspect "0"
seta r_tvModeAspect "0"
seta r_virtualMode "-1"
seta r_film "0"
seta r_alternateBrightness "0"
seta r_textureDither "0"
seta r_lightmapBits "0"
seta r_iconBits "0"
seta r_iconmip "0"
seta r_slowness_gpu "96"
seta r_slowness_cpu "300"
seta r_slowness "0"
seta r_particles "0"
seta r_palletize "0"
seta r_anime "0"
seta r_suggestiveThemes "1"
seta r_retroAA "0"
seta r_ntsc "0"
seta r_detailtextureLayers "0"
seta r_detailtextureScale "0"
seta r_modelshader "0"
seta r_leifx "0"
seta r_flaresMotionBlur "0"
seta r_flareSun "0"
seta r_flaresDlightScale "0.7"
seta r_flaresDlightOpacity "0.5"
seta r_flaresDlightFade "0"
seta r_flaresDlightShrink "1"
seta r_flareMethod "0"
seta r_flareQuality "4"
seta r_ext_gamma_control "1"
seta r_ext_paletted_texture "0"
seta j_up_axis "2"
seta j_side_axis "0"
seta j_forward_axis "1"
seta j_yaw_axis "4"
seta j_pitch_axis "3"
seta j_up "1"
seta j_side "0.25"
seta j_forward "-0.25"
seta j_yaw "-0.022"
seta j_pitch "0.022"
seta sv_dlRate "100"
seta ui_browserHidePrivate "1"
seta ui_pos_timelimit "20"
seta ui_pos_fraglimit "120"
seta ui_dom_fraglimit "500"
seta ui_lms_capturelimit "20"
seta ui_harvester_fraglimit "20"
seta com_hunkMegs "128"
seta com_altivec "0"
seta com_maxfps "125"
seta com_blood "1"
seta com_ansiColor "0"
seta com_maxfpsUnfocused "0"
seta com_maxfpsMinimized "0"
seta com_busyWait "0"
seta com_introplayed "1"
seta vm_cgame "2"
seta vm_game "2"
seta vm_ui "2"
seta dmflags "0"
seta fraglimit "15"
seta timelimit "0"
seta sv_hostname "noname"
seta sv_maxclients "8"
seta sv_minRate "0"
seta sv_maxRate "0"
seta sv_minPing "0"
seta sv_maxPing "0"
seta sv_floodProtect "1"
seta sv_fps "20"
seta sv_dlURL ""
seta sv_master2 ""
seta sv_master3 ""
seta sv_master4 ""
seta sv_master5 ""
seta sv_lanForceRate "1"
seta sv_banFile "serverbans.dat"
seta cl_timeNudge "0"
seta cl_timedemoLog ""
seta cl_autoRecordDemo "0"
seta cl_aviFrameRate "25"
seta cl_aviMotionJpeg "1"
seta cl_maxpackets "30"
seta cl_packetdup "1"
seta cl_run "1"
seta sensitivity "5"
seta cl_mouseAccel "0"
seta cl_freelook "1"
seta cl_mouseAccelStyle "0"
seta cl_mouseAccelOffset "5"
seta cl_allowDownload "1"
seta cl_cURLLib "libcurl-3.dll"
seta r_inGameVideo "1"
seta cg_autoswitch "2"
seta m_pitch "0.022000"
seta m_yaw "0.022"
seta m_forward "0.25"
seta m_side "0.25"
seta m_filter "0"
seta cl_maxPing "800"
seta cl_lanForcePackets "1"
seta cl_guidServerUniq "1"
seta cl_consoleKeys "~ ` 0x7e 0x60"
seta cl_consoleType "0"
seta cl_consoleColorRed "1"
seta cl_consoleColorGreen "0"
seta cl_consoleColorBlue "0"
seta cl_consoleColorAlpha "0.8"
seta cl_consoleHeight "0.5"
seta name "^4Neon^0_^4Knight"
seta rate "25000"
seta snaps "20"
seta model "skelebot/default"
seta headmodel "skelebot/default"
seta team_model "skelebot/default"
seta team_headmodel "skelebot/default"
seta g_redTeam "Stroggs"
seta g_blueTeam "Pagans"
seta color1 "4"
seta color2 "5"
seta handicap "100"
seta sex "male"
seta cl_anonymous "0"
seta cg_predictItems "1"
seta cl_useMumble "0"
seta cl_mumbleScale "0.0254"
seta cl_voipGainDuringCapture "0.2"
seta cl_voipCaptureMult "2.0"
seta cl_voipUseVAD "0"
seta cl_voipVADThreshold "0.25"
seta cl_voipShowMeter "1"
seta cl_voip "1"
seta cg_viewsize "100"
seta r_allowExtensions "1"
seta r_ext_compressed_textures "0"
seta r_ext_multitexture "1"
seta r_ext_compiled_vertex_array "1"
seta r_ext_texture_env_add "1"
seta r_ext_texture_filter_anisotropic "1"
seta r_ext_max_anisotropy "8"
seta r_postprocess "none"
seta r_ext_vertex_shader "0"
seta r_picmip "0"
seta r_roundImagesDown "1"
seta r_detailtextures "1"
seta r_texturebits "32"
seta r_colorbits "0"
seta r_stencilbits "0"
seta r_depthbits "0"
seta r_ext_multisample "0"
seta r_overBrightBits "1"
seta r_ignorehwgamma "0"
seta r_mode "-1"
seta r_fullscreen "1"
seta r_noborder "0"
seta r_customwidth "1366"
seta r_customheight "768"
seta r_customPixelAspect "1"
seta r_simpleMipMaps "1"
seta r_subdivisions "4"
seta r_smp "0"
seta r_stereoEnabled "0"
seta r_ignoreFastPath "1"
seta r_greyscale "0"
seta r_monolightmaps "0"
seta r_lodCurveError "250"
seta r_lodbias "0"
seta r_flares "1"
seta r_zproj "64"
seta r_stereoSeparation "64"
seta r_ignoreGLErrors "1"
seta r_fastsky "0"
seta r_drawSun "0"
seta r_dynamiclight "1"
seta r_dlightBacks "1"
seta r_finish "0"
seta r_textureMode "GL_LINEAR_MIPMAP_LINEAR"
seta r_swapInterval "0"
seta r_gamma "1"
seta r_facePlaneCull "1"
seta r_railWidth "16"
seta r_railCoreWidth "6"
seta r_railSegmentLength "32"
seta r_primitives "0"
seta r_anaglyphMode "0"
seta cg_shadows "1"
seta r_marksOnTriangleMeshes "0"
seta r_aviMotionJpegQuality "90"
seta r_screenshotJpegQuality "90"
seta r_flaresDlight "0"
seta r_envMode "1"
seta r_specMode "1"
seta r_lensReflection1 "1"
seta r_lensReflection2 "0"
seta r_lensReflectionBrightness "0.5"
seta r_bloom "1"
seta r_bloom_alpha "0.3"
seta r_bloom_diamond_size "8"
seta r_bloom_intensity "1.3"
seta r_bloom_darken "4"
seta r_bloom_sample_size "256"
seta r_bloom_fast_sample "0"
seta r_bloom_cascade "0"
seta r_bloom_cascade_blur ".4"
seta r_bloom_cascade_intensity "20"
seta r_bloom_cascade_alpha "0.15"
seta r_bloom_cascade_dry "0.8"
seta r_bloom_dry "1"
seta r_bloom_reflection "0"
seta r_bloom_sky_only "0"
seta r_allowResize "0"
seta r_centerWindow "0"
seta in_keyboardDebug "0"
seta in_mouse "1"
seta in_nograb "0"
seta in_joystick "0"
seta in_joystickThreshold "0.15"
seta s_volume "0.862500"
seta s_musicvolume "0.25"
seta s_doppler "1"
seta s_muteWhenMinimized "0"
seta s_muteWhenUnfocused "0"
seta s_useOpenAL "1"
seta s_alPrecache "1"
seta s_alGain "1.0"
seta s_alSources "96"
seta s_alDopplerFactor "1.0"
seta s_alDopplerSpeed "2200"
seta s_alDriver "OpenAL32.dll"
seta s_alDevice ""
seta s_khz "22"
seta s_mixahead "0.2"
seta s_mixPreStep "0.05"
seta s_sdlBits "16"
seta s_sdlSpeed "0"
seta s_sdlChannels "2"
seta s_sdlDevSamps "0"
seta s_sdlMixSamps "0"
seta com_soundMegs "8"
seta ui_ffa_fraglimit "20"
seta ui_ffa_timelimit "0"
seta ui_tourney_fraglimit "0"
seta ui_tourney_timelimit "15"
seta ui_team_fraglimit "0"
seta ui_team_timelimit "20"
seta ui_team_friendly "1"
seta ui_ctf_capturelimit "8"
seta ui_ctf_timelimit "30"
seta ui_ctf_friendly "0"
seta ui_1fctf_capturelimit "8"
seta ui_1fctf_timelimit "30"
seta ui_1fctf_friendly "0"
seta ui_overload_capturelimit "8"
seta ui_overload_timelimit "30"
seta ui_overload_friendly "0"
seta ui_harvester_capturelimit "20"
seta ui_harvester_timelimit "30"
seta ui_harvester_friendly "0"
seta ui_elimination_capturelimit "8"
seta ui_elimination_timelimit "20"
seta ui_ctf_elimination_capturelimit "8"
seta ui_ctf_elimination_timelimit "30"
seta ui_lms_fraglimit "20"
seta ui_lms_timelimit "0"
seta ui_dd_capturelimit "8"
seta ui_dd_timelimit "30"
seta ui_dd_friendly "0"
seta ui_dom_capturelimit "500"
seta ui_dom_timelimit "30"
seta ui_dom_friendly "0"
seta g_spScores1 ""
seta g_spScores2 ""
seta g_spScores3 ""
seta g_spScores4 ""
seta g_spScores5 ""
seta g_spAwards ""
seta g_spVideos ""
seta g_spSkill "3"
seta ui_browserMaster "0"
seta ui_browserGameType "0"
seta ui_browserSortKey "4"
seta ui_browserShowFull "1"
seta ui_browserShowEmpty "1"
seta cg_brassTime "2500"
seta cg_drawCrosshair "4"
seta cg_drawCrosshairNames "1"
seta cg_marks "1"
seta server1 ""
seta server2 ""
seta server3 ""
seta server4 ""
seta server5 ""
seta server6 ""
seta server7 ""
seta server8 ""
seta server9 ""
seta server10 ""
seta server11 ""
seta server12 ""
seta server13 ""
seta server14 ""
seta server15 ""
seta server16 ""
seta ui_browserOnlyHumans "0"
seta ui_setupchecked "1"
seta net_enabled "3"
seta net_mcast6addr "ff04::696f:7175:616b:6533"
seta net_mcast6iface "0"
seta net_socksEnabled "0"
seta net_socksServer ""
seta net_socksPort "1080"
seta net_socksUsername ""
seta net_socksPassword ""
seta cg_voipTeamOnly "0"
seta cg_autovertex "0"
seta cm_playerCurveClip "1"
seta g_maxGameClients "0"
seta videoflags "7"
seta capturelimit "8"
seta g_friendlyFire "0"
seta g_teamAutoJoin "0"
seta g_teamForceBalance "0"
seta g_warmup "20"
seta g_doWarmup "0"
seta g_log "games.log"
seta g_logsync "0"
seta g_banIPs ""
seta g_filterBan "1"
seta g_respawntime "0"
seta g_allowVote "1"
seta g_maxVotes "3"
seta g_voteNames "/map_restart/nextmap/map/g_gametype/kick/clientkick/g_doWarmup/timelimit/fraglimit/shuffle/"
seta g_voteBan "0"
seta g_voteGametypes "/0/1/3/4/5/6/7/8/9/10/11/12/"
seta g_voteMaxTimelimit "1000"
seta g_voteMinTimelimit "0"
seta g_voteMaxFraglimit "0"
seta g_voteMinFraglimit "0"
seta pmove_fixed "0"
seta pmove_msec "11"
seta pmove_float "1"
seta g_delagHitscan "1"
seta g_truePing "0"
seta g_lagLightning "1"
seta g_spawnprotect "500"
seta elimination_startHealth "200"
seta elimination_startArmor "150"
seta elimination_bfg "0"
seta elimination_grapple "0"
seta elimination_roundtime "120"
seta elimination_warmup "7"
seta elimination_activewarmup "5"
seta elimination_machinegun "500"
seta elimination_shotgun "500"
seta elimination_grenade "100"
seta elimination_rocket "50"
seta elimination_railgun "20"
seta elimination_lightning "300"
seta elimination_plasmagun "200"
seta elimination_chain "0"
seta elimination_mine "0"
seta elimination_nail "0"
seta elimination_ctf_oneway "1"
seta g_awardpushing "1"
seta g_runes "0"
seta g_lms_mode "0"
seta g_catchup "0"
seta g_autonextmap "0"
seta g_mappools "0\maps_dm.cfg\1\maps_tourney.cfg\3\maps_tdm.cfg\4\maps_ctf.cfg\5\maps_oneflag.cfg\6\maps_obelisk.cfg\7\maps_harvester.cfg\8\maps_elimination.cfg\9\maps_ctf.cfg\10\maps_lms.cfg\11\maps_dd.cfg\12\maps_dom.cfg\"
seta g_floodMaxDemerits "5000"
seta g_floodMinTime "2000"
seta g_admin "admin.dat"
seta g_adminLog "admin.log"
seta g_adminParseSay "1"
seta g_adminNameProtect "1"
seta g_adminTempBan "2m"
seta g_adminMaxBan "2w"
seta g_specChat "1"
seta g_publicAdminMessages "1"
seta g_maxWarnings "3"
seta g_warningExpire "3600"
seta cg_drawGun "1"
seta cg_zoomfov "22.5"
seta cg_fov "100"
seta cg_gibs "1"
seta cg_draw2D "1"
seta cg_drawStatus "1"
seta cg_drawTimer "1"
seta cg_drawFPS "1"
seta cg_drawSnapshot "0"
seta cg_draw3dIcons "1"
seta cg_drawIcons "1"
seta cg_drawAmmoWarning "1"
seta cg_drawAttacker "1"
seta cg_drawSpeed "1"
seta cg_drawRewards "1"
seta cg_crosshairSize "24"
seta cg_crosshairHealth "1"
seta cg_crosshairX "0"
seta cg_crosshairY "0"
seta cg_simpleItems "0"
seta cg_lagometer "1"
seta cg_railTrailTime "600"
seta cg_runpitch "0.002"
seta cg_runroll "0.005"
seta cg_bobpitch ".00625"
seta cg_bobroll ".00625"
seta cg_teamChatTime "3000"
seta cg_teamChatHeight "0"
seta cg_forceModel "0"
seta cg_deferPlayers "1"
seta cg_drawTeamOverlay "1"
seta cg_drawFriend "1"
seta cg_teamChatsOnly "0"
seta cg_noVoiceChats "0"
seta cg_noVoiceText "0"
seta cg_alwaysWeaponBar "0"
seta cg_hitsound "1"
seta cg_cyclegrapple "1"
seta cg_cameraOrbitDelay "50"
seta cg_scorePlums "1"
seta cg_noTaunt "0"
seta cg_noProjectileTrail "0"
seta ui_smallFont "0.25"
seta ui_bigFont "0.4"
seta cg_oldRail "0"
seta cg_oldRocket "1"
seta cg_leiEnhancement "0"
seta cg_leiGoreNoise "0"
seta cg_leiBrassNoise "0"
seta cg_leiSuperGoreyAwesome "0"
seta cg_oldPlasma "1"
seta cg_delag "1"
seta cg_cmdTimeNudge "0"
seta cg_projectileNudge "0"
seta cg_optimizePrediction "1"
seta cg_trueLightning "0.0"
seta cg_music ""
seta cg_fragmsgsize "1.0"
seta cg_crosshairPulse "1"
seta cg_differentCrosshairs "0"
seta cg_ch1 "1"
seta cg_ch1size "24"
seta cg_ch2 "1"
seta cg_ch2size "24"
seta cg_ch3 "1"
seta cg_ch3size "24"
seta cg_ch4 "1"
seta cg_ch4size "24"
seta cg_ch5 "1"
seta cg_ch5size "24"
seta cg_ch6 "1"
seta cg_ch6size "24"
seta cg_ch7 "1"
seta cg_ch7size "24"
seta cg_ch8 "1"
seta cg_ch8size "24"
seta cg_ch9 "1"
seta cg_ch9size "24"
seta cg_ch10 "1"
seta cg_ch10size "24"
seta cg_ch11 "1"
seta cg_ch11size "24"
seta cg_ch12 "1"
seta cg_ch12size "24"
seta cg_ch13 "1"
seta cg_ch13size "24"
seta cg_crosshairColorRed "1.0"
seta cg_crosshairColorGreen "1.0"
seta cg_crosshairColorBlue "1.0"
seta cg_weaponBarStyle "0"
seta cg_weaponOrder "/1/2/4/3/6/7/8/9/5/"
seta cg_chatBeep "1"
seta cg_teamChatBeep "1"
seta g_grapple "1"
seta g_harvesterFromBodies "0"
seta g_emptyCommand "map_restart"
seta g_emptytime "0"
seta g_ddCaptureTime "10"
seta g_ddRespawnDelay "10"
seta cg_viewnudge "0"
seta cg_bob "6"
seta cg_bobmodel "0"
seta cg_kickScale "1.0"
seta cg_obituaryOutput "3"
seta cg_leiWidescreen "1"
seta cg_deathcam "1"
seta cg_cameramode "0"
seta cg_cameraEyes "0"
seta cg_modelEyes_Up "3"
seta cg_modelEyes_Right "3"
seta cg_modelEyes_Fwd "3"
seta cg_muzzleflashStyle "5"
seta missionpackChecks "1"
seta ui_ffa_scorelimit "20"
seta ui_tourney_scorelimit "0"
seta ui_team_scorelimit "0"
seta ui_ctf_scorelimit "8"
seta ui_1fctf_scorelimit "8"
seta ui_overload_scorelimit "8"
seta ui_harvester_scorelimit "20"
seta ui_elimination_scorelimit "8"
seta ui_ctf_elimination_scorelimit "8"
seta ui_lms_scorelimit "20"
seta ui_dd_scorelimit "8"
seta ui_dom_scorelimit "500"
seta ui_pos_scorelimit "120"
seta s_alCapture "1"
seta g_voteMaps "*"
seta r_vertexLight "0"
seta com_zoneMegs "24"

[OAX b53] Overload obelisk and base rendering between matches

As reported by @The-Gig in the forums

When g_obeliskRespawnDelay value <> 10, [the rendering has issues]. Steps to reproduce: devmap a map in g_gametype 6, give all, destroy the obelisk. Do tests with different values.

  • With the cvar set to 5 you can see the obelisk immediately re-appears without the "growing crystal" animation, although it isn't possible to damage it yet (The problem is you see the obelisk there, while it shouldn't be there yet).
  • With 6 you can see the animation play very fast, ending before you can actually start damaging the obelisk again. (The problem is you see the obelisk there, while it shouldn't be there yet)
  • With 15 or 20, the animation plays slowly, which is not a problem, the problem is that at the middle of the animation it "skips" the second half of it and suddenly passes to show the complete crystal (that you can damage), which isn't very nice to see.

Possible culprits:

  • This sounds like a regression. Maybe a comparison with the original TA code is in order.

Hud bug for widescreen (16:10)

The levelshot during the loading of the map and the hud are not set for widescreen.

cgs.screenXScale and cgs.screenYScale was not set correctly for widescreen, there was a fix for widescreen support in cg_drawitems that works but the one in cg_main.c cause some problems, I remove it and it fixed the issue.

cg_main.c.zip

Capture dโ€™eฬcran 2022-02-17 aฬ€ 16 28 25
Capture dโ€™eฬcran 2022-02-17 aฬ€ 16 28 09

Problem with MPUI backcode: Left and Right commands don't work as they should on menus.

Leaving this here while searching for a solution.

While working on UI3, leilei told me in Discord that the left and right commands (in both joystick and keyboard) don't work as they should. So we're tied to do menus in a single column, for example.

Looking at the code, I saw that both the left and right commands perform the same actions as the up and down commands. This is something IMHO anti-intuitive.

Piece of relevant code from code/ui/ui_shared.c; I think there's no equivalents for Menu_SetNextCursorItem(menu); and Menu_SetPrevCursorItem(menu);:

void Menu_HandleKey(menuDef_t *menu, int key, qboolean down) {
	int i;
	itemDef_t *item = NULL;

	// Changed RD
	if (DC->getCVarValue("ui_transitionkey")) {
		for (i = 0; i < menu->itemCount; i++) {
			if (menu->items[i]->window.flags & WINDOW_INTRANSITION) {
				return;
			}
		}
	}
	// end changed RD
	if (g_waitingForKey && down) {
		Item_Bind_HandleKey(g_bindItem, key, down);
		return;
	}

	if (g_editingField && down) {
		if (!Item_TextField_HandleKey(g_editItem, key)) {
			g_editingField = qfalse;
			g_editItem = NULL;
			return;
		} else if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_MOUSE3) {
			g_editingField = qfalse;
			g_editItem = NULL;
			Display_MouseMove(NULL, DC->cursorx, DC->cursory);
		} else if (key == K_TAB || key == K_UPARROW || key == K_JOY29 || key == K_JOY31 || key == K_DOWNARROW) {
			return;
		}
	}

	if (menu == NULL) {
		return;
	}

	// see if the mouse is within the window bounds and if so is this a mouse click
	if (down && !(menu->window.flags & WINDOW_POPUP) && !Rect_ContainsPoint(&menu->window.rect, DC->cursorx, DC->cursory)) {
		static qboolean inHandleKey = qfalse;
		// bk001206 - parentheses
		if (!inHandleKey && (key == K_MOUSE1 || key == K_MOUSE2 || key == K_MOUSE3)) {
			inHandleKey = qtrue;
			Menus_HandleOOBClick(menu, key, down);
			inHandleKey = qfalse;
			return;
		}
	}

	// get the item with focus
	for (i = 0; i < menu->itemCount; i++) {
		if (menu->items[i]->window.flags & WINDOW_HASFOCUS) {
			item = menu->items[i];
		}
	}

	if (item != NULL) {
		if (Item_HandleKey(item, key, down)) {
			Item_Action(item);
			return;
		}
	}

	if (!down) {
		return;
	}

	// default handling
	switch (key) {

		case K_F11:
			if (DC->getCVarValue("developer")) {
				debugMode ^= 1;
			}
			break;

		case K_F12:
			if (DC->getCVarValue("developer")) {
				DC->executeText(EXEC_APPEND, "screenshot\n");
			}
			break;
		case K_UPARROW:
			Menu_SetPrevCursorItem(menu);
			break;
		case K_JOY29:
			Menu_SetPrevCursorItem(menu);
			break;

		case K_ESCAPE:
			if (!g_waitingForKey && menu->onESC) {
				itemDef_t it;
				it.parent = menu;
				it.transitionEnd = menu->esctransitionEnd;
				Item_RunScript(&it, menu->onESC);
			}
			break;
		case K_JOY4:
			if (!g_waitingForKey && menu->onESC) {
				itemDef_t it;
				it.parent = menu;
				it.transitionEnd = menu->esctransitionEnd;
				Item_RunScript(&it, menu->onESC);
			}
			break;
		case K_TAB:
		case K_DOWNARROW:
			Menu_SetNextCursorItem(menu);
			break;
		case K_JOY31:
			Menu_SetNextCursorItem(menu);
			break;
		case K_MOUSE1:
		case K_MOUSE2:
			if (item) {
				if (item->type == ITEM_TYPE_TEXT) {
					if (Rect_ContainsPoint(Item_CorrectedTextRect(item), DC->cursorx, DC->cursory)) {
						Item_Action(item);
					}
				} else if (item->type == ITEM_TYPE_EDITFIELD || item->type == ITEM_TYPE_NUMERICFIELD) {
					if (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory)) {
						item->cursorPos = 0;
						g_editingField = qtrue;
						g_editItem = item;
					}
				} else {
					// Changed RD
					if (item->type != ITEM_TYPE_COMBO) {
						if (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory)) {
							if (item->type == ITEM_TYPE_LISTBOX) {
								if (!(item->window.flags & (WINDOW_LB_LEFTARROW | WINDOW_LB_RIGHTARROW | WINDOW_LB_PGUP | WINDOW_LB_PGDN | WINDOW_LB_THUMB | WINDOW_FOCUSDISABLE))) {
									Item_Action(item);
								}
							} else {
								Item_Action(item);
							}
						}
					}
					// end changed RD
				}
			}
			break;

			//		case K_JOY1:
			//		case K_JOY2:
			//		case K_JOY3:
			//		case K_JOY4:
		case K_AUX1:
		case K_AUX2:
		case K_AUX3:
		case K_AUX4:
		case K_AUX5:
		case K_AUX6:
		case K_AUX7:
		case K_AUX8:
		case K_AUX9:
		case K_AUX10:
		case K_AUX11:
		case K_AUX12:
		case K_AUX13:
		case K_AUX14:
		case K_AUX15:
		case K_AUX16:
			break;
		case K_JOY1:
		case K_KP_ENTER:
		case K_ENTER:
			if (item) {
				if (item->type == ITEM_TYPE_EDITFIELD || item->type == ITEM_TYPE_NUMERICFIELD) {
					item->cursorPos = 0;
					g_editingField = qtrue;
					g_editItem = item;
				} else {
					Item_Action(item);
				}
			}
			break;
	}
}

How can this be solved?

[OAX b53] Capturelimit affecting Fraglimit-based gametypes.

Straightforward, and leaving this here so we don't confuse it with #267.

  • Open a match in any fraglimit-based gametype.
  • Set fraglimit to 10 and timelimit to 0. Additionally: set capturelimit to 5.
  • Expected result: Match ends when fraglimit (NOT capturelimit) hit.

[Feature] Tell players about missing objective entities

The idea is this: checking whether a map is lacking required entities and clearly inform players that the current gametype cannot be played there, like writing "Neutral flag missing, unable to play Oneflag mode in this map!" in the middle of the screen. So people will stop running around the whole map searching for something that isn't there because the mapper forgot to add it or because the server admin "disabled" it.
Maybe a good "reminder" for map authors, too.

IIRC, there are a few warnings in console in a few gametypes (something similar to "Warning: Oneflag without white flag", I don't remember exactly), but I fear they are incomplete and I'm unsure whether they are shown in players' console, server console or both (should be both, I guess). They have the advantage of being able to handle multiple missing entities by just printing a couple of lines in console, but aren't very noticeable. I think one might kepp both the console warnings and a big message for players (existing console warnings should be checked and completed).

About how to manage multiple missing entities in the middle of the screen message, I'm not sure. Just naming the first one (like it says you miss the red flag, then you recompile the map with the white flag and then it says you miss the blue one)? Or just a generic "Required objective entities missing, unable to play <gametypename> in this map!"?

To sum up, if I'm not mistaken:

  • Gametype 4 (ctf) should warn in case of missing red or blue flags.
  • Gametype 5 (oneflag) should warn in case of missing red/blue/neutral flags.
  • Gametype 6 (overload) should warn in case of missing red/blue obelisks.
  • Gametype 7 (harvester) should warn in case of missing red/blue/neutral obelisks. If only neutral obelisk is missing, the message should be something like "Neutral oblisk is missing. It is still possible to play in this map by enabling g_harvesterFromBodies." (which however isn't something players can do online, unless server admin created Custom Votes for that).
  • Should Gametype 9 (eCTF) "warn big" in case of missing red or blue flags, or only "warn small"? You can still play and win it like classic Elimination by just fragging the other team members, although you see messages like "RED flag has return" despite being no flag. But again, if people search for flags around the map, they may search forever. So, I don't know.
  • Gametype 11 (DoubleDom) should warn in case of missing red/blue flags.
  • Gametype 12 (Dom) should warn in caso of missing Dom points.
  • Gametype 13 (Pos) probably doesn't need to warn anything, as it automatically uses neutral flag, dom points or player spawn points depending from what it finds available.

[OAX b53] Bot chat problem

As described by @The-Gig in the OA Discord:

I was doing one test in Elimination mode and a bot, MAjor, my teammate, said in team chat "I'm defending the .". I had just fired a few shots towards her, but maybe it was just a coincidence, as in the following rounds I tried shooting at her again and she said nothing.

Possible culprits: the bot reporting feature in ai_cmds.c

Disable obituary output to console

Playing a game of insta ctf mod, frag messages appear in small intervals, clogging the console and making the chat history unreadable. The same probably applies to deathmatch mode.

I am thinking of implementing a variable cg_fragmsgoutput [0|1], zero disabling the output of obituary messages to console. The frag message would still appear on the hud (upper left corner).

[OAX b53] Too many "map.info not found"

This one is straightforward. When opening a map, you get tons of this kind of messages, which really are only relevant for mappers.

Instead of informing the players about the missing .info files, restrict the message to developer mode.

[Feature] Additional in-game announcer feedback

Some of the ideas I was toying with in a now-deleted announcer branch. I'll write them here so I remember to properly implement them:

  • New cvar: cg_customAnnouncer: allows the usage of a, well, alternate announcer to that of main OA. It can also be set to 0 in order to disable announcements.
  • New cvar: cg_announcePowerups: 10 seconds prior to the respawning of a holdable or timed powerup, the announcer will proclaim "[Powerup] is about to respawn"
  • Countdown feedback extended from 3 to 10
  • Capturelimit feedback: "Three captures left/Two captures left/One capture left". Won't work if capturelimit <= 3.
  • For Double Domination: "Blue Team Dominates!" and "Red Team Dominates!" whenever both points are under control of a team, much like UT2003/2004.
  • For Overload: "Blue/Red/Your/The Enemy Obelisk is under attack!", "Blue/Red/Your/The Enemy Obelisk is at 50%" (right at 50%), "Blue/Red/Your/The Enemy Obelisk is Critical!" (10% or below), "Blue/Red/Your/The Enemy Obelisk has been Destroyed!"
  • Spectator-specific announcements:
    • "Lead Switch" any time there's a lead change in FFA-based gametypes.
    • "The Blue/Red Team has the Red/Blue Flag" for CTF/eCTF.
    • "The Blue/Red Team has the Flag" for 1FCTF.
    • "The Flag has Returned/been Taken/Dropped" for Possession.
    • "You Are Attacking/Defending" and "Red/Blue Team is on Offence" for eCTF in AvD mode.

Too bad for main OA announcer many of these can't be done. :(

Dead animation does not always play

Some bug have slipped in there the dead animation does not always play. This can even happen to yourself if using cg_deathcam. I have not yet been able to reproduce it consistently and have no idea what causes it. At first I thought it was caused by a partially implemented animation system but the code did not suggest such.
oa_dead_player_is_not_dead

[Glitch] Firing lightning/gauntlet from dead body in Elimination/ECTF modes.

As requested, I open a new "issue" for this.
For some reason, in Elimination/ECTF the lightning gun and the gauntlet can still be viewed/heard firing after you're died in Elimination and Elimination CTF modes. I don't know why it seems to affect only these two weapons.

In OA 0.8.x gamecode it was more annoying, as there you could keep firing the lightining gun from your dead body for some time even after the new "inactive" warmup has started and you were hence spectating around the map.
A recent backport (#92) of an ioquake3 fix (ioquake/ioq3@f717a839) partially fixed the issue, as with current nightly gamecode build the lightning gun stops firing when the new inactive warmup starts. But the lightning gun and the gauntlet can still "fire" for the time your camera is fixed above your corpse.

Steps to reproduce:

  1. Load a map in g_gametype 8 or 9. Choose a map where bots will easily find you, e.g. am_galmevish.
  2. Set "elimination_" cvars to be sure you have lightning gun ammo. I suggest to remove rockets, grenades and railgun to minimize the chances of being gibbed.
  3. Add a bot in a team, and join the other one (make 1 vs 1 teams).
  4. Switch to the lightning gun or gauntlet, and start shooting when you have low health. Let the bot kill you and continue firing. You will see/hear your weapon firing from your corpse.

Doing these tests again, I noticed some things:

  • It doesn't affect LMS mode. In LMS mode when you get killed, your weapon disappears (like it's "dropped", despite not being a real drop).
  • If there are more players in your team, the problem happens only if you are the last player of your team to be fragged: if you are not the last one, the weapon disappears from your hands as soon as you get fragged (like it happens in LMS mode).

This suggests two things:

  1. The gravity of the issue is probably less than expected.
  2. The issue might be caused by "round ending" preventing some "(sort of?) weapon-drop" routine from running properly, so your dead body has still got a weapon in its hand, while it shouldn't.

Other:

  • My original forum post from 2010: http://openarena.ws/board/index.php?topic=3578.msg33231#msg33231. That seems to be like from some other team-based mode with g_elimination 1 as somehow I respawned and fired lightning before the corpse disappeared, but I haven't been able to reproduce (I tried TDM with g_elimination 1 and the weapon disappeared when I got fragged). Who knows!

[Feature] Mutant/Overdose mode for Possession

Leaving this here so I remember details.

This is an option for Possession mode, as it's the mode that seems to fit the best. Basically, upon picking up the white flag, the flag carrier automatically gains Quad Damage/Invulnerability/Battle Suit/Regeneration/Haste until they die. The inspirations for this option are, of course, Unreal Tournament 2003/2004's Mutant and Unreal Championship 2's Overdose gametypes. Fragging the flag carrier gives 10 points to the killer.

The actual cvar could be g_possessionMutant, g_possessionOverdose or g_possessionSuperPowerMode.

Options?

&1 enables the mode, giving all powerups.
&2 enables the mode, giving just one of five powerups at random.
&4 enables the mode, giving a time limit for the flag carrier. Upon reaching this time limit, the flag carrier dies and the flag is dropped.

As &1 and &2 basically overlap, when the cvar acquires the values 3 and 7, the Flight powerup (or a holdable) is instead added to the Powerup pool.

So the resulting values may give the following effects:

  1. Default mode.
  2. Carrier gains all powerups on flag pickup.
  3. Carrier gains one of five powerups at random on flag pickup.
  4. Carrier gains all powerups + Flight on flag pickup.
  5. Carrier has a time limit on flag pickup.
  6. Carrier gains all powerups on flag pickup and has a time limit.
  7. Carrier gains one of five powerups at random on flag pickup.
  8. Carrier gains all powerups + Flight on flag pickup and has a time limit.

Is it dead?

Hi,

I was a great fan of Open Arena but it seems to be dead. No new downloads on the official site, problems with the resolution and frame rate (especially on Linux), ...

Is it officially dead?

Decomposing BotMapScripts (game/ai_dmq3.c)

On trying to split this piece of code from ai_dmq3.c...

/*
==================
BotMapScripts
==================
 */
void BotMapScripts(bot_state_t *bs) {
	char info[1024];
	char mapname[128];
	int i, shootbutton;
	float aim_accuracy;
	aas_entityinfo_t entinfo;
	vec3_t dir;

	trap_GetServerinfo(info, sizeof (info));

	Q_strncpyz(mapname, Info_ValueForKey(info, "mapname"), sizeof (mapname));

	if (Q_strequal(mapname, "q3tourney6") || Q_strequal(mapname, "q3tourney6_ctf") || Q_strequal(mapname, "mpq3tourney6")) {
		vec3_t mins = {694, 200, 480}, maxs = {968, 472, 680};
		vec3_t buttonorg = {304, 352, 920};
		//NOTE: NEVER use the func_bobbing in q3tourney6
		bs->tfl &= ~TFL_FUNCBOB;
		//crush area is higher in mpq3tourney6
		if (Q_strequal(mapname, "mpq3tourney6")) {
			mins[2] += 64;
			maxs[2] += 64;
		}
		//if the bot is in the bounding box of the crush area
		if (bs->origin[0] > mins[0] && bs->origin[0] < maxs[0]) {
			if (bs->origin[1] > mins[1] && bs->origin[1] < maxs[1]) {
				if (bs->origin[2] > mins[2] && bs->origin[2] < maxs[2]) {
					return;
				}
			}
		}
		shootbutton = qfalse;
		//if an enemy is in the bounding box then shoot the button
		for (i = 0; i < level.maxclients; i++) {

			if (i == bs->client) continue;
			//
			BotEntityInfo(i, &entinfo);
			//
			if (!entinfo.valid) continue;
			//if the enemy isn't dead and the enemy isn't the bot self
			if (EntityIsDead(&entinfo) || entinfo.number == bs->entitynum) continue;
			//
			if (entinfo.origin[0] > mins[0] && entinfo.origin[0] < maxs[0]) {
				if (entinfo.origin[1] > mins[1] && entinfo.origin[1] < maxs[1]) {
					if (entinfo.origin[2] > mins[2] && entinfo.origin[2] < maxs[2]) {
						//if there's a team mate below the crusher
						if (BotSameTeam(bs, i)) {
							shootbutton = qfalse;
							break;
						} else if (bs->enemy == i) {
							shootbutton = qtrue;
						}
					}
				}
			}
		}
		if (shootbutton) {
			bs->flags |= BFL_IDEALVIEWSET;
			VectorSubtract(buttonorg, bs->eye, dir);
			vectoangles(dir, bs->ideal_viewangles);
			aim_accuracy = trap_Characteristic_BFloat(bs->character, CHARACTERISTIC_AIM_ACCURACY, 0, 1);
			bs->ideal_viewangles[PITCH] += 8 * crandom() * (1 - aim_accuracy);
			bs->ideal_viewangles[PITCH] = AngleMod(bs->ideal_viewangles[PITCH]);
			bs->ideal_viewangles[YAW] += 8 * crandom() * (1 - aim_accuracy);
			bs->ideal_viewangles[YAW] = AngleMod(bs->ideal_viewangles[YAW]);
			//
			if (InFieldOfVision(bs->viewangles, 20, bs->ideal_viewangles)) {
				trap_EA_Attack(bs->client);
			}
		}
	}
}

Into this:

/*
==================
BotMapScripts
==================
 */
void BotMapScripts(bot_state_t *bs) {
	char info[1024];
	char mapname[128];

	trap_GetServerinfo(info, sizeof (info));

	Q_strncpyz(mapname, Info_ValueForKey(info, "mapname"), sizeof (mapname));

	if (Q_strequal(mapname, "q3tourney6") || Q_strequal(mapname, "q3tourney6_ctf") || Q_strequal(mapname, "mpq3tourney6")) {
		vec3_t mins = {694, 200, 480}, maxs = {968, 472, 680};
		vec3_t buttonorg = {304, 352, 920};
		//NOTE: NEVER use the func_bobbing in q3tourney6
		bs->tfl &= ~TFL_FUNCBOB;
		//crush area is higher in mpq3tourney6
		if (Q_strequal(mapname, "mpq3tourney6")) {
			mins[2] += 64;
			maxs[2] += 64;
		}
		if (BotScript_EnemyIsAtLocation(bs,mins,maxs)) {
			BotScript_ShootAt(bs,buttonorg);
		}
	}
}

/*
==================
BotScript_ShootAt
Tells a bot where to shoot at.
==================
 */
void BotScript_ShootAt(bot_state_t *bs, vec3_t target)
{
	float aim_accuracy;
	vec3_t dir;

	bs->flags |= BFL_IDEALVIEWSET;
	VectorSubtract(target, bs->eye, dir);
	vectoangles(dir, bs->ideal_viewangles);
	aim_accuracy = trap_Characteristic_BFloat(bs->character, CHARACTERISTIC_AIM_ACCURACY, 0, 1);
	bs->ideal_viewangles[PITCH] += 8 * crandom() * (1 - aim_accuracy);
	bs->ideal_viewangles[PITCH] = AngleMod(bs->ideal_viewangles[PITCH]);
	bs->ideal_viewangles[YAW] += 8 * crandom() * (1 - aim_accuracy);
	bs->ideal_viewangles[YAW] = AngleMod(bs->ideal_viewangles[YAW]);
	//
	if (InFieldOfVision(bs->viewangles, 20, bs->ideal_viewangles)) {
		trap_EA_Attack(bs->client);
	}
}

/*
==================
BotScript_EnemyIsAtLocation
Returns true if an enemy is inside of a location.
==================
 */
qboolean BotScript_EnemyIsAtLocation(bot_state_t *bs, vec3_t boxStart, vec3_t boxEnd)
{
	int i;
	aas_entityinfo_t entinfo;

	if (bs->origin[0] > boxStart[0] && bs->origin[0] < boxEnd[0]) {
		if (bs->origin[1] > boxStart[1] && bs->origin[1] < boxEnd[1]) {
			if (bs->origin[2] > boxStart[2] && bs->origin[2] < boxEnd[2]) {
				return qfalse;
			}
		}
	}

	//if an enemy is in the bounding box then shoot the button
	for (i = 0; i < level.maxclients; i++) {
		if (i == bs->client) continue;
		//
		BotEntityInfo(i, &entinfo);
		//
		if (!entinfo.valid) continue;
		//if the enemy isn't dead and the enemy isn't the bot itself
		if (EntityIsDead(&entinfo) || entinfo.number == bs->entitynum) continue;
		//
		if (entinfo.origin[0] > boxStart[0] && entinfo.origin[0] < boxEnd[0]) {
			if (entinfo.origin[1] > boxStart[1] && entinfo.origin[1] < boxEnd[1]) {
				if (entinfo.origin[2] > boxStart[2] && entinfo.origin[2] < boxEnd[2]) {
					//if there's a team mate below the crusher
					if (BotSameTeam(bs, i)) {
						return qfalse;
						break;
					} else if (bs->enemy == i) {
						return qtrue;
					}
				}
			}
		}
	}
	return qtrue;
}

I get lots of warnings and sometimes errors.

What may I be doing wrong?

Are the game assets, models, textures open source?

Sorry to ask here, but the forums are closed :(

I'm wanting to use the models, textures for another Q3 engine based game mod. But I'm not sure if they are open source. Wanted to ask, so I know if I'll have to make stuff myself or if I'll be able to use these and modify them a bit to save time.

Thanks

[Small issue] If you pause bots, they get disconnected due to inactivity.

Description:
This is just a small issue because it's only relevant to a few development/testing scenarios, however I write it down anyway, as it actually happened to me while doing a few tests.
If you "pause" bots, they will be "disconnected" after three minutes, due to inactivity. In case you are doing some testing which requires to keep them quiet, stationary and unaggressive for a long time, this can be a problem.

How to reproduce:

  • load a map with devmap [mapname]
  • add one or more bots
  • bot_pause 1
  • wait three minutes (you can speed up things by tweaking timescale value)
  • see bots disconnect with "timed out" in console.
    UPDATE: It looks like the above happens with non-team-based modes (I tested gametype 0): in team-based modes (I tested 3, 5 and 8) the bot disconnects earlier (like one minute and half?) and with "server command overflow" in console instead of "timed out".

Suggested behavior:
I guess the inactivity check routine should verify whether the client is a bot, and whether bot_pause<>0: if both are true, the client should not be disconnected, assuming that there is a developer/tester which is purposedly testing something.
Or maybe just ignore bots at all?

Harvester bug: flags becoming skulls!

Hi! I just noticed a couple of bugs in Harvester (g_gametype 7).

The first one is so insignificant that maybe it isn't worth a dedicated "issue"... if you start a match and suicide with /kill immediately afterwards, the skull/cube of your death doesn't spawn, then for later suicides it seems to start working correctly. I'm not sure if sometimes it may happen also later or not, however at the start of the match is clearly visible, especially if you are alone in the server.

The second one is a bit more worrisome: for some reason, you can grab red/blue/white flags as if they were skulls/cubes: if you run over one of them, you can see your "owned skull counter" in lower right corner goes up 1 (and in thirdperson you can see a skull following you), so if you then go to the enemy obelisk, you can score even if you are the only player in the game.
Although the white flag is automatically hidden in this gametype, it can still be touched and collected as a skull.
It happens only once per match, as the flags don't respawn.

So, for the moment, it's important that map designers use gametype/!gametype keys to prevent red/blue/neutral flag from spawning in harvester mode.
I guess for a server admin/local player point of view, the current workaround would be to temporarily
set disable_team_CTF_redflag 1
set disable_team_CTF_blueflag 1
set disable_team_CTF_neutralflag 1
just before loading a map suffering the problem in harvester, and then unset them to do not break the rest of the game.

[Feature] "dropweapon" command

This is a feature highly used in team games in competitive settings. It's also present in almost every other big name FPS, so it deserves an open thread.

I've tried porting it from both Aftershock and Ratmod, but it's too big of a job. -.- That, or I was really tired when I tried this.

In addition, I've observed both mods have flags regarding what players are allowed to throw, since they can also throw game objectives, items, and other stuff. Indeed, with the addition of dropweapon there should be a cvar that regulates what can be thrown. The commands will still be functional by default, as it makes no sense to be able to bind a key that does nothing.

[WIP] Refactoring the Missionpack/UI3 code

Leaving here as a reminder note, since @sago007 mentioned once (I think it was on the forums) that's a thing that must be done. Taking a look at the code in ui/ (not q3_ui/, which is the classic but hardcoded Q3 menu) it's not hard to see why.

[Feature] Bot-less "race" mode (DeFRaG, DPM)

Writing this here so I don't forget to figure out how to implement it. If someone else wants to implement it, they're welcome.

This is a gametype not meant for online play, but rather for tutorial/improvement purposes.

The player starts alone in a map, and must reach the end of the stage in the shortest time as possible. If a "Tutorial mode" switch is set, the player will be greeted with a hint or set of hints on how to reach the end of the level; "Tutorial mode" will also disable the timer so the player won't get pressured.

As for limits, only end of race and (if "Tutorial mode" is disabled) time limit.

[BUG] Accuracy overlay shows wrong values for Nailgun

It's possible to bind "+acc" command to a key in order to get an "Accuracy overlay" shown while holding that key.
Example /bind l "+acc" will make the table show when you will be holding the "l" key.

But the percentages shown for Nailgun are clearly wrong. You may fire a single shot at close range and then see a 600% accuracy for that weapon, which makes no sense. I mean, if one or more nails of a single shot hit, you should consider it 1 hit/1 shot; if no nails hit, you should consider 0 hit/1 shot.

Maybe the problem could be somehow related to the fact that a single Nailgun shot actually fires 15 nails, which reach the target at different times.

Considerations:

  • Wondering whether "Accuracy" medal (which is single player deathmatch only, which is earned if you land more than 50% of shots) calculations are affected, too. Harder to test, I fear... By the way, considering Accuracy Overlay does not consider Gauntlet and Proximity Mines, I wonder whether Accuracy Medal considers them or not.
  • Shotgun seems to do not have the same issue. Considering that's an hitscan (instant hit) weapon, I guess the code is quite different.
  • While doing the testing, be aware that to update the stats shown there, you have to release and push the button again, as the table is not updated automatically. IDK if that's on purpose to be able to see the stats of a "static" moment instead of ever-changing values or to prevent excessive computational work... or just an overlook. Thinking about it, if the table would have been updated automatically, people would have been able to enable/disable the overlay by typing /+acc and /-acc in console, which may have been nice, although not really definitive anyway (just a simple vid_restart would have disabled it again).

shot0247

Printing vote text in console?

Hello.
When someone asks for a vote, it's possible to notice that the console doesn't show the text of the vote, hence it's not logged, while it may be an interesting info for admins managing servers (you cannot know what has been voted for, especially if the vote failed). What about adding it?
I don't know whether it would be a gamecode or engine thing, but I can guess the voting code should be in gamecode... (well, maybe one may "intercept" votes from engine to apply the change also to old mods, but probably that would be a more "hacky" thing, probably not worth it).

Note: in case of custom votes (http://openarena.wikia.com/wiki/Custom_votes), I don't know if it would be better to show "votecommand", "displayname" or "command" value, probably "displayname".

`pmove_float` causes acceleration on slick with no user input.

Go to a map that has slick, such as psidm7 or dfwc2017-6.

Set these settings:

pmove_float 0
pmove_fixed 1

Step on the slick. Nothing of interest happens.

pmove_float 1
pmove_fixed 0

Step on the slick. You begin to slowly accelerate.

I see one call to trap_SnapVector in the code, so my guess is that this bug is present in Q3 as well, but hidden by snapping.

[Classic UI] cg_weaponBarStyle issues

While trying to document cg_weaponBarStyle, I've found some issues with this command. These shots and the test were done with the most recent nightlies. Admittedly, they take place with classic UI, but... they're still bugs, so I'm reporting them.

  • cg_weaponBarStyle 2 and 4 behave the same. The code seems to be different in both cases, but in-game they have the same effect (they draw the available weapons at the left with the same properties, no apparent difference). Likewise with 5 and 7.
  • cg_weaponBarStyle 2, 3 and 4 aren't drawn at the very left, obstructing some of the screen.

cg_weaponBarStyle 2

cg_weaponBarStyle 3

[Feature] "Advanced Options" menu for Skirmish/Create Server in Classic UI

This one I'll add so we can declutter the options page, as OA now has plenty of options and there isn't space for everything. Only score, time, and round time limits will remain. Everything else will be moved to this screen.

What will it contain?

  • Enable/Disable Grappling Hook
  • Weapon Rulesets
  • Physics Rulesets
  • Vampire mode
  • Regeneration mode
  • Gametype-specific cvars

[BUG] Warmup feature completely breaks some gametypes

Hi, a guy pointed out to me a bug with Possession mode, as he reported to me that the score count didn't go up when someone was holding the flag. I wasn't able to reproduce his bug at first, but then he discovered it happened in case g_dowarmup was enabled.
So, now I can confirm the bug is there.

If you start a Possession match (g_gametype 13) in OAX with g_dowarmup 1, "waiting for players" text is displayed all the time even if there are some bots in the map and score remains at 0. Your g_warmup time does not seem to make any difference. If you set g_dowarmup back to 0 and then restart the map, "waiting for players" disappears and people can actually score.

Long story short: Possession doesn't work if warmup is enabled.

(Update: it also affects some other gametypes, see later messages.)

[Feature] g_elimination_enableItems

Idea taken from this post on the OA forums. After getting used to the code, it shouldn't be that different, plus we have already an antecedent of a similar gamemode working, and it's Unreal Tournament 4's (Team) Showdown mode. I've also opened a similar thread however I'm not sure about picking up a spawnpoint before the round begins.

Implementation would be similar to Sago's suggestion: a single bitflag cvar.
g_elimination_enableItems & 1 (ELIMINATION_ITEMS_ENABLEWEAPONS) = enable weapons
g_elimination_enableItems & 2 (ELIMINATION_ITEMS_ENABLEHEALTHARMOR) = enable health/armor
g_elimination_enableItems & 4 (ELIMINATION_ITEMS_ENABLEPOWERUPS) = enable powerups/holdables

[Feature] Halftime option for CTF, 1FCTF, Harvester and Overload.

The mode is better explained by how Unreal Tournament 4 handles it. The time limit is divided in two halves, with a short halftime in the middle. In the second half, members of both teams switch sides, red team members play in the blue half and viceversa.

The obvious benefit this approach has is that it allows asymmetrical CTF maps to become viable.

In OpenArena this could be implemented in the non-round, base-based modes such as CTF, 1FCTF, Harvester and Overload. Round-based modes such as Elimination, eCTF and Double Domination won't benefit from this as much.

Failed to load the native uix86_64.so when I execute the supermake_native script.

the log is following:

Try loading dll file /home/suijingfeng/.local/share/OpenArena/oax/uix86_64.so
Loading DLL file: /home/suijingfeng/.local/share/OpenArena/oax/uix86_64.so
Sys_LoadGameDll(/home/suijingfeng/.local/share/OpenArena/oax/uix86_64.so) failed to find vmMain function:

"Failed loading vmMain: /home/suijingfeng/.local/share/OpenArena/oax/uix86_64.so: undefined symbol: _vmMain" !
Failed loading dll, trying next
Loading vm file vm/ui.qvm...
File "vm/ui.qvm" found in "/home/suijingfeng/.local/share/OpenArena/oax/oax.pk3"
...which has vmMagic VM_MAGIC_VER2
Loading 1604 jump table targets
VM file ui compiled to 795835 bytes of code
ui loaded in 1857280 bytes on the hunk

can be fixed by add Q_EXPORT at the front of vmMain function, https://github.com/OpenArena/gamecode/blob/master/code/q3_ui/ui_main.c

[Bug] Bots won't attack the enemy obelisk in Overload.

Leaving this here so I remember to take care of it and see what's causing the issue. Probably a piece of code enclosed in a rogue #ifdef or something like that.

Basically, the bots get stuck in front of the enemy obelisk while attacking. Found this bug while testing the spectator-specific announcer lines in #123.

EDIT: This happens in maps where the obelisk doesn't fall to the ground.

cvar name not consistency

Engine part of OA using a cvar named as com_hunkMegs but the gamecode part using com_hunkmegs,
not sure if this could cause problems.

code/q3_ui/ui_video.c: trap_Cvar_SetValue( "com_hunkmegs", 128 );

./code/qcommon/common.c: cvar_t* cv = Cvar_Get( "com_hunkMegs", DEF_COMHUNKMEGS_S, CVAR_LATCH | CVAR_ARCHIVE );

[Feature] FreezeTag mode as an option for Elimination

Related thread: http://openarena.ws/board/index.php?topic=5440.0

I have worked in the past on porting the Freezetag mod to OA code, though I've lost a bit of momentum and will due to the FT code itself not being GPL'd, and scrapped the whole thing.

Basics of FreezeTag (as a gamemode):

  • Round-based, team-based mode (so everything that can affect Elimination and/or CTF Elimination is fair game for FT)
  • Players get frozen instead of killed by weapon fire.
    • Level hazards (lava, slime, void... even water?) kill players as usual.
    • Frozen players are displayed with a shader covering the entirety of their body (leilei did a frozen shader some days ago).
    • In CTF Elimination, frozen players drop the flag.
  • Unlike dead players, frozen players can be thawed either on their own (1 HP/s) or with nearby teammates (5 HP/s).
    • A frozen player is thawed once they reach 100 HP/s.
    • Their arsenal is kept intact and they start from the player they were when frozen.
    • Alternatively, players slowly regenerate health (1 HP/s), but have a separate meter indicating the level of thawing (0%..100%). Nearby teammates thaw 5%, regular thawing is 1%. This is more complicated that the HP approach, though.
  • Scoring is the same as in Elimination/eCTF. Perhaps as a motivation, players willing to freeze teammates get score (1 point per second) based on the amount of time spent thawing teammates?

Proposed implementation in OA:

  • Due to OA already having a lot of gamemodes, it could be implemented instead as an option for Elimination and eCTF. (Using a cvar like elimination_freezetag) Therefore the main check should be G_IsARoundBasedGametype() && G_IsATeamBasedGametype.
  • Cvars elimination_ftThawTime and elimination_ftAlliedThawTime determining how much HP the frozen players restore on their own and with teammates.
  • HUD:
    • New center messages: has frozen you!, is thawing you, You have been thawed!.
    • New obituaryOutput messages: has been frozen, has been frozen, has been thawed**, has been thawed, .

In theory, this should require few lines of code. However, there's a lot

[Feature] Optional Dodging?

Hello, just dropping here a random idea which crossed my mind. I'm not saying it's a good idea, it's just an idea.
I don't even remember whether someone already proposed it in the past or not.

What about an optional "dodging" feature? Like in UT99, you could double press a direction to perform a sort of lateral jump towards that direction, in order to quickly evade an incoming attack.

I can imagine a way younger me thinking "Oh, cool!" when UT99 tutorial told me about that feature. I have to admit I don't remember how often I actually used it in-game, though!

It's years I don't play UT99, so I don't remember whether it has got a cooldown time or how it works when you are already moving at fast speed... And speed in OA can become very high.... Maybe we should only allow that if your horizontal speed is slower or equal to a certain percentage of g_speed (80%? 100%? 120% 150%? 200%? IDK)? Or maybe after a certain percentage of g_speed, the resulting movement should become diagonal? I don't know.

By the way, I'm just asking for the simple "dodging" feature, not for other advanced stuff like sliding, wall jumping, double jumping, wall running or else. I remember a few years ago I tried the -unfortunately unfinished- Unreal Tournament reboot (https://en.wikipedia.org/wiki/Unreal_Tournament_(cancelled_video_game)), and I had an hard time trying to memorize all the advanced controls. I'm not 20 anymore...
However, while dodging might be the only thing I could be able to handle comfortably, I guess it might be like g_advancedControls 1 as a bitfield so one might theoretically add other advanced movement features in the future and enable/disable them individually.

I repeat, this is just a random idea. I don't know whether it might be good or not. The only thing I know for sure is that I would want it as optional, as it adds a mechanic that could change the way the game is played and how some maps are meant to be played.

One big potential issue one should consider before adding new movement features would be characters animations. In the case of dodging, I guess the usual jump animations may fit.

[Feature] Elimination warmup time to behave more like Duel

I'm a bit confused about how this works, so I can't get a clear idea on how to implement it. Maybe with mods that actually implemented the feature as intended I can get an idea clearer enough to make a proper decision and a proper implementation.

Here are some comments made by ::: about this feature:

to make it behave like in Duel, so you could control yourself when to respawn. meaning respawn during warmap and respawn into spec during game

well, during a warmup, when you were fragged, you could press fire button very fast, respawn fast and have a chance to warm up for some more time. or you could chose not to come back to warm up and sit in this limbo mode the whole warm up till when the round starts. as for "during a round", when you were fragged, you could just press fire button immediately and get into spec mode as fast as possible, not seeing how an enemy butchers your gibs. or you can chose to stay in this limbo mode kinda frozen up for a bit longer and see how the game continues from the place you were fragged, and go to spec later. should not affect the time of initial entering a game round. everybody enter the same time. the point being - to control how fast you can respawn during a warmup and how fast you go into spec after you were fragged during the game. now this time in elimination mode is fixed and can be set by e.g. a mod to be 5 or 10 seconds or whatever, but would be nice to be able to control this time by yourself. by "going into spec mode" i mean when you are fragged and waiting, spectating, till next round starts

[Feature] Using the player/bot counts from the `.info` files.

With the success of the implementation of fraglimit, timelimit, special and mpBots (bots) into the SP, I'm figuring out other ways to implement the rest of the .info fields into the game so they actually matter.

We have these unimplemented fields to work with:

  • redBots: bot list for the red team.
  • redBotCount: number of random bots to be summoned in the red team.
  • blueBots: bot list for the blue team.
  • blueBotCount: number of random bots to be summoned in the blue team.
  • mpBots: the aforementioned bot list.
  • mpBotCount: random number of bots to be summoned in the match.
  • teamBotCount: for those occasions where you want an exact amount of bots per team. redBotCount and blueBotCount may not be equal, after all. (Could be fun for challenges)

We also have these:

  • minPlayers, maxPlayers and recommendedPlayers: More than enforced limits, these are suggested player limits. A map supporting 2-8 players has a minPlayers of 2 and a maxPlayers of 8. However, the map may not exactly recommend 4 as its recommendedPlayers if the mapper wishes to do so. These should be used for team-agnostic games (FFA, LMS, POS, etc...)
  • Likewise we have minTeamSize, maxTeamSize and recommendedTeamSize for team games, which instead control how many players should be in a team.

So, where to implement these?

We have bot_autominplayers, but I need to inspect this cvar better.
We can start supporting other gametypes in Classic SP or have an alternate SP where we can mix and match gamemodes and options.
We can also use these counts somewhere else. I need to analyze q3_ui and ui carefully.

better grenade launcher

grenade launcher is useless most of the time it would be better to have a alt click to blow them or have proximity modes

[Feature] Objectives for team games on the HUD

I just had this idea, I thought I coukd write it here before it leaves my head.

As of now, OA has 13 gametypes, yet outside of the classic ones (FFA, TDM, CTF...) few people have a concrete idea of what certain gametypes are all about.

This could be solved by adding gametype objectives to the HUD. These objectives could be seen as an alternative to screen messages.

Here's how I would implement it:

  1. Add a new option in "Player Setup" called "Preferred team game role" with three options: Attacker, Defender, Roamer and Supporter. On first setup (cl_preferredTeamRole <0), players will be required to specify it, so -1 is the default setting.

  2. Once in a game, players will see their main objective on the screen, right below the chat.

Suppose the gamemode is CTF, the objective for attackers (Offense) would be "Get the enemy flag" while for Defenders "Defend your flag from attacks", for Roamers "Help your defenders and attackers" and for Supporters "Help your attackers steal the enemy flag". OFC objectives aren't static, so when the own team has the flag, the objectives for Attackers and Supporters change: for flag carriers "Bring the enemy flag to your base", and for the rest "Protect your flag carrier at all costs". If the enemy has the flag, Defenders and Roamers would see changes in their objectives, both of them will see "Recover your flag from the enemy team" as their objective.

For 1FCTF this would be "Get the neutral flag" for Attackers, "Support your attackers going for the neutral flag" for Supporters, "Stay ready for incoming attacks" for Roamers and Defenders. Once your team picked up the flag, Attackers and Supporters would see a change in their objectives: "Carry the flag to the enemy base" for the flag carrier and "Cover your flag carrier" for the rest. If the enemy has the flag, Defenders and Roamers would see the message "Prevent the enemy flag from reaching your team's flag".

For Harvester, Attackers and Supporters would see "Frag enemies and pick up their skulls" while Defenders and Roamers would see "Stay ready for incoming attacks". If an enemy has some skulls, Defenders and Roamers would see "Prevent the enemy from depositing the skulls in your receptacle", and if you have some skulls, you'll see the message "Carry the skulls to the enemy base".

And so on. Here's a bunch of objectives I've gathered:

TDM:
All roles: "Frag the enemy team's members and avoid being fragged"
-------------------
CTF:
No flags taken:
- Attackers: "Get the enemy flag"
- Defenders: "Defend your team's flag from incoming attacks"
- Roamers: "Collect items and await further instructions"
- Supporters: "Assist your attackers while going for the enemy flag"

Enemy flag taken by yourself:
- All roles, own flag secure: "Bring the enemy flag to your base"
- All roles, own flag taken by the enemy: "Hold your ground while your teammates recover your team's flag"

Enemy flag taken by a teammate (far from base):
- Attackers and Supporters: "Cover your team's flag carrier"
- Defenders and Roamers: "Defend your base and stay alert for your team's flag carrier"

Enemy flag taken by a teammate (at own team's base):
- All roles: "Cover your team's flag carrier"

Enemy flag dropped:
- Attackers and Supporters: "Touch the enemy team's flag in order to carry it"

Own flag taken by the enemy:
- Defenders and Roamers: "Frag the enemy flag carrier"

Own flag dropped by the enemy:
- Defenders and Roamers: "Touch your team's fallen flag in order to return it"
-------------------
1FCTF:
No flags taken:
- Attackers: "Get the neutral flag"
- Defenders and Roamers: "Collect items and await further instructions"
- Supporters: "Assist your attackers while going for the neutral flag"

Neutral flag taken by yourself (far from enemy base):
- All roles: "Bring the neutral flag to your enemy's base"

Neutral flag taken by yourself (at the enemy base):
- All roles: "Touch the enemy flag while carrying the neutral flag in order to score"

Neutral flag taken by the enemy (far from your team's base):
- Attackers and Supporters: "Frag the enemy flag carrier"
- Defenders and Roamers: "Prevent the enemy flag carrier from entering your base"

Neutral flag taken by the enemy (at your team's base):
- Attackers and Supporters: "Frag the enemy flag carrier before they score"
- Defenders and Roamers: "Prevent the enemy flag carrier from touching your flag"

Neutral flag dropped:
- Attackers: "Get the neutral flag"
- Supporters: "Assist your attackers while going for the neutral flag"
-------------------
Harvester:
No skulls taken (skulls from receptacle mode):
- Attackers and Supporters: "Frag enemies and grab their skulls at the receptacle"
- Defenders and Roamers: "Collect items and await further instructions"

No skulls taken (skulls from bodies mode):
- Attackers and Supporters: "Frag enemies and grab their skulls"
- Defenders and Roamers: "Collect items and await further instructions"

You have some skulls:
- All roles: "Deliver your skulls to the enemy team's receptacle"

A teammate has some skulls:
- Attackers and Supporters: "Accompany your teammates to secure the harvested skulls"

An enemy has some skulls (far from your team's base):
- Defenders and Roamers: "Prevent the enemy from entering your base with skulls"

An enemy has some skulls (at your team's base):
- Defenders and Roamers: "Prevent the enemy from touching your receptacle"
-------------------
Overload:
No base under attack:
- Attackers: "Infiltrate the enemy base"
- Supporters: "Accompany your attackers in the infiltration"
- Roamers: "Collect items and await further instructions"
- Defenders: "Prevent the enemy from entering your base"

Your team infiltrates the enemy base:
- Attackers: "Locate the crystal and shoot it until it's destroyed"
- Supporters: "Accompany your attackers in the destruction"

The enemy team infiltrates your base:
- Roamers and Defenders: "Frag the enemy attackers before they destroy your crystal"
-------------------
Elimination:
All roles: "Frag the enemy team's members and avoid being fragged"
-------------------

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.