Compare commits

...
201 Commits
Author SHA1 Message Date
smallmodel 08d97e0277 Added snd_miles source files 2024-01-07 23:50:02 +01:00
smallmodel 21d0675035 Using vec3_t instead of a pointer to float 2024-01-07 23:42:32 +01:00
smallmodel 1dfb81917c Added public driver functions 2024-01-07 23:38:57 +01:00
smallmodel af8c92f090 Added public OPENAL driver declarations 2024-01-07 23:36:32 +01:00
smallmodel 04e0242422 Added source files for OpenAL FAKK (unimplemented) 2024-01-07 20:10:53 +01:00
pryon 110ffc3a01 Implement UIField (#90)
* Implement UIField

* Formatting and naming fixes

- Ran clang-format on previously modified files
- Replaced ifdef guards with `#pragma once`
- Changed wording in comments above OPM-only changes for easier searchability
2024-01-04 23:51:16 +01:00
smallmodel 6b4a8bd627 Fixed jumpstart modheight not working on AA 2024-01-02 23:32:06 +01:00
smallmodel 0d851fdb68 Players now get correct weapons depending on the target game version 2024-01-02 18:38:21 +01:00
smallmodel 5064f2c16d Added g_target_game 2024-01-02 18:30:46 +01:00
smallmodel ac46d0eef0 Added sv_minplayers variable 2024-01-02 18:14:13 +01:00
smallmodel 70c71b69ee Added a feature to let each team have their own objective location 2024-01-02 00:52:25 +01:00
smallmodel 4487113c58 Fixed dlight image name 2024-01-01 23:52:38 +01:00
smallmodel 983f5b9ca4 Fixed UI sounds 2024-01-01 23:17:09 +01:00
smallmodel 13612d3de9 r_fastdlights is not a cheat-protected cvar 2024-01-01 22:52:08 +01:00
smallmodel 6317ca7183 Fixed the origin of cone emitters 2024-01-01 22:33:05 +01:00
smallmodel 2b96aac1c8 PointToSelectionPoint: the p parameter must be a constant 2024-01-01 21:57:49 +01:00
smallmodel a6b75aefa4 Implemented UIMultiLineEdit 2024-01-01 20:34:50 +01:00
smallmodel 7dc72b435e Formatted multiline edit source file 2024-01-01 15:57:44 +01:00
smallmodel 5a586f4700 Implemented UIHorizScroll 2024-01-01 15:45:40 +01:00
smallmodel ef50a5f2cd Prepared UIHorizScroll for implementation 2024-01-01 15:01:23 +01:00
smallmodel c2c3f6aa1b Implemented miniconsole 2024-01-01 14:53:16 +01:00
smallmodel 9c8ca98e68 Added anisotropic filtering 2024-01-01 14:25:02 +01:00
smallmodel 3a18c9f327 Fixed PrintJustified virtual parameter 2024-01-01 01:53:23 +01:00
smallmodel 9438f6497d Added partial implementations 2024-01-01 01:50:10 +01:00
smallmodel 5c3c3f8e70 Finished View3D implementation (implemented PrintSound, LocationPrint, DrawSubtitleOverlay, and CenterPrint) 2024-01-01 01:42:44 +01:00
smallmodel 3d3c99cd22 Formatted cl_uiview3d source files 2024-01-01 00:32:31 +01:00
smallmodel b3464e620e Updated features implementation 2023-12-31 23:43:30 +01:00
smallmodel 72a38b0b68 Implemented UIDialog 2023-12-31 23:43:22 +01:00
smallmodel 46e7f29820 Fixed dialog bad cancel command 2023-12-31 23:43:05 +01:00
smallmodel cb36015a38 Updated features implementation 2023-12-31 23:15:22 +01:00
smallmodel 66cb10a3bf Added a fix that reset the viewangles if it is NaN 2023-12-31 23:14:22 +01:00
smallmodel bfdd99a028 Added m_parent to get values from parent 2023-12-31 23:13:24 +01:00
smallmodel 63ef75222e Added isVirtual and getVirtualScale 2023-12-31 23:12:40 +01:00
smallmodel 072ba0a38f Fixed fullbright light not setting the colors correctly 2023-12-31 22:15:19 +01:00
smallmodel 576869bda0 Fixed UIFakkLabel::Draw() implementation 2023-12-31 22:02:59 +01:00
smallmodel 0d556b1b40 Implemented cl_invrender 2023-12-31 22:02:47 +01:00
smallmodel 0cd217b484 Fixed RB_Sphere_SetupGlobals() setting up sphere in leafs when there is no world loaded 2023-12-31 21:53:13 +01:00
smallmodel 907255837e Added INV_ALIGN_NONE 2023-12-31 15:35:00 +01:00
smallmodel ebf33349a3 Added EV_ClearInvItemReference declaration 2023-12-31 15:34:53 +01:00
smallmodel ea6920b711 Added CL_Key_ForceCommand 2023-12-31 15:34:45 +01:00
smallmodel 53a47d470a Implemented cl_inv 2023-12-31 14:19:57 +01:00
smallmodel 7fe7b6ce79 Formatted cl_inv* source files 2023-12-31 13:32:46 +01:00
smallmodel 0110704abd Fixed after a map change when setting sv_maxclients 2023-12-31 01:17:16 +01:00
smallmodel aca23fc62f Fixed call vote button not working 2023-12-31 01:01:38 +01:00
smallmodel c0a284927e Fixed vote item name being empty 2023-12-31 00:53:26 +01:00
smallmodel 2d911c37a4 Added vote commands for cgame 2023-12-31 00:39:43 +01:00
smallmodel 1e7af27227 Fixed DM map selection having the incorrect map path 2023-12-31 00:38:41 +01:00
smallmodel 06678a8b0a Added UI_MultiplayerMainMenuWidgetsUpdate from mohaas/mohaab 2023-12-31 00:38:22 +01:00
smallmodel e1706610c4 Fixed versions for mohaas server 2023-12-30 23:52:25 +01:00
smallmodel 7bb940d819 Implemented LAN game list 2023-12-30 23:03:56 +01:00
smallmodel b4e0120428 Using ioquake3 code for IPv6 support and network fixes 2023-12-30 23:03:49 +01:00
smallmodel db1013d926 Use clc.connectStartTime instead of clc.connectTime 2023-12-30 22:59:57 +01:00
smallmodel 759dacd345 Added com_gamename 2023-12-30 21:36:54 +01:00
smallmodel 903fd28953 set cls.bNewLocalServerInfo to tell when there are new local servers 2023-12-30 21:10:27 +01:00
smallmodel 6c520babf0 Make sure to register the material for each GetMaterial() call 2023-12-30 21:09:23 +01:00
smallmodel 9bb2fda6df Fixed events declaration 2023-12-30 19:50:15 +01:00
smallmodel d48b37ece1 Implemented UIGlobalGameList 2023-12-30 19:18:59 +01:00
smallmodel f4164e84e1 Made fields and methods protected instead of private 2023-12-30 19:18:54 +01:00
smallmodel 33aabadaf5 Implemented FAKK Load game class 2023-12-30 19:09:48 +01:00
smallmodel e815fda908 Fixed save's comment being set to the filename 2023-12-30 19:09:31 +01:00
smallmodel fe04adee1d Formatted source files 2023-12-30 17:36:01 +01:00
smallmodel 115647a8c0 Use ApplyPlayerModel/GetPlayerModel from mohaab 2.40 2023-12-30 17:23:30 +01:00
smallmodel ddd70eadf6 Exported PM_FilenameToDisplayname and PM_DisplaynameT 2023-12-30 17:23:11 +01:00
smallmodel 319e00214e Refactored DeactivateCurrentSmart 2023-12-30 17:11:25 +01:00
smallmodel 6bdcfc2b6f Fixed PassEventToWidget improperly passing events to widgets not matching the name 2023-12-30 17:11:12 +01:00
smallmodel ae0a2238da Set mouse position with player model 2023-12-30 16:55:06 +01:00
smallmodel a69f9fe88b Implemented UI player model picker 2023-12-30 16:54:57 +01:00
smallmodel 696b57f990 Formatted uWinMan source file 2023-12-30 16:54:46 +01:00
smallmodel 998c1b78c7 Added all picker models from mohaa 1.0 up to mohaab 2.40 2023-12-30 14:10:06 +01:00
smallmodel 8c207f094d Implemented PMPickerItem and added name parameter to FileSelected/FileChosen methods 2023-12-30 02:22:41 +01:00
smallmodel 09c9c0ef51 Added UI map rotation from BT 2.40 2023-12-30 01:59:03 +01:00
smallmodel 8cd571c96c Implemented all UIListBox methods and implemented Draw() from BT 2.40 2023-12-30 01:50:12 +01:00
smallmodel 979af2925d Fixed hide commands and show commands not executing properly 2023-12-30 01:09:11 +01:00
smallmodel f092eab842 Added InsertItem() and setCurrentItem() for UIListBox 2023-12-30 00:03:21 +01:00
smallmodel 3d4832ca85 Formatted uilistbox source files 2023-12-30 00:01:14 +01:00
smallmodel b120fc6f2f Fixed sorting being wrong 2023-12-29 23:03:08 +01:00
smallmodel c299ad92aa Improver UI_DMMapSelect_f for SH/BT 2023-12-29 22:06:49 +01:00
smallmodel 956cd59385 Implemented MP map picker 2023-12-29 22:06:36 +01:00
smallmodel acbd802790 Make COM_IsMapValid always return true from now 2023-12-29 21:59:23 +01:00
smallmodel c4bcecf5e0 Added COM_IsMapValid 2023-12-29 21:24:23 +01:00
smallmodel 09949251ac Implemented cl_uisoundpicker 2023-12-29 20:23:42 +01:00
smallmodel 43218f1685 Use a const str& reference 2023-12-29 20:19:28 +01:00
smallmodel eb7d01b3e7 Implemented cl_uimaprunner 2023-12-29 20:18:04 +01:00
smallmodel c58e6d58b4 Filter "_sml" maps for maplist 2023-12-29 20:05:36 +01:00
smallmodel 3a892e1a47 Implemented file picker class 2023-12-29 20:05:29 +01:00
smallmodel 5bb487e1fa Set default parameter for fontname 2023-12-29 20:04:57 +01:00
smallmodel 4ae091be4b Added a slash at the end of the scripts folder name 2023-12-29 19:56:34 +01:00
smallmodel 7654ab6be6 FS_ListFilteredFiles: Fixed subdirectory listing and added support for searching multiple extensions 2023-12-29 19:56:23 +01:00
smallmodel 193cc9dc10 Added FS_FileTime (unimplemented) 2023-12-29 18:59:06 +01:00
smallmodel a6d268e1a1 Added subdirectory and directory search support for FS_ListFilteredFiles 2023-12-29 18:27:41 +01:00
smallmodel 7822e94e61 Formatted picker source files 2023-12-29 14:38:55 +01:00
smallmodel eb663fdbc1 Fixed a crash due to subtitle when there is no player 2023-12-28 21:08:07 +01:00
smallmodel c738a40c05 Fixed links 2023-12-28 21:03:58 +01:00
smallmodel 2ca3443b7f Moved Playing with bots section to getting_started_running.md doc 2023-12-28 21:02:05 +01:00
smallmodel 06be4c03fa Use htmlpreview to open the g_allclasses.html file 2023-12-28 20:59:43 +01:00
smallmodel 32d77f4a7d Split README into multiple docs 2023-12-28 20:54:05 +01:00
smallmodel d217b1d561 Fixed some events having wrong parameters for documentation 2023-12-28 20:50:47 +01:00
smallmodel 0167f0a3a4 Using Added in OPM comments 2023-12-28 20:35:33 +01:00
smallmodel 4304ad0faa Fixed weapon attachment not correcting properly 2023-12-28 19:16:54 +01:00
smallmodel 3be17376e4 Fixed wrong landmine defuse direction 2023-12-28 18:55:43 +01:00
smallmodel 0b4fd4c17e Fixed isabandoned returning 1 if the player has a landmine 2023-12-28 18:53:32 +01:00
smallmodel 66c4499b2e Fixed ScriptThreadLabel::Execute with other/owner param 2023-12-28 18:30:15 +01:00
smallmodel cde13177a4 Don't set the ground entity in Entity::droptofloor 2023-12-28 18:22:10 +01:00
smallmodel 9fce2575ab Commented out the code that makes triggers only respond to killed/activate messages 2023-12-28 18:21:58 +01:00
smallmodel 8f8e92c8c3 Don't cound the number of shots if the owner is the world 2023-12-28 17:47:18 +01:00
smallmodel 8683d317fe Set origin2 and player's num shots fired when placing landmine 2023-12-28 17:45:53 +01:00
smallmodel 1178c619bc Fixed variables not being restored properly 2023-12-28 17:31:36 +01:00
smallmodel 2fa568eb01 CL_KeyEvent must not handle GUI mouse events, as it's the job of the UIWindowManager 2023-12-28 17:26:32 +01:00
smallmodel d62242d653 use PRINT_WARNING instead of PRINT_DEVELOPER when an image couldn't be found 2023-12-28 17:25:51 +01:00
smallmodel 991bf2f1f5 Fixed m_firstResponder being nulled out in UIWindowManager::getFirstResponder() 2023-12-28 17:21:56 +01:00
smallmodel 2f241343ff Don't accept the bind for null and pause keys 2023-12-28 17:21:32 +01:00
smallmodel 035de09c15 Formatted cl_keys.cpp source file 2023-12-28 17:21:02 +01:00
smallmodel d3a4407391 Make sure to not service a view event if the first responder is NULL 2023-12-28 13:04:29 +01:00
smallmodel 395c16ce24 Fixed bind label selection 2023-12-28 12:50:40 +01:00
smallmodel f7accc01ad Fixed bind selection and highlight 2023-12-28 12:47:27 +01:00
smallmodel 3733154e63 Fixed alternate binding not working properly 2023-12-28 01:29:46 +01:00
smallmodel 2ef95ddba9 Fixed improper binding and text location 2023-12-28 01:29:33 +01:00
smallmodel 043f8cba22 Implemented UIFakkBindList and UIFakkBindListLabel 2023-12-28 01:12:43 +01:00
smallmodel 09ab172630 Added UIBindButton events 2023-12-28 01:12:19 +01:00
smallmodel c23a182bec Added bindlistener events 2023-12-28 01:11:17 +01:00
smallmodel c321470382 Implemented CL_LoadBind 2023-12-27 22:53:49 +01:00
smallmodel 932bdd402c Implemented UIBindButton 2023-12-27 22:47:01 +01:00
smallmodel 3692671f49 Implemented bind_t and bindlistener 2023-12-27 20:19:58 +01:00
smallmodel 1cd4c35a79 Bumped version number 2023-12-27 18:54:57 +01:00
smallmodel c0f7a48649 Formatted ui source files 2023-12-27 18:54:20 +01:00
smallmodel c1258f160b Do not clear sv_fps cvar when restarting/switching map 2023-12-27 18:43:37 +01:00
smallmodel bdb9feb7c5 Updated README 2023-12-27 18:18:45 +01:00
smallmodel 830cbe7af2 Fixed issues with animation when sv_fps was above 20 2023-12-27 18:04:41 +01:00
smallmodel 4eb83c0766 Fixed weapon attachments not being detached 2023-12-27 16:29:00 +01:00
smallmodel 210f2fef77 Formatted source file 2023-12-27 16:28:28 +01:00
smallmodel d19a6160d2 Call SetWeaponAnim() instead of NewAnim() for weapon animation 2023-12-27 16:25:37 +01:00
smallmodel cd773cf73f Set last active weapon only if the weapon is not an inventory item 2023-12-27 16:13:12 +01:00
smallmodel f3b9a10f7a Detach weapons already attached to the attach tag only if the current weapon attach tag is valid 2023-12-27 15:54:55 +01:00
smallmodel 709283ff33 Fixed MAX_ACTIVE_WEAPONS check (out of bounds) 2023-12-27 15:49:33 +01:00
smallmodel fae261d7da UI game message fix 2023-12-27 15:43:28 +01:00
smallmodel 6b5e527b6b Fixed callvote line breaks 2023-12-27 15:38:17 +01:00
smallmodel b7005a310e Fixed callvote still executing kick with an invalid player 2023-12-27 15:14:08 +01:00
smallmodel edd25b9264 Readded support for supporting configstrings in multiple chunks 2023-12-27 15:13:42 +01:00
smallmodel 65a8b03ee4 Fixed infinite loop in SV_SendConfigstring when sending multiple chunks 2023-12-27 15:13:17 +01:00
smallmodel 0044ec0ac0 Increased MAX_CMD_LINE for testing purposes 2023-12-27 15:11:17 +01:00
smallmodel 73111d854d Fixed an infinite loop bug when selecting the previous/next weapon 2023-12-27 14:07:57 +01:00
smallmodel 065ab98175 Added a comment in CondMinChargeTime about the crash fix 2023-12-27 14:07:34 +01:00
smallmodel cbeaeba828 Use IsSubclassOfWeapon() and IsSubclassOfPlayer() 2023-12-27 14:06:22 +01:00
smallmodel 7af2a9444e Updated paragraph about bug reports 2023-12-26 18:40:54 +01:00
smallmodel f476f3690a Another README update 2023-12-26 12:22:37 +01:00
smallmodel fae02da4b1 Updated README 2023-12-26 12:14:38 +01:00
smallmodel b0e4e29ce3 Merge pull request #88 from pryon/misc-fixes
Misc fixes
2023-12-20 19:34:26 +01:00
pryon 11f7728b9d Move strdup'd string cleanup to uipopup_describe's dtor 2023-12-20 17:52:02 +01:00
pryon 7510b05d25 Properly free memory allocated by strdup calls 2023-12-18 19:56:26 +01:00
pryon e467f91262 Fix pulldown menu labels showing raw cvar values 2023-12-18 17:49:01 +01:00
pryon b03afb899d Add thirdparties dir and generated parser/lexer files to .gitignore 2023-12-18 17:46:52 +01:00
pryon ec71ff3c3c Implement UIPopupMenu (#87)
* Implement UIPopupMenu

* Use `std::fmax` for floats
2023-12-17 22:51:18 +01:00
smallmodel 02ce50ace2 Treat "not all control paths return a value" warning as an error 2023-12-07 18:32:10 +01:00
smallmodel 4a4a552a05 Fixed crash due to corrupted stack values 2023-12-07 18:04:57 +01:00
pryon 5b3615d262 Implement UIPulldownMenuContainer (#86)
* Implement UIPulldownMenuContainer

* Review suggestions:
 - remove unnecessary extern declarations
 - add comment about a possible memleak
2023-12-05 23:27:27 +01:00
pryon 2821488c93 Implement UIPulldownMenu (#85)
* Implement UIPulldownMenu

* Remove unnecessary value-type member initialization
2023-12-05 19:50:41 +01:00
smallmodel 9814887b10 Don't execute Git if the source directory is not a working Git repo 2023-11-29 19:04:24 +01:00
smallmodel 3f86381541 Only allow builds on branches (and not tags), as tags are built during the deployment 2023-11-29 18:18:30 +01:00
smallmodel 7736966dc1 Fixed the README 2023-11-29 18:17:14 +01:00
smallmodel 60faa9dd9b Updated the version number 2023-11-29 17:57:47 +01:00
smallmodel 75f8f86f86 Fixed compilation error on some compilers 2023-11-29 00:08:35 +01:00
smallmodel 0ee1307e75 Fixed missing m_Thread archive 2023-11-28 20:26:40 +01:00
smallmodel f0c38305b5 Fixed defaultEntry having a NULL value even if there are elements 2023-11-28 20:13:55 +01:00
smallmodel e07dda6991 Fixed defaultEntry not being initialized after archiving 2023-11-28 20:10:23 +01:00
smallmodel b10ce9a426 Added GetKey() / SetKey() in con_set's Entry, so ScriptVariable can override it and set the key appropriately 2023-11-28 19:50:19 +01:00
smallmodel 2ac2800ecb Only archive used variables on the local VM stack 2023-11-28 19:14:09 +01:00
smallmodel e59200a7de Fixed cSpline archiving bad values 2023-11-27 20:35:23 +01:00
smallmodel a7902a8837 Added FollowPathRelativeYaw and NormalAngles 2023-11-27 20:30:36 +01:00
smallmodel 615726cc75 Added FollowPathRelativeYaw 2023-11-27 20:22:37 +01:00
smallmodel 839abf6076 Added missing variables to archive 2023-11-27 20:20:00 +01:00
smallmodel c7c8d4580d Added missed archived variables and using a ScriptThreadLabel instead of an event for the killed handler 2023-11-27 20:07:57 +01:00
smallmodel 2cc47e10f9 Added missing iNextLandTime archived variable 2023-11-27 20:06:19 +01:00
smallmodel 8fc5dacebf Removed bBindChilds unused variable + added more variables to archive 2023-11-27 20:06:05 +01:00
smallmodel cb23f3bb70 Added missing weapon_class archived variable 2023-11-27 20:05:36 +01:00
smallmodel d7350d8629 Added Clear() method in ScriptThreadLabel 2023-11-27 20:05:21 +01:00
smallmodel ac6b5ef1f7 Fixed wrong area portal writing 2023-11-27 19:37:29 +01:00
smallmodel 7fdd26c59e Added m_fHealRate archived variable 2023-11-27 19:37:26 +01:00
smallmodel fad555308b Archive ScriptVM and ScriptThread appropriately 2023-11-27 19:30:40 +01:00
smallmodel 969255c48e Fixed areaPortals being broken after reading from archive 2023-11-26 20:44:21 +01:00
smallmodel 433305617c IsAlive: check if the given listener is an actual entity 2023-11-26 20:38:14 +01:00
smallmodel 5418d84c7e Fixed m_fpsTiki being uninitialized when archiving 2023-11-26 20:36:23 +01:00
smallmodel cca37e3dfe Added and using SAVEGAME_STRUCT_VERSION 2023-11-26 20:33:07 +01:00
smallmodel 0e9d83ee14 Added a check to debug the total of archived items 2023-11-26 20:31:58 +01:00
smallmodel ecbf7f6caa Fixed Archive method not calling parent class archive method 2023-11-26 20:00:12 +01:00
smallmodel 5a3638fa68 Better for loop clarity 2023-11-26 19:55:07 +01:00
smallmodel 111088b540 Formatted document 2023-11-26 19:54:07 +01:00
smallmodel ba1703ebf0 When loading an entity from archive, set the model only if the entity allows model to be archived 2023-11-26 19:49:51 +01:00
smallmodel 825df20a72 Fixed game being stuck on mission stats screen in single-player 2023-11-26 19:30:54 +01:00
smallmodel 0a42fd79d2 Clear radar on cgame shutdown 2023-11-26 19:30:28 +01:00
smallmodel e50a041c12 SimpleEntity subclass flags name now starts with ECF_ prefix 2023-11-16 23:17:06 +01:00
smallmodel ce0e9fe77e Added portable turret anim blends + fixed anim blends 2023-11-16 23:03:04 +01:00
smallmodel 5105dcce04 Updated version patch number 2023-11-15 23:17:37 +01:00
smallmodel 58b4a9a676 Added bullet alpha (from moh 2.0 and above) 2023-11-15 21:02:34 +01:00
smallmodel 1146c834fb Fixed bad bullet coords being sent 2023-11-15 21:02:23 +01:00
smallmodel 9068264132 Make sure to remove the view model and detach the player when the turret gun is being removed 2023-11-15 20:42:16 +01:00
smallmodel 59ac8ea437 Clear the partial immobile flag when initializing the player's physics 2023-11-15 20:41:41 +01:00
smallmodel afafacaeec Fixed bullet tracer issues with multiple bullets 2023-11-15 20:41:35 +01:00
smallmodel baf451d2a2 Cleaned up bg_public 2023-11-15 20:39:09 +01:00
smallmodel d588012168 Don't use ANIM_MASK 2023-11-15 19:45:58 +01:00
smallmodel a3ed25cb2e Use WEAPON_CLASS_ITEM1 instead of raw 256 constant value 2023-11-15 19:36:29 +01:00
smallmodel c399f45841 Weapon::SetItemSlot() fixed missing bitwise negate 2023-11-15 19:36:09 +01:00
171 changed files with 25303 additions and 7974 deletions

No files matched your search

+2
View File
@@ -2,6 +2,8 @@ name: Build
on:
push:
branches:
- '*'
pull_request:
workflow_call:
+2 -1
View File
@@ -44,5 +44,6 @@ profile
*.suo
.vs
out
code_unfinished/*
thirdparties/
code/parser/generated/*
+10 -10
View File
@@ -16,8 +16,17 @@ set(CMAKE_DEBUG_POSTFIX "-dbg")
if(MSVC)
add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
# Treat no return type as error
add_compile_options(/we4715)
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
add_compile_options(-Wno-comment)
# Treat no return type as error
add_compile_options(-Werror=return-type)
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
# Ignore warnings for code like 'assert("Assert string")'
add_compile_options(-Wno-pointer-bool-conversion)
endif()
@@ -119,15 +128,6 @@ if (NOT BUILD_NO_CLIENT)
set_target_properties(openmohaa PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
target_link_libraries(openmohaa PRIVATE jpeg8)
if (USE_OPENAL)
# Try to use OpenAL
find_package(OpenAL)
if (OPENAL_FOUND)
target_compile_definitions(openmohaa PRIVATE USE_OPENAL=1)
target_include_directories(openmohaa PRIVATE ${OPENAL_INCLUDE_DIR})
target_link_libraries(openmohaa PRIVATE ${OPENAL_LIBRARY})
endif()
endif()
if (MSVC)
target_link_options(openmohaa PRIVATE "/MANIFEST:NO")
+15 -151
View File
@@ -15,139 +15,38 @@
|_|
```
## Current State
OpenMoHAA is still under development. The single-player campaign is not yet functional due to AI not being fully stable. But the `training` map can be played from start to end. The current focus is on multiplayer.
## Intro
The main goal of OpenMoHAA is to ensure the future and continuity of **Medal of Honor: Allied Assault**. It has always been a dream in the community to provide patches and security fixes for the game. Thanks to the ioquake3 project, F.A.K.K SDK and other quality tools, OpenMoHAA has already reached more than half of its goal: to create an open-source version of MoH:AA (based on version 2.40) that is fully compatible with the original game (in terms of protocol, assets, and scripts).
## Running
## Getting started
Ensure that you download the binaries compatible with your platform.
- [Installing OpenMoHAA](docs/getting_started_installation.md)
- [Running OpenMoHAA and using expansion assets](docs/getting_started_running.md)
### Requirements
## Current state
You may need to install Microsoft Visual C++ 2015/2017/2019/2022 Redistributable from https://learn.microsoft.com/en-US/cpp/windows/latest-supported-vc-redist?view=msvc-170
### Multiplayer
### Client
The Multiplayer part is almost fully stable.
a) extract archive to your MOHAA installation directory.
Server admins can use OpenMoHAA to [host](docs/getting_started_installation.md#server) a mohaa/mohaas/mohaab server. Bugs must be reported by creating a new [issue](https://github.com/openmoh/openmohaa/issues) on the OpenMoHAA GitHub project. Players can use OpenMoHAA to [play](docs/getting_started_installation.md#client) on a mohaa/mohaas/mohaab server.
-or-
All game modes including `Tug-of-War` from Medal of Honor: Spearhead, and `Liberation` from Medal of Honor: Breakthrough are implemented and are working as intended. Mods like `Freeze-Tag` are working as well.
b) extract archive somewhere on your hard drive, create a shortcut to openmohaa (or omohaaded), and set the start directory to your MOHAA installation directory.
### Single-player
### Server
The `training` map can be played from start to end. The single-player campaign is not fully functional, but at least AI can breathe, talk, run, and shoot.
Extract the archive to your MOHAA server installation directory. Then proceed like you would do with mohaa server:
## Features
- `.\omohaaded.exe +exec server.cfg` on Windows
- `./omohaaded +exec server.cfg` on Linux
Only `omohaaded*` and `game*` binaries are required for the server version, other binaries can be omitted.
### Config file
The config file can be found in different locations depending on the platform:
- `%APPDATA%\openmohaa\<game_name>\configs\omconfig.cfg` on Windows
- `~/.openmohaa/<game_name>/configs/omconfig.cfg` on Linux
This has two advantages:
- On a multi-user system, each user will have their own configuration file
- It doesn't overwrite the existing MOHAA configuration in the MOHAA installation directory.
### Game selection
**Medal of Honor: Allied Assault Spearhead** and **Medal of Honor: Allied Assault Breakthrough** are supported in OpenMoHAA using the `com_target_game` variable. To play an expansion, append the following command-line arguments to the executable:
- `+set com_target_game 1` for Spearhead (mohaas/mohta)
- `+set com_target_game 2` for Breakthrough (mohaab/mohtt)
On Windows, you can create a shortcut to OpenMoHAA with these command-line arguments.
The default value of `com_target_game` is 0 for the base game (main).
With `com_target_game`, OpenMoHAA will support the network protocol accordingly.
You can now start a local OpenMOHAA server or play on a server.
### Playing with bots
OpenMoHAA has a basic bot system that emulates real players. The maximum number of bots is defined by the `sv_maxbots` variable, and the number of initial bots is defined by the `sv_numbots` variable. Bots can also be added or removed using the `addbot` and `removebot` commands.
This feature is a great way to test the gameplay and mods.
## Builds
### Server
The server version can be built successfully, but some features are not functional. For example, the Actor system is almost fully implemented, but it is not yet stable. This means that Actor may not work as expected and could cause crashes.
Overall, the server and the fgame components are almost fully implemented, but they may not be completely stable. There could be some minor bugs (and rare crashes), but the game should be playable.
### Client
The client version of OpenMoHAA has undergone partial implementation, with the cgame module being nearly completed. Credits to the SDK of **Heavy Metal: F.A.K.K. 2** both the cgame and fgame modules.
The current operational status for each component is as follow:
| Component | Full | Almost | Half | Early | Bad | Not working | Comment |
|-------------------------|------|--------|------|-------|-----|-------------|-------------------------------------------------------------------|
| Audio | | | | | x | | Very basic implementation from Quake III |
| CG Module | | x | | | | | Missing FX, Marks and decals |
| Client | | x | | | | | Missing GameSpy, server list, binds, map picker, ... |
| Collision | x | | | | | | |
| Model/TIKI/Skeletor | x | | | | | | |
| Renderer | | x | | | | | Missing ghost, marks, sphere lights, sky portal, sun flare, swipe |
| Server | | x | | | | | Probably a few bugs remaining |
| Server module (fgame) | | x | | | | | Actor, and few gameplay bugs |
| UI | | | x | | | | Has core features only (menu, widgets, console, hud, urc loading) |
- [What's working and what's not](docs/features_implementation.md)
- [New features](docs/features.md)
- [Scripting commands](https://htmlpreview.github.io/?https://github.com/openmoh/openmohaa/blob/main/docs/features_g_allclasses.html)
## Compiling
OpenMoHAA supports any architecture, thanks to the CMake build system and cross-platform code/libraries. While the most common little-Endian architectures (arm, aarch64, x86, x86_64) have been tested and confirmed to work, big-Endian architectures should be supported as well; however, they remain untested.
The following tools are required for all platforms:
- CMake >= 3.5
- Flex (>= 2.6.4) and Bison (>= 3.5.1)
- A C++11 compiler is also required.
The installation directory can be set to the MOHAA directory.
By default, the build will produce both the client and dedicated server versions. The client can be omitted from the build by appending `-DBUILD_NO_CLIENT=1` to the CMake command-line arguments. Using this parameter will result in only the server portion being built.
### Linux
These are the tools required on Linux :
- Clang >= 3.3 or GCC >= 4.8.5
- libsdl2-dev
**clang-3.5** and **gcc-4.8.5** should work (tested on Ubuntu 16.04), but the latest version should be used.
Ubuntu 20.04 is the minimum version required to fully compile the project successfully.
1 line install command with clang:
```sh
sudo apt-get install -y cmake ninja-build clang lld flex bison libsdl2-dev
```
Example with **CMake** and **ninja-build** installed:
```sh
mkdir .cmake && cd .cmake
cmake -G Ninja ../
```
Other compilers can be specified by appending `-DCMAKE_C_COMPILER=/path/to/compiler -DCMAKE_CXX_COMPILER=path/to/compiler` to the CMake command-line.
### Windows
Visual Studio (2019 or 2022) is generally preferred.
Flex and Bison can be downloaded from here: https://github.com/lexxmark/winflexbison/releases/tag/v2.5.25
Append `-DFLEX_EXECUTABLE=...\win_flex.exe -DBISON_EXECUTABLE=...\win_bison.exe` to the CMake command-line to use the package from the link above.
- See [Compiling OpenMoHAA](docs/compiling.md)
## Screenshots
@@ -159,41 +58,6 @@ Append `-DFLEX_EXECUTABLE=...\win_flex.exe -DBISON_EXECUTABLE=...\win_bison.exe`
*More screenshots [here](docs/images)*
## Features
### Features added and not present in MOH:AA
#### Server-side
- Bots
- Spectate players in first-person
- Demo recording
- More script commands for mods
- Non-PVS optimization
##### Non-PVS optimization
For each client, the server optimizes by only sending them information about other players that they can see. Clients won't see other players they can't see.
Enable this feature with `set sv_netoptimize 2`.
#### Client-side and server-side
- Security fixes and features from ioquake3
- IPv6 support (from ioquake3)
### Objectives / planned features
This is a non-exhaustive list of objectives and planned features.
#### Server-side
- 100% compatibility with mohaa content
- More feature for mods
- Anticheat
- Stats system
- Multiple roles/abilities for server admins to reduce password-stealing
## Third party
### SDL
+60 -50
View File
@@ -25,6 +25,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
// text commands typed in at the local console, or executed by a key binding
#include "cg_local.h"
#include "../fgame/bg_voteoptions.h"
void CG_TargetCommand_f(void);
@@ -339,56 +340,65 @@ typedef struct {
} consoleCommand_t;
static consoleCommand_t commands[] = {
{"useweaponclass", &CG_UseWeaponClass_f },
{"weapnext", &CG_NextWeapon_f },
{"weapprev", &CG_PrevWeapon_f },
{"uselast", &CG_UseLastWeapon_f },
{"holster", &CG_HolsterWeapon_f },
{"weapdrop", &CG_DropWeapon_f },
{"toggleitem", &CG_ToggleItem_f },
{"+scores", &CG_ScoresDown_f },
{"-scores", &CG_ScoresUp_f },
{"viewpos", &CG_Viewpos_f },
{"sizeup", &CG_SizeUp_f },
{"sizedown", &CG_SizeDown_f },
{"cg_eventlist", &CG_EventList_f },
{"cg_eventhelp", &CG_EventHelp_f },
{"cg_dumpevents", &CG_DumpEventHelp_f },
{"cg_pendingevents", &CG_PendingEvents_f },
{"cg_classlist", &CG_ClassList_f },
{"cg_classtree", &CG_ClassTree_f },
{"cg_classevents", &CG_ClassEvents_f },
{"cg_dumpclassevents", &CG_DumpClassEvents_f },
{"cg_dumpallclasses", &CG_DumpAllClasses_f },
{"testemitter", &CG_TestEmitter_f },
{"triggertestemitter", &CG_TriggerTestEmitter_f },
{"prevemittercommand", &CG_PrevEmitterCommand_f },
{"nextemittercommand", &CG_NextEmitterCommand_f },
{"newemittercommand", &CG_NewEmitterCommand_f },
{"deleteemittercommand", &CG_DeleteEmitterCommand_f},
{"dumpemitter", &CG_DumpEmitter_f },
{"loademitter", &CG_LoadEmitter_f },
{"resetvss", &CG_ResetVSSSources },
{"getchshader", &CG_GetCHShader },
{"editchshader", &CG_EditCHShader },
{"messagemode", &CG_MessageMode_f },
{"messagemode_all", &CG_MessageMode_All_f },
{"messagemode_team", &CG_MessageMode_Team_f },
{"messagemode_private", &CG_MessageMode_Private_f },
{"say", &CG_MessageSingleAll_f },
{"sayteam", &CG_MessageSingleTeam_f },
{"teamsay", &CG_MessageSingleTeam_f },
{"sayprivate", &CG_MessageSingleClient_f },
{"sayone", &CG_MessageSingleClient_f },
{"wisper", &CG_MessageSingleClient_f },
{"instamsg_main", &CG_InstaMessageMain_f },
{"instamsg_group_a", &CG_InstaMessageGroupA_f },
{"instamsg_group_b", &CG_InstaMessageGroupB_f },
{"instamsg_group_c", &CG_InstaMessageGroupC_f },
{"instamsg_group_d", &CG_InstaMessageGroupD_f },
{"instamsg_group_e", &CG_InstaMessageGroupE_f },
{"pushmenu_teamselect", &CG_PushMenuTeamSelect_f },
{"pushmenu_weaponselect", &CG_PushMenuWeaponSelect_f},
{"useweaponclass", &CG_UseWeaponClass_f },
{"weapnext", &CG_NextWeapon_f },
{"weapprev", &CG_PrevWeapon_f },
{"uselast", &CG_UseLastWeapon_f },
{"holster", &CG_HolsterWeapon_f },
{"weapdrop", &CG_DropWeapon_f },
{"toggleitem", &CG_ToggleItem_f },
{"+scores", &CG_ScoresDown_f },
{"-scores", &CG_ScoresUp_f },
{"viewpos", &CG_Viewpos_f },
{"sizeup", &CG_SizeUp_f },
{"sizedown", &CG_SizeDown_f },
{"cg_eventlist", &CG_EventList_f },
{"cg_eventhelp", &CG_EventHelp_f },
{"cg_dumpevents", &CG_DumpEventHelp_f },
{"cg_pendingevents", &CG_PendingEvents_f },
{"cg_classlist", &CG_ClassList_f },
{"cg_classtree", &CG_ClassTree_f },
{"cg_classevents", &CG_ClassEvents_f },
{"cg_dumpclassevents", &CG_DumpClassEvents_f },
{"cg_dumpallclasses", &CG_DumpAllClasses_f },
{"testemitter", &CG_TestEmitter_f },
{"triggertestemitter", &CG_TriggerTestEmitter_f },
{"prevemittercommand", &CG_PrevEmitterCommand_f },
{"nextemittercommand", &CG_NextEmitterCommand_f },
{"newemittercommand", &CG_NewEmitterCommand_f },
{"deleteemittercommand", &CG_DeleteEmitterCommand_f },
{"dumpemitter", &CG_DumpEmitter_f },
{"loademitter", &CG_LoadEmitter_f },
{"resetvss", &CG_ResetVSSSources },
{"getchshader", &CG_GetCHShader },
{"editchshader", &CG_EditCHShader },
{"messagemode", &CG_MessageMode_f },
{"messagemode_all", &CG_MessageMode_All_f },
{"messagemode_team", &CG_MessageMode_Team_f },
{"messagemode_private", &CG_MessageMode_Private_f },
{"say", &CG_MessageSingleAll_f },
{"sayteam", &CG_MessageSingleTeam_f },
{"teamsay", &CG_MessageSingleTeam_f },
{"sayprivate", &CG_MessageSingleClient_f },
{"sayone", &CG_MessageSingleClient_f },
{"wisper", &CG_MessageSingleClient_f },
{"instamsg_main", &CG_InstaMessageMain_f },
{"instamsg_group_a", &CG_InstaMessageGroupA_f },
{"instamsg_group_b", &CG_InstaMessageGroupB_f },
{"instamsg_group_c", &CG_InstaMessageGroupC_f },
{"instamsg_group_d", &CG_InstaMessageGroupD_f },
{"instamsg_group_e", &CG_InstaMessageGroupE_f },
{"pushmenu_teamselect", &CG_PushMenuTeamSelect_f },
{"pushmenu_weaponselect", &CG_PushMenuWeaponSelect_f },
// Added in 2.0
{"pushcallvote", &CG_PushCallVote_f },
{"pushcallvotesublist", &CG_PushCallVoteSubList_f },
{"pushcallvotesubtext", &CG_PushCallVoteSubText_f },
{"pushcallvotesubinteger",&CG_PushCallVoteSubInteger_f },
{"pushcallvotesubfloat", &CG_PushCallVoteSubFloat_f },
{"pushcallvotesubclient", &CG_PushCallVoteSubClient_f },
{"pushvote", &CG_PushVote_f },
{"callentryvote", &CG_CallEntryVote_f },
};
/*
+4 -1
View File
@@ -689,11 +689,14 @@ Called before every level change or subsystem restart
void CG_Shutdown(void)
{
L_ShutdownEvents();
// Shutdown radar
cgi.CL_InitRadar(NULL, NULL, -1);
// some mods may need to do cleanup work here,
// like closing files or archiving session data
// hide the stats screen
cgi.UI_HideMenu("StatsScreen", 1);
cgi.UI_HideMenu("StatsScreen", qtrue);
// reset the scoreboard
CG_PrepScoreBoardInfo();
+183 -224
View File
@@ -37,6 +37,7 @@ typedef struct {
vec3_t *i_vEnd;
int i_iNumBullets;
qboolean iLarge;
float alpha;
int iTracerVisible;
qboolean bIgnoreEntities;
} bullet_tracer_t;
@@ -60,21 +61,22 @@ static vec3_t flesh_impact_pos[MAX_IMPACTS];
static vec3_t flesh_impact_norm[MAX_IMPACTS];
static int flesh_impact_large[MAX_IMPACTS];
void CG_MakeBulletHoleSound(const vec3_t i_vPos, const vec3_t i_vNorm, int iLarge, trace_t* pPreTrace) {
int iSurfType;
float fVolume;
str sSoundName;
vec3_t vFrom, vDest;
void CG_MakeBulletHoleSound(const vec3_t i_vPos, const vec3_t i_vNorm, int iLarge, trace_t *pPreTrace)
{
int iSurfType;
float fVolume;
str sSoundName;
vec3_t vFrom, vDest;
trace_t trace;
if (pPreTrace) {
trace = *pPreTrace;
}
else {
} else {
VectorMA(i_vPos, 2.0f, i_vNorm, vFrom);
VectorMA(i_vPos, -4.0f, i_vNorm, vDest);
CG_Trace(&trace, vFrom, vec_zero, vec_zero, vDest, ENTITYNUM_NONE, MASK_SHOT, qfalse, qtrue, "CG_MakeBulletHole");
CG_Trace(
&trace, vFrom, vec_zero, vec_zero, vDest, ENTITYNUM_NONE, MASK_SHOT, qfalse, qtrue, "CG_MakeBulletHole"
);
}
iSurfType = trace.surfaceFlags & MASK_SURF_TYPE;
@@ -149,9 +151,12 @@ void CG_MakeBulletHoleSound(const vec3_t i_vPos, const vec3_t i_vNorm, int iLarg
commandManager.PlaySound(sSoundName, vFrom, -1, fVolume, -1.f, -1.f, 1);
}
static void CG_MakeBulletHoleType(const vec3_t i_vPos, const vec3_t i_vNorm, int iLarge, int iEffectNum, float fRadius, qboolean bMakeSound) {
static void CG_MakeBulletHoleType(
const vec3_t i_vPos, const vec3_t i_vNorm, int iLarge, int iEffectNum, float fRadius, qboolean bMakeSound
)
{
if (bMakeSound) {
str sBulletHole = "snd_bh_";
str sBulletHole = "snd_bh_";
float fVolume;
switch (iEffectNum) {
@@ -221,14 +226,15 @@ static void CG_MakeBulletHoleType(const vec3_t i_vPos, const vec3_t i_vNorm, int
sfxManager.MakeEffect_Normal(iEffectNum, i_vPos, i_vNorm);
}
static void CG_MakeBulletHole(const vec3_t i_vPos, const vec3_t i_vNorm, int iLarge, trace_t *pPreTrace, qboolean bMakeSound)
static void
CG_MakeBulletHole(const vec3_t i_vPos, const vec3_t i_vNorm, int iLarge, trace_t *pPreTrace, qboolean bMakeSound)
{
int iSurfType;
int iEffect;
float fRadius;
str sEffectModel;
str sBulletHole;
vec3_t vFrom, vDest;
int iSurfType;
int iEffect;
float fRadius;
str sEffectModel;
str sBulletHole;
vec3_t vFrom, vDest;
trace_t trace;
if (pPreTrace) {
@@ -236,7 +242,9 @@ static void CG_MakeBulletHole(const vec3_t i_vPos, const vec3_t i_vNorm, int iLa
} else {
VectorMA(i_vPos, 2.0f, i_vNorm, vFrom);
VectorMA(i_vPos, -4.0f, i_vNorm, vDest);
CG_Trace(&trace, vFrom, vec_zero, vec_zero, vDest, ENTITYNUM_NONE, MASK_SHOT, qfalse, qtrue, "CG_MakeBulletHole");
CG_Trace(
&trace, vFrom, vec_zero, vec_zero, vDest, ENTITYNUM_NONE, MASK_SHOT, qfalse, qtrue, "CG_MakeBulletHole"
);
}
iSurfType = trace.surfaceFlags & MASK_SURF_TYPE;
@@ -249,7 +257,7 @@ static void CG_MakeBulletHole(const vec3_t i_vPos, const vec3_t i_vNorm, int iLa
}
VectorAdd(trace.endpos, trace.plane.normal, vFrom);
fRadius = 2.0f;
fRadius = 2.0f;
sBulletHole = "bhole_";
switch (iSurfType) {
@@ -347,36 +355,48 @@ static void CG_MakeBubbleTrail(const vec3_t i_vStart, const vec3_t i_vEnd, int i
{
vec3_t vDir;
vec3_t vPos;
float fDist;
float fMove;
float fDist;
float fMove;
VectorSubtract(i_vEnd, i_vStart, vDir);
fDist = VectorNormalize(vDir);
VectorCopy(i_vStart, vPos);
fMove = random() * 8.f;
fMove = random() * 8.f * alpha;
fDist -= fMove;
while (fDist > 0.f) {
VectorMA(vPos, fMove, vDir, vPos);
sfxManager.MakeEffect_Angles(32, vPos, vec_zero);
fMove = 16.f + crandom() * 8.f;
fMove = 16.f + crandom() * 8.f * alpha;
fDist -= fMove;
}
}
static void CG_BulletTracerEffect(const vec3_t i_vStart, const vec3_t i_vEnd)
static void CG_BulletTracerEffect(const vec3_t i_vStart, const vec3_t i_vEnd, int iLarge, float alpha)
{
int iLife;
int iTracerLength;
float fLength, fDist;
int iLife;
int iTracerLength;
float fLength, fDist;
vec4_t fTracerColor;
vec3_t vDir, vNewStart;
float alphaMult;
float scale;
iTracerLength = 450.0f + random() * 150.f;
VectorSubtract(i_vEnd, i_vStart, vDir);
fLength = VectorNormalize(vDir);
if (iLarge > 1) {
alphaMult = random() * 0.2f + 0.9f;
scale = iLarge * 2;
} else {
alphaMult = 1;
scale = 1;
}
fDist = 450.0f + random() * 150.f;
if (fLength < fDist + 150.f) {
float fFrac;
@@ -384,13 +404,15 @@ static void CG_BulletTracerEffect(const vec3_t i_vStart, const vec3_t i_vEnd)
return;
}
fFrac = fLength / (fDist + 150.0);
fFrac = fLength / (fDist + 150.0);
iTracerLength = (int)((float)iTracerLength * fFrac + 0.5f);
fDist *= fFrac;
}
iLife = (int)((fLength - fDist) / 12000.f * 1000.f);
if (iLife < 20) iLife = 20;
iLife = (int)((fLength - fDist) / 12000.f * 1000.f / (alpha * alphaMult));
if (iLife < 20) {
iLife = 20;
}
VectorMA(i_vStart, fDist, vDir, vNewStart);
fTracerColor[0] = 1.f;
@@ -427,53 +449,54 @@ static void CG_BulletTracerEffect(const vec3_t i_vStart, const vec3_t i_vEnd)
}
static void CG_MakeBulletTracerInternal(
const vec3_t i_vBarrel,
const vec3_t i_vStart,
const vec3_t *i_vEnd,
int i_iNumBullets,
qboolean iLarge,
int iTracerVisible,
qboolean bIgnoreEntities
const vec3_t i_vBarrel,
const vec3_t i_vStart,
const vec3_t *i_vEnd,
int i_iNumBullets,
qboolean iLarge,
int iTracerVisible,
qboolean bIgnoreEntities,
float alpha
)
{
vec3_t vPos;
int iBullet;
int iContinueCount;
int iDist;
int iHeadDist;
int iTravelDist;
float fLen, fDist;
trace_t trace;
qboolean bStartInWater, bInWater;
qboolean bBulletDone;
qboolean bMadeTracer;
vec3_t vDir;
vec3_t vTrailStart;
vec3_t vTraceStart;
vec3_t vTraceEnd;
vec3_t vTmp;
int iNumImpacts;
trace_t tImpacts[128];
float fImpSndDistRA;
vec3_t vPos;
int iBullet;
int iContinueCount;
int iDist;
int iHeadDist;
int iTravelDist;
float fLen, fDist;
trace_t trace;
qboolean bStartInWater, bInWater;
qboolean bBulletDone;
qboolean bMadeTracer;
vec3_t vDir;
vec3_t vTrailStart;
vec3_t vTraceStart;
vec3_t vTraceEnd;
vec3_t vTmp;
int iNumImpacts;
trace_t tImpacts[128];
float fImpSndDistRA;
static float fImpSndDistLA;
float fImpSndDistRB;
float fImpSndDistLB;
int iImpSndIndexRA;
int iImpSndIndexRB;
int iImpSndIndexLB;
float fVolume;
float fPitch;
float fZingDistA, fZingDistB, fZingDistC;
vec3_t vZingPosA, vZingPosB, vZingPosC;
float fImpSndDistRB;
float fImpSndDistLB;
int iImpSndIndexRA;
int iImpSndIndexRB;
int iImpSndIndexLB;
float fVolume;
float fPitch;
float fZingDistA, fZingDistB, fZingDistC;
vec3_t vZingPosA, vZingPosB, vZingPosC;
fZingDistB = 9999.0;
fZingDistA = 9999.0;
fZingDistC = 9999.0;
fZingDistB = 9999.0;
fZingDistA = 9999.0;
fZingDistC = 9999.0;
iNumImpacts = 0;
// check to see if it starts in water
bStartInWater = (cgi.CM_PointContents(i_vStart, 0) & CONTENTS_FLUID) != 0;
for (iBullet = 0; iBullet < i_iNumBullets; iBullet++) {
bInWater = bStartInWater;
VectorCopy(i_vBarrel, vTrailStart);
@@ -481,8 +504,8 @@ static void CG_MakeBulletTracerInternal(
fLen = VectorNormalize(vDir);
trace.fraction = 0;
iDist = (int)fLen + 32;
bBulletDone = qfalse;
iDist = (int)fLen + 32;
bBulletDone = qfalse;
iContinueCount = 0;
if (bStartInWater) {
@@ -501,8 +524,7 @@ static void CG_MakeBulletTracerInternal(
if (iDist > BULLET_TRAVEL_DIST) {
iTravelDist += BULLET_TRAVEL_DIST;
iDist -= BULLET_TRAVEL_DIST;
}
else {
} else {
iTravelDist += iDist;
iDist = 0;
}
@@ -513,16 +535,7 @@ static void CG_MakeBulletTracerInternal(
while (trace.fraction < 1) {
if (bIgnoreEntities) {
cgi.CM_BoxTrace(
&trace,
vTraceStart,
vTraceEnd,
vec_zero,
vec_zero,
0,
MASK_SHOT,
qfalse
);
cgi.CM_BoxTrace(&trace, vTraceStart, vTraceEnd, vec_zero, vec_zero, 0, MASK_SHOT, qfalse);
if (trace.fraction == 1.0f) {
trace.entityNum = ENTITYNUM_NONE;
@@ -533,8 +546,7 @@ static void CG_MakeBulletTracerInternal(
if (trace.startsolid) {
trace.entityNum = ENTITYNUM_WORLD;
}
}
else {
} else {
CG_Trace(
&trace,
vTraceStart,
@@ -556,35 +568,29 @@ static void CG_MakeBulletTracerInternal(
VectorNormalizeFast(trace.plane.normal);
}
if (!bInWater && trace.fraction < 1.0f && iNumImpacts <= 127)
{
if (!bInWater && trace.fraction < 1.0f && iNumImpacts <= 127) {
memcpy(&tImpacts[iNumImpacts], &trace, sizeof(trace_t));
iNumImpacts++;
}
if (iTracerVisible && !bMadeTracer)
{
CG_BulletTracerEffect(vTrailStart, trace.endpos);
if (iTracerVisible && !bMadeTracer) {
CG_BulletTracerEffect(vTrailStart, trace.endpos, iLarge, alpha);
bMadeTracer = qtrue;
}
if (trace.fraction < 1.0f) {
if (((trace.surfaceFlags & (SURF_HINT | SURF_NODLIGHT | SURF_SNOW | SURF_FOLIAGE | SURF_DIRT)) || (trace.contents & CONTENTS_WATER))
&& iContinueCount < 5)
{
if (bInWater)
{
if (((trace.surfaceFlags & (SURF_HINT | SURF_NODLIGHT | SURF_SNOW | SURF_FOLIAGE | SURF_DIRT))
|| (trace.contents & CONTENTS_WATER))
&& iContinueCount < 5) {
if (bInWater) {
VectorSubtract(trace.endpos, vDir, vTmp);
if (!(trace.contents & CONTENTS_FLUID)
&& !(trace.surfaceFlags & SURF_PUDDLE)
&& !(cgi.CM_PointContents(vTmp, 0) & CONTENTS_FLUID))
{
CG_MakeBubbleTrail(vTrailStart, trace.endpos, iLarge);
if (!(trace.contents & CONTENTS_FLUID) && !(trace.surfaceFlags & SURF_PUDDLE)
&& !(cgi.CM_PointContents(vTmp, 0) & CONTENTS_FLUID)) {
CG_MakeBubbleTrail(vTrailStart, trace.endpos, iLarge, alpha);
VectorCopy(trace.endpos, vTrailStart);
bInWater = qfalse;
}
}
else if ((trace.contents & CONTENTS_FLUID) || (trace.surfaceFlags & SURF_PUDDLE)) {
} else if ((trace.contents & CONTENTS_FLUID) || (trace.surfaceFlags & SURF_PUDDLE)) {
VectorCopy(trace.endpos, vTrailStart);
bInWater = qtrue;
}
@@ -593,11 +599,9 @@ static void CG_MakeBulletTracerInternal(
VectorAdd(vTraceStart, vTraceStart, trace.endpos);
iContinueCount++;
}
else
{
} else {
trace.fraction = 1.0f;
bBulletDone = qtrue;
bBulletDone = qtrue;
}
}
}
@@ -605,14 +609,14 @@ static void CG_MakeBulletTracerInternal(
}
if (bInWater) {
CG_MakeBubbleTrail(vTraceStart, trace.endpos, iLarge);
CG_MakeBubbleTrail(vTraceStart, trace.endpos, iLarge, alpha);
}
if (iTracerVisible) {
iTracerVisible--;
}
fLen = ProjectPointOnLine(i_vStart, i_vEnd[iBullet], cg.SoundOrg, vPos);
fLen = ProjectPointOnLine(i_vStart, i_vEnd[iBullet], cg.SoundOrg, vPos);
iHeadDist = (int)Distance(vPos, cg.SoundOrg);
if (iHeadDist > 255) {
continue;
@@ -629,7 +633,7 @@ static void CG_MakeBulletTracerInternal(
if (fLen < 0.f) {
VectorCopy(i_vStart, vPos);
} else if(fDist >= fLen) {
} else if (fDist >= fLen) {
VectorCopy(i_vEnd[iBullet], vPos);
}
@@ -652,11 +656,11 @@ static void CG_MakeBulletTracerInternal(
}
if (iNumImpacts > 2) {
fImpSndDistRA = 9999.0f;
fImpSndDistRB = 9999.0f;
fImpSndDistRA = 9999.0f;
fImpSndDistRB = 9999.0f;
iImpSndIndexRA = 0;
iImpSndIndexRB = 0;
fImpSndDistLB = 9999.0f;
fImpSndDistLB = 9999.0f;
iImpSndIndexLB = 0;
for (iBullet = 0; iBullet < iNumImpacts; iBullet++) {
@@ -671,27 +675,23 @@ static void CG_MakeBulletTracerInternal(
VectorSubtract(tImpacts[iImpSndIndexLB].endpos, cg.SoundOrg, vTmp);
iHeadDist = VectorLength(vTmp);
if (DotProduct(vTmp, cg.SoundAxis[1]) <= 0.f)
{
if (DotProduct(vTmp, cg.SoundAxis[1]) <= 0.f) {
if (iHeadDist < 9999.0f || iHeadDist < fImpSndDistLB) {
if (iHeadDist < 9999.0f) {
fImpSndDistRA = iHeadDist;
fImpSndDistLB = 9999.0;
fImpSndDistRA = iHeadDist;
fImpSndDistLB = 9999.0;
iImpSndIndexRA = iBullet;
} else if (iHeadDist < fImpSndDistLB) {
fImpSndDistLB = iHeadDist;
}
}
}
else
{
if (iHeadDist < fImpSndDistRA || iHeadDist < fImpSndDistRB)
{
} else {
if (iHeadDist < fImpSndDistRA || iHeadDist < fImpSndDistRB) {
if (iHeadDist < fImpSndDistRA) {
iImpSndIndexRB = iImpSndIndexRA;
iImpSndIndexRA = iBullet;
} else if (iHeadDist < fImpSndDistRB) {
fImpSndDistRB = iHeadDist;
fImpSndDistRB = iHeadDist;
iImpSndIndexRB = iBullet;
}
}
@@ -720,11 +720,7 @@ static void CG_MakeBulletTracerInternal(
} else {
for (iBullet = 0; iBullet < iNumImpacts; iBullet++) {
CG_MakeBulletHole(
tImpacts[iBullet].endpos,
tImpacts[iBullet].plane.normal,
iNumImpacts,
&tImpacts[iBullet],
qtrue
tImpacts[iBullet].endpos, tImpacts[iBullet].plane.normal, iNumImpacts, &tImpacts[iBullet], qtrue
);
}
}
@@ -732,10 +728,10 @@ static void CG_MakeBulletTracerInternal(
if (fZingDistA < 9999.0f) {
if (iLarge) {
fVolume = 1.0f;
fPitch = 0.8f;
fPitch = 0.8f;
} else {
fVolume = 0.8f;
fPitch = 1.0f;
fPitch = 1.0f;
}
commandManager.PlaySound("snd_b_zing", vZingPosA, -1, fVolume, -1.0f, fPitch, 1);
@@ -774,13 +770,14 @@ static void CG_MakeBulletTracer(
bullet_tracer->i_vEnd = &bullet_tracer_bullets[bullet_tracers_count];
bullet_tracer->i_iNumBullets = i_iNumBullets;
for (i = 0; i < i_iNumBullets; ++i) {
bullet_tracer_bullets[bullet_tracers_count][0] = (*i_vEnd)[i];
bullet_tracer_bullets[bullet_tracers_count][1] = (*i_vEnd)[i + 1];
bullet_tracer_bullets[bullet_tracers_count++][2] = (*i_vEnd)[i + 2];
for (i = 0; i < i_iNumBullets; i++, bullet_tracers_count++) {
bullet_tracer_bullets[bullet_tracers_count][0] = i_vEnd[i][0];
bullet_tracer_bullets[bullet_tracers_count][1] = i_vEnd[i][1];
bullet_tracer_bullets[bullet_tracers_count][2] = i_vEnd[i][2];
}
bullet_tracer->iLarge = iLarge;
bullet_tracer->alpha = alpha;
bullet_tracer->iTracerVisible = iTracerVisible;
bullet_tracer->bIgnoreEntities = bIgnoreEntities;
}
@@ -797,7 +794,8 @@ void CG_AddBulletTracers()
bullet_tracers[i].i_iNumBullets,
bullet_tracers[i].iLarge,
bullet_tracers[i].iTracerVisible,
bullet_tracers[i].bIgnoreEntities
bullet_tracers[i].bIgnoreEntities,
bullet_tracers[i].alpha
);
}
@@ -807,26 +805,24 @@ void CG_AddBulletTracers()
void CG_AddBulletImpacts()
{
int i;
int iHeadDist;
float fVolume;
float fImpSndDistRA;
int i;
int iHeadDist;
float fVolume;
float fImpSndDistRA;
static float fImpSndDistLA = 9999.f;
float fImpSndDistRB;
float fImpSndDistLB;
int iImpSndIndexRA;
int iImpSndIndexRB;
int iImpSndIndexLB;
vec3_t vTmp;
str sSoundName;
float fImpSndDistRB;
float fImpSndDistLB;
int iImpSndIndexRA;
int iImpSndIndexRB;
int iImpSndIndexLB;
vec3_t vTmp;
str sSoundName;
if (wall_impact_count)
{
if (wall_impact_count > 4)
{
fImpSndDistRA = fImpSndDistLA;
fImpSndDistRB = fImpSndDistLA;
fImpSndDistLB = fImpSndDistLA;
if (wall_impact_count) {
if (wall_impact_count > 4) {
fImpSndDistRA = fImpSndDistLA;
fImpSndDistRB = fImpSndDistLA;
fImpSndDistLB = fImpSndDistLA;
iImpSndIndexRA = 0;
iImpSndIndexRB = 0;
iImpSndIndexLB = 0;
@@ -834,33 +830,28 @@ void CG_AddBulletImpacts()
for (i = 0; i < wall_impact_count; i++) {
VectorSubtract(wall_impact_pos[i], cg.SoundOrg, vTmp);
iHeadDist = VectorLength(vTmp);
if (DotProduct(vTmp, cg.SoundAxis[1]) > 0.f)
{
if (iHeadDist < fImpSndDistRA || iHeadDist < fImpSndDistRB)
{
if (DotProduct(vTmp, cg.SoundAxis[1]) > 0.f) {
if (iHeadDist < fImpSndDistRA || iHeadDist < fImpSndDistRB) {
if (iHeadDist < fImpSndDistRA) {
fImpSndDistRB = fImpSndDistRA;
fImpSndDistRA = iHeadDist;
fImpSndDistRB = fImpSndDistRA;
fImpSndDistRA = iHeadDist;
iImpSndIndexRB = iImpSndIndexRA;
iImpSndIndexRA = i;
} else if (iHeadDist < fImpSndDistRB) {
fImpSndDistRB = iHeadDist;
fImpSndDistRB = iHeadDist;
iImpSndIndexRB = i;
}
}
}
else
{
if (iHeadDist < fImpSndDistLA || iHeadDist < fImpSndDistLB)
{
} else {
if (iHeadDist < fImpSndDistLA || iHeadDist < fImpSndDistLB) {
if (iHeadDist < fImpSndDistLA) {
fImpSndDistRA = iHeadDist;
fImpSndDistLB = fImpSndDistLA;
fImpSndDistRA = iHeadDist;
fImpSndDistLB = fImpSndDistLA;
iImpSndIndexLB = 0;
iImpSndIndexRA = i;
} else if (iHeadDist < fImpSndDistLB) {
fImpSndDistLB = iHeadDist;
fImpSndDistLB = iHeadDist;
iImpSndIndexLB = i;
}
}
@@ -908,8 +899,7 @@ void CG_AddBulletImpacts()
if (wall_impact_type[iImpSndIndexRB] == 2 || wall_impact_type[iImpSndIndexRB] == 3) {
sSoundName = "snd_bh_metal";
}
else {
} else {
sSoundName = "snd_bh_wood";
}
@@ -942,26 +932,15 @@ void CG_AddBulletImpacts()
if (wall_impact_type[0] == 2 || wall_impact_type[0] == 3) {
sSoundName = "snd_bh_metal";
}
else {
} else {
sSoundName = "snd_bh_wood";
}
commandManager.PlaySound(sSoundName, wall_impact_pos[0], -1, fVolume, -1, -1, 1);
sfxManager.MakeEffect_Normal(
wall_impact_type[0],
wall_impact_pos[0],
wall_impact_norm[0]
);
sfxManager.MakeEffect_Normal(wall_impact_type[0], wall_impact_pos[0], wall_impact_norm[0]);
} else {
CG_MakeBulletHole(
wall_impact_pos[0],
wall_impact_norm[0],
wall_impact_large[0],
NULL,
qtrue
);
CG_MakeBulletHole(wall_impact_pos[0], wall_impact_norm[0], wall_impact_large[0], NULL, qtrue);
}
}
@@ -969,15 +948,13 @@ void CG_AddBulletImpacts()
if (wall_impact_type[iImpSndIndexLB]) {
if (wall_impact_large[iImpSndIndexLB]) {
fVolume = 1.f;
}
else {
} else {
fVolume = 0.75f;
}
if (wall_impact_type[iImpSndIndexLB] == 2 || wall_impact_type[iImpSndIndexLB] == 3) {
sSoundName = "snd_bh_metal";
}
else {
} else {
sSoundName = "snd_bh_wood";
}
@@ -998,45 +975,31 @@ void CG_AddBulletImpacts()
);
}
}
}
else
{
} else {
for (i = 0; i < wall_impact_count; i++) {
CG_MakeBulletHole(
wall_impact_pos[i],
wall_impact_norm[i],
wall_impact_large[i],
NULL,
qtrue
);
CG_MakeBulletHole(wall_impact_pos[i], wall_impact_norm[i], wall_impact_large[i], NULL, qtrue);
}
}
wall_impact_count = 0;
}
if (flesh_impact_count)
{
if (flesh_impact_count > 1)
{
fImpSndDistRA = 9999.0;
if (flesh_impact_count) {
if (flesh_impact_count > 1) {
fImpSndDistRA = 9999.0;
iImpSndIndexRA = 0;
for (i = 0; i < flesh_impact_count; i++) {
VectorSubtract(wall_impact_pos[i], cg.SoundOrg, vTmp);
iHeadDist = VectorLength(vTmp);
if (DotProduct(vTmp, cg.SoundAxis[1]) > 0.f)
{
if (iHeadDist < fImpSndDistRA)
{
fImpSndDistRA = iHeadDist;
if (DotProduct(vTmp, cg.SoundAxis[1]) > 0.f) {
if (iHeadDist < fImpSndDistRA) {
fImpSndDistRA = iHeadDist;
iImpSndIndexRA = i;
}
}
else if (iHeadDist < fImpSndDistLA)
{
fImpSndDistRA = iHeadDist;
} else if (iHeadDist < fImpSndDistLA) {
fImpSndDistRA = iHeadDist;
iImpSndIndexRA = i;
}
}
@@ -1105,8 +1068,7 @@ void CG_MakeExplosionEffect(const vec3_t vPos, int iType)
fRadius = 0;
break;
case SURF_SNOW:
switch (iBaseEffect)
{
switch (iBaseEffect) {
case SFX_EXP_TANK_BASE:
iSurfEffect = SFX_EXP_TANK_SNOW;
break;
@@ -1122,7 +1084,7 @@ void CG_MakeExplosionEffect(const vec3_t vPos, int iType)
iBaseEffect = -1;
break;
}
fRadius = 0;
fRadius = 0;
break;
case SURF_CARPET:
iSurfEffect = SFX_EXP_GREN_CARPET;
@@ -1147,8 +1109,7 @@ void CG_MakeExplosionEffect(const vec3_t vPos, int iType)
fRadius = 0;
break;
case SURF_DIRT:
switch (iBaseEffect)
{
switch (iBaseEffect) {
case SFX_EXP_TANK_BASE:
iSurfEffect = SFX_EXP_TANK_DIRT;
break;
@@ -1164,15 +1125,14 @@ void CG_MakeExplosionEffect(const vec3_t vPos, int iType)
iBaseEffect = -1;
break;
}
fRadius = 0;
fRadius = 0;
break;
case SURF_GRILL:
iSurfEffect = SFX_EXP_GREN_GRILL;
fRadius = 0;
break;
case SURF_GRASS:
switch (iBaseEffect)
{
switch (iBaseEffect) {
case SFX_EXP_TANK_BASE:
iSurfEffect = SFX_EXP_TANK_DIRT;
break;
@@ -1190,8 +1150,7 @@ void CG_MakeExplosionEffect(const vec3_t vPos, int iType)
fRadius = 0;
break;
case SURF_ROCK:
switch (iBaseEffect)
{
switch (iBaseEffect) {
case SFX_EXP_TANK_BASE:
iSurfEffect = SFX_EXP_TANK_STONE;
break;
+3 -4
View File
@@ -1182,10 +1182,9 @@ void ClientGameCommandManager::SpawnTempModel(int mcount)
cosa = cos(fAngle);
p->cgd.origin = start + vForward * fHeight;
p->cgd.origin += start + vLeft * (cosa * fRadius);
p->cgd.origin += start + vUp * (sina * fRadius);
} else if (m_spawnthing->sphereRadius != 0) // Offset in a spherical pattern
{
p->cgd.origin += vLeft * (cosa * fRadius);
p->cgd.origin += vUp * (sina * fRadius);
} else if (m_spawnthing->sphereRadius != 0) { // Offset in a spherical pattern
Vector dir, end;
dir = Vector(crandom(), crandom(), crandom());
+8 -8
View File
@@ -882,13 +882,13 @@ void CG_DrawActiveFrame(int serverTime, int frameTime, stereoFrame_t stereoView,
{
default:
case 0:
cgi.UI_ShowMenu("mission_success_1", CVAR_ARCHIVE);
cgi.UI_HideMenu("mission_success_1", CVAR_ARCHIVE);
break;
case 2:
cgi.UI_ShowMenu("mission_success_2", CVAR_ARCHIVE);
cgi.UI_HideMenu("mission_success_2", CVAR_ARCHIVE);
break;
case 3:
cgi.UI_ShowMenu("mission_success_3", CVAR_ARCHIVE);
cgi.UI_HideMenu("mission_success_3", CVAR_ARCHIVE);
break;
}
} else {
@@ -896,21 +896,21 @@ void CG_DrawActiveFrame(int serverTime, int frameTime, stereoFrame_t stereoView,
{
default:
case 0:
cgi.UI_ShowMenu("mission_failed_1", CVAR_ARCHIVE);
cgi.UI_HideMenu("mission_failed_1", CVAR_ARCHIVE);
break;
case 2:
cgi.UI_ShowMenu("mission_failed_2", CVAR_ARCHIVE);
cgi.UI_HideMenu("mission_failed_2", CVAR_ARCHIVE);
break;
case 3:
cgi.UI_ShowMenu("mission_failed_3", CVAR_ARCHIVE);
cgi.UI_HideMenu("mission_failed_3", CVAR_ARCHIVE);
break;
}
}
} else {
if (cgi.Cvar_Get("g_success", "", 0)->integer) {
cgi.UI_ShowMenu("StatsScreen_Success", qfalse);
cgi.UI_HideMenu("StatsScreen_Success", qfalse);
} else {
cgi.UI_ShowMenu("StatsScreen_Failed", qfalse);
cgi.UI_HideMenu("StatsScreen_Failed", qfalse);
}
}
}
+28 -1
View File
@@ -8,7 +8,6 @@ file(GLOB_RECURSE SOURCES_UILIB "../uilib/*.c*")
# Made as an interface and not static, as static only links used methods
add_library(omohclient INTERFACE)
target_sources(omohclient INTERFACE ${SOURCES_CLIENT} ${SOURCES_UILIB})
target_compile_definitions(omohclient INTERFACE APP_MODULE)
target_compile_features(omohclient INTERFACE cxx_nullptr)
target_compile_features(omohclient INTERFACE c_variadic_macros)
@@ -18,5 +17,33 @@ target_link_libraries(omohclient INTERFACE gcd)
# Sound stuff
target_compile_definitions(omohclient INTERFACE USE_CODEC_MP3)
if (USE_SOUND_NEW)
# Try to use OpenAL
find_package(OpenAL)
if (OPENAL_FOUND)
target_compile_definitions(omohclient INTERFACE USE_SOUND_NEW=1)
if (MSVC)
target_include_directories(omohclient INTERFACE ${OPENAL_INCLUDE_DIR}/AL)
else()
target_include_directories(omohclient INTERFACE ${OPENAL_INCLUDE_DIR})
endif()
target_link_libraries(omohclient INTERFACE ${OPENAL_LIBRARY})
endif()
list(FILTER SOURCES_CLIENT EXCLUDE REGEX "./snd_([a-zA-Z0-9_]+)\.c$")
endif()
if (USE_OPENAL)
# Try to use OpenAL
find_package(OpenAL)
if (OPENAL_FOUND)
target_compile_definitions(omohclient INTERFACE USE_OPENAL=1)
target_include_directories(omohclient INTERFACE ${OPENAL_INCLUDE_DIR}/AL)
target_link_libraries(omohclient INTERFACE ${OPENAL_LIBRARY})
endif()
endif()
target_sources(omohclient INTERFACE ${SOURCES_CLIENT} ${SOURCES_UILIB})
add_subdirectory("../libmad-0.15.1b" "./libmad")
target_link_libraries(omohclient INTERFACE libmad)
+4
View File
@@ -334,6 +334,9 @@ writing the actual data can begin
*/
qboolean CL_OpenAVIForWriting( const char *fileName )
{
return qfalse;
// Removed in OPM
#if 0
if( afd.fileOpen )
return qfalse;
@@ -425,6 +428,7 @@ qboolean CL_OpenAVIForWriting( const char *fileName )
afd.fileOpen = qtrue;
return qtrue;
#endif
}
/*
+33 -3
View File
@@ -395,8 +395,8 @@ Set up argc/argv for the given command
===================
*/
qboolean CL_GetServerCommand( int serverCommandNumber, qboolean differentServer ) {
char *s;
char *cmd;
char *s;
char *cmd;
static char bigConfigString[BIG_INFO_STRING];
// if we have irretrievably lost a reliable command, drop the connection
@@ -421,9 +421,39 @@ qboolean CL_GetServerCommand( int serverCommandNumber, qboolean differentServer
Com_DPrintf( "serverCommand: %i : %s\n", serverCommandNumber, s );
}
Cmd_TokenizeString( s );
Cmd_TokenizeString(s);
cmd = Cmd_Argv(0);
// Readded in OPM (from ioquake)
// Configstring big buffer
if (!strcmp(cmd, "bcs0")) {
Com_sprintf(bigConfigString, BIG_INFO_STRING, "cs %s \"%s", Cmd_Argv(1), Cmd_Argv(2));
return qfalse;
}
if (!strcmp(cmd, "bcs1")) {
s = Cmd_Argv(2);
if (strlen(bigConfigString) + strlen(s) >= BIG_INFO_STRING) {
Com_Error(ERR_DROP, "bcs exceeded BIG_INFO_STRING");
}
strcat(bigConfigString, s);
return qfalse;
}
if (!strcmp(cmd, "bcs2")) {
s = Cmd_Argv(2);
if (strlen(bigConfigString) + strlen(s) + 1 >= BIG_INFO_STRING) {
Com_Error(ERR_DROP, "bcs exceeded BIG_INFO_STRING");
}
strcat(bigConfigString, s);
strcat(bigConfigString, "\"");
s = bigConfigString;
// reparse
Cmd_TokenizeString(s);
cmd = Cmd_Argv(0);
}
return CL_ProcessServerCommand(s, cmd, differentServer);
}
+7
View File
@@ -1091,6 +1091,8 @@ static void RoQReset( void ) {
static void RoQInterrupt(void)
{
// Removed in OPM
#if 0
byte *framedata;
short sbuf[32768];
int ssize;
@@ -1214,6 +1216,7 @@ redump:
// assert(cinTable[currentHandle].RoQFrameSize <= 65536);
// r = FS_Read( cin.file, cinTable[currentHandle].RoQFrameSize+8, cinTable[currentHandle].iFile );
cinTable[currentHandle].RoQPlayed += cinTable[currentHandle].RoQFrameSize+8;
#endif
}
/******************************************************************************
@@ -1397,6 +1400,9 @@ CIN_PlayCinematic
==================
*/
int CIN_PlayCinematic( const char *arg, int x, int y, int w, int h, int systemBits ) {
return 0;
// Removed in OPM
#if 0
unsigned short RoQID;
char name[MAX_OSPATH];
int i;
@@ -1478,6 +1484,7 @@ int CIN_PlayCinematic( const char *arg, int x, int y, int w, int h, int systemBi
RoQShutdown();
return -1;
#endif
}
void CIN_SetExtents (int handle, int x, int y, int w, int h) {
+8
View File
@@ -575,6 +575,14 @@ void CL_MouseMove( usercmd_t *cmd ) {
cl.viewangles[PITCH] += m_pitch->value * my;
else
cmd->forwardmove = ClampChar(cmd->forwardmove - m_forward->value * my);
if (!isfinite(cl.viewangles[PITCH]) || !isfinite(cl.viewangles[YAW])) {
Com_Printf("Invalid client viewangles encountered!\n");
Com_Printf("cgameSensitivity: %f - mx: %f - my: %f - m_pitch: %f - m_yaw: %f", cgameSensitivity, mx, my, m_pitch->value, m_yaw->value);
Com_Printf("Resetting client viewangles");
cl.viewangles[PITCH] = 0;
cl.viewangles[YAW] = 0;
}
}
/*
+973 -130
View File
File diff suppressed because it is too large. Load diff
+173 -150
View File
@@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@@ -20,175 +20,198 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#ifndef __CL_INV_H__
#define __CL_INV_H__
#pragma once
typedef enum { INV_MOVE_NONE, INV_MOVE_BOB, INV_MOVE_SPIN } inv_move_type;
typedef enum { INV_CASCADE_LEFT, INV_CASCADE_RIGHT } inv_cascade_type;
typedef enum { INV_HUDANGLES_BASE, INV_HUDANGLES_COMPASS, INV_HUDANGLES_COMPASS_NEEDLE } inv_hudangles_type;
typedef enum {
INV_MOVE_NONE,
INV_MOVE_BOB,
INV_MOVE_SPIN
} inv_move_type;
class item_properties_t : public Class {
public:
float scale;
Vector angles;
Vector angledeltas;
Vector rotateoffset;
Vector offset;
inv_move_type move;
str model;
str anim;
};
typedef enum {
INV_ALIGN_NONE,
INV_ALIGN_LEFT,
INV_ALIGN_RIGHT
} inv_align_type;
class inventory_item_t : public Class {
public:
str name;
str ammoname;
int equip;
int width;
int height;
int barwidth;
int barheight;
int baroffsetY;
int baroffsetX;
float modelWindowX;
float modelWindowY;
float modelWindowWidth;
float modelWindowHeight;
bool selShaderOnTop;
bool checkammo;
str command;
inv_hudangles_type anglesType;
item_properties_t hudprops;
item_properties_t invprops;
UIReggedMaterial *bgshader;
UIReggedMaterial *barshader;
UIReggedMaterial *selshader;
};
typedef enum {
INV_CASCADE_LEFT,
INV_CASCADE_RIGHT
} inv_cascade_type;
class inventory_type_t {
public:
str name;
bool bg_tile;
UIReggedMaterial *texture;
UIReggedMaterial *bg;
UIReggedMaterial *hoverTexture;
UIReggedMaterial *selTexture;
Container<inventory_item_t *> items;
typedef enum {
INV_HUDANGLES_BASE,
INV_HUDANGLES_COMPASS,
INV_HUDANGLES_COMPASS_NEEDLE
} inv_hudangles_type;
int IndexOfItemPtr( inventory_item_t *item );
};
inline
int inventory_type_t::IndexOfItemPtr( inventory_item_t *item )
class item_properties_t : public Class
{
for( int i = items.NumObjects(); i > 0; i-- )
{
if( items.ObjectAt( i ) == item )
{
return i;
}
}
public:
float scale;
Vector angles;
Vector angledeltas;
Vector rotateoffset;
Vector offset;
inv_move_type move;
str model;
str anim;
};
return 0;
class inventory_item_t : public Class
{
public:
str name;
str ammoname;
int equip;
int width;
int height;
int barwidth;
int barheight;
int baroffsetY;
int baroffsetX;
float modelWindowX;
float modelWindowY;
float modelWindowWidth;
float modelWindowHeight;
bool selShaderOnTop;
bool checkammo;
str command;
inv_hudangles_type anglesType;
item_properties_t hudprops;
item_properties_t invprops;
UIReggedMaterial *bgshader;
UIReggedMaterial *barshader;
UIReggedMaterial *selshader;
};
class inventory_type_t
{
public:
str name;
bool bg_tile;
UIReggedMaterial *texture;
UIReggedMaterial *bg;
UIReggedMaterial *hoverTexture;
UIReggedMaterial *selTexture;
Container<inventory_item_t *> items;
int IndexOfItemPtr(inventory_item_t *item);
};
inline int inventory_type_t::IndexOfItemPtr(inventory_item_t *item)
{
for (int i = items.NumObjects(); i > 0; i--) {
if (items.ObjectAt(i) == item) {
return i;
}
}
return 0;
}
class inventory_t {
class inventory_t
{
public:
int typewidth;
int typeheight;
int horizoffset;
int vertoffset;
int align;
inv_cascade_type cascade;
str selectsound;
str rejectsound;
str changesound;
Container<inventory_type_t *> types;
int typewidth;
int typeheight;
int horizoffset;
int vertoffset;
inv_align_type align;
inv_cascade_type cascade;
str selectsound;
str rejectsound;
str changesound;
Container<inventory_type_t *> types;
void Clear() { types.ClearObjectList(); }
public:
inventory_t();
~inventory_t();
inventory_t(const inventory_t& other);
inventory_t& operator=(const inventory_t& other);
void Clear();
};
class invlistener : public Listener {
class invlistener : public Listener
{
protected:
inventory_t *inv;
inventory_type_t *curtype;
inventory_item_t *curitem;
int defaultWidth;
int defaultHeight;
int defaultBarWidth;
int defaultBarHeight;
int defaultBarOffsetX;
int defaultBarOffsetY;
inventory_t *inv;
inventory_type_t *curtype;
inventory_item_t *curitem;
int defaultWidth;
int defaultHeight;
int defaultBarWidth;
int defaultBarHeight;
int defaultBarOffsetX;
int defaultBarOffsetY;
public:
CLASS_PROTOTYPE( invlistener );
CLASS_PROTOTYPE(invlistener);
protected:
void verify_curitem( void );
void verify_curtype( void );
void verify_one_arg( Event *ev );
void verify_curitem(void);
void verify_curtype(void);
void verify_one_arg(Event *ev);
public:
invlistener( inventory_t *i );
invlistener();
invlistener(inventory_t *i);
invlistener();
bool Load( Script& script );
void InvSelectSound( Event *ev );
void InvRejectSound( Event *ev );
void InvChangeSound( Event *ev );
void InvWidth( Event *ev );
void InvHeight( Event *ev );
void InvHorizOffset( Event *ev );
void InvVertOffset( Event *ev );
void InvAlign( Event *ev );
void InvCascade( Event *ev );
void Typedef( Event *ev );
void OpenBrace( Event *ev );
void CloseBrace( Event *ev );
void ButtonShader( Event *ev );
void HoverShader( Event *ev );
void SelShader( Event *ev );
void Background( Event *ev );
void BackgroundTile( Event *ev );
void Width( Event *ev );
void Height( Event *ev );
void BarWidth( Event *ev );
void BarHeight( Event *ev );
void BarOffsetX( Event *ev );
void BarOffsetY( Event *ev );
void Item( Event *ev );
void Ammo( Event *ev );
void Equip( Event *ev );
void CheckAmmo( Event *ev );
void Command( Event *ev );
void BGShader( Event *ev );
void BarShader( Event *ev );
void SelItemShader( Event *ev );
void SelItemShaderOnTop( Event *ev );
void RotateOffset( Event *ev );
void Offset( Event *ev );
void Model( Event *ev );
void Anim( Event *ev );
void Scale( Event *ev );
void Angles( Event *ev );
void AngleDeltas( Event *ev );
void Move( Event *ev );
void ModelWindow( Event *ev );
void HudRotateOffset( Event *ev );
void HudOffset( Event *ev );
void HudModel( Event *ev );
void HudAnim( Event *ev );
void HudScale( Event *ev );
void HudAngles( Event *ev );
void HudAngleDeltas( Event *ev );
void HudMove( Event *ev );
void HudCompassAngles( Event *ev );
void HudCompassNeedleAngles( Event *ev );
bool Load(Script& script);
void InvSelectSound(Event *ev);
void InvRejectSound(Event *ev);
void InvChangeSound(Event *ev);
void InvWidth(Event *ev);
void InvHeight(Event *ev);
void InvHorizOffset(Event *ev);
void InvVertOffset(Event *ev);
void InvAlign(Event *ev);
void InvCascade(Event *ev);
void Typedef(Event *ev);
void OpenBrace(Event *ev);
void CloseBrace(Event *ev);
void ButtonShader(Event *ev);
void HoverShader(Event *ev);
void SelShader(Event *ev);
void Background(Event *ev);
void BackgroundTile(Event *ev);
void Width(Event *ev);
void Height(Event *ev);
void BarWidth(Event *ev);
void BarHeight(Event *ev);
void BarOffsetX(Event *ev);
void BarOffsetY(Event *ev);
void Item(Event *ev);
void Ammo(Event *ev);
void Equip(Event *ev);
void CheckAmmo(Event *ev);
void Command(Event *ev);
void BGShader(Event *ev);
void BarShader(Event *ev);
void SelItemShader(Event *ev);
void SelItemShaderOnTop(Event *ev);
void RotateOffset(Event *ev);
void Offset(Event *ev);
void Model(Event *ev);
void Anim(Event *ev);
void Scale(Event *ev);
void Angles(Event *ev);
void AngleDeltas(Event *ev);
void Move(Event *ev);
void ModelWindow(Event *ev);
void HudRotateOffset(Event *ev);
void HudOffset(Event *ev);
void HudModel(Event *ev);
void HudAnim(Event *ev);
void HudScale(Event *ev);
void HudAngles(Event *ev);
void HudAngleDeltas(Event *ev);
void HudMove(Event *ev);
void HudCompassAngles(Event *ev);
void HudCompassNeedleAngles(Event *ev);
};
bool CL_LoadInventory( const char *filename, inventory_t *inv );
inventory_item_t *CL_GetInvItemByName( inventory_t *inv, const char *name );
qboolean CL_HasInventoryItem( const char *name );
void CL_AmmoCount( const char *name, int *ammo_count, int *max_ammo_count );
#endif // __CL_INV_H__
bool CL_LoadInventory(const char *filename, inventory_t *inv);
inventory_item_t *CL_GetInvItemByName(inventory_t *inv, const char *name);
qboolean CL_HasInventoryItem(const char *name);
void CL_AmmoCount(const char *name, int *ammo_count, int *max_ammo_count);
File diff suppressed because it is too large. Load diff
+81 -58
View File
@@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@@ -20,79 +20,102 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#ifndef __CL_INVRENDER_H__
#define __CL_INVRENDER_H__
#pragma once
class FakkInventory;
typedef enum { selectsound, rejectsound, changesound } invsound_t;
class FakkItemList : public UIWidget {
typedef enum {
selectsound,
rejectsound,
changesound
} invsound_t;
class FakkItemList : public UIWidget
{
protected:
inventory_type_t *type;
uipopup_describe m_describe[ 10 ];
inventory_item_t *m_hoveritem;
inventory_item_t *m_lastmenuitem;
FakkInventory *m_parent;
float m_hovertop;
inventory_type_t *type;
uipopup_describe m_describe[10];
inventory_item_t *m_hoveritem;
inventory_item_t *m_lastmenuitem;
FakkInventory *m_parent;
float m_hovertop;
public:
CLASS_PROTOTYPE( FakkItemList );
CLASS_PROTOTYPE(FakkItemList);
FakkItemList();
~FakkItemList();
FakkItemList();
~FakkItemList();
void VerifyItemUp( inventory_item_t *item, qboolean warpmouse );
void setType( inventory_type_t *t );
void Create( float x, float y, FakkInventory *parent );
bool HasAnyItems( void );
void Draw( void ) override;
void OnLeftMouseDown( Event *ev );
void OnRightMouseDown( Event *ev );
void OnLeftMouseUp( Event *ev );
void OnRightMouseUp( Event *ev );
void OnMouseMove( Event *ev );
void OnMouseEnter( Event *ev );
void OnMouseLeave( Event *ev );
void OnMenuKilled( Event *ev );
void EquipItem( Event *ev );
void VerifyItemUp(inventory_item_t *item, qboolean warpmouse);
void setType(inventory_type_t *t);
void Create(float x, float y, FakkInventory *parent);
bool HasAnyItems(void);
void Draw(void) override;
void OnLeftMouseDown(Event *ev);
void OnRightMouseDown(Event *ev);
void OnLeftMouseUp(Event *ev);
void OnRightMouseUp(Event *ev);
void OnMouseMove(Event *ev);
void OnMouseEnter(Event *ev);
void OnMouseLeave(Event *ev);
void OnMenuKilled(Event *ev);
void EquipItem(Event *ev);
inventory_item_t *getHoverItem() const;
};
class FakkInventory : public UIWidget {
class FakkInventory : public UIWidget
{
protected:
inventory_t *m_inv;
SafePtr<FakkItemList> m_currentlist;
inventory_type_t *m_currenttype;
int m_currentitemnum;
inventory_t *m_inv;
SafePtr<FakkItemList> m_currentlist;
inventory_type_t *m_currenttype;
int m_currentitemnum;
public:
CLASS_PROTOTYPE( FakkInventory );
protected:
void VerifyItemUp( inventory_item_t *item, qboolean warpmouse );
CLASS_PROTOTYPE(FakkInventory);
public:
FakkInventory();
~FakkInventory();
qboolean m_mouse_active;
void setInventory( inventory_t *i );
void Draw( void ) override;
void OnMouseMove( Event *ev );
void OnMouseLeave( Event *ev );
void OnMouseEnter( Event *ev );
void OnMouseDown( Event *ev );
void WarpTo( const char *name );
void WarpTo( int slotnum );
void NextItem( void );
void PrevItem( void );
qboolean isDying( void );
qboolean KeyEvent( int key, unsigned int time ) override;
void PlaySound( invsound_t type );
void Timeout( Event *ev );
void ChangeItem( int sign );
int FindFirstItem( int itemindex, int sign );
protected:
void VerifyTypeUp(inventory_type_t *t, qboolean warpmouse);
public:
FakkInventory();
~FakkInventory();
void setInventory(inventory_t *i);
void Draw(void) override;
void OnMouseMove(Event *ev);
void OnMouseLeave(Event *ev);
void OnMouseEnter(Event *ev);
void OnMouseDown(Event *ev);
void WarpTo(const char *name);
void WarpTo(int slotnum);
void NextItem(void);
void PrevItem(void);
qboolean isDying(void);
qboolean KeyEvent(int key, unsigned int time) override;
void PlaySound(invsound_t type);
void Timeout(Event *ev);
void ChangeItem(int sign);
int FindFirstItem(int itemindex, int sign);
};
void CL_Draw3DModel( float x, float y, float w, float h, qhandle_t model, vec3_t origin, vec3_t rotateoffset, vec3_t offset, vec3_t angle, vec3_t color, str anim );
qboolean UI_CloseInventory( void );
void CL_Draw3DModel(
float x,
float y,
float w,
float h,
qhandle_t model,
vec3_t origin,
vec3_t rotateoffset,
vec3_t offset,
vec3_t angle,
vec3_t color,
str anim
);
#endif // __CL_INVRENDER_H__
void UI_DoInventory(qboolean activate_mouse);
qboolean UI_CloseInventory(void);
+927 -915
View File
File diff suppressed because it is too large. Load diff
+290 -174
View File
@@ -769,7 +769,9 @@ void CL_ShutdownAll(qboolean shutdownRef) {
CL_cURL_Shutdown();
#endif
// clear sounds
#if !defined(USE_SOUND_NEW) || !USE_SOUND_NEW
S_DisableSounds();
#endif
// shutdown CGame
CL_ShutdownCGame();
// shutdown UI
@@ -1547,7 +1549,11 @@ void CL_Vid_Restart_f( void ) {
SV_FinishSvsTimeFixups();
#if !defined(USE_SOUND_NEW) || !USE_SOUND_NEW
S_Init();
#else
S_Init(qtrue);
#endif
if (clc.state > CA_CONNECTED && clc.state != CA_CINEMATIC)
{
@@ -1569,8 +1575,13 @@ handles will be invalid
=================
*/
void CL_Snd_Restart_f( void ) {
#if !defined(USE_SOUND_NEW) || !USE_SOUND_NEW
S_Shutdown();
S_Init();
#else
S_Shutdown(qfalse);
S_Init(qfalse);
#endif
CL_Vid_Restart_f();
}
@@ -2017,13 +2028,8 @@ void CL_MotdPacket( netadr_t from ) {
CL_InitServerInfo
===================
*/
void CL_InitServerInfo( serverInfo_t *server, serverAddress_t *address ) {
server->adr.type = NA_IP;
server->adr.ip[0] = address->ip[0];
server->adr.ip[1] = address->ip[1];
server->adr.ip[2] = address->ip[2];
server->adr.ip[3] = address->ip[3];
server->adr.port = address->port;
void CL_InitServerInfo( serverInfo_t *server, netadr_t *address ) {
server->adr = *address;
server->clients = 0;
server->hostName[0] = '\0';
server->mapName[0] = '\0';
@@ -2043,14 +2049,14 @@ void CL_InitServerInfo( serverInfo_t *server, serverAddress_t *address ) {
CL_ServersResponsePacket
===================
*/
void CL_ServersResponsePacket( netadr_t from, msg_t *msg ) {
int i, count, max, total;
serverAddress_t addresses[MAX_SERVERSPERPACKET];
void CL_ServersResponsePacket( const netadr_t* from, msg_t *msg, qboolean extended ) {
int i, j, count, total;
netadr_t addresses[MAX_SERVERSPERPACKET];
int numservers;
byte* buffptr;
byte* buffend;
Com_Printf("CL_ServersResponsePacket\n");
Com_Printf("CL_ServersResponsePacket from %s\n", NET_AdrToStringwPort(*from));
if (cls.numglobalservers == -1) {
// state to detect lack of servers or lack of response
@@ -2058,71 +2064,84 @@ void CL_ServersResponsePacket( netadr_t from, msg_t *msg ) {
cls.numGlobalServerAddresses = 0;
}
if (cls.nummplayerservers == -1) {
cls.nummplayerservers = 0;
}
// parse through server response string
numservers = 0;
buffptr = msg->data;
buffend = buffptr + msg->cursize;
while (buffptr+1 < buffend) {
// advance to initial token
do {
if (*buffptr++ == '\\')
break;
}
while (buffptr < buffend);
if ( buffptr >= buffend - 6 ) {
// advance to initial token
do
{
if(*buffptr == '\\' || (extended && *buffptr == '/'))
break;
buffptr++;
} while (buffptr < buffend);
while (buffptr + 1 < buffend)
{
// IPv4 address
if (*buffptr == '\\')
{
buffptr++;
if (buffend - buffptr < sizeof(addresses[numservers].ip) + sizeof(addresses[numservers].port) + 1)
break;
for(i = 0; i < sizeof(addresses[numservers].ip); i++)
addresses[numservers].ip[i] = *buffptr++;
addresses[numservers].type = NA_IP;
}
// IPv6 address, if it's an extended response
else if (extended && *buffptr == '/')
{
buffptr++;
// parse out ip
addresses[numservers].ip[0] = *buffptr++;
addresses[numservers].ip[1] = *buffptr++;
addresses[numservers].ip[2] = *buffptr++;
addresses[numservers].ip[3] = *buffptr++;
if (buffend - buffptr < sizeof(addresses[numservers].ip6) + sizeof(addresses[numservers].port) + 1)
break;
for(i = 0; i < sizeof(addresses[numservers].ip6); i++)
addresses[numservers].ip6[i] = *buffptr++;
addresses[numservers].type = NA_IP6;
addresses[numservers].scope_id = from->scope_id;
}
else
// syntax error!
break;
// parse out port
addresses[numservers].port = (*buffptr++)<<8;
addresses[numservers].port = (*buffptr++) << 8;
addresses[numservers].port += *buffptr++;
addresses[numservers].port = BigShort( addresses[numservers].port );
// syntax check
if (*buffptr != '\\') {
if (*buffptr != '\\' && *buffptr != '/')
break;
}
Com_DPrintf( "server: %d ip: %d.%d.%d.%d:%d\n",numservers,
addresses[numservers].ip[0],
addresses[numservers].ip[1],
addresses[numservers].ip[2],
addresses[numservers].ip[3],
addresses[numservers].port );
numservers++;
if (numservers >= MAX_SERVERSPERPACKET) {
if (numservers >= MAX_SERVERSPERPACKET)
break;
}
// parse out EOT
if (buffptr[1] == 'E' && buffptr[2] == 'O' && buffptr[3] == 'T') {
break;
}
}
if (cls.masterNum == 0) {
count = cls.numglobalservers;
max = MAX_GLOBAL_SERVERS;
} else {
count = cls.nummplayerservers;
max = MAX_OTHER_SERVERS;
}
count = cls.numglobalservers;
for (i = 0; i < numservers && count < max; i++) {
for (i = 0; i < numservers && count < MAX_GLOBAL_SERVERS; i++) {
// build net address
serverInfo_t *server = (cls.masterNum == 0) ? &cls.globalServers[count] : &cls.mplayerServers[count];
serverInfo_t *server = &cls.globalServers[count];
// Tequila: It's possible to have sent many master server requests. Then
// we may receive many times the same addresses from the master server.
// We just avoid to add a server if it is still in the global servers list.
for (j = 0; j < count; j++)
{
if (NET_CompareAdr(cls.globalServers[j].adr, addresses[i]))
break;
}
if (j < count)
continue;
CL_InitServerInfo( server, &addresses[i] );
// advance to next slot
@@ -2130,29 +2149,18 @@ void CL_ServersResponsePacket( netadr_t from, msg_t *msg ) {
}
// if getting the global list
if (cls.masterNum == 0) {
if ( cls.numGlobalServerAddresses < MAX_GLOBAL_SERVERS ) {
// if we couldn't store the servers in the main list anymore
for (; i < numservers && count >= max; i++) {
serverAddress_t *addr;
// just store the addresses in an additional list
addr = &cls.globalServerAddresses[cls.numGlobalServerAddresses++];
addr->ip[0] = addresses[i].ip[0];
addr->ip[1] = addresses[i].ip[1];
addr->ip[2] = addresses[i].ip[2];
addr->ip[3] = addresses[i].ip[3];
addr->port = addresses[i].port;
}
if ( count >= MAX_GLOBAL_SERVERS && cls.numGlobalServerAddresses < MAX_GLOBAL_SERVERS )
{
// if we couldn't store the servers in the main list anymore
for (; i < numservers && cls.numGlobalServerAddresses < MAX_GLOBAL_SERVERS; i++)
{
// just store the addresses in an additional list
cls.globalServerAddresses[cls.numGlobalServerAddresses++] = addresses[i];
}
}
if (cls.masterNum == 0) {
cls.numglobalservers = count;
total = count + cls.numGlobalServerAddresses;
} else {
cls.nummplayerservers = count;
total = count;
}
cls.numglobalservers = count;
total = count + cls.numGlobalServerAddresses;
Com_Printf("%d servers parsed (total %d)\n", numservers, total);
}
@@ -2280,7 +2288,7 @@ void CL_ConnectionlessPacket( netadr_t from, msg_t *msg ) {
// echo request from server
if ( !Q_strncmp(c, "getserversResponse", 18) ) {
CL_ServersResponsePacket( from, msg );
CL_ServersResponsePacket( &from, msg, qfalse );
return;
}
@@ -3390,7 +3398,9 @@ void CL_Init( void ) {
Cvar_Set( "cl_running", "1" );
#if !defined(USE_SOUND_NEW) || !USE_SOUND_NEW
S_Init2();
#endif
// fixme: should we leave it?
CL_GenerateQKey();
@@ -3431,7 +3441,11 @@ void CL_Shutdown(const char* finalmsg, qboolean disconnect, qboolean quit) {
if(disconnect)
CL_Disconnect();
#if !defined(USE_SOUND_NEW) || !USE_SOUND_NEW
S_Shutdown();
#else
S_Shutdown(qtrue);
#endif
CL_ShutdownRef();
CL_ShutdownUI();
@@ -3523,15 +3537,39 @@ CL_ServerInfoPacket
void CL_ServerInfoPacket( netadr_t from, msg_t *msg ) {
int i, type;
char info[MAX_INFO_STRING];
const char* str;
char *infoString;
int prot;
char *gamename;
qboolean gameMismatch;
infoString = MSG_ReadString( msg );
// if this isn't the correct gamename, ignore it
gamename = Info_ValueForKey( infoString, "gamename" );
#ifdef LEGACY_PROTOCOL
// gamename is optional for legacy protocol
if (com_legacyprotocol->integer && !*gamename)
gameMismatch = qfalse;
else
#endif
gameMismatch = !*gamename || strcmp(gamename, com_gamename->string) != 0;
if (gameMismatch)
{
Com_DPrintf( "Game mismatch in info packet: %s\n", infoString );
return;
}
// if this isn't the correct protocol version, ignore it
prot = atoi( Info_ValueForKey( infoString, "protocol" ) );
if ( prot != PROTOCOL_VERSION ) {
if(prot != com_protocol->integer
#ifdef LEGACY_PROTOCOL
&& prot != com_legacyprotocol->integer
#endif
)
{
Com_DPrintf( "Different protocol info packet: %s\n", infoString );
return;
}
@@ -3542,7 +3580,7 @@ void CL_ServerInfoPacket( netadr_t from, msg_t *msg ) {
if ( cl_pinglist[i].adr.port && !cl_pinglist[i].time && NET_CompareAdr( from, cl_pinglist[i].adr ) )
{
// calc ping time
cl_pinglist[i].time = cls.realtime - cl_pinglist[i].start + 1;
cl_pinglist[i].time = Sys_Milliseconds() - cl_pinglist[i].start;
Com_DPrintf( "ping time %dms from %s\n", cl_pinglist[i].time, NET_AdrToString( from ) );
// save of info
@@ -3554,12 +3592,12 @@ void CL_ServerInfoPacket( netadr_t from, msg_t *msg ) {
{
case NA_BROADCAST:
case NA_IP:
str = "udp";
type = 1;
break;
case NA_IP6:
type = 2;
break;
default:
str = "???";
type = 0;
break;
}
@@ -3594,24 +3632,16 @@ void CL_ServerInfoPacket( netadr_t from, msg_t *msg ) {
// add this to the list
cls.numlocalservers = i+1;
cls.localServers[i].adr = from;
cls.localServers[i].clients = 0;
cls.localServers[i].hostName[0] = '\0';
cls.localServers[i].mapName[0] = '\0';
cls.localServers[i].maxClients = 0;
cls.localServers[i].maxPing = 0;
cls.localServers[i].minPing = 0;
cls.localServers[i].ping = -1;
cls.localServers[i].game[0] = '\0';
cls.localServers[i].gameType = 0;
cls.localServers[i].netType = from.type;
cls.bNewLocalServerInfo = true;
CL_InitServerInfo( &cls.localServers[i], &from );
CL_SetServerInfo( &cls.localServers[i], infoString, 0 );
Q_strncpyz( info, MSG_ReadString( msg ), MAX_INFO_STRING );
if (strlen(info)) {
if (info[strlen(info)-1] != '\n') {
strncat(info, "\n", sizeof(info) - 1);
Q_strcat(info, sizeof(info), "\n");
}
Com_Printf( "%s: %s", NET_AdrToString( from ), info );
Com_Printf( "%s: %s", NET_AdrToStringwPort( from ), info );
}
}
@@ -3621,10 +3651,8 @@ CL_GetServerStatus
===================
*/
serverStatus_t *CL_GetServerStatus( netadr_t from ) {
serverStatus_t *serverStatus;
int i, oldest, oldestTime;
serverStatus = NULL;
for (i = 0; i < MAX_SERVERSTATUSREQUESTS; i++) {
if ( NET_CompareAdr( from, cl_serverStatusList[i].address ) ) {
return &cl_serverStatusList[i];
@@ -3643,11 +3671,7 @@ serverStatus_t *CL_GetServerStatus( netadr_t from ) {
oldestTime = cl_serverStatusList[i].startTime;
}
}
if (oldest != -1) {
return &cl_serverStatusList[oldest];
}
serverStatusCount++;
return &cl_serverStatusList[serverStatusCount & (MAX_SERVERSTATUSREQUESTS-1)];
return &cl_serverStatusList[oldest];
}
/*
@@ -3669,7 +3693,7 @@ int CL_ServerStatus( const char *serverAddress, char *serverStatusString, int ma
return qfalse;
}
// get the address
if ( !NET_StringToAdr( serverAddress, &to, NA_IP ) ) {
if ( !NET_StringToAdr( serverAddress, &to, NA_UNSPEC) ) {
return qfalse;
}
serverStatus = CL_GetServerStatus( to );
@@ -3681,7 +3705,7 @@ int CL_ServerStatus( const char *serverAddress, char *serverStatusString, int ma
// if this server status request has the same address
if ( NET_CompareAdr( to, serverStatus->address) ) {
// if we recieved an response for this server status request
// if we received a response for this server status request
if (!serverStatus->pending) {
Q_strncpyz(serverStatusString, serverStatus->string, maxLen);
serverStatus->retrieved = qtrue;
@@ -3719,10 +3743,10 @@ CL_ServerStatusResponse
===================
*/
void CL_ServerStatusResponse( netadr_t from, msg_t *msg ) {
const char *s;
char *s;
char info[MAX_INFO_STRING];
int i, l, score, ping;
size_t len;
int len;
serverStatus_t *serverStatus;
serverStatus = NULL;
@@ -3821,6 +3845,7 @@ void CL_LocalServers_f( void ) {
// reset the list, waiting for response
cls.numlocalservers = 0;
cls.bNewLocalServerInfo = true;
cls.pingUpdateSource = AS_LOCAL;
for (i = 0; i < MAX_OTHER_SERVERS; i++) {
@@ -3845,6 +3870,9 @@ void CL_LocalServers_f( void ) {
to.type = NA_BROADCAST;
NET_SendPacket( NS_CLIENT, strlen( message ), message, to );
// Added in OPM (from ioquake3)
to.type = NA_MULTICAST6;
NET_SendPacket( NS_CLIENT, strlen( message ), message, to );
}
}
}
@@ -3972,47 +4000,101 @@ void CL_GamespyServers_f( void ) {
/*
==================
CL_GlobalServers_f
Originally master 0 was Internet and master 1 was MPlayer.
ioquake3 2008; added support for requesting five separate master servers using 0-4.
ioquake3 2017; made master 0 fetch all master servers and 1-5 request a single master server.
==================
*/
void CL_GlobalServers_f( void ) {
netadr_t to;
int i;
int count;
char *buffptr;
char command[1024];
int count, i, masterNum;
char command[1024], *masteraddress;
if ((count = Cmd_Argc()) < 3 || (masterNum = atoi(Cmd_Argv(1))) < 0 || masterNum > MAX_MASTER_SERVERS)
{
Com_Printf("usage: globalservers <master# 0-%d> <protocol> [keywords]\n", MAX_MASTER_SERVERS);
return;
}
if ( Cmd_Argc() < 3) {
Com_Printf( "usage: globalservers <master# 0-1> <protocol> [keywords]\n");
// request from all master servers
if ( masterNum == 0 ) {
int numAddress = 0;
for ( i = 1; i <= MAX_MASTER_SERVERS; i++ ) {
sprintf(command, "sv_master%d", i);
masteraddress = Cvar_VariableString(command);
if(!*masteraddress)
continue;
numAddress++;
Com_sprintf(command, sizeof(command), "globalservers %d %s %s\n", i, Cmd_Argv(2), Cmd_ArgsFrom(3));
Cbuf_AddText(command);
}
if ( !numAddress ) {
Com_Printf( "CL_GlobalServers_f: Error: No master server addresses.\n");
}
return;
}
cls.masterNum = atoi( Cmd_Argv(1) );
Com_Printf( "Requesting servers from the master...\n");
sprintf(command, "sv_master%d", masterNum);
masteraddress = Cvar_VariableString(command);
if(!*masteraddress)
{
Com_Printf( "CL_GlobalServers_f: Error: No master server address given.\n");
return;
}
// reset the list, waiting for response
// -1 is used to distinguish a "no response"
NET_StringToAdr( cl_master->string, &to, NA_IP );
if( cls.masterNum == 1 ) {
cls.nummplayerservers = -1;
cls.pingUpdateSource = AS_MPLAYER;
i = NET_StringToAdr(masteraddress, &to, NA_UNSPEC);
if(!i)
{
Com_Printf( "CL_GlobalServers_f: Error: could not resolve address of master %s\n", masteraddress);
return;
}
else {
cls.numglobalservers = -1;
cls.pingUpdateSource = AS_GLOBAL;
else if(i == 2)
to.port = BigShort(PORT_MASTER);
Com_Printf("Requesting servers from %s (%s)...\n", masteraddress, NET_AdrToStringwPort(to));
cls.numglobalservers = -1;
cls.pingUpdateSource = AS_GLOBAL;
// Use the extended query for IPv6 masters
if (to.type == NA_IP6 || to.type == NA_MULTICAST6)
{
int v4enabled = Cvar_VariableIntegerValue("net_enabled") & NET_ENABLEV4;
if(v4enabled)
{
Com_sprintf(command, sizeof(command), "getserversExt %s %s",
com_gamename->string, Cmd_Argv(2));
}
else
{
Com_sprintf(command, sizeof(command), "getserversExt %s %s ipv6",
com_gamename->string, Cmd_Argv(2));
}
}
to.type = NA_IP;
to.port = BigShort(PORT_MASTER);
//else if ( !Q_stricmp( com_gamename->string, LEGACY_MASTER_GAMENAME ) )
// Com_sprintf(command, sizeof(command), "getservers %s",
// Cmd_Argv(2));
else
Com_sprintf(command, sizeof(command), "getservers %s %s",
com_gamename->string, Cmd_Argv(2));
sprintf( command, "getservers %s", Cmd_Argv(2) );
// tack on keywords
buffptr = command + strlen( command );
count = Cmd_Argc();
for (i=3; i<count; i++)
buffptr += sprintf( buffptr, " %s", Cmd_Argv(i) );
for (i=3; i < count; i++)
{
Q_strcat(command, sizeof(command), " ");
Q_strcat(command, sizeof(command), Cmd_Argv(i));
}
NET_OutOfBandPrint( NS_SERVER, to, "%s", command );
}
@@ -4029,22 +4111,22 @@ void CL_GetPing( int n, char *buf, int buflen, int *pingtime )
int time;
int maxPing;
if (!cl_pinglist[n].adr.port)
if (n < 0 || n >= MAX_PINGREQUESTS || !cl_pinglist[n].adr.port)
{
// empty slot
// empty or invalid slot
buf[0] = '\0';
*pingtime = 0;
return;
}
str = NET_AdrToString( cl_pinglist[n].adr );
str = NET_AdrToStringwPort( cl_pinglist[n].adr );
Q_strncpyz( buf, str, buflen );
time = cl_pinglist[n].time;
if (!time)
{
// check for timeout
time = cls.realtime - cl_pinglist[n].start;
time = Sys_Milliseconds() - cl_pinglist[n].start;
maxPing = Cvar_VariableIntegerValue( "cl_maxPing" );
if( maxPing < 100 ) {
maxPing = 100;
@@ -4083,9 +4165,9 @@ CL_GetPingInfo
*/
void CL_GetPingInfo( int n, char *buf, int buflen )
{
if (!cl_pinglist[n].adr.port)
if (n < 0 || n >= MAX_PINGREQUESTS || !cl_pinglist[n].adr.port)
{
// empty slot
// empty or invalid slot
if (buflen)
buf[0] = '\0';
return;
@@ -4138,7 +4220,7 @@ CL_GetFreePing
ping_t* CL_GetFreePing( void )
{
ping_t* pingptr;
ping_t* best;
ping_t* best;
int oldest;
int i;
int time;
@@ -4151,7 +4233,7 @@ ping_t* CL_GetFreePing( void )
{
if (!pingptr->time)
{
if (cls.realtime - pingptr->start < 500)
if (Sys_Milliseconds() - pingptr->start < 500)
{
// still waiting for response
continue;
@@ -4176,7 +4258,7 @@ ping_t* CL_GetFreePing( void )
for (i=0; i<MAX_PINGREQUESTS; i++, pingptr++ )
{
// scan for oldest
time = cls.realtime - pingptr->start;
time = Sys_Milliseconds() - pingptr->start;
if (time > oldest)
{
oldest = time;
@@ -4196,29 +4278,45 @@ void CL_Ping_f( void ) {
netadr_t to;
ping_t* pingptr;
char* server;
int argc;
netadrtype_t family = NA_UNSPEC;
if ( Cmd_Argc() != 2 ) {
Com_Printf( "usage: ping [server]\n");
return;
argc = Cmd_Argc();
if ( argc != 2 && argc != 3 ) {
Com_Printf( "usage: ping [-4|-6] server\n");
return;
}
if(argc == 2)
server = Cmd_Argv(1);
else
{
if(!strcmp(Cmd_Argv(1), "-4"))
family = NA_IP;
else if(!strcmp(Cmd_Argv(1), "-6"))
family = NA_IP6;
else
Com_Printf( "warning: only -4 or -6 as address type understood.\n");
server = Cmd_Argv(2);
}
Com_Memset( &to, 0, sizeof(netadr_t) );
server = Cmd_Argv(1);
if ( !NET_StringToAdr( server, &to, NA_IP ) ) {
if ( !NET_StringToAdr( server, &to, family ) ) {
return;
}
pingptr = CL_GetFreePing();
memcpy( &pingptr->adr, &to, sizeof (netadr_t) );
pingptr->start = cls.realtime;
pingptr->start = Sys_Milliseconds();
pingptr->time = 0;
CL_SetServerInfoByAddress(pingptr->adr, NULL, 0);
NET_OutOfBandPrint( NS_CLIENT, to, "\x02getinfo" );
NET_OutOfBandPrint( NS_CLIENT, to, "\x02getinfo xxx" );
}
/*
@@ -4342,16 +4440,11 @@ qboolean CL_UpdateVisiblePings_f(int source) {
if (slots < MAX_PINGREQUESTS) {
serverInfo_t *server = NULL;
max = (source == AS_GLOBAL) ? MAX_GLOBAL_SERVERS : MAX_OTHER_SERVERS;
switch (source) {
case AS_LOCAL :
server = &cls.localServers[0];
max = cls.numlocalservers;
break;
case AS_MPLAYER :
server = &cls.mplayerServers[0];
max = cls.nummplayerservers;
break;
case AS_GLOBAL :
server = &cls.globalServers[0];
max = cls.numglobalservers;
@@ -4360,6 +4453,8 @@ qboolean CL_UpdateVisiblePings_f(int source) {
server = &cls.favoriteServers[0];
max = cls.numfavoriteservers;
break;
default:
return qfalse;
}
for (i = 0; i < max; i++) {
if (server[i].visible) {
@@ -4386,7 +4481,7 @@ qboolean CL_UpdateVisiblePings_f(int source) {
}
}
memcpy(&cl_pinglist[j].adr, &server[i].adr, sizeof(netadr_t));
cl_pinglist[j].start = cls.realtime;
cl_pinglist[j].start = Sys_Milliseconds();
cl_pinglist[j].time = 0;
NET_OutOfBandPrint( NS_CLIENT, cl_pinglist[j].adr, "getinfo xxx" );
slots++;
@@ -4408,7 +4503,7 @@ qboolean CL_UpdateVisiblePings_f(int source) {
}
}
}
}
}
if (slots) {
status = qtrue;
@@ -4433,32 +4528,53 @@ CL_ServerStatus_f
==================
*/
void CL_ServerStatus_f(void) {
netadr_t to;
netadr_t to, *toptr = NULL;
char *server;
serverStatus_t *serverStatus;
int argc;
netadrtype_t family = NA_UNSPEC;
Com_Memset( &to, 0, sizeof(netadr_t) );
argc = Cmd_Argc();
if ( Cmd_Argc() != 2 ) {
if ( clc.state != CA_ACTIVE || clc.demoplaying ) {
if ( argc != 2 && argc != 3 )
{
if (clc.state != CA_ACTIVE || clc.demoplaying)
{
Com_Printf ("Not connected to a server.\n");
Com_Printf( "Usage: serverstatus [server]\n");
Com_Printf( "usage: serverstatus [-4|-6] server\n");
return;
}
server = cls.servername;
toptr = &clc.serverAddress;
}
else {
server = Cmd_Argv(1);
if(!toptr)
{
Com_Memset( &to, 0, sizeof(netadr_t) );
if(argc == 2)
server = Cmd_Argv(1);
else
{
if(!strcmp(Cmd_Argv(1), "-4"))
family = NA_IP;
else if(!strcmp(Cmd_Argv(1), "-6"))
family = NA_IP6;
else
Com_Printf( "warning: only -4 or -6 as address type understood.\n");
server = Cmd_Argv(2);
}
toptr = &to;
if ( !NET_StringToAdr( server, toptr, family ) )
return;
}
if ( !NET_StringToAdr( server, &to, NA_IP ) ) {
return;
}
NET_OutOfBandPrint( NS_CLIENT, *toptr, "getstatus" );
NET_OutOfBandPrint( NS_CLIENT, to, "getstatus" );
serverStatus = CL_GetServerStatus( to );
serverStatus->address = to;
serverStatus = CL_GetServerStatus( *toptr );
serverStatus->address = *toptr;
serverStatus->print = qtrue;
serverStatus->pending = qtrue;
}
+167 -75
View File
@@ -149,6 +149,7 @@ static str ui_sCurrentLoadingMenu;
static Container<Menu *> hudList;
void UI_MultiplayerMenuWidgetsUpdate(void);
void UI_MultiplayerMainMenuWidgetsUpdate(void);
void UI_MainMenuWidgetsUpdate(void);
static UIRect2D getDefaultGMBoxRectangle(void);
@@ -1250,20 +1251,22 @@ UI_PrintConsole
*/
void UI_PrintConsole(const char *msg)
{
UColor *pColor = NULL;
char szString[1024];
char szBlah[1024];
qboolean bPrintedDMBox = qfalse;
UColor *pColor = NULL;
const char *pszString;
char szString[1024];
char szBlah[1024];
qboolean bPrintedDMBox = qfalse;
memcpy(szString, msg, sizeof(szString));
pszString = msg;
strncpy(szString, msg, 1024);
if (*szString < MESSAGE_MAX) {
if (*pszString < MESSAGE_MAX) {
qboolean bNormalMessage = qfalse;
qboolean bDMMessage = qfalse;
qboolean bBold = qfalse;
qboolean bDeathMessage = qfalse;
switch (*szString) {
switch (*pszString) {
case MESSAGE_YELLOW:
bNormalMessage = qtrue;
pColor = &UHudColor;
@@ -1277,16 +1280,16 @@ void UI_PrintConsole(const char *msg)
pColor = &UWhite;
break;
case MESSAGE_CHAT_RED:
bDeathMessage = qtrue;
bDeathMessage = MESSAGE_CHAT_RED;
pColor = &ULightRed;
break;
case MESSAGE_CHAT_GREEN:
bDeathMessage = qtrue;
bDeathMessage = MESSAGE_CHAT_GREEN;
pColor = &UGreen;
break;
}
msg++;
pszString++;
//
// print to the deathmatch console
@@ -1306,10 +1309,11 @@ void UI_PrintConsole(const char *msg)
if (bDMMessage) {
*szString = MESSAGE_CHAT_WHITE;
dmbox->Print(szString);
pszString = msg + 1;
bPrintedDMBox = qtrue;
} else if (bDeathMessage) {
dmbox->Print(szString);
*szString = MESSAGE_CHAT_RED;
*szString = bDeathMessage;
bPrintedDMBox = qtrue;
}
}
@@ -1322,6 +1326,7 @@ void UI_PrintConsole(const char *msg)
*szString = MESSAGE_WHITE;
gmbox->Print(szString);
uii.Snd_PlaySound("objective_text");
pszString = msg + 1;
} else {
gmbox->Print(szString + 1);
}
@@ -1330,15 +1335,18 @@ void UI_PrintConsole(const char *msg)
return;
}
memcpy(szBlah, "Game Message: ", 15);
Q_strcat(szBlah, sizeof(szBlah), szString + 1);
if (!bDMMessage) {
memcpy(szBlah, "Game Message: ", 15);
Q_strcat(szBlah, sizeof(szBlah), pszString);
pszString = szBlah;
}
}
}
if (*msg == 7) {
msg++;
if (*pszString == '\a') {
pszString++;
if (mini_console) {
mini_console->Print(msg + 1);
mini_console->Print(pszString);
return;
}
}
@@ -1350,10 +1358,10 @@ void UI_PrintConsole(const char *msg)
s_intermediateconsole = NULL;
}
fakk_console->AddText(msg, pColor);
fakk_console->AddText(pszString, pColor);
if (mini_console) {
mini_console->Print(msg);
mini_console->Print(pszString);
}
} else {
if (!s_intermediateconsole) {
@@ -1792,6 +1800,8 @@ void UI_Update(void)
if (currentMenu == menuManager.FindMenu("main")) {
UI_MainMenuWidgetsUpdate();
} else if (currentMenu == menuManager.FindMenu("dm_main")) {
UI_MultiplayerMainMenuWidgetsUpdate();
}
// don't care about the intro
@@ -1820,7 +1830,7 @@ void UI_Update(void)
}
}
if (clc.connectTime >= cls.realtime - 1000 * cl_connect_timeout->integer) {
if (clc.connectStartTime >= cls.realtime - 1000 * cl_connect_timeout->integer) {
if (currentMenu != ui_pConnectingMenu) {
UI_ForceMenuOff(true);
UI_DeactiveFloatingWindows();
@@ -2382,6 +2392,44 @@ void UI_MainMenuWidgetsUpdate(void)
UI_UpdateContinueGame();
}
/*
====================
UI_MultiplayerMainMenuWidgetsUpdate
====================
*/
// Added in 2.0
void UI_MultiplayerMainMenuWidgetsUpdate(void)
{
static const cvar_t *cg_allowvote = Cvar_Get("cg_allowvote", "1", 0);
if (cg_allowvote->integer) {
menuManager.PassEventToWidget("cantvote", new Event(EV_Widget_Disable));
if (atoi(CL_ConfigString(CS_VOTE_TIME))) {
menuManager.PassEventToWidget("callvotebutton", new Event(EV_Widget_Disable));
if (cl.snap.ps.voted) {
menuManager.PassEventToWidget("votebutton", new Event(EV_Widget_Disable));
menuManager.PassEventToWidget("alreadyvoted", new Event(EV_Widget_Enable));
} else {
menuManager.PassEventToWidget("votebutton", new Event(EV_Widget_Enable));
menuManager.PassEventToWidget("alreadyvoted", new Event(EV_Widget_Disable));
}
} else {
menuManager.PassEventToWidget("callvotebutton", new Event(EV_Widget_Enable));
menuManager.PassEventToWidget("votebutton", new Event(EV_Widget_Disable));
menuManager.PassEventToWidget("alreadyvoted", new Event(EV_Widget_Disable));
}
} else {
menuManager.PassEventToWidget("callvotebutton", new Event(EV_Widget_Disable));
menuManager.PassEventToWidget("votebutton", new Event(EV_Widget_Disable));
menuManager.PassEventToWidget("alreadyvoted", new Event(EV_Widget_Disable));
menuManager.PassEventToWidget("cantvote", new Event(EV_Widget_Enable));
}
UI_UpdateContinueGame();
}
/*
====================
UI_ToggleMenu
@@ -2446,9 +2494,11 @@ void UI_PopMenu(qboolean restore_cvars)
menu = menuManager.CurrentMenu();
if (menu) {
if (!memcmp(menu->m_name.c_str(), "main", 5)) {
if (!str::cmp(menu->m_name, "main")) {
UI_MainMenuWidgetsUpdate();
} else if (!memcmp(menu->m_name.c_str(), "multiplayer", 12)) {
} else if (!str::cmp(menu->m_name, "dm_main")) {
UI_MultiplayerMainMenuWidgetsUpdate();
} else if (!str::cmp(menu->m_name, "multiplayer")) {
UI_MultiplayerMenuWidgetsUpdate();
}
}
@@ -2484,9 +2534,11 @@ void UI_PushMenu(const char *name)
UI_FocusMenuIfExists();
if (!memcmp(name, "main", 5)) {
if (!str::cmp(name, "main")) {
UI_MainMenuWidgetsUpdate();
} else if (!memcmp(name, "multiplayer", 12)) {
} else if (!str::cmp(name, "dm_main")) {
UI_MultiplayerMainMenuWidgetsUpdate();
} else if (!str::cmp(name, "multiplayer")) {
UI_MultiplayerMenuWidgetsUpdate();
}
}
@@ -2819,9 +2871,11 @@ qboolean UI_PushReturnMenu()
return qfalse;
}
if (!memcmp(sMenuName.c_str(), "main", 5)) {
if (!str::cmp(sMenuName, "main")) {
UI_MainMenuWidgetsUpdate();
} else if (!memcmp(sMenuName.c_str(), "multiplayer", 12)) {
} else if (!str::cmp(sMenuName, "dm_main")) {
UI_MultiplayerMainMenuWidgetsUpdate();
} else if (!str::cmp(sMenuName, "multiplayer")) {
UI_MultiplayerMenuWidgetsUpdate();
}
@@ -2851,33 +2905,44 @@ void UI_MenuEscape(const char *name)
if (uWinMan.BindActive()) {
UI_KeyEvent(K_ESCAPE, qfalse);
} else if (menuManager.CurrentMenu() != mainmenu || clc.state != CA_DISCONNECTED) {
if (uWinMan.DialogExists()) {
uWinMan.RemoveAllDialogBoxes();
} else {
if (menuManager.CurrentMenu()) {
menuManager.PopMenu(qtrue);
} else if (!Q_stricmp(name, "main") && clc.state > CA_PRIMED && cg_gametype->integer > 0) {
UI_PushMenu("dm_main");
return;
}
if (menuManager.CurrentMenu() == mainmenu && clc.state == CA_DISCONNECTED) {
if (developer->integer) {
if (UI_ConsoleIsVisible()) {
UI_CloseConsole();
} else {
UI_PushMenu(name);
}
UI_FocusMenuIfExists();
if (menuManager.CurrentMenu()) {
if (!memcmp(name, "main", 5)) {
UI_MainMenuWidgetsUpdate();
} else if (!memcmp(name, "multiplayer", 12)) {
UI_MultiplayerMenuWidgetsUpdate();
}
UI_OpenConsole();
}
}
} else if (developer->integer) {
if (UI_ConsoleIsVisible()) {
UI_CloseConsole();
} else {
UI_OpenConsole();
return;
}
if (uWinMan.DialogExists()) {
uWinMan.RemoveAllDialogBoxes();
return;
}
if (menuManager.CurrentMenu()) {
menuManager.PopMenu(qtrue);
} else if (!Q_stricmp(name, "main") && clc.state > CA_PRIMED && cg_gametype->integer > 0) {
// multiplayer
UI_PushMenu("dm_main");
} else {
// single-player
UI_PushMenu(name);
}
UI_FocusMenuIfExists();
if (menuManager.CurrentMenu()) {
if (!str::cmp(name, "main")) {
UI_MainMenuWidgetsUpdate();
} else if (!str::cmp(name, "dm_main")) {
UI_MultiplayerMainMenuWidgetsUpdate();
} else if (!str::cmp(name, "multiplayer")) {
UI_MultiplayerMenuWidgetsUpdate();
}
}
}
@@ -2989,7 +3054,7 @@ void UI_MapList_f(void)
}
MapRunnerClass *map = new MapRunnerClass;
map->Setup("maps", mappath, ".bsp");
map->Setup("maps", mappath, ".bsp", "_sml");
CL_SetMousePos(cls.glconfig.vidWidth / 2, cls.glconfig.vidHeight / 2);
}
@@ -3002,20 +3067,34 @@ UI_DMMapSelect_f
void UI_DMMapSelect_f(void)
{
str basepath = "maps";
str mappath = "maps";
str mappath;
str gametype;
if (Cmd_Argc() > 1) {
mappath += "/";
mappath += Cmd_Argv(1);
}
const char *path;
if (Cmd_Argc() > 2) {
basepath += "/";
basepath += Cmd_Argv(2);
path = Cmd_Argv(1);
if (strcmp(path, ".")) {
basepath += "/";
basepath += path;
}
if (Cmd_Argc() > 2) {
path = Cmd_Argv(2);
if (strcmp(path, ".")) {
mappath += "maps/";
mappath += path;
}
}
if (Cmd_Argc() > 3) {
gametype = Cmd_Argv(3);
}
}
MpMapPickerClass *map = new MpMapPickerClass;
map->Setup(basepath, mappath);
map->Setup(basepath, mappath, gametype);
CL_SetMousePos(cls.glconfig.vidWidth / 2, cls.glconfig.vidHeight / 2);
}
@@ -3200,6 +3279,8 @@ void UI_PlayerModel_f(void)
PlayerModelPickerClass *picker = new PlayerModelPickerClass;
picker->Setup("models/player", modelpath, bGermanModel);
CL_SetMousePos(cls.glconfig.vidWidth / 2, cls.glconfig.vidHeight / 2);
}
/*
@@ -3210,14 +3291,20 @@ UI_ApplyPlayerModel_f
void UI_ApplyPlayerModel_f(void)
{
const char *pszUIPlayerModel;
char donotshowssindeorfr[64];
pszUIPlayerModel = CvarGetForUI("ui_dm_playermodel", "american_army");
pszUIPlayerModel = CvarGetForUI("ui_dm_playermodel_set", "american_army");
Cvar_Set("dm_playermodel", pszUIPlayerModel);
pszUIPlayerModel = CvarGetForUI("ui_dm_playergermanmodel", "german_wehrmacht_soldier");
Cvar_Set("ui_dm_playergermanmodel", pszUIPlayerModel);
pszUIPlayerModel = CvarGetForUI("ui_dm_playergermanmodel_set", "german_wehrmacht_soldier");
if (!Q_stricmpn(pszUIPlayerModel, "german_waffen", 14)) {
Q_strcat(donotshowssindeorfr, sizeof(donotshowssindeorfr), pszUIPlayerModel + 14);
Cvar_Set("dm_playergermanmodel", donotshowssindeorfr);
} else {
Cvar_Set("dm_playergermanmodel", pszUIPlayerModel);
}
Cvar_Set("name", CvarGetForUI("ui_name", "*** Blank Name ***"));
Cvar_Set("name", CvarGetForUI("ui_name", "UnnamedSoldier"));
}
/*
@@ -3230,24 +3317,29 @@ void UI_GetPlayerModel_f(void)
const char *pszUIPlayerModel;
char donotshowssindeorfr[64];
//
// Allies
//
pszUIPlayerModel = CvarGetForUI("dm_playermodel", "american_army");
Cvar_Set("ui_dm_playermodel", pszUIPlayerModel);
Cvar_Set("ui_dm_playermodel", PM_FilenameToDisplayname(pszUIPlayerModel));
Cvar_Set("ui_dm_playermodel_set", pszUIPlayerModel);
Cvar_Set("ui_disp_playermodel", va("models/player/%s.tik", pszUIPlayerModel));
//
// Axis
//
pszUIPlayerModel = CvarGetForUI("dm_playergermanmodel", "german_wehrmacht_soldier");
Cvar_Set("ui_dm_playergermanmodel", pszUIPlayerModel);
Cvar_Set("ui_dm_playergermanmodel", PM_FilenameToDisplayname(pszUIPlayerModel));
Cvar_Set("ui_dm_playergermanmodel_set", pszUIPlayerModel);
if (!strncmp(pszUIPlayerModel, "german_waffen_", 14)) {
memcpy(donotshowssindeorfr, "german_waffenss_", 17);
strncat(donotshowssindeorfr, pszUIPlayerModel + 14, 48);
Q_strcat(donotshowssindeorfr, sizeof(donotshowssindeorfr), pszUIPlayerModel + 14);
Cvar_Set("ui_disp_playergermanmodel", va("models/player/%s.tik", donotshowssindeorfr));
} else {
strncpy(donotshowssindeorfr, pszUIPlayerModel, sizeof(donotshowssindeorfr));
Cvar_Set("ui_disp_playergermanmodel", va("models/player/%s.tik", pszUIPlayerModel));
}
Cvar_Set("ui_disp_playergermanmodel", va("models/player/%s.tik", donotshowssindeorfr));
Cvar_Set("ui_name", CvarGetForUI("name", "*** Blank Name ***"));
Cvar_Set("ui_name", CvarGetForUI("name", "UnnamedSoldier"));
}
/*
@@ -3773,7 +3865,7 @@ void UI_CreateDialog(
dlg->Create(NULL, rect, title, bgColor, UHudColor);
dlg->LinkCvar(cvarname);
dlg->SetOKCommand(command);
dlg->SetCancelCommand(command);
dlg->SetCancelCommand(cancelCommand);
dlg->SetLabelMaterial(uWinMan.RegisterShader(shader));
dlg->SetOkMaterial(uWinMan.RegisterShader(okshader));
@@ -4178,7 +4270,7 @@ public:
virtual griditemtype_t getListItemType(int which) const;
virtual str getListItemString(int i) const;
virtual int getListItemValue(int which) const;
virtual void DrawListItem(int iColumn, const UIRect2D &drawRect, bool bSelected, UIFont *pFont);
virtual void DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont);
virtual qboolean IsHeaderEntry(void) const;
};
@@ -4342,8 +4434,8 @@ public:
virtual griditemtype_t getListItemType(int which) const;
virtual str getListItemString(int i) const;
virtual int getListItemValue(int which) const;
virtual void DrawListItem(int iColumn, const UIRect2D &drawRect, bool bSelected, UIFont *pFont);
void SetColors(const UColor &newTextColor, const UColor &newBackColor);
virtual void DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont);
void SetColors(const UColor& newTextColor, const UColor& newBackColor);
void ClearColors(void);
void SetTitleItem(qboolean bSet);
virtual qboolean IsHeaderEntry(void) const;
+430 -182
View File
@@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@@ -24,281 +24,529 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
bind_t::bind_t()
{
// FIXME: stub
int i;
commandwidth = 100;
commandheight = 20;
primarykeywidth = 100;
primarykeyheight = 20;
alternatekeywidth = 100;
alternatekeyheight = 20;
fillwidth = 16;
fillmaterial = NULL;
for (i = 0; i < ARRAY_LEN(headermats); i++) {
headermats[i] = NULL;
}
}
bind_t::~bind_t()
{
Clear();
Clear();
}
void bind_t::Clear
(
void
)
void bind_t::Clear(void)
{
// FIXME: stub
for (int i = binds.NumObjects(); i > 0; i--) {
bind_item_t *bi;
bi = binds.ObjectAt(i);
binds.RemoveObjectAt(i);
if (bi) {
delete bi;
}
}
}
CLASS_DECLARATION( Listener, bindlistener, NULL )
{
{ NULL, NULL }
Event EV_Bind_Header
(
"header",
EV_DEFAULT,
"iss",
"column_num name material",
"Set the header of each column"
);
Event EV_Bind_Width
(
"bind_width",
EV_DEFAULT,
"i",
"width",
"Width of the bind menu"
);
Event EV_Bind_Height
(
"bind_height",
EV_DEFAULT,
"i",
"height",
"Height of the bind menu"
);
Event EV_Bind_FillWidth
(
"bind_fillwidth",
EV_DEFAULT,
"iS",
"width material",
"Width of the filling between widgets"
);
Event EV_Bind_CommandWidth
(
"bind_commandwidth",
EV_DEFAULT,
"i",
"width",
"Width of the command item"
);
Event EV_Bind_CommandHeight
(
"bind_commandheight",
EV_DEFAULT,
"i",
"height",
"Height of the command item"
);
Event EV_Bind_PrimaryKeyWidth
(
"bind_primarykeywidth",
EV_DEFAULT,
"i",
"width",
"Width of the primary key item"
);
Event EV_Bind_PrimaryKeyHeight
(
"bind_primarykeyheight",
EV_DEFAULT,
"i",
"height",
"Height of the primary key item"
);
Event EV_Bind_AlternateKeyWidth
(
"bind_alternatekeywidth",
EV_DEFAULT,
"i",
"width",
"Width of the alternate key item"
);
Event EV_Bind_AlternateKeyHeight
(
"bind_alternatekeyheight",
EV_DEFAULT,
"i",
"height",
"Height of the alternate key item"
);
Event EV_Bind_NewItem
(
"binditem",
EV_DEFAULT,
"ss",
"name command",
"Create a new bind item in the interface"
);
Event EV_Bind_Align
(
"align",
EV_DEFAULT,
"sSSSSS",
"arg1 arg2 arg3 arg4 arg5 arg6",
"Set the alignment on the bind menu"
);
Event EV_Bind_TitleForegroundColor
(
"titleforegroundcolor",
EV_DEFAULT,
"ffff",
"r g b a",
"Set the color for the title foreground"
);
Event EV_Bind_TitleBackgroundColor
(
"titlebackgroundcolor",
EV_DEFAULT,
"ffff",
"r g b a",
"Set the color for the title background"
);
Event EV_Bind_InactiveForegroundColor
(
"inactiveforegroundcolor",
EV_DEFAULT,
"ffff",
"r g b a",
"Set the color for the inactive button foreground"
);
Event EV_Bind_InactiveBackgroundColor
(
"inactivebackgroundcolor",
EV_DEFAULT,
"ffff",
"r g b a",
"Set the color for the inactive button background"
);
Event EV_Bind_ActiveForegroundColor
(
"activeforegroundcolor",
EV_DEFAULT,
"ffff",
"r g b a",
"Set the color for the active button foreground"
);
Event EV_Bind_ActiveBackgroundColor
(
"activebackgroundcolor",
EV_DEFAULT,
"ffff",
"r g b a",
"Set the color for the active button background"
);
Event EV_Bind_ActiveBorderColor
(
"activebordercolor",
EV_DEFAULT,
"ffff",
"r g b a",
"Set the color for the active button border"
);
Event EV_Bind_HighlightForegroundColor
(
"highlightforegroundcolor",
EV_DEFAULT,
"ffff",
"r g b a",
"Set the color for the highlighted button foreground"
);
Event EV_Bind_HighlightBackgroundColor
(
"highlightbackgroundcolor",
EV_DEFAULT,
"ffff",
"r g b a",
"Set the color for the highlighted button background"
);
Event EV_Bind_SelectForegroundColor
(
"selectforegroundcolor",
EV_DEFAULT,
"ffff",
"r g b a",
"Set the color for the selected button foreground"
);
Event EV_Bind_SelectBackgroundColor
(
"selectbackgroundcolor",
EV_DEFAULT,
"ffff",
"r g b a",
"Set the color for the selected button background"
);
Event EV_Bind_ChangeSound
(
"changesound",
EV_DEFAULT,
"s",
"soundname",
"Set the name of the sound to play when the highlighted item changes"
);
Event EV_Bind_ActiveSound
(
"activesound",
EV_DEFAULT,
"s",
"soundname",
"Set the name of the sound to play when the item is made active"
);
Event EV_Bind_EnterSound
(
"entersound",
EV_DEFAULT,
"s",
"soundname",
"Set the name of the sound to play when the key is entered"
);
CLASS_DECLARATION(Listener, bindlistener, NULL) {
{&EV_Bind_Width, &bindlistener::Width },
{&EV_Bind_Height, &bindlistener::Height },
{&EV_Bind_FillWidth, &bindlistener::FillWidth },
{&EV_Bind_CommandWidth, &bindlistener::CommandWidth },
{&EV_Bind_CommandHeight, &bindlistener::CommandHeight },
{&EV_Bind_PrimaryKeyWidth, &bindlistener::PrimaryKeyWidth },
{&EV_Bind_PrimaryKeyHeight, &bindlistener::PrimaryKeyHeight },
{&EV_Bind_AlternateKeyWidth, &bindlistener::AlternateKeyWidth },
{&EV_Bind_AlternateKeyHeight, &bindlistener::AlternateKeyHeight },
{&EV_Bind_Header, &bindlistener::Header },
{&EV_Bind_NewItem, &bindlistener::NewItem },
{&EV_Bind_Align, &bindlistener::Align },
{&EV_Bind_TitleForegroundColor, &bindlistener::TitleForegroundColor },
{&EV_Bind_TitleBackgroundColor, &bindlistener::TitleBackgroundColor },
{&EV_Bind_InactiveForegroundColor, &bindlistener::InactiveForegroundColor },
{&EV_Bind_InactiveBackgroundColor, &bindlistener::InactiveBackgroundColor },
{&EV_Bind_ActiveForegroundColor, &bindlistener::ActiveForegroundColor },
{&EV_Bind_ActiveBackgroundColor, &bindlistener::ActiveBackgroundColor },
{&EV_Bind_ActiveBorderColor, &bindlistener::ActiveBorderColor },
{&EV_Bind_HighlightForegroundColor, &bindlistener::HighlightForegroundColor},
{&EV_Bind_HighlightBackgroundColor, &bindlistener::HighlightBackgroundColor},
{&EV_Bind_SelectForegroundColor, &bindlistener::SelectForegroundColor },
{&EV_Bind_SelectBackgroundColor, &bindlistener::SelectBackgroundColor },
{&EV_Bind_ChangeSound, &bindlistener::ChangeSound },
{&EV_Bind_ActiveSound, &bindlistener::ActiveSound },
{&EV_Bind_EnterSound, &bindlistener::EnterSound },
{NULL, NULL }
};
bindlistener::bindlistener()
bindlistener::bindlistener() {}
bindlistener::bindlistener(bind_t *b)
{
bind = b;
}
bindlistener::bindlistener
(
bind_t *b
)
void bindlistener::Header(Event *ev)
{
bind = b;
int num;
num = ev->GetInteger(1) - 1;
if (num > ARRAY_LEN(bind_t::headers)) {
return;
}
bind->headers[num] = ev->GetString(2);
if (ev->NumArgs() > 2) {
bind->headermats[num] = uWinMan.RegisterShader(ev->GetString(3));
}
}
bool bindlistener::Load
(
Script& script
)
void bindlistener::ChangeSound(Event *ev)
{
// FIXME: stub
return false;
bind->changesound = ev->GetString(1);
}
void bindlistener::Header
(
Event *ev
)
void bindlistener::ActiveSound(Event *ev)
{
// FIXME: stub
bind->activesound = ev->GetString(1);
}
void bindlistener::Width
(
Event *ev
)
void bindlistener::EnterSound(Event *ev)
{
// FIXME: stub
bind->entersound = ev->GetString(1);
}
void bindlistener::FillWidth
(
Event *ev
)
void bindlistener::SelectForegroundColor(Event *ev)
{
// FIXME: stub
bind->selectfgcolor.r = ev->GetFloat(1);
bind->selectfgcolor.g = ev->GetFloat(2);
bind->selectfgcolor.b = ev->GetFloat(3);
bind->selectfgcolor.a = ev->GetFloat(4);
}
void bindlistener::Height
(
Event *ev
)
void bindlistener::SelectBackgroundColor(Event *ev)
{
// FIXME: stub
bind->selectbgcolor.r = ev->GetFloat(1);
bind->selectbgcolor.g = ev->GetFloat(2);
bind->selectbgcolor.b = ev->GetFloat(3);
bind->selectbgcolor.a = ev->GetFloat(4);
}
void bindlistener::CommandWidth
(
Event *ev
)
void bindlistener::TitleForegroundColor(Event *ev)
{
// FIXME: stub
bind->titlefgcolor.r = ev->GetFloat(1);
bind->titlefgcolor.g = ev->GetFloat(2);
bind->titlefgcolor.b = ev->GetFloat(3);
bind->titlefgcolor.a = ev->GetFloat(4);
}
void bindlistener::CommandHeight
(
Event *ev
)
void bindlistener::TitleBackgroundColor(Event *ev)
{
// FIXME: stub
bind->titlebgcolor.r = ev->GetFloat(1);
bind->titlebgcolor.g = ev->GetFloat(2);
bind->titlebgcolor.b = ev->GetFloat(3);
bind->titlebgcolor.a = ev->GetFloat(4);
}
void bindlistener::PrimaryKeyWidth
(
Event *ev
)
void bindlistener::ActiveBorderColor(Event *ev)
{
// FIXME: stub
bind->activebordercolor.r = ev->GetFloat(1);
bind->activebordercolor.g = ev->GetFloat(2);
bind->activebordercolor.b = ev->GetFloat(3);
bind->activebordercolor.a = ev->GetFloat(4);
}
void bindlistener::PrimaryKeyHeight
(
Event *ev
)
void bindlistener::ActiveForegroundColor(Event *ev)
{
// FIXME: stub
bind->activefgcolor.r = ev->GetFloat(1);
bind->activefgcolor.g = ev->GetFloat(2);
bind->activefgcolor.b = ev->GetFloat(3);
bind->activefgcolor.a = ev->GetFloat(4);
}
void bindlistener::AlternateKeyWidth
(
Event *ev
)
void bindlistener::ActiveBackgroundColor(Event *ev)
{
// FIXME: stub
bind->activebgcolor.r = ev->GetFloat(1);
bind->activebgcolor.g = ev->GetFloat(2);
bind->activebgcolor.b = ev->GetFloat(3);
bind->activebgcolor.a = ev->GetFloat(4);
}
void bindlistener::AlternateKeyHeight
(
Event *ev
)
void bindlistener::InactiveForegroundColor(Event *ev)
{
// FIXME: stub
bind->inactivefgcolor.r = ev->GetFloat(1);
bind->inactivefgcolor.g = ev->GetFloat(2);
bind->inactivefgcolor.b = ev->GetFloat(3);
bind->inactivefgcolor.a = ev->GetFloat(4);
}
void bindlistener::NewItem
(
Event *ev
)
void bindlistener::InactiveBackgroundColor(Event *ev)
{
// FIXME: stub
bind->inactivebgcolor.r = ev->GetFloat(1);
bind->inactivebgcolor.g = ev->GetFloat(2);
bind->inactivebgcolor.b = ev->GetFloat(3);
bind->inactivebgcolor.a = ev->GetFloat(4);
}
void bindlistener::Align
(
Event *ev
)
void bindlistener::HighlightForegroundColor(Event *ev)
{
// FIXME: stub
bind->highlightfgcolor.r = ev->GetFloat(1);
bind->highlightfgcolor.g = ev->GetFloat(2);
bind->highlightfgcolor.b = ev->GetFloat(3);
bind->highlightfgcolor.a = ev->GetFloat(4);
}
void bindlistener::TitleForegroundColor
(
Event *ev
)
void bindlistener::HighlightBackgroundColor(Event *ev)
{
// FIXME: stub
bind->highlightbgcolor.r = ev->GetFloat(1);
bind->highlightbgcolor.g = ev->GetFloat(2);
bind->highlightbgcolor.b = ev->GetFloat(3);
bind->highlightbgcolor.a = ev->GetFloat(4);
}
void bindlistener::TitleBackgroundColor
(
Event *ev
)
void bindlistener::Align(Event *ev)
{
// FIXME: stub
int i;
for (i = 1; i <= ev->NumArgs(); i++) {
str align = ev->GetString(i);
if (!str::icmp(align, "left")) {
bind->align |= WA_LEFT;
} else if (!str::icmp(align, "right")) {
bind->align |= WA_RIGHT;
} else if (!str::icmp(align, "top")) {
bind->align |= WA_TOP;
} else if (!str::icmp(align, "bottom")) {
bind->align |= WA_BOTTOM;
} else if (!str::icmp(align, "centerx")) {
bind->align |= WA_CENTERX;
} else if (!str::icmp(align, "centery")) {
bind->align |= WA_CENTERY;
}
}
}
void bindlistener::InactiveForegroundColor
(
Event *ev
)
void bindlistener::NewItem(Event *ev)
{
// FIXME: stub
bind_item_t *bt;
UIReggedMaterial *mat = NULL;
if (ev->NumArgs() > 2) {
mat = uWinMan.RegisterShader(ev->GetString(3));
}
str n = ev->GetString(1);
str c = ev->GetString(2);
bt = new bind_item_t;
bt->name = n;
bt->command = c;
bt->nameMaterial = mat;
bind->binds.AddObject(bt);
}
void bindlistener::InactiveBackgroundColor
(
Event *ev
)
void bindlistener::Width(Event *ev)
{
// FIXME: stub
bind->width = ev->GetInteger(1);
}
void bindlistener::ActiveForegroundColor
(
Event *ev
)
void bindlistener::Height(Event *ev)
{
// FIXME: stub
bind->height = ev->GetInteger(1);
}
void bindlistener::ActiveBackgroundColor
(
Event *ev
)
void bindlistener::FillWidth(Event *ev)
{
// FIXME: stub
bind->fillwidth = ev->GetInteger(1);
if (ev->NumArgs() > 1) {
bind->fillmaterial = uWinMan.RegisterShader(ev->GetString(2));
}
}
void bindlistener::ActiveBorderColor
(
Event *ev
)
void bindlistener::CommandWidth(Event *ev)
{
// FIXME: stub
bind->commandwidth = ev->GetInteger(1);
}
void bindlistener::HighlightForegroundColor
(
Event *ev
)
void bindlistener::CommandHeight(Event *ev)
{
// FIXME: stub
bind->commandheight = ev->GetInteger(1);
}
void bindlistener::HighlightBackgroundColor
(
Event *ev
)
void bindlistener::PrimaryKeyWidth(Event *ev)
{
// FIXME: stub
bind->primarykeywidth = ev->GetInteger(1);
}
void bindlistener::SelectForegroundColor
(
Event *ev
)
void bindlistener::PrimaryKeyHeight(Event *ev)
{
// FIXME: stub
bind->primarykeyheight = ev->GetInteger(1);
}
void bindlistener::SelectBackgroundColor
(
Event *ev
)
void bindlistener::AlternateKeyWidth(Event *ev)
{
// FIXME: stub
bind->alternatekeywidth = ev->GetInteger(1);
}
void bindlistener::ChangeSound
(
Event *ev
)
void bindlistener::AlternateKeyHeight(Event *ev)
{
// FIXME: stub
bind->alternatekeyheight = ev->GetInteger(1);
}
void bindlistener::ActiveSound
(
Event *ev
)
bool bindlistener::Load(Script& script)
{
// FIXME: stub
str token;
str errortext;
while (script.TokenAvailable(true)) {
token = script.GetToken(true);
if (!token.length() || !ValidEvent(token)) {
throw "invalid token";
}
Event *event = new Event(token);
while (script.TokenAvailable(false)) {
event->AddToken(script.GetToken(false));
}
ProcessEvent(event);
}
return true;
}
void bindlistener::EnterSound
(
Event *ev
)
bool CL_LoadBind(const char *filename, bind_t *bind)
{
// FIXME: stub
Script script;
bind->Clear();
bindlistener listener(bind);
script.LoadFile(filename);
// Load the bind file
return listener.Load(script);
}
+82 -88
View File
@@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@@ -20,115 +20,109 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#ifndef __CL_UIBIND_H__
#define __CL_UIBIND_H__
#pragma once
class bind_item_t {
class bind_item_t
{
public:
str name;
str command;
UIReggedMaterial *nameMaterial;
str name;
str command;
UIReggedMaterial *nameMaterial;
bind_item_t();
bind_item_t( str name, str command, UIReggedMaterial *nameMaterial );
bind_item_t();
bind_item_t(str name, str command, UIReggedMaterial *nameMaterial);
};
inline
bind_item_t::bind_item_t()
inline bind_item_t::bind_item_t()
{
nameMaterial = NULL;
nameMaterial = NULL;
}
inline
bind_item_t::bind_item_t
(
str name,
str command,
UIReggedMaterial *nameMaterial
)
inline bind_item_t::bind_item_t(str name, str command, UIReggedMaterial *nameMaterial)
{
this->name = name;
this->command = command;
this->nameMaterial = nameMaterial;
this->name = name;
this->command = command;
this->nameMaterial = nameMaterial;
}
class bind_t {
class bind_t
{
public:
int width;
int height;
int fillwidth;
int commandwidth;
int commandheight;
int primarykeywidth;
int primarykeyheight;
int alternatekeywidth;
int alternatekeyheight;
int align;
UColor titlebgcolor;
UColor titlefgcolor;
UColor activefgcolor;
UColor activebgcolor;
UColor activebordercolor;
UColor inactivefgcolor;
UColor inactivebgcolor;
UColor highlightfgcolor;
UColor highlightbgcolor;
UColor selectfgcolor;
UColor selectbgcolor;
str changesound;
str activesound;
str entersound;
str headers[ 3 ];
UIReggedMaterial *headermats[ 3 ];
UIReggedMaterial *fillmaterial;
Container<bind_item_t *> binds;
int width;
int height;
int fillwidth;
int commandwidth;
int commandheight;
int primarykeywidth;
int primarykeyheight;
int alternatekeywidth;
int alternatekeyheight;
int align;
UColor titlebgcolor;
UColor titlefgcolor;
UColor activefgcolor;
UColor activebgcolor;
UColor activebordercolor;
UColor inactivefgcolor;
UColor inactivebgcolor;
UColor highlightfgcolor;
UColor highlightbgcolor;
UColor selectfgcolor;
UColor selectbgcolor;
str changesound;
str activesound;
str entersound;
str headers[3];
UIReggedMaterial *headermats[3];
UIReggedMaterial *fillmaterial;
Container<bind_item_t *> binds;
public:
bind_t();
~bind_t();
bind_t();
~bind_t();
void Clear( void );
void Clear(void);
};
class bindlistener : public Listener {
class bindlistener : public Listener
{
protected:
bind_t *bind;
bind_t *bind;
public:
CLASS_PROTOTYPE( bindlistener );
CLASS_PROTOTYPE(bindlistener);
public:
bindlistener();
bindlistener( bind_t *b );
bindlistener();
bindlistener(bind_t *b);
bool Load( Script& script );
void Header( Event *ev );
void Width( Event *ev );
void FillWidth( Event *ev );
void Height( Event *ev );
void CommandWidth( Event *ev );
void CommandHeight( Event *ev );
void PrimaryKeyWidth( Event *ev );
void PrimaryKeyHeight( Event *ev );
void AlternateKeyWidth( Event *ev );
void AlternateKeyHeight( Event *ev );
void NewItem( Event *ev );
void Align( Event *ev );
void TitleForegroundColor( Event *ev );
void TitleBackgroundColor( Event *ev );
void InactiveForegroundColor( Event *ev );
void InactiveBackgroundColor( Event *ev );
void ActiveForegroundColor( Event *ev );
void ActiveBackgroundColor( Event *ev );
void ActiveBorderColor( Event *ev );
void HighlightForegroundColor( Event *ev );
void HighlightBackgroundColor( Event *ev );
void SelectForegroundColor( Event *ev );
void SelectBackgroundColor( Event *ev );
void ChangeSound( Event *ev );
void ActiveSound( Event *ev );
void EnterSound( Event *ev );
bool Load(Script& script);
void Header(Event *ev);
void Width(Event *ev);
void FillWidth(Event *ev);
void Height(Event *ev);
void CommandWidth(Event *ev);
void CommandHeight(Event *ev);
void PrimaryKeyWidth(Event *ev);
void PrimaryKeyHeight(Event *ev);
void AlternateKeyWidth(Event *ev);
void AlternateKeyHeight(Event *ev);
void NewItem(Event *ev);
void Align(Event *ev);
void TitleForegroundColor(Event *ev);
void TitleBackgroundColor(Event *ev);
void InactiveForegroundColor(Event *ev);
void InactiveBackgroundColor(Event *ev);
void ActiveForegroundColor(Event *ev);
void ActiveBackgroundColor(Event *ev);
void ActiveBorderColor(Event *ev);
void HighlightForegroundColor(Event *ev);
void HighlightBackgroundColor(Event *ev);
void SelectForegroundColor(Event *ev);
void SelectBackgroundColor(Event *ev);
void ChangeSound(Event *ev);
void ActiveSound(Event *ev);
void EnterSound(Event *ev);
};
#endif
bool CL_LoadBind(const char* filename, bind_t* bind);
+209 -27
View File
@@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@@ -22,72 +22,254 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "cl_ui.h"
CLASS_DECLARATION( USignal, FilePickerClass, NULL )
class FilePickerItem : public UIListCtrlItem
{
{ NULL, NULL }
str strings[3];
public:
FilePickerItem(const str& fileName, const str& date, const str& size);
int getListItemValue(int which) const override;
griditemtype_t getListItemType(int which) const override;
str getListItemString(int which) const override;
void DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont) override;
qboolean IsHeaderEntry() const override;
};
CLASS_DECLARATION(USignal, FilePickerClass, NULL) {
{&EV_UIListBase_ItemSelected, &FilePickerClass::FileSelected },
{&EV_UIListBase_ItemDoubleClicked, &FilePickerClass::FileChosen },
{&W_Deactivated, &FilePickerClass::OnDeactivated},
{NULL, NULL }
};
FilePickerClass::FilePickerClass()
{
// FIXME: stub
window = new UIFloatingWindow();
window->Create(
NULL,
UIRect2D((cls.glconfig.vidWidth - 400) / 2, (cls.glconfig.vidHeight - 300) / 2, 400, 300),
"File Picker",
UColor(0.15f, 0.195f, 0.278f),
UHudColor
);
window->Connect(this, W_Deactivated, W_Deactivated);
listbox = new UIListCtrl();
listbox->InitFrame(window->getChildSpace(), window->getChildSpace()->getClientFrame(), 0);
listbox->setBackgroundColor(UColor(0.02f, 0.07f, 0.005f), true);
listbox->setForegroundColor(UHudColor);
listbox->AddColumn("File Name", 0, 175, false, false);
listbox->AddColumn("Date", 1, 125, false, false);
listbox->AddColumn("Size", 2, 100, true, false);
listbox->Connect(this, EV_UIListBase_ItemDoubleClicked, EV_UIListBase_ItemDoubleClicked);
listbox->Connect(this, EV_UIListBase_ItemSelected, EV_UIListBase_ItemSelected);
listbox->AllowActivate(true);
// Added in 2.0
// Don't localize elements
listbox->SetDontLocalize();
}
FilePickerClass::~FilePickerClass()
{
// FIXME: stub
if (listbox) {
delete listbox;
listbox = NULL;
}
if (window) {
delete window;
window = NULL;
}
}
void FilePickerClass::SetupFiles( void )
void FilePickerClass::Setup(
const char *root_directory, const char *current_directory, const char *ext, const char *ignore_files
)
{
// FIXME: stub
Initialize(root_directory, current_directory, ext, ignore_files);
}
void FilePickerClass::GotoParentDirectory( void )
void FilePickerClass::Initialize(
const char *root_directory, const char *current_directory, const char *ext, const char *ignore_files
)
{
// FIXME: stub
rootDirectory = root_directory;
if (rootDirectory.length() > 1 && rootDirectory[rootDirectory.length() - 1] != '/') {
rootDirectory += "/";
}
currentDirectory = current_directory;
if (currentDirectory.length() > 1 && currentDirectory[currentDirectory.length() - 1] != '/') {
currentDirectory += "/";
}
extension = ext;
ignoredFiles = ignore_files;
SetupFiles();
}
void FilePickerClass::GotoSubDirectory( str subdir )
void FilePickerClass::GotoParentDirectory(void)
{
// FIXME: stub
int i;
if (currentDirectory == rootDirectory) {
return;
}
for (i = currentDirectory.length() - 2; i > 0; i--) {
if (currentDirectory[i] == '/') {
break;
}
}
if (currentDirectory[i] == '/') {
i++;
}
currentDirectory = str(currentDirectory, 0, i);
// refresh files
SetupFiles();
}
void FilePickerClass::Initialize( const char *root_directory, const char *current_directory, const char *ext )
void FilePickerClass::GotoSubDirectory(str subdir)
{
// FIXME: stub
currentDirectory += subdir + "/";
// refresh files
SetupFiles();
}
void FilePickerClass::CloseWindow( void )
void FilePickerClass::SetupFiles(void)
{
// FIXME: stub
str mappath;
str work;
char **filenames;
int numfiles;
int i;
char date[128];
char size[128];
listbox->DeleteAllItems();
if (currentDirectory != rootDirectory) {
// create the parent directory item
listbox->AddItem(new FilePickerItem("..", "", ""));
}
// retrieve directories
filenames = FS_ListFiles(currentDirectory, "/", qfalse, &numfiles);
for (i = 0; i < numfiles; i++) {
const char *filename = filenames[i];
if (filename[0] == '.' || !strlen(filename)) {
continue;
}
work = "[";
work += filename;
work += "]";
FS_FileTime(currentDirectory + filename, date, size);
listbox->AddItem(new FilePickerItem(work, date, size));
}
FS_FreeFileList(filenames);
filenames = FS_ListFiles(currentDirectory, extension, qfalse, &numfiles);
for (i = 0; i < numfiles; i++) {
const char *filename = filenames[i];
if (ignoredFiles.length() && strstr(filename, ignoredFiles)) {
// Added in 2.0
// Check for ignored files
continue;
}
work = filename;
FS_FileTime(currentDirectory + work, date, size);
listbox->AddItem(new FilePickerItem(work, date, size));
}
FS_FreeFileList(filenames);
window->setTitle(currentDirectory);
}
void FilePickerClass::FileSelected( Event *ev )
void FilePickerClass::FileSelected(const str& currentDirectory, const str& partialName, const str& fullname) {}
void FilePickerClass::FileSelected(Event *ev)
{
// FIXME: stub
str name = listbox->GetItem(listbox->getCurrentItem())->getListItemString(0);
if (*name != '[' && *name != '.') {
FileSelected(currentDirectory, name, currentDirectory + name);
}
uii.Snd_PlaySound("sound/menu/scroll.wav");
}
void FilePickerClass::FileSelected( str &currentDirectory, str &partialName, str &fullname )
void FilePickerClass::FileChosen(const str& currentDirectory, const str& partialName, const str& fullname) {}
void FilePickerClass::FileChosen(Event *ev)
{
// FIXME: stub
str filename = listbox->GetItem(listbox->getCurrentItem())->getListItemString(0);
if (*filename == '[') {
uii.Snd_PlaySound("sound/menu/scroll.wav");
GotoSubDirectory(str(filename, 1, filename.length() - 1));
} else if (*filename == '.') {
GotoParentDirectory();
} else {
uii.Snd_PlaySound("sound/menu/apply.wav");
FileChosen(currentDirectory, filename, currentDirectory + filename);
}
}
void FilePickerClass::FileChosen( Event *ev )
void FilePickerClass::CloseWindow(void)
{
// FIXME: stub
PostEvent(EV_Remove, 0);
}
void FilePickerClass::FileChosen( str &currentDirectory, str &partialName, str &fullname )
void FilePickerClass::OnDeactivated(Event *ev)
{
// FIXME: stub
CloseWindow();
}
void FilePickerClass::OnDeactivated( Event *ev )
FilePickerItem::FilePickerItem(const str& fileName, const str& date, const str& size)
{
// FIXME: stub
strings[0] = fileName;
strings[1] = date;
strings[2] = size;
}
void FilePickerClass::Setup( const char *root_directory, const char *current_directory, const char *ext )
int FilePickerItem::getListItemValue(int which) const
{
// FIXME: stub
return atoi(strings[which]);
}
griditemtype_t FilePickerItem::getListItemType(int which) const
{
return griditemtype_t::TYPE_STRING;
}
str FilePickerItem::getListItemString(int which) const
{
return strings[which];
}
void FilePickerItem::DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont) {}
qboolean FilePickerItem::IsHeaderEntry() const
{
return qfalse;
}
+26 -25
View File
@@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@@ -20,40 +20,41 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#ifndef __CL_UIFILEPICKER_H__
#define __CL_UIFILEPICKER_H__
#pragma once
class UIListCtrl;
class FilePickerClass : public USignal {
UIFloatingWindow *window;
UIListCtrl *listbox;
str currentDirectory;
str rootDirectory;
str extension;
class FilePickerClass : public USignal
{
UIFloatingWindow *window;
UIListCtrl *listbox;
str currentDirectory;
str rootDirectory;
str extension;
// Added in 2.0
str ignoredFiles;
public:
CLASS_PROTOTYPE( FilePickerClass );
CLASS_PROTOTYPE(FilePickerClass);
private:
void SetupFiles( void );
void GotoParentDirectory( void );
void GotoSubDirectory( str subdir );
void Initialize( const char *root_directory, const char *current_directory, const char *ext );
void SetupFiles(void);
void GotoParentDirectory(void);
void GotoSubDirectory(str subdir);
// ignore_files parameter, added in 2.0
void Initialize(const char *root_directory, const char *current_directory, const char *ext, const char* ignore_files);
protected:
void CloseWindow( void );
void FileSelected( Event *ev );
virtual void FileSelected( str &currentDirectory, str &partialName, str &fullname );
void FileChosen( Event *ev );
virtual void FileChosen( str &currentDirectory, str &partialName, str &fullname );
void OnDeactivated( Event *ev );
void CloseWindow(void);
void FileSelected(Event *ev);
virtual void FileSelected(const str& currentDirectory, const str& partialName, const str& fullname);
void FileChosen(Event *ev);
virtual void FileChosen(const str& currentDirectory, const str& partialName, const str& fullname);
void OnDeactivated(Event *ev);
public:
FilePickerClass();
~FilePickerClass();
FilePickerClass();
~FilePickerClass();
void Setup( const char *root_directory, const char *current_directory, const char *ext );
void Setup(const char *root_directory, const char *current_directory, const char *ext, const char* ignore_files = NULL);
};
#endif /* __CL_UIFILEPICKER_H__ */
+183 -17
View File
@@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@@ -21,44 +21,210 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "cl_ui.h"
#include "../qcommon/localization.h"
CLASS_DECLARATION( UIListCtrl, UILANGameClass, NULL )
class LANGameItem : public UIListCtrlItem
{
{ NULL, NULL }
str strings[5];
public:
LANGameItem();
LANGameItem(
const str& hostName, const str& mapName, const str& players, const str& gameTypeString, const str& ping
);
int getListItemValue(int which) const override;
griditemtype_t getListItemType(int which) const override;
str getListItemString(int which) const override;
void DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont) override;
qboolean IsHeaderEntry() const override;
};
Event EV_LANGame_JoinGame
(
"joingame",
EV_DEFAULT,
NULL,
NULL,
"Join the currently selected server"
);
CLASS_DECLARATION(UIListCtrl, UILANGameClass, NULL) {
{&EV_UIListBase_ItemSelected, &UILANGameClass::SelectServer},
{&EV_UIListBase_ItemDoubleClicked, &UILANGameClass::JoinServer },
{&EV_LANGame_JoinGame, &UILANGameClass::JoinServer },
{NULL, NULL }
};
UILANGameClass::UILANGameClass()
{
// FIXME: stub
Connect(this, EV_UIListBase_ItemDoubleClicked, EV_UIListBase_ItemDoubleClicked);
Connect(this, EV_UIListBase_ItemSelected, EV_UIListBase_ItemSelected);
AllowActivate(true);
setHeaderFont("facfont-20");
m_iLastUpdateTime = 0;
m_noservers_mat = uWinMan.RegisterShader("textures/menu/noservers");
}
void UILANGameClass::SetupServers( void )
void UILANGameClass::Draw(void)
{
// FIXME: stub
if (cls.bNewLocalServerInfo) {
SetupServers();
}
UIListCtrl::Draw();
if (!getNumItems() && m_noservers_mat) {
float x, y, w, h;
w = re.GetShaderWidth(m_noservers_mat->GetMaterial()) * m_vVirtualScale[0];
h = re.GetShaderHeight(m_noservers_mat->GetMaterial()) * m_vVirtualScale[1];
UIRect2D frame = getClientFrame();
x = (frame.size.width - w) * 0.5f;
y = (frame.size.height - h) * 0.5f;
re.DrawStretchPic(x, y, w, h, 0, 0, 1, 1, m_noservers_mat->GetMaterial());
}
if (m_iLastUpdateTime && m_iLastUpdateTime < cls.realtime) {
Cvar_Set("cl_langamerefreshstatus", "Ready");
m_iLastUpdateTime = 0;
}
}
void UILANGameClass::Draw( void )
void UILANGameClass::UpdateUIElement(void)
{
// FIXME: stub
float width;
RemoveAllColumns();
width = getClientFrame().size.width - 16.f;
AddColumn(Sys_LV_CL_ConvertString("Server Name"), 0, width * 0.4f, false, false);
AddColumn(Sys_LV_CL_ConvertString("Map"), 1, width * 0.15f, false, false);
AddColumn(Sys_LV_CL_ConvertString("Players"), 2, width * 0.165f, true, true);
AddColumn(Sys_LV_CL_ConvertString("GameType"), 3, width * 0.22f, false, false);
AddColumn(Sys_LV_CL_ConvertString("Ping"), 4, width * 0.065f, true, false);
uWinMan.ActivateControl(this);
SetupServers();
}
void UILANGameClass::SelectServer( Event *ev )
void UILANGameClass::SetupServers(void)
{
// FIXME: stub
int i;
LANGameItem *pItem;
const serverInfo_t *pServerInfo;
for (i = 1; i <= cls.numlocalservers; i++) {
pServerInfo = &cls.localServers[i - 1];
if (i > getNumItems()) {
pItem = new LANGameItem();
AddItem(pItem);
} else {
pItem = static_cast<LANGameItem *>(GetItem(i));
}
*pItem = LANGameItem(
pServerInfo->hostName,
pServerInfo->mapName,
va("%02i/%02i", pServerInfo->clients, pServerInfo->maxClients),
pServerInfo->gameTypeString,
str(pServerInfo->ping)
);
}
while (cls.numlocalservers < getNumItems()) {
DeleteItem(getNumItems());
}
cls.bNewLocalServerInfo = false;
m_iLastUpdateTime = 0;
}
void UILANGameClass::JoinServer( Event *ev )
void UILANGameClass::SelectServer(Event *ev)
{
// FIXME: stub
const serverInfo_t& serverInfo = cls.localServers[getCurrentItem() - 1];
static const char info[] = "\xFF\xFF\xFF\xFF\x02getinfo xxx";
Com_Printf("Requesting updated info from server...\n");
Cvar_Set("cl_langamerefreshstatus", "Requesting updated info from server...");
NET_SendPacket(NS_CLIENT, sizeof(info), info, serverInfo.adr);
m_iLastUpdateTime = cls.realtime + 3000;
}
qboolean UILANGameClass::KeyEvent( int key, unsigned int time )
void UILANGameClass::JoinServer(Event *ev)
{
// FIXME: stub
return qfalse;
if (!getCurrentItem()) {
return;
}
const serverInfo_t& serverInfo = cls.localServers[getCurrentItem() - 1];
UI_SetReturnMenuToCurrent();
CL_Connect(NET_AdrToString(serverInfo.adr), netadrtype_t::NA_UNSPEC);
}
void UILANGameClass::UpdateUIElement( void )
qboolean UILANGameClass::KeyEvent(int key, unsigned int time)
{
// FIXME: stub
switch (key) {
case K_ENTER:
case K_KP_ENTER:
JoinServer(NULL);
return true;
case K_UPARROW:
if (getCurrentItem() > 1) {
TrySelectItem(getCurrentItem() - 1);
SelectServer(NULL);
}
return false;
case K_DOWNARROW:
if (getCurrentItem() < getNumItems()) {
TrySelectItem(getCurrentItem() + 1);
SelectServer(NULL);
}
return false;
}
return UIListBase::KeyEvent(key, time);
}
LANGameItem::LANGameItem() {}
LANGameItem::LANGameItem(
const str& hostName, const str& mapName, const str& players, const str& gameTypeString, const str& ping
)
{
strings[0] = hostName;
strings[1] = mapName;
strings[2] = players;
strings[3] = gameTypeString;
strings[4] = ping;
}
int LANGameItem::getListItemValue(int which) const
{
return atoi(strings[which]);
}
griditemtype_t LANGameItem::getListItemType(int which) const
{
return griditemtype_t::TYPE_STRING;
}
str LANGameItem::getListItemString(int which) const
{
return strings[which];
}
void LANGameItem::DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont) {}
qboolean LANGameItem::IsHeaderEntry() const
{
return qfalse;
}
+14 -16
View File
@@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@@ -20,29 +20,27 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#ifndef __CL_UILANGAME_H__
#define __CL_UILANGAME_H__
#pragma once
class UILANGameClass : public UIListCtrl {
class UILANGameClass : public UIListCtrl
{
protected:
int m_iLastUpdateTime;
UIReggedMaterial *m_noservers_mat;
int m_iLastUpdateTime;
UIReggedMaterial *m_noservers_mat;
public:
CLASS_PROTOTYPE( UILANGameClass );
CLASS_PROTOTYPE(UILANGameClass);
private:
void SetupServers( void );
void SetupServers(void);
protected:
void Draw( void ) override;
void SelectServer( Event *ev );
void JoinServer( Event *ev );
qboolean KeyEvent( int key, unsigned int time ) override;
void UpdateUIElement( void ) override;
void Draw(void) override;
void SelectServer(Event *ev);
void JoinServer(Event *ev);
qboolean KeyEvent(int key, unsigned int time) override;
void UpdateUIElement(void) override;
public:
UILANGameClass();
UILANGameClass();
};
#endif /* __CL_UILANGAME_H__ */
+314 -25
View File
@@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@@ -21,63 +21,352 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "cl_ui.h"
#include "../qcommon/localization.h"
CLASS_DECLARATION( UIListCtrl, UIFAKKLoadGameClass, NULL )
class FAKKLoadGameItem : public UIListCtrlItem
{
{ NULL, NULL }
str strings[4];
public:
FAKKLoadGameItem(const str& missionName, const str& elapsedTime, const str& dateTime, const str& fileName);
int getListItemValue(int which) const override;
griditemtype_t getListItemType(int which) const override;
str getListItemString(int which) const override;
void DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont) override;
qboolean IsHeaderEntry() const override;
};
static UIFAKKLoadGameClass *loadgame_ui = NULL;
Event EV_FAKKLoadGame_LoadGame
(
"loadgame",
EV_DEFAULT,
NULL,
NULL,
"Load the currently selected game"
);
Event EV_FAKKLoadGame_RemoveGame
(
"removegame",
EV_DEFAULT,
NULL,
NULL,
"Delete the currently selected game"
);
Event EV_FAKKLoadGame_DeleteGame
(
"deletegame",
EV_DEFAULT,
NULL,
NULL,
"Delete the currently selected game... for real"
);
Event EV_FAKKLoadGame_NoDeleteGame
(
"nodeletegame",
EV_DEFAULT,
NULL,
NULL,
"Delete the currently selected game... for real"
);
Event EV_FAKKLoadGame_SaveGame
(
"savegame",
EV_DEFAULT,
NULL,
NULL,
"Save the currently selected game"
);
CLASS_DECLARATION(UIListCtrl, UIFAKKLoadGameClass, NULL) {
{&EV_UIListBase_ItemSelected, &UIFAKKLoadGameClass::SelectGame },
{&EV_UIListBase_ItemDoubleClicked, &UIFAKKLoadGameClass::LoadGame },
{&EV_FAKKLoadGame_RemoveGame, &UIFAKKLoadGameClass::RemoveGame },
{&EV_FAKKLoadGame_DeleteGame, &UIFAKKLoadGameClass::DeleteGame },
{&EV_FAKKLoadGame_NoDeleteGame, &UIFAKKLoadGameClass::NoDeleteGame},
{&EV_FAKKLoadGame_LoadGame, &UIFAKKLoadGameClass::LoadGame },
{&EV_FAKKLoadGame_SaveGame, &UIFAKKLoadGameClass::SaveGame },
{NULL, NULL }
};
UIFAKKLoadGameClass::UIFAKKLoadGameClass()
{
// FIXME: stub
Connect(this, EV_UIListBase_ItemDoubleClicked, EV_UIListBase_ItemDoubleClicked);
Connect(this, EV_UIListBase_ItemSelected, EV_UIListBase_ItemSelected);
AllowActivate(false);
m_bRemovePending = false;
setHeaderFont("facfont-20");
loadgame_ui = this;
}
void UIFAKKLoadGameClass::SelectGame( Event *ev )
UIFAKKLoadGameClass::~UIFAKKLoadGameClass()
{
// FIXME: stub
loadgame_ui = NULL;
}
void UIFAKKLoadGameClass::LoadGame( Event *ev )
void UIFAKKLoadGameClass::UpdateUIElement(void)
{
// FIXME: stub
float width;
RemoveAllColumns();
width = getClientFrame().size.width;
AddColumn(Sys_LV_CL_ConvertString("Mission"), 0, width * 0.555, false, false);
AddColumn(Sys_LV_CL_ConvertString("Elapsed Time"), 1, width * 0.17f, true, true);
AddColumn(Sys_LV_CL_ConvertString("Date & Time Logged"), 2, width * 0.275f, true, true);
uWinMan.ActivateControl(this);
SetupFiles();
}
void UIFAKKLoadGameClass::SaveGame( Event *ev )
void UIFAKKLoadGameClass::SetupFiles(void)
{
// FIXME: stub
char **filenames;
int numfiles;
int i;
const char *searchFolder = Com_GetArchiveFolder();
// cleanup
DeleteAllItems();
filenames = FS_ListFiles(searchFolder, "ssv", qfalse, &numfiles);
for (i = 0; i < numfiles; i++) {
const char *filename;
str work;
str gametime;
str date;
fileHandle_t f;
savegamestruct_t save;
filename = filenames[i];
work = searchFolder;
work += "/";
work += filename;
FS_FOpenFileRead(work, &f, qfalse, qtrue);
if (!f) {
continue;
}
FS_Read(&save, sizeof(savegamestruct_t), f);
FS_FCloseFile(f);
if (save.version != SAVEGAME_STRUCT_VERSION) {
// wrong save game version
continue;
}
gametime = (save.mapTime / 1000);
date = save.time;
AddItem(new FAKKLoadGameItem(save.comment, gametime, date, save.saveName));
}
FS_FreeFileList(filenames);
// sort by date
SortByColumn(2);
// select the first item
TrySelectItem(1);
SelectGame(NULL);
}
void UIFAKKLoadGameClass::RemoveGame( Event *ev )
void UIFAKKLoadGameClass::SelectGame(Event *ev)
{
// FIXME: stub
UIWidget *wid;
const char *shotName;
if (getCurrentItem() > 0) {
shotName = Com_GetArchiveFileName(GetItem(getCurrentItem())->getListItemString(3), "tga");
} else {
shotName = "textures/menu/no_saved_games.tga";
}
wid = findSibling("LoadSaveShot");
if (!wid) {
return;
}
wid->setMaterial(uWinMan.RefreshShader(shotName));
}
void UIFAKKLoadGameClass::DeleteGame( Event *ev )
void UIFAKKLoadGameClass::RemoveGame(Event *ev)
{
// FIXME: stub
if (m_bRemovePending || getCurrentItem() <= 0) {
return;
}
Cbuf_ExecuteText(
EXEC_NOW,
"dialog \"\" \"\" \"widgetcommand LoadSaveList deletegame\" \"widgetcommand LoadSaveList nodeletegame\" 256 64 "
"confirm_delete menu_button_trans menu_button_trans\n"
);
m_bRemovePending = true;
}
void UIFAKKLoadGameClass::NoDeleteGame( Event *ev )
void UIFAKKLoadGameClass::NoDeleteGame(Event *ev)
{
// FIXME: stub
m_bRemovePending = false;
}
qboolean UIFAKKLoadGameClass::KeyEvent( int key, unsigned int time )
void UIFAKKLoadGameClass::DeleteGame(Event *ev)
{
// FIXME: stub
return qfalse;
str name;
cvar_t *var;
m_bRemovePending = false;
if (getCurrentItem() <= 0) {
return;
}
name = GetItem(getCurrentItem())->getListItemString(3);
var = Cvar_Get("g_lastsave", "", 0);
if (!strcmp(name, var->string)) {
// Make sure the last save is not the save being deleted
Cvar_Set("g_lastsave", "");
}
Com_WipeSavegame(name);
SetupFiles();
}
void UIFAKKLoadGameClass::UpdateUIElement( void )
void UIFAKKLoadGameClass::LoadGame(Event *ev)
{
// FIXME: stub
char cmdString[266];
str name;
if (getCurrentItem() <= 0) {
return;
}
name = GetItem(getCurrentItem())->getListItemString(3);
// Execute the command
Com_sprintf(cmdString, sizeof(cmdString), "loadgame %s\n", name.c_str());
Cbuf_AddText(cmdString);
}
void UIFAKKLoadGameClass::SetupFiles( void )
void UIFAKKLoadGameClass::SaveGame(Event *ev)
{
// FIXME: stub
Cbuf_ExecuteText(EXEC_NOW, "savegame");
}
void UI_SetupFiles( void ) {
// FIXME: stub
qboolean UIFAKKLoadGameClass::KeyEvent(int key, unsigned int time)
{
switch (key) {
case K_DEL:
RemoveGame(NULL);
return qtrue;
case K_ENTER:
case K_KP_ENTER:
LoadGame(NULL);
return qtrue;
case K_UPARROW:
if (getCurrentItem() > 1) {
TrySelectItem(getCurrentItem() - 1);
SelectGame(NULL);
return qtrue;
}
break;
case K_DOWNARROW:
if (getCurrentItem() < getNumItems()) {
TrySelectItem(getCurrentItem() + 1);
SelectGame(NULL);
return qtrue;
}
break;
default:
return UIListBase::KeyEvent(key, time);
}
return qfalse;
}
void UI_SetupFiles(void)
{
if (loadgame_ui && loadgame_ui->getShow()) {
loadgame_ui->SetupFiles();
}
}
FAKKLoadGameItem::FAKKLoadGameItem(
const str& missionName, const str& elapsedTime, const str& dateTime, const str& fileName
)
{
strings[0] = missionName;
strings[1] = elapsedTime;
strings[2] = dateTime;
strings[3] = fileName;
}
int FAKKLoadGameItem::getListItemValue(int which) const
{
return atoi(strings[which]);
}
griditemtype_t FAKKLoadGameItem::getListItemType(int which) const
{
return griditemtype_t::TYPE_STRING;
}
str FAKKLoadGameItem::getListItemString(int which) const
{
str itemstring;
switch (which) {
case 0:
case 3:
itemstring = strings[which];
break;
case 1:
{
int numseconds;
int numseconds_hours;
// hours
numseconds = atol(strings[1]);
itemstring += (numseconds / 3600);
itemstring += ":";
// minutes
numseconds_hours = numseconds % 3600;
if (numseconds_hours / 60 <= 9) {
itemstring += "0";
}
itemstring += (numseconds_hours / 60);
itemstring += ":";
// seconds
if (numseconds_hours / 60 <= 9) {
itemstring += "0";
}
itemstring += (numseconds_hours % 60);
}
break;
case 2:
{
time_t time;
char buffer[2048];
time = atol(strings[2]);
strftime(buffer, sizeof(buffer), "%a %b %d %H:%M:%S %Y", localtime(&time));
itemstring = buffer;
}
break;
}
return itemstring;
}
void FAKKLoadGameItem::DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont) {}
qboolean FAKKLoadGameItem::IsHeaderEntry() const
{
return qfalse;
}
+18 -15
View File
@@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@@ -22,23 +22,26 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#pragma once
class UIFAKKLoadGameClass : public UIListCtrl {
bool m_bRemovePending;
class UIFAKKLoadGameClass : public UIListCtrl
{
bool m_bRemovePending;
public:
CLASS_PROTOTYPE( UIFAKKLoadGameClass );
CLASS_PROTOTYPE(UIFAKKLoadGameClass);
protected:
void SelectGame( Event *ev );
void LoadGame( Event *ev );
void SaveGame( Event *ev );
void RemoveGame( Event *ev );
void DeleteGame( Event *ev );
void NoDeleteGame( Event *ev );
qboolean KeyEvent( int key, unsigned int time ) override;
void UpdateUIElement( void ) override;
public:
UIFAKKLoadGameClass();
void SelectGame(Event *ev);
void LoadGame(Event *ev);
void SaveGame(Event *ev);
void RemoveGame(Event *ev);
void DeleteGame(Event *ev);
void NoDeleteGame(Event *ev);
qboolean KeyEvent(int key, unsigned int time) override;
void UpdateUIElement(void) override;
void SetupFiles( void );
public:
UIFAKKLoadGameClass();
~UIFAKKLoadGameClass();
void SetupFiles(void);
};
+449
View File
@@ -0,0 +1,449 @@
/*
===========================================================================
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code 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.
OpenMoHAA source code 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include "cl_ui.h"
#include "cl_uimaprotationsetup.h"
Event EV_MapListBox_RefreshMapList
(
"RefreshMapList",
EV_DEFAULT,
NULL,
NULL,
"Refreshes the map list."
);
Event EV_MapRotationListBox_RefreshRotationList
(
"RefreshRotationList",
EV_DEFAULT,
NULL,
NULL,
"Refreshed the map rotation list."
);
CLASS_DECLARATION(UIListBox, UIMapRotationListBox, NULL) {
{&EV_MapRotationListBox_RefreshRotationList, &UIMapRotationListBox::RefreshRotationList},
{NULL, NULL }
};
UIMapRotationListBox::UIMapRotationListBox() {}
void UIMapRotationListBox::RefreshRotationList(Event *ev)
{
DeleteAllItems();
PopulateRotationList();
}
void UIMapRotationListBox::PopulateRotationList()
{
cvar_t *filter;
cvar_t *maplistVar;
const char *token;
char mapBuffer[1024];
filter = Cvar_Get("g_maprotation_filter", "ffa", 0);
if (!Q_stricmp(filter->string, "obj")) {
maplistVar = Cvar_Get("ui_maplist_obj", "", 0);
} else if (!Q_stricmp(filter->string, "tow")) {
maplistVar = Cvar_Get("ui_maplist_tow", "", 0);
} else if (!Q_stricmp(filter->string, "lib")) {
maplistVar = Cvar_Get("ui_maplist_lib", "", 0);
} else if (!Q_stricmp(filter->string, "team")) {
maplistVar = Cvar_Get("ui_maplist_team", "", 0);
} else if (!Q_stricmp(filter->string, "round")) {
maplistVar = Cvar_Get("ui_maplist_round", "", 0);
} else {
maplistVar = Cvar_Get("ui_maplist_ffa", "", 0);
}
strcpy(mapBuffer, maplistVar->string);
for (token = strtok(mapBuffer, " /"); token; token = strtok(NULL, " /")) {
if (!Q_stricmp(token, "dm")) {
continue;
}
if (!Q_stricmp(token, "obj")) {
continue;
}
if (!Q_stricmp(token, "lib")) {
continue;
}
AddItem(token, NULL);
}
}
CLASS_DECLARATION(UIListBox, UIMapListBox, NULL) {
{&EV_MapListBox_RefreshMapList, &UIMapListBox::RefreshMapList},
{NULL, NULL }
};
UIMapListBox::UIMapListBox() {}
void UIMapListBox::RefreshMapList(Event *ev)
{
DeleteAllItems();
PopulateMapList();
}
void UIMapListBox::PopulateMapList()
{
cvar_t *filter;
char **filenames;
int numfiles;
str path;
int i;
bool bTugOfWar = false;
bool bObjective = false;
bool bLiberation = false;
filter = Cvar_Get("g_maprotation_filter", "ffa", 0);
if (!Q_stricmp(filter->string, "lib")) {
path = "maps/lib/";
bLiberation = true;
} else if (!Q_stricmp(filter->string, "obj") || !Q_stricmp(filter->string, "tow")) {
path = "maps/obj/";
if (!Q_stricmp(filter->string, "tow")) {
bTugOfWar = true;
} else {
bObjective = true;
}
} else {
path = "maps/dm/";
}
filenames = FS_ListFiles(path, ".bsp", qfalse, &numfiles);
for (i = 0; i < numfiles; i++) {
const char *filename = filenames[i];
const char *token;
char mapName[256];
char tokenized[256];
bool bHasMP = false;
bool bHasTOW = false;
bool bHasLib = false;
strcpy(mapName, filename);
mapName[strlen(mapName) - 4] = 0;
if (!COM_IsMapValid(mapName)) {
continue;
}
if (bTugOfWar || bLiberation) {
strcpy(tokenized, mapName);
for (token = strtok(tokenized, "_"); token; token = strtok(NULL, "_")) {
if (bLiberation) {
if (!Q_stricmp(token, "MP")) {
bHasMP = true;
}
if (!Q_stricmp(token, "LIB")) {
bHasLib = true;
}
if (bHasMP && bHasLib) {
AddItem(mapName, NULL);
break;
}
}
if (bTugOfWar) {
if (!Q_stricmp(token, "MP")) {
bHasMP = true;
}
if (!Q_stricmp(token, "TOW")) {
bHasTOW = true;
}
if (bHasMP && bHasTOW) {
AddItem(mapName, NULL);
break;
}
}
}
} else if (bObjective) {
strcpy(tokenized, mapName);
for (token = strtok(tokenized, "_"); token; token = strtok(NULL, "_")) {
if (!Q_stricmp(token, "obj")) {
AddItem(mapName, NULL);
break;
}
}
if (!Q_stricmp(mapName, "mp_ship_lib")) {
AddItem(mapName, NULL);
}
} else {
AddItem(mapName, NULL);
}
}
if (bObjective) {
path = "maps/lib/";
filenames = FS_ListFiles(path, ".bsp", qfalse, &numfiles);
for (i = 0; i < numfiles; i++) {
const char *filename = filenames[i];
const char *token;
char mapName[256];
char tokenized[256];
strcpy(mapName, filename);
mapName[strlen(mapName) - 4] = 0;
strcpy(tokenized, mapName);
token = strtok(tokenized, "_");
if (!Q_stricmp(token, "obj") || !Q_stricmp(mapName, "mp_ship_lib")) {
AddItem(mapName, NULL);
break;
}
}
}
if (!bTugOfWar && !bObjective && !bLiberation) {
int type;
for (type = 0; type < 2; type++) {
if (type == 0) {
path = "maps/obj/";
} else {
path = "maps/lib/";
}
filenames = FS_ListFiles(path, ".bsp", qfalse, &numfiles);
for (i = 0; i < numfiles; i++) {
const char *filename = filenames[i];
char mapName[256];
strcpy(mapName, filename);
mapName[strlen(mapName) - 4] = 0;
if (!COM_IsMapValid(mapName)) {
continue;
}
if (!Q_stricmp(mapName, "obj_team2") || !Q_stricmp(mapName, "obj_team4")) {
continue;
}
AddItem(mapName, NULL);
}
}
}
}
CLASS_DECLARATION(UIButton, UIAddToRotationButton, NULL) {
{&W_LeftMouseUp, &UIAddToRotationButton::Released},
{NULL, NULL }
};
void UIAddToRotationButton::Released(Event *ev)
{
UIListBox *mapList;
UIListBox *rotationList;
size_t prefixLength;
int i;
mapList = static_cast<UIListBox *>(uWinMan.FindWidget("Map List"));
rotationList = static_cast<UIListBox *>(uWinMan.FindWidget("Rotation List"));
if (Cvar_Get("g_maprotation_filter", "ffa", 0)) {
prefixLength = strlen("obj/") + 1;
} else {
prefixLength = 1;
}
if (mapList && rotationList) {
size_t mapLength = 0;
int item = mapList->getCurrentItem();
for (i = 1; i <= rotationList->getNumItems(); i++) {
str text = rotationList->getItemText(i);
mapLength += text.length();
}
if (item) {
str text = mapList->getItemText(item);
if (prefixLength + mapLength + text.length() < 256) {
rotationList->AddItem(text, NULL);
}
}
}
UIButtonBase::Released(ev);
}
CLASS_DECLARATION(UIButton, UIRemoveFromRotationButton, NULL) {
{&W_LeftMouseUp, &UIRemoveFromRotationButton::Released},
{NULL, NULL }
};
void UIRemoveFromRotationButton::Released(Event *ev)
{
UIListBox *list;
list = static_cast<UIListBox *>(uWinMan.FindWidget("Rotation List"));
if (list) {
list->DeleteItem(list->getCurrentItem());
}
UIButtonBase::Released(ev);
}
CLASS_DECLARATION(UIButton, UIRotationApplyButton, NULL) {
{&W_LeftMouseUp, &UIRotationApplyButton::Released},
{NULL, NULL }
};
void UIRotationApplyButton::Released(Event *ev)
{
UIListBox *list;
cvar_t *filter;
str cvarName;
str maplistStr;
int i;
bool bObjective = false;
bool bLiberation = false;
filter = Cvar_Get("g_maprotation_filter", "ffa", 0);
if (!Q_stricmp(filter->string, "obj")) {
cvarName = "ui_maplist_obj";
bObjective = true;
} else if (!Q_stricmp(filter->string, "tow")) {
cvarName = "ui_maplist_obj";
bObjective = true;
} else if (!Q_stricmp(filter->string, "lib")) {
cvarName = "ui_maplist_lib";
bLiberation = true;
} else if (!Q_stricmp(filter->string, "team")) {
cvarName = "ui_maplist_team";
} else if (!Q_stricmp(filter->string, "round")) {
cvarName = "ui_maplist_round";
} else {
cvarName = "ui_maplist_ffa";
}
Cvar_Set(cvarName, "");
list = static_cast<UIListBox *>(uWinMan.FindWidget("Rotation List"));
if (list) {
for (i = 1; i <= list->getNumItems(); i++) {
const char *token;
str text = list->getItemText(i);
char map[256];
bool bHasTOW = false, bHasObj = false, bHasLib = false, bHasShip = false;
strcpy(map, text);
for (token = strtok(map, "_"); token; token = strtok(NULL, "_")) {
if (!Q_stricmp(token, "TOW")) {
bHasTOW = true;
break;
}
if (!Q_stricmp(token, "obj")) {
bHasObj = true;
break;
}
if (!Q_stricmp(token, "lib")) {
bHasLib = true;
break;
}
if (!Q_stricmp(token, "ship")) {
bHasShip = true;
break;
}
}
if (bHasShip) {
maplistStr += "lib/";
} else if (bObjective || bHasTOW || bHasObj) {
maplistStr += "obj/";
} else if (bHasLib || bLiberation) {
maplistStr += "lib/";
} else {
maplistStr += "dm/";
}
maplistStr += text;
maplistStr += " ";
if (i == 1) {
Cvar_Set("ui_dmmap", maplistStr);
}
}
}
Cvar_Set(cvarName, maplistStr);
UIButtonBase::Released(ev);
}
CLASS_DECLARATION(UIButton, UIRotationMoveItemUpButton, NULL) {
{&W_LeftMouseUp, &UIRotationMoveItemUpButton::Released},
{NULL, NULL }
};
void UIRotationMoveItemUpButton::Released(Event *ev)
{
UIListBox *list;
int item;
list = static_cast<UIListBox *>(uWinMan.FindWidget("Rotation List"));
item = list->getCurrentItem();
if (item < list->getNumItems() && list->getNumItems() > 1) {
str text = list->getItemText(item + 1);
list->DeleteItem(list->getCurrentItem() - 1);
list->InsertItem(text, item);
list->setCurrentItem(item - 1);
}
UIButtonBase::Released(ev);
}
CLASS_DECLARATION(UIButton, UIRotationMoveItemDownButton, NULL) {
{&W_LeftMouseUp, &UIRotationMoveItemDownButton::Released},
{NULL, NULL }
};
void UIRotationMoveItemDownButton::Released(Event *ev)
{
UIListBox *list;
int item;
list = static_cast<UIListBox *>(uWinMan.FindWidget("Rotation List"));
item = list->getCurrentItem();
if (item < list->getNumItems() && list->getNumItems() > 1) {
str text = list->getItemText(item + 1);
list->DeleteItem(list->getCurrentItem() + 1);
list->InsertItem(text, item);
list->setCurrentItem(item + 1);
}
UIButtonBase::Released(ev);
}
+87
View File
@@ -0,0 +1,87 @@
/*
===========================================================================
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code 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.
OpenMoHAA source code 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#pragma once
#include "../uilib/uilistbox.h"
class UIMapRotationListBox : public UIListBox
{
CLASS_PROTOTYPE(UIMapRotationListBox);
public:
UIMapRotationListBox();
void RefreshRotationList(Event *ev);
void PopulateRotationList();
};
class UIMapListBox : public UIListBox
{
CLASS_PROTOTYPE(UIMapListBox);
public:
UIMapListBox();
void RefreshMapList(Event *ev);
void PopulateMapList();
};
class UIAddToRotationButton : public UIButton
{
CLASS_PROTOTYPE(UIAddToRotationButton);
public:
void Released(Event *ev);
};
class UIRemoveFromRotationButton : public UIButton
{
CLASS_PROTOTYPE(UIRemoveFromRotationButton);
public:
void Released(Event *ev);
};
class UIRotationApplyButton : public UIButton
{
CLASS_PROTOTYPE(UIRotationApplyButton);
public:
void Released(Event *ev);
};
class UIRotationMoveItemUpButton : public UIButton
{
CLASS_PROTOTYPE(UIRotationMoveItemUpButton);
public:
void Released(Event *ev);
};
class UIRotationMoveItemDownButton : public UIButton
{
CLASS_PROTOTYPE(UIRotationMoveItemDownButton);
public:
void Released(Event *ev);
};
+84 -24
View File
@@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@@ -22,47 +22,107 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "cl_ui.h"
CLASS_DECLARATION( FilePickerClass, MapRunnerClass, NULL )
{
{ NULL, NULL }
CLASS_DECLARATION(FilePickerClass, MapRunnerClass, NULL) {
{NULL, NULL}
};
void MapRunnerClass::FileChosen( str &currentDirectory, str &partialName, str &fullname )
void MapRunnerClass::FileChosen(const str& currentDirectory, const str& partialName, const str& fullname)
{
// FIXME: stub
str newName;
newName = "spmap " + str(fullname, 5, fullname.length() - 4) + "\n";
// insert the command
Cbuf_AddText(newName);
CloseWindow();
}
CLASS_DECLARATION( FilePickerClass, ViewSpawnerClass, NULL )
{
{ NULL, NULL }
CLASS_DECLARATION(FilePickerClass, UIPickFileClass, NULL) {
{NULL, NULL}
};
void ViewSpawnerClass::FileChosen( str &currentDirectory, str &partialName, str &fullname )
UIPickFileClass::UIPickFileClass()
{
// FIXME: stub
retobj = NULL;
retevent = NULL;
}
CLASS_DECLARATION( FilePickerClass, LODSpawnerClass, NULL )
UIPickFileClass::~UIPickFileClass()
{
{ NULL, NULL }
if (retevent) {
delete retevent;
}
}
void UIPickFileClass::FileChosen(const str& currentDirectory, const str& partialName, const str& fullname)
{
if (!retobj || !retevent) {
CloseWindow();
return;
}
retevent->AddString(fullname);
retobj->ProcessEvent(retevent);
retevent = NULL;
retobj = NULL;
CloseWindow();
}
void PickFile(const char *name, Listener *obj, Event& event)
{
UIPickFileClass *picker;
str currentpath;
int i;
picker = new UIPickFileClass();
picker->retevent = new Event(event);
picker->retobj = obj;
if (name && *name && strchr(name, '/')) {
currentpath = name;
for (i = currentpath.length(); i > 0; i--) {
if (currentpath[i] == '/') {
break;
}
}
currentpath = str(currentpath, 0, i + 1);
} else {
currentpath = "";
}
picker->Setup("", currentpath, ".*");
}
CLASS_DECLARATION(FilePickerClass, ViewSpawnerClass, NULL) {
{NULL, NULL}
};
void LODSpawnerClass::FileChosen( str &currentDirectory, str &partialName, str &fullname )
void ViewSpawnerClass::FileChosen(const str& currentDirectory, const str& partialName, const str& fullname)
{
// FIXME: stub
str newName;
newName = "viewspawn " + fullname + "\n";
// insert the command
Cbuf_AddText(newName);
CloseWindow();
}
CLASS_DECLARATION( FilePickerClass, UIPickFileClass, NULL )
{
{ NULL, NULL }
CLASS_DECLARATION(FilePickerClass, LODSpawnerClass, NULL) {
{NULL, NULL}
};
void UIPickFileClass::FileChosen( str &currentDirectory, str &partialName, str &fullname )
void LODSpawnerClass::FileChosen(const str& currentDirectory, const str& partialName, const str& fullname)
{
// FIXME: stub
}
str newName;
void PickFile( const char *name, Listener *obj, Event& event )
{
// FIXME: stub
newName = "lod_spawn " + fullname + "\n";
// insert the command
Cbuf_AddText(newName);
CloseWindow();
}
+24 -20
View File
@@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@@ -20,40 +20,44 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#ifndef __CL_UIMAPRUNNER_H__
#define __CL_UIMAPRUNNER_H__
#pragma once
class MapRunnerClass : public FilePickerClass {
class MapRunnerClass : public FilePickerClass
{
public:
CLASS_PROTOTYPE( MapRunnerClass );
CLASS_PROTOTYPE(MapRunnerClass);
void FileChosen( str &currentDirectory, str &partialName, str &fullname ) override;
void FileChosen(const str& currentDirectory, const str& partialName, const str& fullname) override;
};
class ViewSpawnerClass : public FilePickerClass {
class ViewSpawnerClass : public FilePickerClass
{
public:
CLASS_PROTOTYPE( ViewSpawnerClass );
CLASS_PROTOTYPE(ViewSpawnerClass);
void FileChosen( str &currentDirectory, str &partialName, str &fullname ) override;
void FileChosen(const str& currentDirectory, const str& partialName, const str& fullname) override;
};
class LODSpawnerClass : public FilePickerClass {
class LODSpawnerClass : public FilePickerClass
{
public:
CLASS_PROTOTYPE( LODSpawnerClass );
CLASS_PROTOTYPE(LODSpawnerClass);
void FileChosen( str &currentDirectory, str &partialName, str &fullname ) override;
void FileChosen(const str& currentDirectory, const str& partialName, const str& fullname) override;
};
class UIPickFileClass : public FilePickerClass {
class UIPickFileClass : public FilePickerClass
{
public:
Listener *retobj;
Event *retevent;
Listener *retobj;
Event *retevent;
CLASS_PROTOTYPE( UIPickFileClass );
CLASS_PROTOTYPE(UIPickFileClass);
void FileChosen( str &currentDirectory, str &partialName, str &fullname ) override;
UIPickFileClass();
~UIPickFileClass();
void FileChosen(const str& currentDirectory, const str& partialName, const str& fullname) override;
};
void PickFile( const char *name, Listener *obj, Event& event );
#endif /* __CL_UIMAPRUNNER_H__ */
void PickFile(const char *name, Listener *obj, Event& event);
+138 -27
View File
@@ -22,68 +22,179 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "cl_ui.h"
CLASS_DECLARATION( UIWidget, FakkMiniconsole, NULL )
{
{ NULL, NULL }
Event EV_Minicon_Goin("_minicon_goin", EV_DEFAULT, NULL, NULL, "Event to make the miniconsole disappear");
CLASS_DECLARATION(UIWidget, FakkMiniconsole, NULL) {
{&W_SizeChanged, &FakkMiniconsole::OnSizeChanged},
{&EV_Minicon_Goin, &FakkMiniconsole::MoveInEvent },
{NULL, NULL }
};
FakkMiniconsole::FakkMiniconsole()
{
// FIXME: stub
m_maxlines = 0;
m_reallyshown = true;
m_boxstate = boxstate_t::box_in;
m_boxtime = uid.time;
m_movespeed = 500;
}
void FakkMiniconsole::VerifyBoxOut( void )
void FakkMiniconsole::setShowState(void)
{
// FIXME: stub
if (m_reallyshown) {
setShow(m_boxstate != boxstate_t::box_in);
} else {
setShow(false);
}
}
void FakkMiniconsole::ChangeBoxState( boxstate_t state )
void FakkMiniconsole::setRealShow(bool b)
{
// FIXME: stub
m_reallyshown = b;
setShowState();
}
void FakkMiniconsole::HandleBoxMoving( void )
void FakkMiniconsole::VerifyBoxOut(void)
{
// FIXME: stub
PostMoveinEvent();
if (m_boxstate && m_boxstate != boxstate_t::box_out) {
ChangeBoxState(box_moving_out);
}
}
void FakkMiniconsole::PostMoveinEvent( void )
void FakkMiniconsole::Print(const char *text)
{
// FIXME: stub
str *lastline;
const char *p;
if (!m_lines.NumObjects()) {
m_lines.AddObject({});
}
lastline = &m_lines.ObjectAt(m_lines.NumObjects());
if (*text) {
for (p = text; *p; p++) {
if (*p != '\n') {
*lastline += *p;
} else {
m_lines.AddObject({});
lastline = &m_lines.ObjectAt(m_lines.NumObjects());
}
}
}
if (lastline && lastline->length() > 128) {
Print("\n");
}
if (m_maxlines < 0) {
m_maxlines = 1;
}
while (m_lines.NumObjects() > this->m_maxlines) {
m_lines.RemoveObjectAt(1);
}
VerifyBoxOut();
}
void FakkMiniconsole::setShowState( void )
void FakkMiniconsole::PostMoveinEvent(void)
{
// FIXME: stub
if (m_boxstate != boxstate_t::box_out) {
return;
}
CancelEventsOfType(EV_Minicon_Goin);
PostEvent(new Event(EV_Minicon_Goin), 5.f);
}
void FakkMiniconsole::OnSizeChanged( Event *ev )
void FakkMiniconsole::OnSizeChanged(Event *ev)
{
// FIXME: stub
m_maxlines = m_frame.size.height / m_font->getHeight(false);
}
void FakkMiniconsole::Print( const char *text )
void FakkMiniconsole::MoveInEvent(Event *ev)
{
// FIXME: stub
ChangeBoxState(boxstate_t::box_moving_in);
}
void FakkMiniconsole::Create( const UISize2D& size, const UColor& fore, const UColor& back, float alpha )
void FakkMiniconsole::HandleBoxMoving(void)
{
// FIXME: stub
int delta;
UIRect2D newRect;
if (m_boxstate == boxstate_t::box_out || m_boxstate == boxstate_t::box_in) {
return;
}
delta = m_movespeed * (uid.time - m_boxtime) / 1000;
m_boxtime = 1000 * delta / m_movespeed + m_boxtime;
switch (m_boxstate) {
case boxstate_t::box_moving_in:
newRect = UIRect2D(delta + m_frame.pos.x, m_frame.pos.y, m_frame.size.width, m_frame.size.height);
if (newRect.pos.x >= uid.vidWidth) {
newRect.pos.x = uid.vidWidth;
ChangeBoxState(boxstate_t::box_in);
}
break;
case boxstate_t::box_moving_out:
newRect = UIRect2D(-delta + m_frame.pos.x, m_frame.pos.y, m_frame.size.width, m_frame.size.height);
if (newRect.pos.x <= uid.vidWidth - newRect.size.width) {
newRect.pos.x = uid.vidWidth - newRect.size.width;
ChangeBoxState(boxstate_t::box_out);
}
break;
default:
ChangeBoxState(boxstate_t::box_in);
break;
}
setFrame(newRect);
}
void FakkMiniconsole::MoveInEvent( Event *ev )
void FakkMiniconsole::Draw(void)
{
// FIXME: stub
float aty;
int i;
HandleBoxMoving();
m_font->setColor(m_foreground_color);
aty = m_frame.size.height - m_font->getHeight(false);
for (i = m_lines.NumObjects(); i > 0; i--) {
if (-m_font->getHeight(false) >= aty) {
break;
}
m_font->Print(0, aty, m_lines.ObjectAt(i), -1, false);
aty -= m_font->getHeight(false);
}
}
void FakkMiniconsole::Draw( void )
void FakkMiniconsole::Create(const UISize2D& size, const UColor& fore, const UColor& back, float alpha)
{
// FIXME: stub
InitFrame(NULL, uid.vidWidth, 0, size.width, size.height, 0);
setBackgroundColor(back, true);
setForegroundColor(fore);
setBackgroundAlpha(alpha);
Connect(this, W_SizeChanged, W_SizeChanged);
OnSizeChanged(NULL);
m_movespeed = size.width * 3;
setShowState();
}
void FakkMiniconsole::setRealShow( bool b )
void FakkMiniconsole::ChangeBoxState(boxstate_t state)
{
// FIXME: stub
m_boxstate = state;
m_boxtime = uid.time;
setShowState();
if (state == boxstate_t::box_out) {
PostMoveinEvent();
}
}
+23 -25
View File
@@ -20,38 +20,36 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#ifndef __CL_UIMINICON_H__
#define __CL_UIMINICON_H__
#pragma once
class FakkMiniconsole : public UIWidget {
class FakkMiniconsole : public UIWidget
{
protected:
Container<str> m_lines;
int m_maxlines;
bool m_reallyshown;
bool m_boxmovingout;
boxstate_t m_boxstate;
int m_boxtime;
int m_movespeed;
Container<str> m_lines;
int m_maxlines;
bool m_reallyshown;
bool m_boxmovingout;
boxstate_t m_boxstate;
int m_boxtime;
int m_movespeed;
public:
CLASS_PROTOTYPE( FakkMiniconsole );
CLASS_PROTOTYPE(FakkMiniconsole);
protected:
void VerifyBoxOut( void );
void ChangeBoxState( boxstate_t state );
void HandleBoxMoving( void );
void PostMoveinEvent( void );
void setShowState( void );
void VerifyBoxOut(void);
void ChangeBoxState(boxstate_t state);
void HandleBoxMoving(void);
void PostMoveinEvent(void);
void setShowState(void);
public:
FakkMiniconsole();
FakkMiniconsole();
void OnSizeChanged( Event *ev );
void Print( const char *text );
void Create( const UISize2D& size, const UColor& fore, const UColor& back, float alpha );
void MoveInEvent( Event *ev );
void Draw( void ) override;
void setRealShow( bool b );
void OnSizeChanged(Event *ev);
void Print(const char *text);
void Create(const UISize2D& size, const UColor& fore, const UColor& back, float alpha);
void MoveInEvent(Event *ev);
void Draw(void) override;
void setRealShow(bool b);
};
#endif
+291 -27
View File
@@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@@ -21,73 +21,337 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "cl_ui.h"
#include "../qcommon/localization.h"
CLASS_DECLARATION( USignal, MpMapPickerClass, NULL )
class MpMapPickerItem : public UIListCtrlItem
{
{ NULL, NULL }
str m_string;
// Added in 2.0
str m_directory;
public:
MpMapPickerItem(const str& string, const str& directory);
int getListItemValue(int which) const override;
griditemtype_t getListItemType(int which) const override;
str getListItemString(int which) const override;
void DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont) override;
qboolean IsHeaderEntry() const override;
};
CLASS_DECLARATION(USignal, MpMapPickerClass, NULL) {
{&EV_UIListBase_ItemSelected, &MpMapPickerClass::FileSelected },
{&EV_UIListBase_ItemDoubleClicked, &MpMapPickerClass::FileChosen },
{&W_Deactivated, &MpMapPickerClass::OnDeactivated},
{NULL, NULL }
};
MpMapPickerClass::MpMapPickerClass()
{
// FIXME: stub
window = new UIFloatingWindow();
window->Create(
NULL,
UIRect2D((cls.glconfig.vidWidth - 300) / 2, (cls.glconfig.vidHeight - 200) / 2, 300, 200),
"Select a Map",
UColor(0.15f, 0.195f, 0.278f),
UHudColor
);
window->setFont("facfont-20");
window->PassEventToWidget("closebutton", new Event(EV_Widget_Disable));
window->PassEventToWidget("minimizebutton", new Event(EV_Widget_Disable));
window->Connect(this, W_Deactivated, W_Deactivated);
listbox = new UIListCtrl();
listbox->InitFrame(window->getChildSpace(), window->getChildSpace()->getClientFrame(), 0);
listbox->SetDrawHeader(false);
listbox->setFont("facfont-20");
listbox->FrameInitialized();
listbox->AddColumn(Sys_LV_CL_ConvertString("Select a Map"), 0, 400, false, false);
listbox->Connect(this, EV_UIListBase_ItemDoubleClicked, EV_UIListBase_ItemDoubleClicked);
listbox->Connect(this, EV_UIListBase_ItemSelected, EV_UIListBase_ItemSelected);
listbox->AllowActivate(true);
// Added in 2.0
// Don't localize elements
listbox->SetDontLocalize();
}
MpMapPickerClass::~MpMapPickerClass()
{
// FIXME: stub
if (listbox) {
delete listbox;
listbox = NULL;
}
if (window) {
delete window;
window = NULL;
}
}
void MpMapPickerClass::SetupFiles( void )
void MpMapPickerClass::Setup(const char *root_directory, const char *current_directory, const char *game_type)
{
// FIXME: stub
Initialize(root_directory, current_directory, game_type);
}
void MpMapPickerClass::GotoParentDirectory( void )
void MpMapPickerClass::Initialize(const char *root_directory, const char *current_directory, const char *game_type)
{
// FIXME: stub
rootDirectory = root_directory;
if (rootDirectory.length() > 1 && rootDirectory[rootDirectory.length() - 1] != '/') {
rootDirectory += "/";
}
currentDirectory = current_directory;
if (currentDirectory.length() > 1 && currentDirectory[currentDirectory.length() - 1] != '/') {
currentDirectory += "/";
}
if (game_type) {
gameType = game_type;
}
SetupFiles();
}
void MpMapPickerClass::GotoSubDirectory( str subdir )
void MpMapPickerClass::GotoParentDirectory(void)
{
// FIXME: stub
uintptr_t i;
if (currentDirectory == rootDirectory) {
return;
}
for (i = currentDirectory.length() - 2; i > 0; i--) {
if (currentDirectory[i] == '/') {
break;
}
}
if (currentDirectory[i] == '/') {
i++;
}
currentDirectory = str(currentDirectory, 0, i);
// refresh files
SetupFiles();
}
void MpMapPickerClass::Initialize( const char *root_directory, const char *current_directory )
void MpMapPickerClass::GotoSubDirectory(str subdir)
{
// FIXME: stub
currentDirectory += subdir + "/";
// refresh files
SetupFiles();
}
void MpMapPickerClass::CloseWindow( void )
void MpMapPickerClass::SetupFiles(void)
{
// FIXME: stub
char **filenames;
int numfiles;
int i;
char mapname[128];
bool bTugOfWar = false, bObjective = false, bLiberation = false;
listbox->DeleteAllItems();
if (gameType == "tow") {
bTugOfWar = true;
} else if (gameType == "obj") {
bObjective = true;
} else if (gameType == "lib") {
bLiberation = true;
} else {
// retrieve directories
filenames = FS_ListFiles(rootDirectory, ".bsp", qfalse, &numfiles);
for (i = 0; i < numfiles; i++) {
const char *filename = filenames[i];
strcpy(mapname, filename);
mapname[strlen(mapname) - 4] = 0;
if (COM_IsMapValid(mapname)) {
listbox->AddItem(new MpMapPickerItem(mapname, rootDirectory));
}
}
FS_FreeFileList(filenames);
}
if (currentDirectory.length()) {
if (currentDirectory == "maps/-/") {
SetupSecondaryFiles(currentDirectory, bTugOfWar, bObjective, bLiberation);
} else {
SetupSecondaryFiles("maps/obj/", bTugOfWar, bObjective, bLiberation);
SetupSecondaryFiles("maps/lib/", bTugOfWar, bObjective, bLiberation);
}
}
listbox->SortByColumn(0);
}
void MpMapPickerClass::FileSelected( Event *ev )
void MpMapPickerClass::SetupSecondaryFiles(const char *path, bool bTugOfWar, bool bObjective, bool bLiberation)
{
// FIXME: stub
char **filenames;
int numfiles;
int i;
char mapname[128];
char string[1024];
filenames = FS_ListFiles(path, ".bsp", qfalse, &numfiles);
for (i = 0; i < numfiles; i++) {
const char *filename = filenames[i];
const char *token;
strcpy(mapname, filename);
mapname[strlen(mapname) - 4] = 0;
if (!COM_IsMapValid(mapname)) {
continue;
}
if (bTugOfWar || bObjective || bLiberation) {
bool bHasMP = false, bHasTOW = false, bHasLib = false;
strcpy(string, mapname);
for (token = strtok(string, "_"); token; token = strtok(NULL, "_")) {
if (bObjective) {
if (!Q_stricmp(token, "obj")) {
listbox->AddItem(new MpMapPickerItem(mapname, path));
} else if (!Q_stricmp(token, "ship")) {
listbox->AddItem(new MpMapPickerItem(mapname, path));
}
}
if (bTugOfWar) {
if (!Q_stricmp(token, "MP")) {
bHasMP = true;
}
if (!Q_stricmp(token, "TOW")) {
bHasTOW = true;
}
if (bHasMP && bHasTOW) {
listbox->AddItem(new MpMapPickerItem(mapname, path));
}
}
if (bLiberation) {
if (!Q_stricmp(token, "MP")) {
bHasMP = true;
}
if (!Q_stricmp(token, "LIB")) {
bHasLib = true;
}
if (bHasMP && bHasLib) {
listbox->AddItem(new MpMapPickerItem(mapname, path));
}
}
}
} else {
if (!Q_stricmp(mapname, "obj_team2") || !Q_stricmp(mapname, "obj_team4")) {
continue;
}
listbox->AddItem(new MpMapPickerItem(mapname, path));
}
}
FS_FreeFileList(filenames);
}
void MpMapPickerClass::FileSelected( str& currentDirectory, str& partialName, str& fullname )
void MpMapPickerClass::FileSelected(const str& currentDirectory, const str& partialName, const str& fullname)
{
// FIXME: stub
FileChosen(currentDirectory, partialName, fullname);
}
void MpMapPickerClass::FileChosen( Event *ev )
void MpMapPickerClass::FileSelected(Event *ev)
{
// FIXME: stub
if (!listbox->getCurrentItem()) {
return;
}
uii.Snd_PlaySound("sound/menu/apply.wav");
UIListCtrlItem* item = listbox->GetItem(listbox->getCurrentItem());
str name = item->getListItemString(0);
str directory = item->getListItemString(1);
FileSelected(directory, name, directory + name);
}
void MpMapPickerClass::FileChosen( str& currentDirectory, str& partialName, str& fullname )
void MpMapPickerClass::FileChosen(const str& currentDirectory, const str& partialName, const str& fullname)
{
// FIXME: stub
const char *pszFilename;
str sCommand;
pszFilename = fullname.c_str();
sCommand = va("ui_dmmap %s\n", pszFilename + 5);
Cbuf_AddText(sCommand);
CloseWindow();
}
void MpMapPickerClass::OnDeactivated( Event *ev )
void MpMapPickerClass::FileChosen(Event *ev)
{
// FIXME: stub
if (!listbox->getCurrentItem()) {
return;
}
uii.Snd_PlaySound("sound/menu/apply.wav");
UIListCtrlItem* item = listbox->GetItem(listbox->getCurrentItem());
str name = item->getListItemString(0);
str directory = item->getListItemString(1);
FileSelected(directory, name, directory + name);
}
void MpMapPickerClass::Setup( const char *root_directory, const char *current_directory )
void MpMapPickerClass::CloseWindow(void)
{
// FIXME: stub
PostEvent(EV_Remove, 0);
}
void MpMapPickerClass::OnDeactivated(Event *ev)
{
CloseWindow();
}
MpMapPickerItem::MpMapPickerItem(const str& string, const str& directory)
{
m_string = string;
m_directory = directory;
}
int MpMapPickerItem::getListItemValue(int which) const
{
return atoi(m_string);
}
griditemtype_t MpMapPickerItem::getListItemType(int which) const
{
return griditemtype_t::TYPE_STRING;
}
str MpMapPickerItem::getListItemString(int which) const
{
switch (which) {
default:
case 0:
return m_string;
case 1:
return m_directory;
}
}
void MpMapPickerItem::DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont) {}
qboolean MpMapPickerItem::IsHeaderEntry() const
{
return qfalse;
}
+25 -24
View File
@@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@@ -20,39 +20,40 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#ifndef __CL_UIMPMAPPICKER_H__
#define __CL_UIMPMAPPICKER_H__
#pragma once
class UIFloatingWindow;
class MpMapPickerClass : public USignal {
UIFloatingWindow *window;
UIListCtrl *listbox;
str currentDirectory;
str rootDirectory;
class MpMapPickerClass : public USignal
{
UIFloatingWindow *window;
UIListCtrl *listbox;
str currentDirectory;
str rootDirectory;
str gameType;
public:
CLASS_PROTOTYPE( MpMapPickerClass );
CLASS_PROTOTYPE(MpMapPickerClass);
private:
void SetupFiles( void );
void GotoParentDirectory( void );
void GotoSubDirectory( str subdir );
void Initialize( const char *root_directory, const char *current_directory );
void SetupFiles(void);
void SetupSecondaryFiles(const char *path, bool bTugOfWar, bool bObjective, bool bLiberation);
void GotoParentDirectory(void);
void GotoSubDirectory(str subdir);
void Initialize(const char *root_directory, const char *current_directory, const char *game_type);
protected:
void CloseWindow( void );
void FileSelected( Event *ev );
virtual void FileSelected( str& currentDirectory, str& partialName, str& fullname );
void FileChosen( Event *ev );
virtual void FileChosen( str& currentDirectory, str& partialName, str& fullname );
void OnDeactivated( Event *ev );
void CloseWindow(void);
void FileSelected(Event *ev);
virtual void FileSelected(const str& currentDirectory, const str& partialName, const str& fullname);
void FileChosen(Event *ev);
virtual void FileChosen(const str& currentDirectory, const str& partialName, const str& fullname);
void OnDeactivated(Event *ev);
public:
MpMapPickerClass();
~MpMapPickerClass();
MpMapPickerClass();
~MpMapPickerClass();
void Setup( const char *root_directory, const char *current_directory );
// game_type was added in 2.0
void Setup(const char *root_directory, const char *current_directory, const char *game_type = NULL);
};
#endif /* __CL_UIMPMAPPICKER_H__ */
+322 -23
View File
@@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@@ -22,62 +22,361 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "cl_ui.h"
CLASS_DECLARATION( USignal, PlayerModelPickerClass, NULL )
class PMPickerItem : public UIListCtrlItem
{
{ NULL, NULL }
str m_string;
public:
PMPickerItem(const str& string);
int getListItemValue(int which) const override;
griditemtype_t getListItemType(int which) const override;
str getListItemString(int which) const override;
void DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont) override;
qboolean IsHeaderEntry() const override;
};
typedef struct {
const char *fileName;
const char *displayName;
} PMPickerModel_t;
static const PMPickerModel_t pickerModels[] = {
// 2.0 skins
{"allied_101st_captain", "US - 101st Airborne Captain" },
{"allied_101st_infantry", "US - 101st Airborne Private 1" },
{"allied_101st_scout", "US - 101st Airborne Private 2" },
{"allied_501st_pir_scout", "US - 501st Paratrooper 1" },
{"allied_501st_pir_soldier", "US - 501st Paratrooper 2" },
// 1.0 skins
{"allied_airborne", "US - 501st Paratrooper 3" },
// Readded in OPM (was removed in 2.0)
{"allied_manon", "US - Manon" },
// 2.0 skins
{"allied_british_6th_airborne_captain", "UK - 6th Airborne Captain" },
{"allied_british_6th_airborne_paratrooper", "UK - 6th Airborne Paratrooper" },
// 1.0 skins
{"allied_pilot", "US - Army Pilot" },
// 2.0 skins
{"allied_russian_corporal", "RA - Corporal" },
{"allied_russian_crazy_boris", "RA - Crazy Boris" },
{"allied_russian_recon_scout", "RA - Junior Lieutenant" },
{"allied_russian_recon_soldier", "RA - Black Sea Petty Officer" },
// 1.0 skins
{"allied_sas", "UK - SAS Officer" },
{"american_army", "US - Soldier" },
{"american_ranger", "US - Ranger" },
// 1.0 skins
{"german_afrika_officer", "DE - Afrika Officer" },
{"german_afrika_private", "DE - Afrika Private" },
// 2.0 skins
{"german_ardennes_artillery_commander", "DE - Artillery Commander" },
{"german_dday_colonel", "DE - Normandy Colonel" },
// 1.0 skins
{"german_elite_officer", "DE - Elite Officer" },
{"german_elite_sentry", "DE - Elite Sentry" },
{"german_kradshutzen", "DE - Kradshutzen" },
{"german_panzer_grenadier", "DE - Panzer Grenadier" },
{"german_panzer_obershutze", "DE - Panzer Obershutze" },
{"german_panzer_shutze", "DE - Panzer Shutze" },
{"german_panzer_tankcommander", "DE - Panzer Tank Commander" },
{"german_scientist", "DE - German Scientist" },
// Those skins were superseded by german_waffenss
{"german_waffen_officer", "DE - Waffen Officer" },
{"german_waffen_shutze", "DE - Waffen Shutze" },
// 1.0 skins
{"german_waffenss_officer", "DE - Waffen Officer" },
{"german_waffenss_shutze", "DE - Waffen Shutze" },
{"german_wehrmacht_officer", "DE - Wehrmacht Officer" },
{"german_wehrmacht_soldier", "DE - Wehrmacht Soldier" },
{"german_winter_1", "DE - Winter Infantry 1" },
{"german_winter_2", "DE - Winter Infantry 2" },
{"german_worker", "DE - German Mechanic" },
// 2.11 skins
{"allied_british_tank_corporal", "UK - 6th Royal Tank Regiment" },
{"allied_russian_seaman", "RA - Red Navy Seaman" },
{"german_Panzer_Corporal", "DE - 1st Panzer Regiment" },
{"allied_technician", "US - Air Force Technician" },
{"german_stukageschwader", "DE - Stukageschwader" },
// 2.30 skins
{"It_AX_Ital_Vol", "IT - 10th Army XXI Corps" },
{"SC_AX_Ital_Inf", "IT - 6th Army 202nd Coastal Div"},
{"SC_AX_Ital_Inf2", "IT - 114th Inf Regiment" },
{"SC_AX_ITAL_PARA", "IT - Paracadutista Militare" },
// 2.40 skins
{"allied_Wheathers", "US - General Wheathers" },
{"allied_US_Tank", "US - II Corps Tank Commander" },
{"allied_US_Mask", "US - II Corps Infantry" },
{"allied_british_Cmd", "UK - 10th Corps" },
{"allied_british_Tank", "UK - 8th Army" },
{NULL, NULL }
};
const char *PM_FilenameToDisplayname(const char *fileName)
{
int i;
for (i = 0; pickerModels[i].fileName; i++) {
const PMPickerModel_t& model = pickerModels[i];
if (!Q_stricmp(model.fileName, fileName)) {
return model.displayName;
}
}
return fileName;
}
const char *PM_DisplaynameToFilename(const char *displayName)
{
int i;
for (i = 0; pickerModels[i].fileName; i++) {
const PMPickerModel_t& model = pickerModels[i];
if (!Q_stricmp(model.displayName, displayName)) {
return model.fileName;
}
}
return displayName;
}
CLASS_DECLARATION(USignal, PlayerModelPickerClass, NULL) {
{&EV_UIListBase_ItemSelected, &PlayerModelPickerClass::FileSelected },
{&EV_UIListBase_ItemDoubleClicked, &PlayerModelPickerClass::FileChosen },
{&UIFloatingWindow::W_ClosePressed, &PlayerModelPickerClass::OnDeactivated},
{&W_Deactivated, &PlayerModelPickerClass::OnDeactivated},
{NULL, NULL }
};
PlayerModelPickerClass::PlayerModelPickerClass()
{
// FIXME: stub
window = new UIFloatingWindow();
window->Create(
NULL,
UIRect2D((cls.glconfig.vidWidth - 400) / 2, (cls.glconfig.vidHeight - 300) / 2, 400, 300),
"Player Model Select...",
UColor(0.15f, 0.195f, 0.278f),
UHudColor
);
window->setFont("facfont-20");
window->PassEventToWidget("closebutton", new Event(EV_Widget_Disable));
window->PassEventToWidget("minimizebutton", new Event(EV_Widget_Disable));
window->Connect(this, W_Deactivated, W_Deactivated);
listbox = new UIListCtrl();
listbox->InitFrame(window->getChildSpace(), window->getChildSpace()->getClientFrame(), 0);
listbox->SetDrawHeader(false);
listbox->setFont("facfont-20");
listbox->FrameInitialized();
listbox->AddColumn("Player Model", 0, 400, false, false);
listbox->Connect(this, EV_UIListBase_ItemDoubleClicked, EV_UIListBase_ItemDoubleClicked);
listbox->Connect(this, EV_UIListBase_ItemSelected, EV_UIListBase_ItemSelected);
listbox->AllowActivate(true);
// Added in 2.0
// Don't localize elements
listbox->SetDontLocalize();
m_bGermanModels = false;
}
PlayerModelPickerClass::~PlayerModelPickerClass()
{
// FIXME: stub
if (listbox) {
delete listbox;
listbox = NULL;
}
if (window) {
delete window;
window = NULL;
}
}
void PlayerModelPickerClass::SetupFiles( void )
void PlayerModelPickerClass::Setup(const char *root_directory, const char *current_directory, qboolean bGermanModels)
{
// FIXME: stub
Initialize(root_directory, current_directory, bGermanModels);
}
void PlayerModelPickerClass::Initialize( const char *root_directory, const char *current_directory, qboolean bGermanModels )
void PlayerModelPickerClass::Initialize(
const char *root_directory, const char *current_directory, qboolean bGermanModels
)
{
// FIXME: stub
rootDirectory = root_directory;
m_bGermanModels = bGermanModels;
if (rootDirectory.length() > 1 && rootDirectory[rootDirectory.length() - 1] != '/') {
rootDirectory += "/";
}
currentDirectory = current_directory;
if (currentDirectory.length() > 1 && currentDirectory[currentDirectory.length() - 1] != '/') {
currentDirectory += "/";
}
SetupFiles();
}
void PlayerModelPickerClass::CloseWindow( void )
void PlayerModelPickerClass::SetupFiles(void)
{
// FIXME: stub
str mappath;
char work[128];
char **filenames;
const char *displayName;
int numfiles;
int i;
int iLen;
qboolean bIsGerman;
// cleanup
listbox->DeleteAllItems();
if (m_bGermanModels) {
window->setTitle("Select Your Axis Player Model");
} else {
window->setTitle("Select Your Allied Player Model");
}
filenames = FS_ListFiles(currentDirectory, ".tik", qfalse, &numfiles);
for (i = 0; i < numfiles; i++) {
Q_strncpyz(work, filenames[i], sizeof(work));
if (strstr(work, "_fps")) {
// ignore view models
continue;
}
if (work[0] == '_') {
// ignore hidden models
continue;
}
// allied_manon readded in OPM
//if (!Q_stricmpn(work, "allied_manon")) {
// continue;
//}
bIsGerman = !Q_stricmpn(work, "german", 6u) || !Q_stricmpn(work, "axis", 4u) || !Q_stricmpn(work, "it", 2u)
|| !Q_stricmpn(work, "sc", 2u);
if (m_bGermanModels != bIsGerman) {
continue;
}
// strip the extension
work[strlen(work) - 4] = 0;
displayName = PM_FilenameToDisplayname(work);
listbox->AddItem(new PMPickerItem(displayName));
}
FS_FreeFileList(filenames);
listbox->SortByColumn(0);
}
void PlayerModelPickerClass::FileSelected( Event *ev )
void PlayerModelPickerClass::FileSelected(
const str& name, const str& currentDirectory, const str& partialName, const str& fullname
)
{
// FIXME: stub
FileChosen(name, currentDirectory, partialName, fullname);
}
void PlayerModelPickerClass::FileSelected( str& currentDirectory, str& partialName, str& fullname )
void PlayerModelPickerClass::FileSelected(Event *ev)
{
// FIXME: stub
str name;
char donotshowssindeorfr[64];
str fullname;
name = listbox->GetItem(listbox->getCurrentItem())->getListItemString(0);
fullname = PM_DisplaynameToFilename(name);
if (!Q_stricmpn(fullname, "german_waffen_", 14)) {
Q_strncpyz(donotshowssindeorfr, "german_waffen_", sizeof(donotshowssindeorfr));
Q_strcat(donotshowssindeorfr, sizeof(donotshowssindeorfr), fullname.c_str() + 14);
} else {
Q_strncpyz(donotshowssindeorfr, fullname, sizeof(donotshowssindeorfr));
}
FileSelected(name, currentDirectory, fullname, currentDirectory + donotshowssindeorfr);
}
void PlayerModelPickerClass::FileChosen( Event *ev )
void PlayerModelPickerClass::FileChosen(
const str& name, const str& currentDirectory, const str& partialName, const str& fullname
)
{
// FIXME: stub
str sCommand;
if (m_bGermanModels) {
sCommand += "ui_dm_playergermanmodel \"" + name;
sCommand += "\" ; ui_dm_playergermanmodel_set " + partialName;
sCommand += " ; ui_disp_playergermanmodel " + fullname + ".tik";
} else {
sCommand += "ui_dm_playermodel \"" + name;
sCommand += "\" ; ui_dm_playermodel_set " + partialName;
sCommand += " ; ui_disp_playermodel " + fullname + ".tik";
}
sCommand += "\n";
Cbuf_AddText(sCommand);
CloseWindow();
}
void PlayerModelPickerClass::FileChosen( str& currentDirectory, str& partialName, str& fullname )
void PlayerModelPickerClass::FileChosen(Event *ev)
{
// FIXME: stub
str name;
char donotshowssindeorfr[64];
str fullname;
name = listbox->GetItem(listbox->getCurrentItem())->getListItemString(0);
fullname = PM_DisplaynameToFilename(name);
if (!Q_stricmpn(fullname, "german_waffen_", 14)) {
Q_strncpyz(donotshowssindeorfr, "german_waffen_", sizeof(donotshowssindeorfr));
Q_strcat(donotshowssindeorfr, sizeof(donotshowssindeorfr), fullname.c_str() + 14);
} else {
Q_strncpyz(donotshowssindeorfr, fullname, sizeof(donotshowssindeorfr));
}
FileChosen(name, currentDirectory, fullname, currentDirectory + donotshowssindeorfr);
}
void PlayerModelPickerClass::OnDeactivated( Event *ev )
void PlayerModelPickerClass::CloseWindow(void)
{
// FIXME: stub
PostEvent(EV_Remove, 0);
}
void PlayerModelPickerClass::Setup( const char *root_directory, const char *current_directory, qboolean bGermanModels )
void PlayerModelPickerClass::OnDeactivated(Event *ev)
{
// FIXME: stub
CloseWindow();
}
PMPickerItem::PMPickerItem(const str& string)
{
m_string = string;
}
int PMPickerItem::getListItemValue(int which) const
{
return atoi(m_string);
}
griditemtype_t PMPickerItem::getListItemType(int which) const
{
return griditemtype_t::TYPE_STRING;
}
str PMPickerItem::getListItemString(int which) const
{
return m_string;
}
void PMPickerItem::DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont) {}
qboolean PMPickerItem::IsHeaderEntry() const
{
return qfalse;
}
+26 -22
View File
@@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@@ -20,37 +20,41 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#ifndef __CL_UIPLAYERMODELPICKER_H__
#define __CL_UIPLAYERMODELPICKER_H__
#pragma once
class UIFloatingWindow;
class PlayerModelPickerClass : public USignal {
UIFloatingWindow *window;
UIListCtrl *listbox;
str currentDirectory;
str rootDirectory;
qboolean m_bGermanModels;
class PlayerModelPickerClass : public USignal
{
UIFloatingWindow *window;
UIListCtrl *listbox;
str currentDirectory;
str rootDirectory;
qboolean m_bGermanModels;
public:
CLASS_PROTOTYPE( PlayerModelPickerClass );
CLASS_PROTOTYPE(PlayerModelPickerClass);
private:
void SetupFiles( void );
void Initialize( const char *root_directory, const char *current_directory, qboolean bGermanModels );
void SetupFiles(void);
void Initialize(const char *root_directory, const char *current_directory, qboolean bGermanModels);
protected:
void CloseWindow( void );
void FileSelected( Event *ev );
virtual void FileSelected( str& currentDirectory, str& partialName, str& fullname );
void FileChosen( Event *ev );
virtual void FileChosen( str& currentDirectory, str& partialName, str& fullname );
void OnDeactivated( Event *ev );
void CloseWindow(void);
void FileSelected(Event *ev);
// The name parameter was added in 2.0.
virtual void FileSelected(const str& name, const str& currentDirectory, const str& partialName, const str& fullname);
void FileChosen(Event *ev);
// The name parameter was added in 2.0.
virtual void FileChosen(const str& name, const str& currentDirectory, const str& partialName, const str& fullname);
void OnDeactivated(Event *ev);
public:
PlayerModelPickerClass();
~PlayerModelPickerClass();
PlayerModelPickerClass();
~PlayerModelPickerClass();
void Setup( const char *root_directory, const char *current_directory, qboolean bGermanModels );
void Setup(const char *root_directory, const char *current_directory, qboolean bGermanModels);
};
#endif /* __CL_UIPLAYERMODELPICKER_H__ */
const char* PM_FilenameToDisplayname(const char* fileName);
const char* PM_DisplaynameToFilename(const char* displayName);
+68 -34
View File
@@ -79,6 +79,7 @@ struct ServerListInstance {
};
class FAKKServerListItem : public UIListCtrlItem {
UIFAKKServerList* m_parent; // Added in OPM
str m_strings[6];
str m_sVersion;
bool m_bDifferentVersion;
@@ -94,7 +95,7 @@ public:
int m_iGameSpyPort;
public:
FAKKServerListItem(str string1, str string2, str string3, str string4, str string5, str string6, str ver);
FAKKServerListItem(UIFAKKServerList* parent, str string1, str string2, str string3, str string4, str string5, str string6, str ver);
griditemtype_t getListItemType(int index) const override;
int getListItemValue(int i) const override;
@@ -125,8 +126,9 @@ ServerListInstance g_ServerListInst[2];
void UpdateServerListCallBack(GServerList serverlist, int msg, void* instance, void* param1, void* param2);
static void AddFilter(char* filter, const char* value);
FAKKServerListItem::FAKKServerListItem(str string1, str string2, str string3, str string4, str string5, str string6, str ver)
FAKKServerListItem::FAKKServerListItem(UIFAKKServerList* parent, str string1, str string2, str string3, str string4, str string5, str string6, str ver)
{
m_parent = parent;
m_strings[0] = string1;
m_strings[1] = string2;
m_strings[2] = string3;
@@ -164,84 +166,95 @@ void FAKKServerListItem::setListItemString(int i, str sNewString)
void FAKKServerListItem::DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont* pFont)
{
static cvar_t *pColoringType = Cvar_Get("cl_browserdetailedcolors", "0", CVAR_ARCHIVE);
UIRect2D newRect = drawRect;
vec2_t virtualScale = { 1.f, 1.f };
/*
if (m_parent->isVirtual()) {
virtualScale[0] = uid.vidWidth / 640.f;
virtualScale[1] = uid.vidHeight / 480.f;
newRect.size.width *= uid.vidWidth / 1024;
newRect.size.height *= uid.vidHeight / 768;
}
*/
if (!pColoringType->integer) {
if (IfQueryFailed() || (IsDifferentVersion() && IsQueried())) {
if (bSelected) {
DrawBox(drawRect, UColor(0.2f, 0.0f, 0.0f), 1.0);
DrawBox(newRect, UColor(0.2f, 0.0f, 0.0f), 1.0);
pFont->setColor(UColor(0.9f, 0.0f, 0.0f));
} else {
DrawBox(drawRect, UColor(0.1f, 0.0f, 0.0f), 1.0);
DrawBox(newRect, UColor(0.1f, 0.0f, 0.0f), 1.0);
pFont->setColor(UColor(0.55f, 0.0f, 0.0f));
}
} else if (IsQueried()) {
if (bSelected) {
DrawBox(drawRect, UColor(0.2f, 0.18f, 0.015f), 1.0);
DrawBox(newRect, UColor(0.2f, 0.18f, 0.015f), 1.0);
pFont->setColor(UColor(0.9f, 0.8f, 0.6f));
} else {
DrawBox(drawRect, UColor(0.02f, 0.07f, 0.004f), 1.0);
DrawBox(newRect, UColor(0.02f, 0.07f, 0.004f), 1.0);
pFont->setColor(UHudColor);
}
} else {
if (bSelected) {
DrawBox(drawRect, UColor(0.15f, 0.18f, 0.18f), 1.0);
DrawBox(newRect, UColor(0.15f, 0.18f, 0.18f), 1.0);
pFont->setColor(UColor(0.6f, 0.7f, 0.8f));
} else {
DrawBox(drawRect, UColor(0.005f, 0.07f, 0.02f), 1.0);
DrawBox(newRect, UColor(0.005f, 0.07f, 0.02f), 1.0);
pFont->setColor(UColor(0.05f, 0.5f, 0.6f));
}
}
pFont->Print(
drawRect.pos.x + 1.0,
drawRect.pos.y,
newRect.pos.x / virtualScale[0] + 1.0,
newRect.pos.y / virtualScale[1],
getListItemString(iColumn).c_str(),
-1,
qfalse
false //m_parent->isVirtual()
);
} else {
if (IsDifferentVersion()) {
if (IsQueried()) {
if (bSelected) {
DrawBox(drawRect, UColor(0.25f, 0.0f, 0.0f), 1.0);
DrawBox(newRect, UColor(0.25f, 0.0f, 0.0f), 1.0);
pFont->setColor(UColor(0.0f, 0.5f, 0.0f));
} else {
DrawBox(drawRect, UColor(0.005f, 0.07f, 0.02f), 1.0);
DrawBox(newRect, UColor(0.005f, 0.07f, 0.02f), 1.0);
pFont->setColor(UColor(0.0f, 0.35f, 0.0f));
}
} else {
if (bSelected) {
DrawBox(drawRect, UColor(0.25f, 0.0f, 0.0f), 1.0);
DrawBox(newRect, UColor(0.25f, 0.0f, 0.0f), 1.0);
pFont->setColor(UColor(0.5f, 0.6f, 0.7f));
} else {
DrawBox(drawRect, UColor(0.15f, 0.0f, 0.0f), 1.0);
DrawBox(newRect, UColor(0.15f, 0.0f, 0.0f), 1.0);
pFont->setColor(UColor(0.05f, 0.4f, 0.5f));
}
}
} else if (IsQueried()) {
if (bSelected) {
DrawBox(drawRect, UColor(0.2f, 0.18f, 0.015f), 1.0);
DrawBox(newRect, UColor(0.2f, 0.18f, 0.015f), 1.0);
pFont->setColor(UColor(0.9f, 0.8f, 0.6f));
} else {
DrawBox(drawRect, UColor(0.02f, 0.07f, 0.005f), 1.0);
DrawBox(newRect, UColor(0.02f, 0.07f, 0.005f), 1.0);
pFont->setColor(UHudColor);
}
} else {
if (bSelected) {
DrawBox(drawRect, UColor(0.15f, 0.18f, 0.18f), 1.0);
DrawBox(newRect, UColor(0.15f, 0.18f, 0.18f), 1.0);
pFont->setColor(UColor(0.6f, 0.7f, 0.8f));
} else {
DrawBox(drawRect, UColor(0.005f, 0.07f, 0.02f), 1.0);
DrawBox(newRect, UColor(0.005f, 0.07f, 0.02f), 1.0);
pFont->setColor(UColor(0.05f, 0.5f, 0.6f));
}
if (IfQueryFailed()) {
DrawBox(
UIRect2D(
drawRect.pos.x,
drawRect.pos.y + drawRect.size.height * 0.5 - 1.0 + drawRect.pos.y,
drawRect.size.width,
drawRect.size.height * 0.5 - 1.0 + drawRect.pos.y
newRect.pos.x,
newRect.pos.y + newRect.size.height * 0.5 - 1.0 + newRect.pos.y,
newRect.size.width,
newRect.size.height * 0.5 - 1.0 + newRect.pos.y
),
URed,
0.3f
@@ -249,19 +262,19 @@ void FAKKServerListItem::DrawListItem(int iColumn, const UIRect2D& drawRect, boo
}
pFont->Print(
drawRect.pos.x + 1.0,
drawRect.pos.y,
newRect.pos.x / virtualScale[0] + 1.0,
newRect.pos.y / virtualScale[1],
getListItemString(iColumn).c_str(),
-1,
qfalse
false //m_parent->isVirtual()
);
if (IsDifferentVersion()) {
DrawBox(
UIRect2D(
drawRect.pos.x,
drawRect.pos.y + drawRect.size.height * 0.5 - 1.0 + drawRect.pos.y,
drawRect.size.width,
newRect.pos.x,
newRect.pos.y + newRect.size.height * 0.5 - 1.0 + newRect.pos.y,
newRect.size.width,
1.0
),
URed,
@@ -730,6 +743,14 @@ void UIFAKKServerList::UpdateServer( Event *ev )
FAKKServerListItem* item = (FAKKServerListItem*)GetItem(getCurrentItem());
ServerListAuxUpdate(m_serverList[0], item->m_sIP.c_str(), item->m_iGameSpyPort, true, GQueryType::qt_status);
if (com_target_game->integer >= target_game_e::TG_MOHTT) {
const cvar_t* dm_omit_spearhead = Cvar_Get("dm_omit_spearhead", "0", CVAR_ARCHIVE);
// check for Spearhead
if (!dm_omit_spearhead->integer) {
ServerListAuxUpdate(m_serverList[1], item->m_sIP.c_str(), item->m_iGameSpyPort, true, GQueryType::qt_status);
}
}
}
int UIFAKKServerList::ServerCompareFunction( const UIListCtrlItem *i1, const UIListCtrlItem *i2, int columnname )
@@ -1019,23 +1040,36 @@ void UpdateServerListCallBack(GServerList serverlist, int msg, void* instance, v
str sServerName;
str sPlayers;
const char* pszGameVer;
const char* pszGameVerNumber;
pszHostName = ServerGetStringValue(server, "hostname", "(NONE)");
bDiffVersion = false;
pszGameVer = ServerGetStringValue(server, "gamever", "1.00");
pszGameVerNumber = pszGameVer;
if (pszGameVerNumber[0] == 'd') {
// demo server
pszGameVerNumber++;
}
if (com_target_game->integer >= target_game_e::TG_MOHTT) {
if (iServerType == target_game_e::TG_MOHTT) {
if (fabs(atof(pszGameVer) - com_target_version->value) > 0.1f) {
//if (fabs(atof(pszGameVerNumber) - com_target_version->value) > 0.1f) {
// bDiffVersion = true;
//}
if (fabs(atof(pszGameVerNumber)) < 2.3f) {
bDiffVersion = true;
}
} else {
if (fabs(atof(pszGameVer) - com_target_version->value) > 0.3f) {
//if (fabs(atof(pszGameVerNumber) - com_target_version->value) > 0.3f) {
// bDiffVersion = true;
//}
if (fabs(atof(pszGameVerNumber)) < 2.1f) {
bDiffVersion = true;
}
}
} else {
if (fabs(atof(pszGameVer) - com_target_version->value) > 0.1f) {
if (fabs(atof(pszGameVerNumber) - com_target_version->value) > 0.1f) {
bDiffVersion = true;
}
}
@@ -1056,7 +1090,7 @@ void UpdateServerListCallBack(GServerList serverlist, int msg, void* instance, v
}
if (i > uiServerList->getNumItems() || !pNewServerItem) {
pNewServerItem = new FAKKServerListItem("?", sAddress, "?", "?/?", "?", "?", "?");
pNewServerItem = new FAKKServerListItem(uiServerList, "?", sAddress, "?", "?/?", "?", "?", "?");
pNewServerItem->m_sIP = ServerGetAddress(server);
pNewServerItem->m_uiRealIP = iRealIP;
pNewServerItem->m_iGameSpyPort = iGameSpyPort;
@@ -1154,7 +1188,7 @@ void UpdateServerListCallBack(GServerList serverlist, int msg, void* instance, v
continue;
}
pNewServerItem = new FAKKServerListItem("?", sAddress, "?", "?/?", "?", "?", "?");
pNewServerItem = new FAKKServerListItem(uiServerList, "?", sAddress, "?", "?/?", "?", "?", "?");
pNewServerItem->m_sIP = ServerGetAddress(arrayServer);
pNewServerItem->m_uiRealIP = iRealIP;
pNewServerItem->m_iPort = PORT_SERVER;
+29 -9
View File
@@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@@ -22,22 +22,42 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "cl_ui.h"
CLASS_DECLARATION( FilePickerClass, SoundPickerClass, NULL )
{
{ NULL, NULL }
CLASS_DECLARATION(FilePickerClass, SoundPickerClass, NULL) {
{NULL, NULL}
};
SoundPickerClass::SoundPickerClass()
{
// FIXME: stub
str soundpath;
str currentpath;
const char *varValue;
int i;
soundpath = "sound";
varValue = UI_GetCvarString("ui_pickedsound", NULL);
if (varValue && *varValue) {
currentpath = varValue;
for (i = currentpath.length(); i > 0; i--) {
if (currentpath[i] == '/') {
break;
}
}
currentpath = str(currentpath, 0, i + 1);
} else {
currentpath = soundpath;
}
}
void SoundPickerClass::FileSelected( str &currentDirectory, str &partialName, str &fullname )
void SoundPickerClass::FileSelected(const str& currentDirectory, const str& partialName, const str& fullname)
{
uii.Snd_PlaySound(fullname);
}
void SoundPickerClass::FileChosen( str &currentDirectory, str &partialName, str &fullname )
void SoundPickerClass::FileChosen(const str& currentDirectory, const str& partialName, const str& fullname)
{
uii.Cvar_Set("ui_pickedsound", fullname);
CloseWindow();
}
+8 -10
View File
@@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@@ -20,17 +20,15 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#ifndef __CL_UISOUNDPICKER_H__
#define __CL_UISOUNDPICKER_H__
#pragma once
class SoundPickerClass : public FilePickerClass {
class SoundPickerClass : public FilePickerClass
{
public:
CLASS_PROTOTYPE( SoundPickerClass );
CLASS_PROTOTYPE(SoundPickerClass);
SoundPickerClass();
SoundPickerClass();
void FileSelected( str &currentDirectory, str &partialName, str &fullname ) override;
void FileChosen( str &currentDirectory, str &partialName, str &fullname ) override;
void FileSelected(const str& currentDirectory, const str& partialName, const str& fullname) override;
void FileChosen(const str& currentDirectory, const str& partialName, const str& fullname) override;
};
#endif /* __CL_UISOUNDPICKER_H__ */
+174 -197
View File
@@ -1294,40 +1294,16 @@ void UIFakkLabel::Draw(void)
{
if (m_stat_alpha != -1) {
float frac;
frac = (cl.snap.ps.stats[m_stat_alpha] + 1) / 100.0;
frac = Q_clamp_float(frac, 0, 1);
m_alpha = frac;
}
if (m_stat == -1 && m_itemindex == -1 && m_inventoryrendermodelindex == -1) {
if (m_stat_configstring != -1) {
m_font->setColor(m_foreground_color);
if (m_bOutlinedText) {
m_font->PrintOutlinedJustified(
getClientFrame(),
m_iFontAlignmentHorizontal,
m_iFontAlignmentVertical,
Sys_LV_CL_ConvertString(va("%s", CL_ConfigString(cl.snap.ps.stats[m_stat_configstring]))),
UBlack,
m_bVirtual ? m_vVirtualScale : NULL
);
} else {
m_font->PrintJustified(
getClientFrame(),
m_iFontAlignmentHorizontal,
m_iFontAlignmentVertical,
Sys_LV_CL_ConvertString(va("%s", CL_ConfigString(cl.snap.ps.stats[m_stat_configstring]))),
m_bVirtual ? m_vVirtualScale : NULL
);
}
return;
}
if (!m_rendermodel && m_statbar_or == L_STATBAR_NONE && !m_sDrawModelName.length()) {
if (m_stat == -1 && m_itemindex == -1 && m_inventoryrendermodelindex == -1 && m_stat_configstring == -1
&& !m_rendermodel && m_statbar_or == L_STATBAR_NONE) {
if (!m_sDrawModelName.length()) {
UILabel::Draw();
return;
}
@@ -1354,28 +1330,13 @@ void UIFakkLabel::Draw(void)
m_bVirtual ? m_vVirtualScale : NULL
);
}
return;
}
if (m_stat == -1) {
float scale;
qhandle_t handle;
vec3_t origin;
vec3_t mins;
vec3_t maxs;
vec3_t angles;
vec3_t offset;
vec3_t rotateoffset;
vec4_t color;
str sAnimName;
float height;
if (m_itemindex != -1) {
if (m_itemindex < 0) {
return;
}
if (m_stat != -1) {
int delta = cl.snap.ps.stats[m_stat];
if (m_statbar_or == L_STATBAR_NONE) {
m_font->setColor(m_foreground_color);
if (m_bOutlinedText) {
@@ -1383,7 +1344,7 @@ void UIFakkLabel::Draw(void)
getClientFrame(),
m_iFontAlignmentHorizontal,
m_iFontAlignmentVertical,
Sys_LV_CL_ConvertString(va("%s", CL_ConfigString(CS_WEAPONS + cl.snap.ps.activeItems[m_itemindex]))),
va("%d", delta),
UBlack,
m_bVirtual ? m_vVirtualScale : NULL
);
@@ -1392,143 +1353,13 @@ void UIFakkLabel::Draw(void)
getClientFrame(),
m_iFontAlignmentHorizontal,
m_iFontAlignmentVertical,
Sys_LV_CL_ConvertString(va("%s", CL_ConfigString(CS_WEAPONS + cl.snap.ps.activeItems[m_itemindex]))),
va("%d", delta),
m_bVirtual ? m_vVirtualScale : NULL
);
}
return;
}
if (m_inventoryrendermodelindex == -1 && !m_sDrawModelName.length() || !m_rendermodel) {
float frac = 0.0;
if (m_statbar_or == L_STATBAR_NONE) {
return;
}
if (m_cvarname.length()) {
frac = Cvar_VariableValue(m_cvarname) / (m_statbar_max - m_statbar_min);
}
if (frac > 1.0) {
frac = 1.0;
}
if (frac < 0.0) {
frac = 0.0;
}
DrawStatbar(frac);
return;
}
VectorSet4(color, 255, 255, 255, 255);
if (m_rendermodel) {
if (!m_cvarname.length()) {
return;
}
handle = re.RegisterModel(Cvar_VariableString(m_cvarname));
if (!handle) {
return;
}
VectorCopy(m_angles, angles);
VectorCopy(m_rotateoffset, rotateoffset);
VectorCopy(m_offset, offset);
scale = m_scale;
sAnimName = m_anim;
} else if (m_sDrawModelName.length()) {
if (m_lastitemindex != cl.snap.ps.activeItems[m_inventoryrendermodelindex]) {
if (!m_lastitem) {
m_lastitem = CL_GetInvItemByName(&client_inv, m_sDrawModelName);
}
}
_shitlabel01:
if (!m_lastitem) {
return;
}
VectorCopy(m_lastitem->hudprops.rotateoffset, rotateoffset);
VectorCopy(m_lastitem->hudprops.offset, offset);
handle = re.RegisterModel(m_lastitem->hudprops.model);
VectorCopy(m_lastitem->hudprops.angledeltas, angles);
if (m_lastitem->hudprops.move == INV_MOVE_BOB) {
float frac = uid.time / 600.0;
angles[0] += sin(frac) * m_lastitem->hudprops.angledeltas[0];
angles[1] += sin(frac) * m_lastitem->hudprops.angledeltas[1];
angles[2] += sin(frac) * m_lastitem->hudprops.angledeltas[2];
} else if (m_lastitem->hudprops.model == INV_MOVE_SPIN) {
float frac = uid.time / 600.0;
angles[0] += frac * m_lastitem->hudprops.angledeltas[0];
angles[1] += frac * m_lastitem->hudprops.angledeltas[1];
angles[2] += frac * m_lastitem->hudprops.angledeltas[2];
}
if (m_rendermodel) {
VectorSet(mins, -16, -16, 0);
VectorSet(maxs, 16, 16, 96);
} else {
re.ModelBounds(handle, mins, maxs);
}
origin[1] = (mins[1] + maxs[1]) * 0.5;
origin[2] = (mins[1] + maxs[1]) * -0.5;
height = maxs[2] - mins[2];
if (height < maxs[1] - mins[1]) {
height = maxs[1] - mins[1];
}
if (height <= maxs[0] - mins[0]) {
height = maxs[0] - mins[0];
}
origin[0] = height * scale * 0.5 / 0.268f;
CL_Draw3DModel(
m_screenframe.pos.x,
m_screenframe.pos.y,
m_screenframe.size.width,
m_screenframe.size.height,
handle,
origin,
rotateoffset,
offset,
angles,
color,
sAnimName
);
return;
}
if (m_lastitemindex == cl.snap.ps.activeItems[m_inventoryrendermodelindex]) {
goto _shitlabel01;
}
if (m_lastitem
== CL_GetInvItemByName(
&client_inv, CL_ConfigString(CS_WEAPONS + cl.snap.ps.activeItems[m_inventoryrendermodelindex])
)) {
m_lastitemindex = cl.snap.ps.activeItems[m_inventoryrendermodelindex];
goto _shitlabel01;
}
m_lastitem = CL_GetInvItemByName(
&client_inv, CL_ConfigString(CS_WEAPONS + cl.snap.ps.activeItems[m_inventoryrendermodelindex])
);
goto _shitlabel01;
}
int delta = cl.snap.ps.stats[m_stat];
if (m_statbar_or) {
if (m_statbar_or == L_STATBAR_VERTICAL_STAGGER_EVEN || m_statbar_or == L_STATBAR_VERTICAL_STAGGER_ODD) {
int stat;
@@ -1574,28 +1405,174 @@ void UIFakkLabel::Draw(void)
}
DrawStatbar(frac);
return;
}
float scale;
qhandle_t handle;
vec3_t origin;
vec3_t mins;
vec3_t maxs;
vec3_t angles;
vec3_t offset;
vec3_t rotateoffset;
vec4_t color;
str sAnimName;
float height;
if (m_itemindex != -1) {
if (m_itemindex < 0) {
return;
}
m_font->setColor(m_foreground_color);
if (m_bOutlinedText) {
m_font->PrintOutlinedJustified(
getClientFrame(),
m_iFontAlignmentHorizontal,
m_iFontAlignmentVertical,
Sys_LV_CL_ConvertString(va("%s", CL_ConfigString(CS_WEAPONS + cl.snap.ps.activeItems[m_itemindex]))),
UBlack,
m_bVirtual ? m_vVirtualScale : NULL
);
} else {
m_font->PrintJustified(
getClientFrame(),
m_iFontAlignmentHorizontal,
m_iFontAlignmentVertical,
Sys_LV_CL_ConvertString(va("%s", CL_ConfigString(CS_WEAPONS + cl.snap.ps.activeItems[m_itemindex]))),
m_bVirtual ? m_vVirtualScale : NULL
);
}
return;
}
m_font->setColor(m_foreground_color);
if (m_inventoryrendermodelindex == -1 && !m_sDrawModelName.length() && !m_rendermodel) {
float frac = 0.0;
if (m_bOutlinedText) {
m_font->PrintOutlinedJustified(
getClientFrame(),
m_iFontAlignmentHorizontal,
m_iFontAlignmentVertical,
va("%d", delta),
UBlack,
m_bVirtual ? m_vVirtualScale : NULL
);
} else {
m_font->PrintJustified(
getClientFrame(),
m_iFontAlignmentHorizontal,
m_iFontAlignmentVertical,
va("%d", delta),
m_bVirtual ? m_vVirtualScale : NULL
);
if (m_statbar_or == L_STATBAR_NONE) {
return;
}
if (m_cvarname.length()) {
frac = Cvar_VariableValue(m_cvarname) / (m_statbar_max - m_statbar_min);
}
if (frac > 1.0) {
frac = 1.0;
}
if (frac < 0.0) {
frac = 0.0;
}
DrawStatbar(frac);
return;
}
VectorSet4(color, 255, 255, 255, 255);
if (m_rendermodel) {
if (!m_cvarname.length()) {
return;
}
handle = re.RegisterModel(Cvar_VariableString(m_cvarname));
if (!handle) {
return;
}
VectorCopy(m_angles, angles);
VectorCopy(m_rotateoffset, rotateoffset);
VectorCopy(m_offset, offset);
scale = m_scale;
sAnimName = m_anim;
// Added in 2.11
// Tunak easter egg
if (Cvar_Get("tunak", "0", 0)->integer) {
// Since 2.15, those animations start has 'zz' prefix
if (strstr(m_anim, "american")) {
sAnimName = "zzamericanspecialidle";
} else {
// Added in 2.15
sAnimName = "zzgermanspecialidle";
}
}
} else {
if (m_sDrawModelName.length()) {
if (!m_lastitem) {
m_lastitem = CL_GetInvItemByName(&client_inv, m_sDrawModelName);
}
} else {
if (m_inventoryrendermodelindex >= 0
&& m_lastitemindex != cl.snap.ps.activeItems[m_inventoryrendermodelindex]) {
m_lastitem = CL_GetInvItemByName(
&client_inv, CL_ConfigString(CS_WEAPONS + cl.snap.ps.activeItems[m_inventoryrendermodelindex])
);
m_lastitemindex = cl.snap.ps.activeItems[m_inventoryrendermodelindex];
}
}
if (!m_lastitem) {
return;
}
VectorCopy(m_lastitem->hudprops.rotateoffset, rotateoffset);
VectorCopy(m_lastitem->hudprops.offset, offset);
scale = m_lastitem->hudprops.scale;
handle = re.RegisterModel(m_lastitem->hudprops.model);
VectorCopy(m_lastitem->hudprops.angledeltas, angles);
if (m_lastitem->hudprops.move == INV_MOVE_BOB) {
float frac = uid.time / 600.0;
angles[0] += sin(frac) * m_lastitem->hudprops.angledeltas[0];
angles[1] += sin(frac) * m_lastitem->hudprops.angledeltas[1];
angles[2] += sin(frac) * m_lastitem->hudprops.angledeltas[2];
} else if (m_lastitem->hudprops.model == INV_MOVE_SPIN) {
float frac = uid.time / 600.0;
angles[0] += frac * m_lastitem->hudprops.angledeltas[0];
angles[1] += frac * m_lastitem->hudprops.angledeltas[1];
angles[2] += frac * m_lastitem->hudprops.angledeltas[2];
}
}
if (m_rendermodel) {
VectorSet(mins, -16, -16, 0);
VectorSet(maxs, 16, 16, 96);
} else {
re.ModelBounds(handle, mins, maxs);
}
origin[1] = (mins[1] + maxs[1]) * 0.5;
origin[2] = (mins[2] + maxs[2]) * -0.5;
height = maxs[2] - mins[2];
if (height < maxs[1] - mins[1]) {
height = maxs[1] - mins[1];
}
if (height < maxs[0] - mins[0]) {
height = maxs[0] - mins[0];
}
origin[0] = height * scale * 0.5 / 0.268f;
CL_Draw3DModel(
m_screenframe.pos.x,
m_screenframe.pos.y,
m_screenframe.size.width,
m_screenframe.size.height,
handle,
origin,
rotateoffset,
offset,
angles,
color,
sAnimName
);
set2D();
}
+2
View File
@@ -37,6 +37,8 @@ typedef enum {
L_STATBAR_HEADING_SPINNER
} statbar_orientation_t;
extern Event EV_ClearInvItemReference;
class UIFakkLabel : public UILabel
{
protected:
+513 -362
View File
@@ -21,424 +21,575 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "cl_ui.h"
#include "../qcommon/localization.h"
CLASS_DECLARATION( UIWidget, View3D, NULL )
{
{ &W_Activated, &View3D::OnActivate },
{ &W_Deactivated, &View3D::OnDeactivate },
{ &W_LeftMouseDown, &View3D::Pressed },
{ NULL, NULL }
CLASS_DECLARATION(UIWidget, View3D, NULL) {
{&W_Activated, &View3D::OnActivate },
{&W_Deactivated, &View3D::OnDeactivate},
{&W_LeftMouseDown, &View3D::Pressed },
{NULL, NULL }
};
#define MAX_SUBTITLES 4
cvar_t* subs[MAX_SUBTITLES];
cvar_t* teams[MAX_SUBTITLES];
float fadeTime[MAX_SUBTITLES];
float subLife[MAX_SUBTITLES];
float alpha[MAX_SUBTITLES];
char oldStrings[MAX_SUBTITLES][2048];
cvar_t *subs[MAX_SUBTITLES];
cvar_t *teams[MAX_SUBTITLES];
float fadeTime[MAX_SUBTITLES];
float subLife[MAX_SUBTITLES];
float alpha[MAX_SUBTITLES];
char oldStrings[MAX_SUBTITLES][2048];
View3D::View3D()
{
// set as transparent
setBackgroundColor(UClear, true);
// no border
setBorderStyle(border_none);
AllowActivate(true);
// set as transparent
setBackgroundColor(UClear, true);
// no border
setBorderStyle(border_none);
AllowActivate(true);
m_printfadetime = 0.0;
m_print_mat = NULL;
m_locationprint = qfalse;
m_printfadetime = 0.0;
m_print_mat = NULL;
m_locationprint = qfalse;
}
void View3D::Draw
(
void
)
void View3D::UpdateLocationPrint(int x, int y, const char *s, float alpha)
{
if (clc.state != CA_DISCONNECTED) {
SCR_DrawScreenField();
}
set2D();
re.SavePerformanceCounters();
Draw2D();
m_printstring = s;
m_printalpha = alpha;
m_printfadetime = 4000.0;
m_x_coord = x;
m_y_coord = y;
m_locationprint = qtrue;
}
void View3D::DrawLetterbox
(
void
)
void View3D::UpdateCenterPrint(const char *s, float alpha)
{
float frac;
vec4_t col;
m_printstring = s;
col[0] = col[1] = col[2] = 0;
col[3] = 1;
if (s[0] == '@') {
m_print_mat = uWinMan.RegisterShader(s + 1);
} else {
m_print_mat = NULL;
}
frac = cl.snap.ps.stats[STAT_LETTERBOX] / 32767.0;
if (frac > 0.0) {
m_letterbox_active = true;
re.SetColor(col);
re.DrawBox(0.0, 0.0, m_screenframe.size.width, m_screenframe.size.height);
re.DrawBox(0.0, m_screenframe.size.height - m_screenframe.size.height * frac, m_screenframe.size.width, m_screenframe.size.height);
} else {
m_letterbox_active = false;
}
m_printalpha = alpha;
m_printfadetime = 4000.0;
m_locationprint = qfalse;
}
void View3D::DrawFades
(
void
)
void View3D::PrintSound(int channel, const char *name, float vol, int rvol, float pitch, float base, int& line)
{
if (cl.snap.ps.blend[3] > 0) {
re.SetColor(cl.snap.ps.blend);
if (cl.snap.ps.stats[STAT_ADDFADE]) {
re.AddBox(0.0, 0.0, m_screenframe.size.width, m_screenframe.size.height);
} else {
re.DrawBox(0.0, 0.0, m_screenframe.size.width, m_screenframe.size.height);
}
}
char buf[255];
float x;
float xStep;
float height;
height = m_font->getHeight(false);
xStep = height;
x = 0;
sprintf(buf, "%d", channel);
m_font->Print(x, height * line + m_frame.pos.y, buf, -1, false);
x += xStep + xStep;
sprintf(buf, "%s", name);
m_font->Print(x, height * line + m_frame.pos.y, buf, -1, false);
x += xStep * 30.0;
sprintf(buf, "vol:%.2f", vol);
m_font->Print(x, height * line + m_frame.pos.y, buf, -1, false);
x += xStep * 8;
sprintf(buf, "rvol:%.2f", (float)(rvol / 128.f));
m_font->Print(x, height * line + m_frame.pos.y, buf, -1, false);
x += xStep * 5;
sprintf(buf, "pit:%.2f", pitch);
m_font->Print(x, height * line + m_frame.pos.y, buf, -1, false);
x += xStep * 5;
sprintf(buf, "base:%d", (int)base);
m_font->Print(x, height * line + m_frame.pos.y, buf, -1, false);
line++;
}
void View3D::Draw2D
(
void
)
void View3D::Pressed(Event *ev)
{
if (!cls.no_menus) {
DrawFades();
}
DrawLetterbox();
if ((cl_debuggraph->integer || cl_timegraph->integer) && !cls.no_menus)
{
SCR_DrawDebugGraph();
}
else if (!cls.no_menus)
{
if (cge) {
cge->CG_Draw2D();
}
if (m_locationprint) {
LocationPrint();
} else {
CenterPrint();
}
if (!cls.no_menus)
{
DrawSoundOverlay();
DrawSubtitleOverlay();
}
}
if (fps->integer && !cls.no_menus)
{
DrawFPS();
DrawProf();
}
IN_MouseOff();
OnActivate(ev);
}
void View3D::DrawFPS
(
void
)
void View3D::OnDeactivate(Event *ev)
{
char string[128];
setFont("verdana-14");
if (fps->integer == 2)
{
re.SetColor(UBlack);
re.DrawBox(
0.0,
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse) * 4.0,
m_frame.pos.x + m_frame.size.width,
m_font->getHeight(qfalse) * 4.0
);
}
sprintf(string, "FPS %4.1f", currentfps);
if (currentfps > 23.94) {
if (cl_greenfps->integer) {
m_font->setColor(UGreen);
} else {
m_font->setColor(UWhite);
}
} else if (currentfps > 18.0) {
m_font->setColor(UYellow);
} else {
// low fps
m_font->setColor(URed);
}
m_font->Print(
m_font->getHeight(qfalse) * 10.0,
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse) * 3.0,
string,
-1,
qfalse
);
// Draw elements count
if (cl_greenfps->integer) {
m_font->setColor(UGreen);
}
else {
m_font->setColor(UWhite);
}
sprintf(string, "wt%5d wv%5d cl%d", cls.world_tris, cls.world_verts, cls.character_lights);
m_font->Print(
m_font->getHeight(qfalse) * 10.0,
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse) * 2.0,
string,
-1,
qfalse
);
sprintf(string, "t%5d v%5d Mtex%5.2f", cls.total_tris, cls.total_verts, (float)cls.total_texels * 0.00000095367432);
m_font->Print(
m_font->getHeight(qfalse) * 10.0,
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse),
string,
-1,
qfalse
);
m_font->setColor(UBlack);
cls.keyCatchers |= KEYCATCH_UI;
}
void View3D::DrawProf
(
void
)
void View3D::OnActivate(Event *ev)
{
// Normal empty function
}
void View3D::PrintSound
(
int channel,
const char *name,
float vol,
int rvol,
float pitch,
float base,
int& line
)
{
// FIXME: unimplemented
}
void View3D::DrawSoundOverlay
(
void
)
{
setFont("verdana-14");
m_font->setColor(UWhite);
if (sound_overlay->integer) {
Com_Printf("sound_overlay isn't supported with OpenAL/SDL right now.\n");
Cvar_Set("sound_overlay", "0");
}
}
void View3D::CenterPrint
(
void
)
{
// FIXME: unimplemented
}
void View3D::LocationPrint
(
void
)
{
// FIXME: unimplemented
}
void View3D::OnActivate
(
Event *ev
)
{
UIWidget* wid;
UList<UIWidget*> widgets;
UIWidget *wid;
UList<UIWidget *> widgets;
UI_CloseInventory();
cls.keyCatchers &= ~KEYCATCH_UI;
for (wid = getParent()->getFirstChild(); wid; wid = getParent()->getNextChild(wid))
{
if (wid->getAlwaysOnBottom() && wid != this) {
widgets.AddTail(wid);
}
}
for (wid = getParent()->getFirstChild(); wid; wid = getParent()->getNextChild(wid)) {
if (wid->getAlwaysOnBottom() && wid != this) {
widgets.AddTail(wid);
}
}
widgets.IterateFromHead();
while (widgets.IsCurrentValid())
{
widgets.getCurrent()->BringToFrontPropogated();
widgets.IterateNext();
}
widgets.IterateFromHead();
while (widgets.IsCurrentValid()) {
widgets.getCurrent()->BringToFrontPropogated();
widgets.IterateNext();
}
}
void View3D::OnDeactivate
(
Event *ev
)
void View3D::LocationPrint(void)
{
cls.keyCatchers |= KEYCATCH_UI;
fonthorzjustify_t horiz;
fontvertjustify_t vert;
int x, y;
const char *p;
float alpha;
UIRect2D frame;
if (!m_printfadetime) {
m_locationprint = false;
return;
}
horiz = FONT_JUSTHORZ_LEFT;
vert = FONT_JUSTVERT_TOP;
p = Sys_LV_CL_ConvertString(m_printstring);
if (m_printfadetime > 3250) {
alpha = 1.f - (m_printfadetime - 3250.f) / 750.f * m_printalpha;
} else if (m_printfadetime >= 750) {
alpha = 1.f;
} else {
alpha = m_printfadetime / 750.f * m_printalpha;
}
alpha = Q_clamp_float(alpha, 0, 1);
x = m_x_coord / 640.f * m_screenframe.size.width;
y = (480 - m_font->getHeight(false) - m_y_coord) / 480.f * m_screenframe.size.height;
if (m_x_coord == -1) {
horiz = FONT_JUSTHORZ_CENTER;
x = 0;
}
if (m_y_coord == -1) {
vert = FONT_JUSTVERT_CENTER;
y = 0;
}
m_font->setColor(UColor(0, 0, 0, alpha));
frame = getClientFrame();
m_font->PrintJustified(
UIRect2D(frame.pos.x + x + 1, frame.pos.y + y + 1, frame.size.width, frame.size.height),
horiz,
vert,
p,
m_bVirtual ? m_vVirtualScale : NULL
);
m_font->setColor(UColor(1, 1, 1, alpha));
frame = getClientFrame();
m_font->PrintJustified(
UIRect2D(frame.pos.x + x, frame.pos.y + y, frame.size.width, frame.size.height),
horiz,
vert,
p,
m_bVirtual ? m_vVirtualScale : NULL
);
m_font->setColor(UBlack);
m_printfadetime -= cls.frametime;
if (m_printfadetime < 0) {
m_printfadetime = 0;
}
}
void View3D::DrawSubtitleOverlay
(
void
)
qboolean View3D::LetterboxActive(void)
{
// FIXME: unimplemented
}
void View3D::ClearCenterPrint
(
void
)
{
m_printfadetime = 0.0;
}
void View3D::UpdateCenterPrint
(
const char *s,
float alpha
)
{
m_printstring = s;
if (s[0] == '@') {
m_print_mat = uWinMan.RegisterShader(s + 1);
} else {
m_print_mat = NULL;
}
m_printalpha = alpha;
m_printfadetime = 4000.0;
m_locationprint = qfalse;
}
void View3D::UpdateLocationPrint
(
int x,
int y,
const char *s,
float alpha
)
{
m_printstring = s;
m_printalpha = alpha;
m_printfadetime = 4000.0;
m_x_coord = x;
m_y_coord = y;
m_locationprint = qtrue;
}
qboolean View3D::LetterboxActive
(
void
)
{
return m_letterbox_active;
return m_letterbox_active;
}
float avWidth = 0.0;
void View3D::InitSubtitle
(
void
)
void View3D::InitSubtitle(void)
{
float totalWidth;
float totalWidth;
for (int i = 0; i < 4; i++) {
subs[i] = Cvar_Get(va("subtitle%d", i), "", 0);
teams[i] = Cvar_Get(va("subteam%d", i), "0", 0);
strcpy(oldStrings[i], subs[i]->string);
fadeTime[i] = 4000.0;
subLife[i] = 4000.0;
}
for (int i = 0; i < 4; i++) {
subs[i] = Cvar_Get(va("subtitle%d", i), "", 0);
teams[i] = Cvar_Get(va("subteam%d", i), "0", 0);
strcpy(oldStrings[i], subs[i]->string);
fadeTime[i] = 4000.0;
subLife[i] = 4000.0;
}
totalWidth = 0.0;
for (char j = 'A'; j <= 'Z'; j++) {
totalWidth += m_font->getCharWidth(j);
}
totalWidth = 0.0;
for (char j = 'A'; j <= 'Z'; j++) {
totalWidth += m_font->getCharWidth(j);
}
avWidth = totalWidth / 26.0;
avWidth = totalWidth / 26.0;
}
void View3D::FrameInitialized
(
void
)
void View3D::FrameInitialized(void)
{
Connect(this, W_Activated, W_Activated);
Connect(this, W_Deactivated, W_Deactivated);
Connect(this, W_Activated, W_Activated);
Connect(this, W_Deactivated, W_Deactivated);
}
void View3D::Pressed
(
Event *ev
)
void View3D::DrawSubtitleOverlay(void)
{
IN_MouseOff();
OnActivate(ev);
cvar_t *subAlpha;
int i;
float minX, maxY;
int line;
subAlpha = Cvar_Get("subAlpha", "0.5", 0);
setFont("facfont-20");
m_font->setColor(URed);
for (i = 0; i < MAX_SUBTITLES; i++) {
if (strcmp(oldStrings[i], subs[i]->string)) {
fadeTime[i] = 2500 * ((strlen(subs[i]->string) / 68) + 1.f) + 1500;
subLife[i] = fadeTime[i];
Q_strncpyz(oldStrings[i], subs[i]->string, sizeof(oldStrings[i]));
}
if (fadeTime[i] > subLife[i] - 750.f) {
alpha[i] = 1.f - (fadeTime[i] - (subLife[i] - 750.f)) / 750.f;
} else if (fadeTime[i] < 750) {
alpha[i] = fadeTime[i] / 750.f;
} else {
alpha[i] = 1.f;
}
fadeTime[i] -= cls.frametime;
if (fadeTime[i] < 0) {
// Clear the subtitle
fadeTime[i] = 0;
oldStrings[i][0] = 0;
Cvar_Set(va("subtitle%d", i), "");
}
}
minX = m_screenframe.size.height - m_font->getHeight(false) * 10;
maxY = (m_frame.pos.x + m_frame.size.width) - (m_frame.pos.x + m_frame.size.width) * 0.2f;
line = 0;
for (i = 0; i < MAX_SUBTITLES; i++) {
if (m_font->getWidth(subs[i]->string, sizeof(oldStrings[i])) > maxY) {
char buf[2048];
char *c;
char *end;
char *start;
float total;
int blockcount;
c = buf;
strcpy(buf, subs[i]->string);
total = 0;
end = NULL;
start = buf;
while (*c) {
blockcount = m_font->DBCSGetWordBlockCount(c, -1);
if (!blockcount) {
break;
}
total += m_font->getWidth(c, blockcount);
c += blockcount;
if (total > maxY) {
total = 0;
if (end < start) {
Com_Printf("ERROR - word longer than possible line\n");
break;
}
m_font->setColor(UColor(0, 0, 0, alpha[i] * subAlpha->value));
m_font->Print(18, m_font->getHeight(false) * line + minX + 1.f, start, -1, false);
m_font->setColor(UColor(1, 1, 1, alpha[i] * subAlpha->value));
m_font->Print(20, m_font->getHeight(false) * line + minX, start, -1, false);
start = end + 1;
c = end + 1;
line++;
}
}
m_font->setColor(UColor(0, 0, 0, alpha[i] * subAlpha->value));
m_font->Print(18, m_font->getHeight(false) * line + minX + 1.f, start, -1, qfalse);
m_font->setColor(UColor(1, 1, 1, alpha[i] * subAlpha->value));
m_font->Print(20, m_font->getHeight(false) * line + minX, start, -1, qfalse);
line++;
} else {
m_font->setColor(UColor(0, 0, 0, alpha[i] * subAlpha->value));
m_font->Print(18, m_font->getHeight(false) * line + minX + 1.f, subs[i]->string, -1, qfalse);
m_font->setColor(UColor(1, 1, 1, alpha[i] * subAlpha->value));
m_font->Print(20, m_font->getHeight(false) * line + minX, subs[i]->string, -1, qfalse);
line++;
}
}
}
CLASS_DECLARATION( UIWidget, ConsoleView, NULL )
void View3D::DrawSoundOverlay(void)
{
{ NULL, NULL }
setFont("verdana-14");
m_font->setColor(UWhite);
// FIXME: TODO
if (sound_overlay->integer) {
Com_Printf("sound_overlay isn't supported with OpenAL/SDL right now.\n");
Cvar_Set("sound_overlay", "0");
}
}
void View3D::DrawProf(void)
{
// Normal empty function
}
void View3D::DrawLetterbox(void)
{
float frac;
vec4_t col;
col[0] = col[1] = col[2] = 0;
col[3] = 1;
frac = cl.snap.ps.stats[STAT_LETTERBOX] / 32767.0;
if (frac > 0.0) {
m_letterbox_active = true;
re.SetColor(col);
re.DrawBox(0.0, 0.0, m_screenframe.size.width, m_screenframe.size.height);
re.DrawBox(
0.0,
m_screenframe.size.height - m_screenframe.size.height * frac,
m_screenframe.size.width,
m_screenframe.size.height
);
} else {
m_letterbox_active = false;
}
}
void View3D::DrawFades(void)
{
if (cl.snap.ps.blend[3] > 0) {
re.SetColor(cl.snap.ps.blend);
if (cl.snap.ps.stats[STAT_ADDFADE]) {
re.AddBox(0.0, 0.0, m_screenframe.size.width, m_screenframe.size.height);
} else {
re.DrawBox(0.0, 0.0, m_screenframe.size.width, m_screenframe.size.height);
}
}
}
void View3D::DrawFPS(void)
{
char string[128];
setFont("verdana-14");
if (fps->integer == 2) {
re.SetColor(UBlack);
re.DrawBox(
0.0,
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse) * 4.0,
m_frame.pos.x + m_frame.size.width,
m_font->getHeight(qfalse) * 4.0
);
}
sprintf(string, "FPS %4.1f", currentfps);
if (currentfps > 23.94) {
if (cl_greenfps->integer) {
m_font->setColor(UGreen);
} else {
m_font->setColor(UWhite);
}
} else if (currentfps > 18.0) {
m_font->setColor(UYellow);
} else {
// low fps
m_font->setColor(URed);
}
m_font->Print(
m_font->getHeight(qfalse) * 10.0,
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse) * 3.0,
string,
-1,
qfalse
);
// Draw elements count
if (cl_greenfps->integer) {
m_font->setColor(UGreen);
} else {
m_font->setColor(UWhite);
}
sprintf(string, "wt%5d wv%5d cl%d", cls.world_tris, cls.world_verts, cls.character_lights);
m_font->Print(
m_font->getHeight(qfalse) * 10.0,
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse) * 2.0,
string,
-1,
qfalse
);
sprintf(string, "t%5d v%5d Mtex%5.2f", cls.total_tris, cls.total_verts, (float)cls.total_texels * 0.00000095367432);
m_font->Print(
m_font->getHeight(qfalse) * 10.0,
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse),
string,
-1,
qfalse
);
m_font->setColor(UBlack);
}
void View3D::Draw2D(void)
{
if (!cls.no_menus) {
DrawFades();
}
DrawLetterbox();
if ((cl_debuggraph->integer || cl_timegraph->integer) && !cls.no_menus) {
SCR_DrawDebugGraph();
} else if (!cls.no_menus) {
if (cge) {
cge->CG_Draw2D();
}
if (m_locationprint) {
LocationPrint();
} else {
CenterPrint();
}
if (!cls.no_menus) {
DrawSoundOverlay();
DrawSubtitleOverlay();
}
}
if (fps->integer && !cls.no_menus) {
DrawFPS();
DrawProf();
}
}
void View3D::Draw(void)
{
if (clc.state != CA_DISCONNECTED) {
SCR_DrawScreenField();
}
set2D();
re.SavePerformanceCounters();
Draw2D();
}
void View3D::ClearCenterPrint(void)
{
m_printfadetime = 0.0;
}
void View3D::CenterPrint(void)
{
float alpha;
const char *p;
qhandle_t mat;
float x, y;
float w, h;
if (!m_printfadetime) {
return;
}
p = Sys_LV_CL_ConvertString(m_printstring);
if (m_printfadetime > 3250) {
alpha = 1.f - (m_printfadetime - 3250.f) / 750.f * m_printalpha;
} else if (m_printfadetime >= 750) {
alpha = 1.f;
} else {
alpha = m_printfadetime / 750.f * m_printalpha;
}
alpha = Q_clamp_float(alpha, 0, 1);
if (!m_print_mat) {
UIRect2D frame;
m_font->setColor(UColor(0, 0, 0, alpha));
frame = getClientFrame();
m_font->PrintJustified(
UIRect2D(frame.pos.x + 1, frame.pos.y + 1, frame.size.width, frame.size.height),
m_iFontAlignmentHorizontal,
m_iFontAlignmentVertical,
p,
m_bVirtual ? m_vVirtualScale : NULL
);
m_font->setColor(UColor(1, 1, 1, alpha));
frame = getClientFrame();
m_font->PrintJustified(
frame, m_iFontAlignmentHorizontal, m_iFontAlignmentVertical, p, m_bVirtual ? m_vVirtualScale : NULL
);
m_font->setColor(UBlack);
} else if ((mat = m_print_mat->GetMaterial())) {
vec4_t col {alpha, alpha, alpha, alpha};
re.SetColor(col);
w = re.GetShaderWidth(mat);
h = re.GetShaderHeight(mat);
x = (m_frame.pos.x + m_frame.size.width - w) * 0.5f;
y = (m_frame.pos.y + m_frame.size.height - h) * 0.5f;
re.DrawStretchPic(x, y, w, h, 0, 0, 1, 1, mat);
}
m_printfadetime -= cls.frametime;
if (m_printfadetime < 0) {
m_printfadetime = 0;
}
}
CLASS_DECLARATION(UIWidget, ConsoleView, NULL) {
{NULL, NULL}
};
void ConsoleView::Draw
(
void
)
{
// FIXME: unimplemented
}
void ConsoleView::Draw(void) {}
+37 -38
View File
@@ -20,55 +20,54 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#ifndef __CL_UIVIEW3D__
#define __CL_UIVIEW3D__
#pragma once
class View3D : public UIWidget {
float m_printfadetime;
float m_printalpha;
str m_printstring;
UIReggedMaterial *m_print_mat;
qboolean m_locationprint;
int m_x_coord;
int m_y_coord;
qboolean m_letterbox_active;
class View3D : public UIWidget
{
float m_printfadetime;
float m_printalpha;
str m_printstring;
UIReggedMaterial *m_print_mat;
qboolean m_locationprint;
int m_x_coord;
int m_y_coord;
qboolean m_letterbox_active;
public:
CLASS_PROTOTYPE( View3D );
CLASS_PROTOTYPE(View3D);
protected:
void Draw( void ) override;
void DrawLetterbox( void );
void DrawFades( void );
void Draw2D( void );
void DrawFPS( void );
void DrawProf( void );
void PrintSound( int channel, const char *name, float vol, int rvol, float pitch, float base, int& line );
void DrawSoundOverlay( void );
void CenterPrint( void );
void LocationPrint( void );
void OnActivate( Event *ev );
void OnDeactivate( Event *ev );
void DrawSubtitleOverlay( void );
void Draw(void) override;
void DrawLetterbox(void);
void DrawFades(void);
void Draw2D(void);
void DrawFPS(void);
void DrawProf(void);
void PrintSound(int channel, const char *name, float vol, int rvol, float pitch, float base, int& line);
void DrawSoundOverlay(void);
void CenterPrint(void);
void LocationPrint(void);
void OnActivate(Event *ev);
void OnDeactivate(Event *ev);
void DrawSubtitleOverlay(void);
public:
View3D();
View3D();
void ClearCenterPrint( void );
void UpdateCenterPrint( const char *s, float alpha );
void UpdateLocationPrint( int x, int y, const char *s, float alpha );
qboolean LetterboxActive( void );
void InitSubtitle( void );
void FrameInitialized( void ) override;
virtual void Pressed( Event *ev );
void ClearCenterPrint(void);
void UpdateCenterPrint(const char *s, float alpha);
void UpdateLocationPrint(int x, int y, const char *s, float alpha);
qboolean LetterboxActive(void);
void InitSubtitle(void);
void FrameInitialized(void) override;
virtual void Pressed(Event *ev);
};
class ConsoleView : public UIWidget {
class ConsoleView : public UIWidget
{
public:
CLASS_PROTOTYPE( ConsoleView );
CLASS_PROTOTYPE(ConsoleView);
protected:
void Draw( void ) override;
void Draw(void) override;
};
#endif /* __CL_UIVIEW3D__ */
+1 -1
View File
@@ -320,7 +320,7 @@ typedef struct {
serverInfo_t globalServers[MAX_GLOBAL_SERVERS];
// additional global servers
int numGlobalServerAddresses;
serverAddress_t globalServerAddresses[MAX_GLOBAL_SERVERS];
netadr_t globalServerAddresses[MAX_GLOBAL_SERVERS];
int numfavoriteservers;
serverInfo_t favoriteServers[MAX_OTHER_SERVERS];
+15 -1
View File
@@ -22,10 +22,16 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "../snd_local.h"
#if !defined(USE_SOUND_NEW) || !USE_SOUND_NEW
void S_Init2()
{
S_Init();
SND_setup();
// HACK: S_RegisterSound returns 0 when unsuccessful, or it returns the the sfx handle
// But the first sfx handle is also 0...
S_RegisterSound("sound/null.wav", qfalse);
}
/*
@@ -91,7 +97,13 @@ S_StartLocalSoundChannel
*/
void S_StartLocalSound(const char* sound_name, qboolean force_load)
{
// FIXME: unimplemented
sfxHandle_t h;
h = S_RegisterSound(sound_name, qfalse);
if (h) {
S_StartLocalSound(h, CHAN_LOCAL_SOUND);
}
}
/*
@@ -438,3 +450,5 @@ void S_LoadData(soundsystemsavegame_t* pSave) {
void S_SaveData(soundsystemsavegame_t* pSave) {
// FIXME: unimplemented
}
#endif
+3 -1
View File
@@ -1581,7 +1581,9 @@ qboolean S_Base_Init( soundInterface_t *si ) {
if ( r ) {
s_soundStarted = 1;
s_soundMuted = 1;
// Fixed in OPM
// The UI must be able to play sounds
// s_soundMuted = 1;
// s_numSfx = 0;
Com_Memset(sfxHash, 0, sizeof(sfx_t *)*LOOP_HASH);
+232
View File
@@ -0,0 +1,232 @@
/*
===========================================================================
Copyright (C) 2024 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code 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.
OpenMoHAA source code 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#if USE_SOUND_NEW
#include "snd_local.h"
#include "snd_openal_new.h"
typedef struct {
vec3_t origin;
vec3_t velocity;
sfx_t *sfx;
int mergeFrame;
} loopSound_t;
# define MAX_SFX 1400
# define MAX_SFX_INFOS 1000
# define MAX_LOOP_SOUNDS 64
qboolean s_bLastInitSound = qfalse;
qboolean s_bSoundStarted = qfalse;
qboolean s_bSoundPaused = qfalse;
qboolean s_bTryUnpause = qfalse;
int s_iListenerNumber = 0;
float s_fAmbientVolume = 1.f;
int number_of_sfx_infos = 0;
cvar_t *s_volume;
cvar_t *s_loadas8bit;
cvar_t *s_khz;
cvar_t *s_show;
cvar_t *s_testsound;
cvar_t *s_separation;
cvar_t *s_musicVolume;
cvar_t *s_ambientVolume;
sfx_info_t sfx_infos[MAX_SFX_INFOS];
sfx_t s_knownSfx[MAX_SFX];
int s_numSfx;
s_entity_t s_entity[MAX_GENTITIES];
static int s_registrationSequence;
static qboolean s_inRegistration;
cvar_t *s_mixPreStep;
cvar_t *s_dialogscale;
int numLoopSounds;
loopSound_t loopSounds[MAX_LOOP_SOUNDS];
void S_SoundInfo_f()
{
// FIXME: unimplemented
}
void S_SoundDump_f()
{
// FIXME: unimplemented
}
void S_Init(qboolean full_startup)
{
// FIXME: unimplemented
}
void S_Shutdown(qboolean full_shutdown)
{
// FIXME: unimplemented
}
qboolean S_NameExists(const char *name)
{
// FIXME: unimplemented
return qfalse;
}
sfx_t *S_FindName(const char *name, int sequenceNumber)
{
// FIXME: unimplemented
return NULL;
}
void S_BeginRegistration()
{
// FIXME: unimplemented
}
void S_DefaultSound(sfx_t *sfx)
{
// FIXME: unimplemented
}
qboolean S_IsSoundRegistered(const char *name)
{
// FIXME: unimplemented
return qfalse;
}
sfxHandle_t S_RegisterSound(const char *name, int streamed, qboolean force_load)
{
// FIXME: unimplemented
return 0;
}
float S_GetSoundTime(sfxHandle_t handle)
{
// FIXME: unimplemented
return 0;
}
void S_EndRegistration()
{
// FIXME: unimplemented
}
void S_UpdateEntity(int entityNum, const vec3_t origin, const vec3_t vel, qboolean use_listener)
{
// FIXME: unimplemented
}
void S_SetGlobalAmbientVolumeLevel(float volume)
{
// FIXME: unimplemented
}
void S_StartSound(
const vec3_t origin,
int entnum,
int entchannel,
sfxHandle_t sfxHandle,
float volume,
float min_dist,
float pitch,
float maxDist,
int streamed
)
{
// FIXME: unimplemented
}
void S_StartLocalSound(const char *sound_name, qboolean force_load)
{
// FIXME: unimplemented
}
void S_StartLocalSoundChannel(const char *sound_name, qboolean force_load, soundChannel_t channel)
{
// FIXME: unimplemented
}
void S_StopAllSounds(qboolean stop_music)
{
// FIXME: unimplemented
}
void S_ClearLoopingSounds()
{
// FIXME: unimplemented
}
void S_AddLoopingSound(
const vec3_t origin,
const vec3_t velocity,
sfxHandle_t sfxHandle,
float volume,
float min_dist,
float max_dist,
float pitch,
int flags
)
{
// FIXME: unimplemented
}
void S_Respatialize(int entityNum, const vec3_t head, vec3_t axis[3])
{
// FIXME: unimplemented
}
void S_Update()
{
// FIXME: unimplemented
}
void S_StopSound(int entnum, int channel)
{
// FIXME: unimplemented
}
void S_SetReverb(int reverb_type, float reverb_level)
{
// FIXME: unimplemented
}
void S_Play()
{
// FIXME: unimplemented
}
void S_SoundList()
{
// FIXME: unimplemented
}
void S_ClearSoundBuffer()
{
// TODO: Remove once AL is fully implemented
}
#endif
+6
View File
@@ -27,6 +27,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "../qcommon/qcommon.h"
#include "snd_public.h"
#if !defined(USE_SOUND_NEW) || !USE_SOUND_NEW
#define PAINTBUFFER_SIZE 4096 // this is in samples
#define SND_CHUNK_SIZE 1024 // samples
@@ -281,3 +283,7 @@ void S_PaintChannelFrom16_altivec( portable_samplepair_t paintbuffer[PAINTBUFFER
#ifdef __cplusplus
}
#endif
#else
# include "snd_local_new.h"
#endif
+164
View File
@@ -0,0 +1,164 @@
/*
===========================================================================
Copyright (C) 2024 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code 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.
OpenMoHAA source code 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#pragma once
#include "../qcommon/q_shared.h"
#include "../qcommon/qcommon.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
int format;
float rate;
float width;
int channels;
int samples;
int dataofs;
int datasize;
} wavinfo_t;
typedef struct sfx_s {
int iFlags;
int length;
int width;
byte *data;
char name[64];
int registration_sequence;
int sfx_info_index;
float time_length;
wavinfo_t info;
unsigned int buffer;
} sfx_t;
typedef struct {
unsigned short wFormatTag;
unsigned short nChannels;
unsigned int nSamplesPerSec;
unsigned int nAvgBytesPerSec;
unsigned short nBlockAlign;
unsigned short wBitsPerSample;
unsigned short cbSize;
} wavinfo_x_t;
typedef struct {
char name[64];
int loop_start;
int loop_end;
int max_number_playing;
float max_factor;
} sfx_info_t;
typedef struct {
vec3_t position;
vec3_t velocity;
int time;
qboolean use_listener;
} s_entity_t;
typedef struct {
char alias[32];
char path[64];
int mood_num;
int flags;
float volume;
float fadetime;
int current_pos;
int current_state;
} song_t;
typedef struct {
int iFlags;
char szName[64];
} sfxsavegame_t;
typedef struct {
qboolean bPlaying;
int iStatus;
sfxsavegame_t sfx;
int iEntNum;
int iEntChannel;
vec3_t vOrigin;
float fVolume;
int iBaseRate;
float fNewPitchMult;
float fMinDist;
float fMaxDist;
int iStartTime;
int iTime;
int iNextCheckObstructionTime;
int iEndTime;
int iFlags;
int iOffset;
int iLoopCount;
} channelbasesavegame_t;
typedef struct {
channelbasesavegame_t Channels[96];
} soundsystemsavegame_t;
// The current sound driver.
// Currently OPENAL
#define SOUND_DRIVER OPENAL
sfx_t *S_FindName(const char *name, int sequenceNumber);
void S_DefaultSound(sfx_t *sfx);
void S_LoadData(soundsystemsavegame_t *pSave);
void S_SaveData(soundsystemsavegame_t *pSave);
void S_ClearSoundBuffer();
#define S_StopAllSounds2 S_StopAllSounds
//
// Driver-specific functions
//
#define S_Call_SndDriver(driver, func) S_##driver##_##func
#define S_Call_SndDriverX(driver, func) S_Call_SndDriver(driver, func)
#define S_Driver_Init S_Call_SndDriverX(SOUND_DRIVER, Init)
#define S_Driver_StartSound S_Call_SndDriverX(SOUND_DRIVER, StartSound)
#define S_Driver_AddLoopingSound S_Call_SndDriverX(SOUND_DRIVER, AddLoopingSound)
#define S_Driver_ClearLoopingSounds S_Call_SndDriverX(SOUND_DRIVER, ClearLoopingSounds)
#define S_Driver_StopSound S_Call_SndDriverX(SOUND_DRIVER, StopSound)
#define S_Driver_StopAllSounds S_Call_SndDriverX(SOUND_DRIVER, StopAllSounds)
#define S_Driver_Respatialize S_Call_SndDriverX(SOUND_DRIVER, Respatialize)
#define S_Driver_SetReverb S_Call_SndDriverX(SOUND_DRIVER, SetReverb)
#define S_Driver_Update S_Call_SndDriverX(SOUND_DRIVER, Update)
#ifdef __cplusplus
}
#endif
+25
View File
@@ -0,0 +1,25 @@
/*
===========================================================================
Copyright (C) 2024 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code 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.
OpenMoHAA source code 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// See the header file for information
#include "snd_miles_new.h"
+28
View File
@@ -0,0 +1,28 @@
/*
===========================================================================
Copyright (C) 2024 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code 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.
OpenMoHAA source code 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
//
// This file exists in the original source code.
// But this driver won't be implemented, as OpenAL is a better sound system!
//
#pragma once
+757
View File
@@ -0,0 +1,757 @@
/*
===========================================================================
Copyright (C) 2024 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code 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.
OpenMoHAA source code 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#if USE_SOUND_NEW
# include "snd_local.h"
# include "snd_openal_new.h"
typedef struct {
char *funcname;
void **funcptr;
bool required;
} extensions_table_t;
# define MAX_MUSIC_SONGS 16
static int s_iNextLoopingWarning = 0;
static int s_iReverbType = 0;
static float s_fReverbLevel = 0;
static bool s_bReverbChanged = false;
static bool s_bFading = false;
static float s_fFadeVolume = 1.f;
cvar_t *s_milesdriver;
cvar_t *s_openaldevice;
cvar_t *s_reverb;
cvar_t *s_show_cpu;
cvar_t *s_show_num_active_sounds;
cvar_t *s_show_sounds;
cvar_t *s_speaker_type;
cvar_t *s_obstruction_cal_time;
cvar_t *s_lastSoundTime;
static float reverb_table[] = {
0.5f, 0.25f, 0.417f, 0.653f, 0.208f, 0.5f, 0.403f, 0.5f, 0.5f,
0.361f, 0.5f, 0.153f, 0.361f, 0.44400001f, 0.25f, 0.111f, 0.111f, 0.19400001f,
1.0f, 0.097000003f, 0.208f, 0.65200001f, 1.0f, 0.875f, 0.139f, 0.486f,
};
static vec3_t vec_zero = {0, 0, 0};
int s_iNumMilesAudioProviders = 0;
bool s_bProvidersEmunerated = false;
static bool al_initialized = false;
static bool al_use_reverb = false;
static float al_current_volume = 0;
static unsigned int al_frequency = 22050;
static void *al_context_id = NULL;
static ALCdevice *al_device = NULL;
static ALboolean (*_alutLoadMP3_LOKI)(unsigned int buffer, const byte *data, int length);
static void (*_alReverbScale_LOKI)();
static void (*_alReverbDelay_LOKI)();
static qboolean music_active = qfalse;
int music_current_mood = 0;
int music_fallback_mood = 0;
float old_music_volume = 1.f;
float music_volume = 1.f;
float new_music_volume = 1.f;
float music_volume_fade_time = 0;
long int music_volume_start_time = 0;
int music_volume_direction = 0;
int music_volume_changed = 0;
int music_loaded = 0;
int music_numsongs = 0;
int music_currentsong = 0;
song_t music_songs[MAX_MUSIC_SONGS];
openal_internal_t openal;
static float s_fFadeStartTime;
static float s_fFadeStopTime;
static char current_soundtrack[128];
static void __alDieIfError(char *file)
{
// FIXME: unimplemented
}
static void S_OPENAL_NukeSource(ALuint *srcptr)
{
// FIXME: unimplemented
}
static void S_OPENAL_NukeBuffer(ALuint *bufptr)
{
// FIXME: unimplemented
}
static void S_OPENAL_NukeChannel(openal_channel *channel)
{
// FIXME: unimplemented
}
static void S_OPENAL_NukeContext()
{
// FIXME: unimplemented
}
static bool S_OPENAL_InitContext()
{
// FIXME: unimplemented
return false;
}
static bool S_OPENAL_InitExtensions()
{
// FIXME: unimplemented
return false;
}
static bool S_OPENAL_InitChannel(int idx, openal_channel *chan)
{
// FIXME: unimplemented
return false;
}
qboolean S_OPENAL_Init()
{
// FIXME: unimplemented
return qfalse;
}
void S_OPENAL_Shutdown()
{
// FIXME: unimplemented
}
void S_FadeSound(float fTime)
{
// FIXME: unimplemented
}
float S_GetBaseVolume()
{
// FIXME: unimplemented
return 0;
}
qboolean S_NeedFullRestart()
{
// FIXME: unimplemented
return qfalse;
}
void S_PrintInfo()
{
// FIXME: unimplemented
}
static void S_DumpStatus(const char *pszChanName, int iChanNum, openal_channel *channel)
{
// FIXME: unimplemented
}
void S_DumpInfo()
{
// FIXME: unimplemented
}
static void S_OPENAL_Pitch()
{
// FIXME: unimplemented
}
static bool S_OPENAL_LoadMP3(const char *_path, openal_channel *chan)
{
// FIXME: unimplemented
return false;
}
static void S_OPENAL_PlayMP3()
{
// FIXME: unimplemented
}
static void S_OPENAL_StopMP3()
{
// FIXME: unimplemented
}
void MUSIC_Pause()
{
// FIXME: unimplemented
}
void MUSIC_Unpause()
{
// FIXME: unimplemented
}
void S_PauseSound()
{
// FIXME: unimplemented
}
void S_UnpauseSound()
{
// FIXME: unimplemented
}
static qboolean S_OPENAL_ShouldPlay(sfx_t *pSfx)
{
// FIXME: unimplemented
return qfalse;
}
static qboolean S_OPENAL_ShouldStart(const vec3_t vOrigin, float fMinDist, float fMaxDist)
{
// FIXME: unimplemented
return qfalse;
}
static int S_OPENAL_PickChannelBase(int iEntNum, int iEntChannel, int iFirstChannel, int iLastChannel)
{
// FIXME: unimplemented
return 0;
}
static int S_OPENAL_PickChannel3D(int iEntNum, int iEntChannel)
{
// FIXME: unimplemented
return 0;
}
static int S_OPENAL_PickChannel2D(int iEntNum, int iEntChannel)
{
// FIXME: unimplemented
return 0;
}
static int S_OPENAL_PickChannel2DStreamed(int iEntNum, int iEntChannel)
{
// FIXME: unimplemented
return 0;
}
void callbackServer(int entnum, int channel_number, const char *name)
{
// FIXME: unimplemented
}
static void S_OPENAL_Start2DSound(
const vec3_t vOrigin,
int iEntNum,
int iEntChannel,
sfx_t *pSfx,
float fVolume,
float fMinDistance,
float fPitch,
float fMaxDistance
)
{
// FIXME: unimplemented
}
void S_OPENAL_StartSound(
const vec3_t vOrigin,
int iEntNum,
int iEntChannel,
sfxHandle_t sfxHandle,
float fVolume,
float fMinDist,
float fPitch,
float fMaxDist,
qboolean bStreamed
)
{
// FIXME: unimplemented
}
void S_OPENAL_AddLoopingSound(
const vec3_t vOrigin,
const vec3_t vVelocity,
sfxHandle_t sfxHandle,
float fVolume,
float fMinDist,
float fMaxDist,
float fPitch,
int iFlags
)
{
// FIXME: unimplemented
}
void S_OPENAL_StopLoopingSound(openal_loop_sound_t *pLoopSound)
{
// FIXME: unimplemented
}
void S_OPENAL_ClearLoopingSounds()
{
// FIXME: unimplemented
}
void S_OPENAL_StopLoopingSounds()
{
// FIXME: unimplemented
}
void S_OPENAL_StopSound(int iEntNum)
{
// FIXME: unimplemented
}
void S_OPENAL_StopAllSounds(qboolean bStopMusic)
{
// FIXME: unimplemented
}
static int S_OPENAL_Start2DLoopSound(
openal_loop_sound_t *pLoopSound, float fVolume, float fVolumeToPlay, float fMinDistance, const vec3_t vLoopOrigin
)
{
// FIXME: unimplemented
return 0;
}
static int S_OPENAL_Start3DLoopSound(
openal_loop_sound_t *pLoopSound,
float fVolumeToPlay,
float fMinDistance,
float fMaxDistance,
const vec3_t vLoopOrigin,
const vec3_t vListenerOrigin
)
{
// FIXME: unimplemented
return 0;
}
static bool S_OPENAL_UpdateLoopSound(
openal_loop_sound_t *pLoopSound,
float fVolumeToPlay,
float fMinDistance,
float fMaxDistance,
const vec3_t vListenerOrigin,
const vec3_t vTempAxis,
const vec3_t vLoopOrigin
)
{
// FIXME: unimplemented
return false;
}
void S_OPENAL_AddLoopSounds(const vec3_t vTempAxis)
{
// FIXME: unimplemented
}
void S_OPENAL_Respatialize(int iEntNum, const vec3_t vHeadPos, const vec3_t vAxis[3])
{
// FIXME: unimplemented
}
static int S_OPENAL_SpatializeStereoSound(const vec3_t listener_origin, const vec3_t listener_left, const vec3_t origin)
{
// FIXME: unimplemented
return 0;
}
static void S_OPENAL_reverb(int iChannel, int iReverbType, float fReverbLevel)
{
// FIXME: unimplemented
}
void S_OPENAL_SetReverb(int iType, float fLevel)
{
// FIXME: unimplemented
}
void S_OPENAL_Update()
{
// FIXME: unimplemented
}
qboolean S_IsSoundPlaying(int channel_number, const char *sfxName)
{
// FIXME: unimplemented
return qfalse;
}
static void S_StoreBase(channelbasesavegame_t *pBase, openal_channel *pChannel)
{
// FIXME: unimplemented
}
static void
S_StartSoundFromBase(channelbasesavegame_t *pBase, openal_channel *pChannel, sfx_t *pSfx, bool bStartUnpaused)
{
// FIXME: unimplemented
}
static void S_LoadBase(channelbasesavegame_t *pBase, openal_channel *pChannel, bool bStartUnpaused)
{
// FIXME: unimplemented
}
void S_SaveData(soundsystemsavegame_t *pSave)
{
// FIXME: unimplemented
}
void S_ReLoad(soundsystemsavegame_t *pSave)
{
// FIXME: unimplemented
}
static void S_InitBase(channelbasesavegame_t *pBase)
{
// FIXME: unimplemented
}
void S_LoadData(soundsystemsavegame_t *pSave)
{
// FIXME: unimplemented
}
void openal_channel::set_velocity(float v0, float v1, float v2)
{
// FIXME: unimplemented
}
void openal_channel::set_position(float v0, float v1, float v2)
{
// FIXME: unimplemented
}
void openal_channel::set_gain(float gain)
{
// FIXME: unimplemented
}
void openal_channel::set_no_3d()
{
// FIXME: unimplemented
}
void openal_channel::set_3d()
{
// FIXME: unimplemented
}
void openal_channel::play()
{
// FIXME: unimplemented
}
void openal_channel::pause()
{
// FIXME: unimplemented
}
void openal_channel::stop()
{
// FIXME: unimplemented
}
ALint openal_channel::get_state()
{
// FIXME: unimplemented
return 0;
}
bool openal_channel::is_free()
{
// FIXME: unimplemented
return false;
}
bool openal_channel::is_paused()
{
// FIXME: unimplemented
return false;
}
bool openal_channel::is_playing()
{
// FIXME: unimplemented
return false;
}
void openal_channel::force_free()
{
// FIXME: unimplemented
}
bool openal_channel::set_sfx(sfx_t *pSfx)
{
// FIXME: unimplemented
return false;
}
void openal_channel::start_sample()
{
// FIXME: unimplemented
}
void openal_channel::stop_sample()
{
// FIXME: unimplemented
}
void openal_channel::resume_sample()
{
// FIXME: unimplemented
}
void openal_channel::end_sample()
{
// FIXME: unimplemented
}
void openal_channel::set_sample_pan(S32 pan)
{
// FIXME: unimplemented
}
void openal_channel::set_sample_playback_rate(S32 rate)
{
// FIXME: unimplemented
}
S32 openal_channel::sample_playback_rate()
{
// FIXME: unimplemented
return 0;
}
S32 openal_channel::sample_volume()
{
// FIXME: unimplemented
return 0;
}
U32 openal_channel::sample_offset()
{
// FIXME: unimplemented
return 0;
}
U32 openal_channel::sample_ms_offset()
{
// FIXME: unimplemented
return 0;
}
U32 openal_channel::sample_loop_count()
{
// FIXME: unimplemented
return 0;
}
void openal_channel::set_sample_offset(U32 offset)
{
// FIXME: unimplemented
}
void openal_channel::set_sample_ms_offset(U32 offset)
{
// FIXME: unimplemented
}
void openal_channel::set_sample_loop_count(S32 count)
{
// FIXME: unimplemented
}
void openal_channel::set_sample_loop_block(S32 start_offset, S32 end_offset)
{
// FIXME: unimplemented
}
U32 openal_channel::sample_status()
{
// FIXME: unimplemented
return 0;
}
qboolean MUSIC_LoadSoundtrackFile(const char *filename)
{
// FIXME: unimplemented
return qfalse;
}
qboolean MUSIC_SongValid(const char *mood)
{
// FIXME: unimplemented
return qfalse;
}
qboolean MUSIC_Loaded()
{
// FIXME: unimplemented
return qfalse;
}
void Music_Update()
{
// FIXME: unimplemented
}
void MUSIC_SongEnded()
{
// FIXME: unimplemented
}
void MUSIC_NewSoundtrack(const char *name)
{
// FIXME: unimplemented
}
void MUSIC_UpdateMood(int current, int fallback)
{
// FIXME: unimplemented
}
void MUSIC_UpdateVolume(float volume, float fade_time)
{
// FIXME: unimplemented
}
void MUSIC_StopAllSongs()
{
// FIXME: unimplemented
}
void MUSIC_FreeAllSongs()
{
// FIXME: unimplemented
}
qboolean MUSIC_Playing()
{
// FIXME: unimplemented
return qfalse;
}
int MUSIC_FindSong(const char *name)
{
// FIXME: unimplemented
return 0;
}
void S_loadsoundtrack()
{
// FIXME: unimplemented
}
const char *S_CurrentSoundtrack()
{
// FIXME: unimplemented
return NULL;
}
void S_PlaySong()
{
// FIXME: unimplemented
}
int MUSIC_CurrentSongChannel()
{
// FIXME: unimplemented
return 0;
}
void MUSIC_StopChannel(int channel_number)
{
// FIXME: unimplemented
}
qboolean MUSIC_PlaySong(const char *alias)
{
// FIXME: unimplemented
return qfalse;
}
void MUSIC_UpdateMusicVolumes()
{
// FIXME: unimplemented
}
void MUSIC_CheckForStoppedSongs()
{
// FIXME: unimplemented
}
void S_TriggeredMusic_SetupHandle(const char *pszName, int iLoopCount, int iOffset, qboolean autostart)
{
// FIXME: unimplemented
}
void S_TriggeredMusic_Start()
{
// FIXME: unimplemented
}
void S_TriggeredMusic_StartLoop()
{
// FIXME: unimplemented
}
void S_TriggeredMusic_Stop()
{
// FIXME: unimplemented
}
void S_TriggeredMusic_Pause()
{
// FIXME: unimplemented
}
void S_TriggeredMusic_Unpause()
{
// FIXME: unimplemented
}
void S_TriggeredMusic_PlayIntroMusic()
{
// FIXME: unimplemented
}
void S_StopMovieAudio()
{
// FIXME: unimplemented
}
void S_SetupMovieAudio(const char *pszMovieName)
{
// FIXME: unimplemented
}
int S_CurrentMoviePosition()
{
// FIXME: unimplemented
return 0;
}
#endif
+170
View File
@@ -0,0 +1,170 @@
/*
===========================================================================
Copyright (C) 2024 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code 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.
OpenMoHAA source code 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#pragma once
#include "qal.h"
#undef OPENAL
typedef int S32;
typedef unsigned int U32;
typedef enum {
FADE_NONE,
FADE_IN,
FADE_OUT
} fade_t;
typedef struct {
vec3_t vOrigin;
vec3_t vRelativeOrigin;
vec3_t vVelocity;
sfx_t *pSfx;
qboolean bPlaying;
int iChannel;
float fVolume;
float fPitch;
int iStartTime;
qboolean bInUse;
qboolean bCombine;
float fBaseVolume;
float fMinDist;
float fMaxDist;
int iFlags;
} openal_loop_sound_t;
struct openal_channel {
sfx_t *pSfx;
int iEntNum;
int iEntChannel;
vec3_t vOrigin;
float fVolume;
int iBaseRate;
float fNewPitchMult;
float fMinDist;
float fMaxDist;
int iStartTime;
int iTime;
int iEndTime;
int iFlags;
int iPausedOffset;
int song_number;
fade_t fading;
int fade_time;
int fade_start_time;
ALuint source;
ALuint buffer;
ALubyte *bufferdata;
void play();
void stop();
void pause();
void set_no_3d();
void set_3d();
ALint get_state();
void set_gain(float gain);
void set_velocity(float v0, float v1, float v2);
void set_position(float v0, float v1, float v2);
bool is_free();
bool is_paused();
bool is_playing();
void force_free();
bool set_sfx(sfx_t *pSfx);
void start_sample();
void stop_sample();
void resume_sample();
void end_sample();
void set_sample_pan(S32 pan);
void set_sample_playback_rate(S32 pan);
S32 sample_playback_rate();
S32 sample_volume();
U32 sample_offset();
U32 sample_ms_offset();
U32 sample_loop_count();
void set_sample_offset(U32 offset);
void set_sample_ms_offset(U32 offset);
void set_sample_loop_count(S32 count);
void set_sample_loop_block(S32 start_offset, S32 end_offset);
U32 sample_status();
};
struct openal_internal_t {
openal_channel chan_3D[32];
openal_channel chan_2D[32];
openal_channel chan_2D_stream[32];
openal_channel chan_song[2];
openal_channel chan_mp3;
openal_channel chan_trig_music;
openal_channel chan_movie;
openal_channel *channel[101];
openal_loop_sound_t loop_sounds[64];
openal_channel movieChannel;
sfx_t movieSFX;
char tm_filename[64];
int tm_loopcount;
};
#ifdef __cplusplus
extern "C" {
#endif
qboolean S_OPENAL_Init();
void S_OPENAL_StartSound(
const vec3_t vOrigin,
int iEntNum,
int iEntChannel,
sfxHandle_t sfxHandle,
float fVolume,
float fMinDist,
float fPitch,
float fMaxDist,
qboolean bStreamed
);
void S_OPENAL_AddLoopingSound(
const vec3_t vOrigin,
const vec3_t vVelocity,
sfxHandle_t sfxHandle,
float fVolume,
float fMinDist,
float fMaxDist,
float fPitch,
int iFlags
);
void S_OPENAL_ClearLoopingSounds();
void S_OPENAL_StopSound(int iEntNum);
void S_OPENAL_StopAllSounds(qboolean bStopMusic);
void S_OPENAL_Respatialize(int iEntNum, const vec3_t vHeadPos, const vec3_t vAxis[3]);
void S_OPENAL_SetReverb(int iType, float fLevel);
void S_OPENAL_Update();
#ifdef __cplusplus
}
#endif
+73
View File
@@ -20,6 +20,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#if !defined(USE_SOUND_NEW) || !USE_SOUND_NEW
#ifdef __cplusplus
extern "C" {
#endif
@@ -89,3 +91,74 @@ void S_MasterGain(float gain);
#endif
#include "new/snd_public_new.h"
#else
#ifdef __cplusplus
extern "C" {
#endif
void S_SoundInfo_f();
void S_SoundDump_f();
void S_Init(qboolean full_startup);
void S_Shutdown(qboolean full_shutdown);
qboolean S_NameExists(const char* name);
void S_BeginRegistration();
qboolean S_IsSoundRegistered(const char* name);
sfxHandle_t S_RegisterSound(const char* name, int streamed, qboolean force_load);
float S_GetSoundTime(sfxHandle_t handle);
void S_EndRegistration();
void S_UpdateEntity(int entityNum, const vec3_t origin, const vec3_t vel, qboolean use_listener);
void S_SetGlobalAmbientVolumeLevel(float volume);
void S_StartSound(const vec3_t origin, int entnum, int entchannel, sfxHandle_t sfxHandle, float volume, float min_dist, float pitch, float maxDist, int streamed);
void S_StartLocalSound(const char* sound_name, qboolean force_load);
void S_StartLocalSoundChannel(const char* sound_name, qboolean force_load, soundChannel_t channel);
void S_StopAllSounds(qboolean stop_music);
void S_ClearLoopingSounds();
void S_AddLoopingSound(const vec3_t origin, const vec3_t velocity, sfxHandle_t sfxHandle, float volume, float min_dist, float max_dist, float pitch, int flags);
void S_Respatialize(int entityNum, const vec3_t head, vec3_t axis[3]);
void S_Update();
void S_StopSound(int entnum, int channel);
void S_SetReverb(int reverb_type, float reverb_level);
void S_Play();
void S_SoundList();
qboolean S_IsSoundPlaying(int channel_number, const char* sfxName);
void S_FadeSound(float fTime);
qboolean MUSIC_LoadSoundtrackFile(const char* filename);
qboolean MUSIC_SongValid(const char* mood);
qboolean MUSIC_Loaded();
void Music_Update();
void MUSIC_SongEnded();
void MUSIC_NewSoundtrack(const char* name);
void MUSIC_UpdateMood(int current, int fallback);
void MUSIC_UpdateVolume(float volume, float fade_time);
void MUSIC_StopAllSongs();
void MUSIC_FreeAllSongs();
qboolean MUSIC_Playing();
int MUSIC_FindSong(const char* name);
void S_loadsoundtrack();
const char* S_CurrentSoundtrack();
void S_PlaySong();
int MUSIC_CurrentSongChannel();
void MUSIC_StopChannel(int channel_number);
qboolean MUSIC_PlaySong(const char* alias);
void MUSIC_UpdateMusicVolumes();
void MUSIC_CheckForStoppedSongs();
void S_TriggeredMusic_SetupHandle(const char* pszName, int iLoopCount, int iOffset, qboolean autostart);
void S_TriggeredMusic_Start();
void S_TriggeredMusic_StartLoop();
void S_TriggeredMusic_Stop();
void S_TriggeredMusic_Pause();
void S_TriggeredMusic_Unpause();
void S_TriggeredMusic_PlayIntroMusic();
void S_StopMovieAudio();
void S_SetupMovieAudio(const char* pszMovieName);
int S_CurrentMoviePosition();
#ifdef __cplusplus
}
#endif
#endif
+4 -4
View File
@@ -1571,8 +1571,8 @@ Event EV_SetTriggered
"triggered",
EV_DEFAULT,
"i",
"0 or 1",
"Set the triggered status",
"triggered",
"Set the triggered status (0 or 1)",
EV_NORMAL
);
Event EV_SetExplosionEffect
@@ -1580,7 +1580,7 @@ Event EV_SetExplosionEffect
"explosioneffect",
EV_DEFAULT,
"s",
"effect model",
"effectModel",
"Set the explosion effect model",
EV_NORMAL
);
@@ -1589,7 +1589,7 @@ Event EV_SetExplosionOffset
"explosionoffset",
EV_DEFAULT,
"v",
"offset vector",
"offset",
"Set the explosion offset",
EV_NORMAL
);
+6 -6
View File
@@ -1607,8 +1607,8 @@ Event EV_Actor_Holster
"holster",
EV_DEFAULT,
"i",
"if non-zero, affects offhand",
"Holster weapon",
"holster",
"If non-zero, affects offhand. Holster weapon",
EV_NORMAL
);
Event EV_Actor_Unholster
@@ -1616,8 +1616,8 @@ Event EV_Actor_Unholster
"unholster",
EV_DEFAULT,
"i",
"if non-zero, affects offhand",
"Unholster weapon",
"holster",
"If non-zero, affects offhand. Unholster weapon",
EV_NORMAL
);
Event EV_Actor_IsEnemyVisible
@@ -2710,7 +2710,7 @@ Constructor
Actor::Actor()
: mVoiceType(-1)
{
entflags |= EF_ACTOR;
entflags |= ECF_ACTOR;
m_pszDebugState = "";
m_pFallPath = NULL;
@@ -2963,7 +2963,7 @@ Actor::~Actor()
ClearPointEntity();
ClearTurnEntity();
entflags &= ~EF_ACTOR;
entflags &= ~ECF_ACTOR;
}
/*
+2 -2
View File
@@ -372,8 +372,8 @@ void ActorPath::UpdatePos(float *origin, float fNodeRadius)
m_bChangeLookAhead = true;
}
// Check added in OPM.
// Make sure to stop if it's the last node
// Added in OPM.
// The check was added to make sure to stop if it's the last node
for (current_path = m_pathpos; current_path >= LastNode(); current_path--) {
VectorSub2D(current_path->point, origin, delta2);
//current_dot = DotProduct2D(delta2, dir) - fNodeRadius;
+10 -4
View File
@@ -167,7 +167,7 @@ static size_t GetLongestClientCmdAllFramesLength(dtiki_t *tiki, int animnum, int
Animate::Animate()
{
entflags |= EF_ANIMATE;
entflags |= ECF_ANIMATE;
syncTime = 0.0f;
syncRate = 1.0f;
@@ -198,7 +198,7 @@ Animate::Animate()
Animate::~Animate()
{
entflags &= ~EF_ANIMATE;
entflags &= ~ECF_ANIMATE;
}
void Animate::ForwardExec(Event *ev)
@@ -629,6 +629,7 @@ void Animate::PostAnimate(void)
float deltaSyncTime;
float total_weight;
float total_angular_delta;
float beforeFrameTime;
Vector vFrameDelta;
bool hasAction = false;
@@ -636,7 +637,8 @@ void Animate::PostAnimate(void)
return;
}
deltaSyncTime = syncTime;
deltaSyncTime = syncTime;
beforeFrameTime = level.frametime / 10.f;
if (!pauseSyncTime) {
syncTime = 1.0f / syncRate * level.frametime + deltaSyncTime;
@@ -698,7 +700,11 @@ void Animate::PostAnimate(void)
continue;
}
} else {
if (edict->s.frameInfo[i].time < (animtimes[i] - 0.01f)) {
// Fixed in OPM
// Previously, beforeFrameTime was a constant of 0.01.
// It caused issues when the number of server frames per second
// was higher. Some animation events were not executing properly.
if (edict->s.frameInfo[i].time < (animtimes[i] - beforeFrameTime)) {
continue;
}
}
+6 -4
View File
@@ -169,22 +169,24 @@ inline void Animate::PauseSyncTime(int pause)
inline void Animate::Archive(Archiver& arc)
{
int i;
Entity::Archive(arc);
for (int i = MAX_FRAMEINFOS - 1; i >= 0; i--) {
for (i = 0; i < MAX_FRAMEINFOS; i++) {
arc.ArchiveInteger(&animFlags[i]);
}
arc.ArchiveFloat(&syncTime);
arc.ArchiveFloat(&syncRate);
arc.ArchiveInteger(&pauseSyncTime);
arc.ArchiveBool(&is_paused);
for (int i = MAX_FRAMEINFOS - 1; i >= 0; i--) {
for (i = 0; i < MAX_FRAMEINFOS; i++) {
arc.ArchiveEventPointer(&doneEvents[i]);
}
for (int i = MAX_FRAMEINFOS - 1; i >= 0; i--) {
for (i = 0; i < MAX_FRAMEINFOS; i++) {
arc.ArchiveFloat(&animtimes[i]);
}
for (int i = MAX_FRAMEINFOS - 1; i >= 0; i--) {
for (i = 0; i < MAX_FRAMEINFOS; i++) {
arc.ArchiveFloat(&frametimes[i]);
}
arc.ArchiveVector(&frame_delta);
+20 -3
View File
@@ -276,7 +276,7 @@ void Container<Type>::Archive(Archiver& arc)
template<typename key, typename value>
void con_set<key, value>::Archive(Archiver& arc)
{
Entry *e;
Entry *e = NULL;
int hash;
int i;
@@ -295,17 +295,34 @@ void con_set<key, value>::Archive(Archiver& arc)
e = new Entry;
e->Archive(arc);
hash = HashCode<key>(e->key) % tableLength;
hash = HashCode<key>(e->GetKey()) % tableLength;
e->next = table[hash];
table[hash] = e;
}
defaultEntry = e;
} else {
for (i = tableLength - 1; i >= 0; i--) {
#ifndef NDEBUG
int total;
total = 0;
for (i = 0; i < tableLength; i++) {
for (e = table[i]; e != NULL; e = e->next) {
e->Archive(arc);
total++;
}
}
// it must match the number of elements
assert(total == count);
#else
for (i = 0; i < tableLength; i++) {
for (e = table[i]; e != NULL; e = e->next) {
e->Archive(arc);
}
}
#endif
}
}
+92 -167
View File
@@ -27,31 +27,23 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#pragma once
#define GAME_VERSION "mohaa-base-1"
#define GAME_VERSION "mohaa-base-1"
#define DEFAULT_GRAVITY 800
static const unsigned int MINS_X = -15;
static const unsigned int MINS_Y = -15;
static const unsigned int MINS_Z = 0; // IneQuation: bounding box and viewheights to match MoHAA
static const unsigned int MAXS_X = 15;
static const unsigned int MAXS_Y = 15;
static const unsigned int MAXS_Z = 96;
#define SCORE_NOT_PRESENT -9999 // for the CS_SCORES[12] when only one player is present
#define VOTE_TIME 30000 // 30 seconds before vote times out
#define MINS_Z 0
#define MINS_X -15
#define MINS_Y -15
#define MAXS_X 15
#define MAXS_Y 15
#define MINS_Z 0 // IneQuation: bounding box and viewheights to match MoHAA
#define MAXS_Z 96
#define DEAD_MINS_Z 32
#define CROUCH_MAXS_Z 49
#define DEFAULT_VIEWHEIGHT 82
#define CROUCH_RUN_VIEWHEIGHT 64
#define JUMP_START_VIEWHEIGHT 52
#define CROUCH_VIEWHEIGHT 48
#define PRONE_VIEWHEIGHT 16
#define DEAD_VIEWHEIGHT 8
static const unsigned int DEAD_MINS_Z = 32;
static const unsigned int CROUCH_MAXS_Z = 49;
static const unsigned int DEFAULT_VIEWHEIGHT = 82;
static const unsigned int CROUCH_RUN_VIEWHEIGHT = 64;
static const unsigned int JUMP_START_VIEWHEIGHT = 52;
static const unsigned int CROUCH_VIEWHEIGHT = 48;
static const unsigned int PRONE_VIEWHEIGHT = 16;
static const unsigned int DEAD_VIEWHEIGHT = 8;
//
// config strings are a general means of communicating variable length strings
@@ -139,10 +131,10 @@ extern "C" {
GT_MAX_GAME_TYPE
} gametype_t;
//
// scale to use when evaluating entityState_t::constantLight scale
//
#define CONSTANTLIGHT_RADIUS_SCALE 8
//
// scale to use when evaluating entityState_t::constantLight scale
//
static const float CONSTANTLIGHT_RADIUS_SCALE = 8;
typedef enum {
GENDER_MALE,
@@ -150,30 +142,31 @@ extern "C" {
GENDER_NEUTER
} gender_t;
// su44: vma indexes are sent as 4 bits
// see playerState_t::iViewModelAnim
typedef enum {
VMA_IDLE,
VMA_CHARGE,
VMA_FIRE,
VMA_FIRE_SECONDARY,
VMA_RECHAMBER,
VMA_RELOAD,
VMA_RELOAD_SINGLE,
VMA_RELOAD_END,
VMA_PULLOUT,
VMA_PUTAWAY,
VMA_LADDERSTEP,
VMA_ENABLE,
VMA_CUSTOMANIMATION,
VMA_NUMANIMATIONS
} viewmodelanim_t;
enum vmAnim_e {
VM_ANIM_DISABLED,
VM_ANIM_IDLE,
VM_ANIM_CHARGE,
VM_ANIM_FIRE,
VM_ANIM_FIRE_SECONDARY,
VM_ANIM_RECHAMBER,
VM_ANIM_RELOAD,
VM_ANIM_RELOAD_SINGLE,
VM_ANIM_RELOAD_END,
VM_ANIM_PULLOUT,
VM_ANIM_PUTAWAY,
VM_ANIM_LADDERSTEP,
VM_ANIM_IDLE_0,
VM_ANIM_IDLE_1,
VM_ANIM_IDLE_2,
};
// su44: playerState_t::activeItems[8] slots
// they are sent as 16 bits
// TODO: find out rest of them
#define ITEM_AMMO 0 // current ammo
#define ITEM_WEAPON 1 // current mainhand weapon
// su44: playerState_t::activeItems[8] slots
// they are sent as 16 bits
// TODO: find out rest of them
enum itemtype_e {
ITEM_AMMO,
ITEM_WEAPON
};
/*
===================================================================================
@@ -186,17 +179,12 @@ movement on the server game.
===================================================================================
*/
#define MAX_CLIP_PLANES 5
#define MIN_WALK_NORMAL 0.7f // can't walk on very steep slopes
static const unsigned int MAX_CLIP_PLANES = 5;
static const float MIN_WALK_NORMAL = 0.7f; // can't walk on very steep slopes
#define STEPSIZE 18
static const float STEPSIZE = 18;
#define WATER_TURBO_SPEED 1.35f
#define WATER_TURBO_TIME 1200
#define MINIMUM_RUNNING_TIME 800
#define MINIMUM_WATER_FOR_TURBO 90
#define OVERCLIP 1.001f
static const float OVERCLIP = 1.001f;
// su44: our pmtype_t enum must be the same
// as in MoHAA, because playerState_t::pm_type
@@ -272,22 +260,25 @@ movement on the server game.
#define PMF_UNKNOWN (1 << 14)
#define PMF_NO_LEAN (1 << 15)
// moveposflags
#define MPF_POSITION_STANDING (1 << 0)
#define MPF_POSITION_CROUCHING (1 << 1)
#define MPF_POSITION_PRONE (1 << 2)
#define MPF_POSITION_OFFGROUND (1 << 3)
// moveposflags
enum moveposflags_e {
MPF_POSITION_STANDING = (1 << 0),
MPF_POSITION_CROUCHING = (1 << 1),
MPF_POSITION_PRONE = (1 << 2),
MPF_POSITION_OFFGROUND = (1 << 3),
MPF_MOVEMENT_WALKING = (1 << 4),
MPF_MOVEMENT_RUNNING = (1 << 5),
MPF_MOVEMENT_FALLING = (1 << 6),
};
#define MPF_MOVEMENT_WALKING (1 << 4)
#define MPF_MOVEMENT_RUNNING (1 << 5)
#define MPF_MOVEMENT_FALLING (1 << 6)
#define MAXTOUCH 32
#define MAXTOUCH 32
#define MOVERESULT_NONE 0 // nothing blocking
#define MOVERESULT_TURNED 1 // move blocked, but player turned to avoid it
#define MOVERESULT_BLOCKED 2 // move blocked by slope or wall
#define MOVERESULT_HITWALL 3 // player ran into wall
enum moveresult_e {
MOVERESULT_NONE, // nothing blocking
MOVERESULT_TURNED, // move blocked, but player turned to avoid it
MOVERESULT_BLOCKED, // move blocked by slope or wall
MOVERESULT_HITWALL // player ran into wall
};
typedef struct {
// state (in / out)
@@ -359,36 +350,33 @@ movement on the server game.
//===================================================================================
#define MAX_LETTERBOX_SIZE 0x7fff
static const unsigned int MAX_LETTERBOX_SIZE = 0x7fff;
#define ITEM_NAME_AMMO 0
#define ITEM_NAME_WEAPON 1
#define WEAPON_CLASS_PISTOL (1 << 0)
#define WEAPON_CLASS_RIFLE (1 << 1)
#define WEAPON_CLASS_SMG (1 << 2)
#define WEAPON_CLASS_MG (1 << 3)
#define WEAPON_CLASS_GRENADE (1 << 4)
#define WEAPON_CLASS_HEAVY (1 << 5)
#define WEAPON_CLASS_CANNON (1 << 6)
#define WEAPON_CLASS_ITEM (1 << 7)
#define WEAPON_CLASS_ITEM1 (1 << 8)
#define WEAPON_CLASS_ITEM2 (1 << 9)
#define WEAPON_CLASS_ITEM3 (1 << 10)
#define WEAPON_CLASS_ITEM4 (1 << 11)
#define WEAPON_CLASS_ANY_ITEM \
(WEAPON_CLASS_ITEM | WEAPON_CLASS_ITEM1 | WEAPON_CLASS_ITEM2 | WEAPON_CLASS_ITEM3 | WEAPON_CLASS_ITEM4)
#define WEAPON_CLASS_ITEM_SLOT_BITS (WEAPON_CLASS_ITEM1 | WEAPON_CLASS_ITEM2 | WEAPON_CLASS_ITEM3 | WEAPON_CLASS_ITEM4)
#define WEAPON_CLASS_PRIMARY (!(WEAPON_CLASS_PISTOL | WEAPON_CLASS_GRENADE))
#define WEAPON_CLASS_SECONDARY (WEAPON_CLASS_PISTOL | WEAPON_CLASS_GRENADE)
#define WEAPON_CLASS_THROWABLE (WEAPON_CLASS_GRENADE | WEAPON_CLASS_ITEM)
#define WEAPON_CLASS_MISC \
(WEAPON_CLASS_CANNON | WEAPON_CLASS_ITEM | WEAPON_CLASS_ITEM1 | WEAPON_CLASS_ITEM2 | WEAPON_CLASS_ITEM3 \
| WEAPON_CLASS_ITEM4)
#define WEAPON_CLASS_ITEMINDEX (WEAPON_CLASS_ITEM1 | WEAPON_CLASS_ITEM2 | WEAPON_CLASS_ITEM3 | WEAPON_CLASS_ITEM4)
#define STAT_DEAD_YAW 5 // su44: Is there a DEAD_YAW stat in MoHAA?
enum weaponclass_e {
WEAPON_CLASS_PISTOL = (1 << 0),
WEAPON_CLASS_RIFLE = (1 << 1),
WEAPON_CLASS_SMG = (1 << 2),
WEAPON_CLASS_MG = (1 << 3),
WEAPON_CLASS_GRENADE = (1 << 4),
WEAPON_CLASS_HEAVY = (1 << 5),
WEAPON_CLASS_CANNON = (1 << 6),
WEAPON_CLASS_ITEM = (1 << 7),
WEAPON_CLASS_ITEM1 = (1 << 8),
WEAPON_CLASS_ITEM2 = (1 << 9),
WEAPON_CLASS_ITEM3 = (1 << 10),
WEAPON_CLASS_ITEM4 = (1 << 11),
WEAPON_CLASS_ANY_ITEM =
(WEAPON_CLASS_ITEM | WEAPON_CLASS_ITEM1 | WEAPON_CLASS_ITEM2 | WEAPON_CLASS_ITEM3 | WEAPON_CLASS_ITEM4),
WEAPON_CLASS_ITEM_SLOT_BITS =
(WEAPON_CLASS_ITEM1 | WEAPON_CLASS_ITEM2 | WEAPON_CLASS_ITEM3 | WEAPON_CLASS_ITEM4),
WEAPON_CLASS_PRIMARY = (!(WEAPON_CLASS_PISTOL | WEAPON_CLASS_GRENADE)),
WEAPON_CLASS_SECONDARY = (WEAPON_CLASS_PISTOL | WEAPON_CLASS_GRENADE),
WEAPON_CLASS_THROWABLE = (WEAPON_CLASS_GRENADE | WEAPON_CLASS_ITEM),
WEAPON_CLASS_MISC =
(WEAPON_CLASS_CANNON | WEAPON_CLASS_ITEM | WEAPON_CLASS_ITEM1 | WEAPON_CLASS_ITEM2 | WEAPON_CLASS_ITEM3
| WEAPON_CLASS_ITEM4),
WEAPON_CLASS_ITEMINDEX = (WEAPON_CLASS_ITEM1 | WEAPON_CLASS_ITEM2 | WEAPON_CLASS_ITEM3 | WEAPON_CLASS_ITEM4)
};
// player_state->persistant[] indexes
// these fields are the only part of player_state that isn't
@@ -401,6 +389,7 @@ movement on the server game.
// entityState_t->eFlags
// su44: eFlags used in MoHAA
#define EF_EVERYFRAME 0x00000008
#define EF_CLIMBWALL 0x00000010
#define EF_UNARMED 0x00000020 // su44: this player has his weapon holstered
#define EF_LINKANGLES 0x00000040
@@ -434,33 +423,11 @@ movement on the server game.
#define EF_AWARD_ASSIST 0x00020000 // draw a assist sprite
#define EF_AWARD_DENIED 0x00040000 // denied
#define EF_TEAMVOTED 0x00080000 // already cast a team vote
#define EF_EVERYFRAME 0x00100000 // def commands will be run every client frame
#define EF_ANTISBJUICE 0x00200000 // anti sucknblow juice
#define EF_DONT_PROCESS_COMMANDS 0x00400000 // don't process client commands for this entity
// these defines could be deleted sometime when code/game/ is cleared of Q3A stuff
#define TEAM_FREE 0
#define TEAM_RED 4
#define TEAM_BLUE 3
#define TEAM_NUM_TEAMS 5
//===================================================================================
// flip the togglebit every time an animation
// changes so a restart of the same anim can be detected
#define ANIM_TOGGLEBIT (1 << 9)
#define ANIM_BLEND (1 << 10)
#define ANIM_NUMBITS 11
// server side anim bits
#define ANIM_SERVER_EXITCOMMANDS_PROCESSED (1 << 12)
#define ANIM_MASK (~(ANIM_TOGGLEBIT | ANIM_BLEND | ANIM_SERVER_EXITCOMMANDS_PROCESSED))
// if FRAME_EXPLICIT is set, don't auto animate
#define FRAME_EXPLICIT 512
#define FRAME_MASK (~FRAME_EXPLICIT)
//
// Tag specific flags
//
@@ -601,9 +568,6 @@ movement on the server game.
SWT_FUSE_WET
} stopWatchType_t;
// How many players on the overlay
#define TEAM_MAXOVERLAY 32
//---------------------------------------------------------
// g_dmflags->integer flags
@@ -638,7 +602,7 @@ movement on the server game.
#define DF_WEAPON_NO_SHOTGUN (1 << 27)
#define DF_WEAPON_NO_LANDMINE (1 << 28)
#define DM_FLAG(flag) (g_gametype->integer && ((int)dmflags->integer & (flag)))
#define DM_FLAG(flag) (g_gametype->integer != GT_SINGLE_PLAYER && ((int)dmflags->integer & (flag)))
// content masks
#define MASK_ALL (-1)
@@ -736,50 +700,11 @@ movement on the server game.
#define MASK_CORNER_NODE \
(CONTENTS_SOLID | CONTENTS_LAVA | CONTENTS_SLIME | CONTENTS_UNKNOWN2 | CONTENTS_WEAPONCLIP | CONTENTS_BODY)
// mohaa mask
/*
#define MASK_ALL -1
#define MASK_SOLID 1
#define MASK_COLLISION 0x26000B21
#define MASK_PERMANENTMARK 0x40000001
#define MASK_AUTOCALCLIFE 0x40002021
#define MASK_EXPLOSION 0x40040001
#define MASK_TREADMARK 0x42012B01
#define MASK_THIRDPERSON 0x42012B39
#define MASK_FOOTSTEP 0x42022901
#define MASK_BEAM 0x42042B01
#define MASK_VISIBLE 0x42042B01
#define MASK_VEHICLE 0x42042B01
#define MASK_BULLET 0x42042B21
#define MASK_SHOT 0x42042BA1
#define MASK_CROSSHAIRSHADER 0x42092B01
#define MASK_TRACER 0x42142B21
*/
void BG_EvaluateTrajectoryDelta(const trajectory_t *tr, int atTime, vec3_t result);
void BG_PlayerStateToEntityState(playerState_t *ps, entityState_t *s, qboolean snap);
void BG_PlayerStateToEntityStateExtraPolate(playerState_t *ps, entityState_t *s, int time, qboolean snap);
enum vmAnim_e {
VM_ANIM_DISABLED,
VM_ANIM_IDLE,
VM_ANIM_CHARGE,
VM_ANIM_FIRE,
VM_ANIM_FIRE_SECONDARY,
VM_ANIM_RECHAMBER,
VM_ANIM_RELOAD,
VM_ANIM_RELOAD_SINGLE,
VM_ANIM_RELOAD_END,
VM_ANIM_PULLOUT,
VM_ANIM_PUTAWAY,
VM_ANIM_LADDERSTEP,
VM_ANIM_IDLE_0,
VM_ANIM_IDLE_1,
VM_ANIM_IDLE_2,
};
enum cg_message_ver_15_e {
CGM_NONE,
CGM_BULLET_1,
+10 -9
View File
@@ -255,6 +255,7 @@ void VoteOptions::ParseVoteOptions()
newOption->m_pListItem = newListItem;
}
listItem = newListItem;
newListItem->m_sItemName = token;
if (!script.TokenAvailable(false)) {
Com_Error(
@@ -462,17 +463,17 @@ void CG_VoteOptions_FinishReadFromServer(const char *string)
g_voteOptions.SetupMainOptionsList();
}
void CG_PushCallVote_f()
void CG_PushCallVote_f(void)
{
g_voteOptions.SetupMainOptionsList();
}
void CG_PushCallVoteSubList_f()
void CG_PushCallVoteSubList_f(void)
{
g_voteOptions.SetupSubOptionsList(atoi(cgi.Argv(1)));
}
void CG_PushCallVoteSubText_f()
void CG_PushCallVoteSubText_f(void)
{
str command;
str name;
@@ -492,7 +493,7 @@ void CG_PushCallVoteSubText_f()
VO_Cvar_Set("ui_votestringentry", "");
}
void CG_PushCallVoteSubInteger_f()
void CG_PushCallVoteSubInteger_f(void)
{
str command;
str name;
@@ -512,7 +513,7 @@ void CG_PushCallVoteSubInteger_f()
VO_Cvar_Set("ui_votestringentry", "");
}
void CG_PushCallVoteSubFloat_f()
void CG_PushCallVoteSubFloat_f(void)
{
str command;
str name;
@@ -532,7 +533,7 @@ void CG_PushCallVoteSubFloat_f()
VO_Cvar_Set("ui_votestringentry", "");
}
void CG_PushCallVoteSubClient_f()
void CG_PushCallVoteSubClient_f(void)
{
str command;
str name;
@@ -578,13 +579,13 @@ void CG_PushCallVoteSubClient_f()
);
}
void CG_PushVote_f()
void CG_PushVote_f(void)
{
VO_Cvar_Set("ui_votesubtitle", cgs.voteString);
VO_ExecuteCommand("forcemenu votecast\n");
}
void CG_CallEntryVote_f()
void CG_CallEntryVote_f(void)
{
str command;
str name;
@@ -607,7 +608,7 @@ void CG_CallEntryVote_f()
VO_ExecuteCommand(va("callvote %i \"%s\"\n", index, entry));
}
void VoteOptions::SetupMainOptionsList()
void VoteOptions::SetupMainOptionsList(void)
{
SingleVoteOption *option;
int count;
+8 -8
View File
@@ -120,14 +120,14 @@ extern "C" {
void CG_VoteOptions_StartReadFromServer(const char *string);
void CG_VoteOptions_ContinueReadFromServer(const char *string);
void CG_VoteOptions_FinishReadFromServer(const char *string);
void CG_PushCallVote_f();
void CG_PushCallVoteSubList_f();
void CG_PushCallVoteSubText_f();
void CG_PushCallVoteSubInteger_f();
void CG_PushCallVoteSubFloat_f();
void CG_PushCallVoteSubClient_f();
void CG_PushVote_f();
void CG_CallEntryVote_f();
void CG_PushCallVote_f(void);
void CG_PushCallVoteSubList_f(void);
void CG_PushCallVoteSubText_f(void);
void CG_PushCallVoteSubInteger_f(void);
void CG_PushCallVoteSubFloat_f(void);
void CG_PushCallVoteSubClient_f(void);
void CG_PushVote_f(void);
void CG_CallEntryVote_f(void);
#endif
#ifdef __cplusplus
+1 -1
View File
@@ -542,7 +542,7 @@ CLASS_DECLARATION(Entity, SplinePath, "info_splinepath") {
SplinePath::SplinePath()
{
entflags |= EF_SPLINEPATH;
entflags |= ECF_SPLINEPATH;
AddWaitTill(STRING_REACH);
+1 -1
View File
@@ -702,7 +702,7 @@ Camera::Camera()
{
Vector ang;
entflags |= EF_CAMERA;
entflags |= ECF_CAMERA;
AddWaitTill(STRING_START);
AddWaitTill(STRING_TRIGGER);
+1 -1
View File
@@ -101,7 +101,7 @@ CLASS_DECLARATION(Entity, CrateObject, "func_crate") {
CrateObject::CrateObject()
{
entflags |= EF_CRATEOBJECT;
entflags |= ECF_CRATEOBJECT;
AddWaitTill(STRING_DEATH);
+2
View File
@@ -310,6 +310,8 @@ void DamageModel::EventSetKillThread(Event *ev)
void DamageModel::Archive(Archiver& arc)
{
Animate::Archive(arc);
label.Archive(arc);
arc.ArchiveSafePointer(&boundingBoxEnt);
}
+1 -1
View File
@@ -321,7 +321,7 @@ Door::Door()
{
float t;
entflags |= EF_DOOR;
entflags |= ECF_DOOR;
if (LoadingSavegame) {
return;
}
+23 -27
View File
@@ -1385,7 +1385,7 @@ Event EV_Entity_SinglePlayerCommand
"sp",
EV_DEFAULT,
"sSSS",
"command parms",
"command parm1 parm2 ...",
"Makes a command be executed only in single player",
EV_NORMAL
);
@@ -1394,7 +1394,7 @@ Event EV_Entity_MultiPlayerCommand
"dm",
EV_DEFAULT,
"sSSS",
"command parms",
"command parm1 parm2 ...",
"Makes a command be executed only in multiplayer",
EV_NORMAL
);
@@ -1403,7 +1403,7 @@ Event EV_Entity_RealismModeCommand
"realism",
EV_DEFAULT,
"sSSS",
"command parms",
"command parm1 parm2 ...",
"Makes a command be executed only in realism mode",
EV_NORMAL
);
@@ -1412,7 +1412,7 @@ Event EV_Entity_SPRealismModeCommand
"sprealism",
EV_DEFAULT,
"sSSS",
"command parms",
"command parm1 parm2 ...",
"Makes a command be executed only in single player realism mode",
EV_NORMAL
);
@@ -1421,7 +1421,7 @@ Event EV_Entity_DMRealismModeCommand
"dmrealism",
EV_DEFAULT,
"sSSS",
"command parms",
"command parm1 parm2 ...",
"Makes a command be executed only in multiplayer realism mode",
EV_NORMAL
);
@@ -1686,7 +1686,7 @@ Entity::Entity()
entnum = edict->s.number;
radnum = -1;
entflags |= EF_ENTITY;
entflags |= ECF_ENTITY;
AddWaitTill(STRING_DAMAGE);
AddWaitTill(STRING_SPAWN);
@@ -1780,9 +1780,6 @@ Entity::Entity()
m_BlockedPaths = NULL;
m_bHintRequiresLookAt = true;
// Misc
m_bBindChilds = false;
}
Entity::~Entity()
@@ -1852,7 +1849,7 @@ Entity::~Entity()
level.FreeEdict(edict);
entflags &= ~EF_ENTITY;
entflags &= ~ECF_ENTITY;
}
void Entity::ClassnameEvent(Event *ev)
@@ -2622,14 +2619,11 @@ qboolean Entity::droptofloor(float maxfall)
trace = G_Trace(start, mins, maxs, end, this, edict->clipmask, false, "Entity::droptofloor");
if (trace.fraction == 1 || trace.startsolid || trace.allsolid || !trace.ent) {
groundentity = world->edict;
return false;
}
setOrigin(trace.endpos);
groundentity = trace.ent;
return true;
}
@@ -3689,7 +3683,7 @@ void Entity::Sound(
}
}
if ((!checkSubtitle || g_subtitle->integer) && ret->subtitle) {
if (g_gametype->integer == GT_SINGLE_PLAYER && (!checkSubtitle || g_subtitle->integer) && ret->subtitle) {
Entity *p = G_GetEntity(0);
if (g_subtitle->integer == 2 || max_dist * max_dist > DistanceSquared(org, p->edict->s.origin)) {
@@ -4704,7 +4698,7 @@ qboolean Entity::isBoundTo(Entity *master)
return false;
}
void Entity::bind(Entity *master, qboolean use_my_angles, qboolean bBindChilds)
void Entity::bind(Entity *master, qboolean use_my_angles)
{
float mat[3][3];
float local[3][3];
@@ -4721,8 +4715,6 @@ void Entity::bind(Entity *master, qboolean use_my_angles, qboolean bBindChilds)
return;
}
m_bBindChilds = bBindChilds;
// unbind myself from my master
unbind();
@@ -4885,17 +4877,10 @@ void Entity::EventUnbind(Event *ev)
void Entity::BindEvent(Event *ev)
{
Entity *ent;
bool bBindChilds;
ent = ev->GetEntity(1);
if (ent) {
if (ev->NumArgs() > 1) {
bBindChilds = ev->GetBoolean(2);
} else {
bBindChilds = false;
}
bind(ent, false, bBindChilds);
bind(ent, false);
}
}
@@ -5783,8 +5768,13 @@ void Entity::Archive(Archiver& arc)
arc.ArchiveInteger(&spawnflags);
arc.ArchiveString(&model);
if (arc.Loading() && model.length()) {
setModel(model);
if (arc.Loading() && AutoArchiveModel()) {
if (model.length() && model[0] == '*') {
// set the brush model
edict->s.modelindex = atoi(model.c_str() + 1);
} else {
setModel(model);
}
}
arc.ArchiveVector(&mins);
@@ -5849,6 +5839,11 @@ void Entity::Archive(Archiver& arc)
ArchiveEnum(takedamage, damage_t);
arc.ArchiveSafePointer(&enemy);
arc.ArchiveFloat(&pain_finished);
arc.ArchiveFloat(&damage_debounce_time);
arc.ArchiveInteger(&damage_type);
arc.ArchiveInteger(&m_iNumGlues);
for (i = 0; i < MAX_GLUE_CHILDREN; i++) {
@@ -5858,6 +5853,7 @@ void Entity::Archive(Archiver& arc)
arc.ArchiveObjectPointer((Class **)&m_pGlueMaster);
arc.ArchiveBool(&m_bGlueAngles);
arc.ArchiveBool(&m_bGlueDuckable);
arc.ArchiveBoolean(&detach_at_death);
arc.ArchiveFloat(&stealthMovementScale);
+5 -2
View File
@@ -285,10 +285,13 @@ public:
// immune list
Container<int> immunities;
//
// Added in OPM
//====
// miscellaneous
qboolean m_bBindChilds;
bool m_bHintRequiresLookAt;
str m_HintString;
//====
Entity();
virtual ~Entity();
@@ -538,7 +541,7 @@ public:
void joinTeam(Entity *teammember);
void quitTeam(void);
qboolean isBoundTo(Entity *master);
virtual void bind(Entity *master, qboolean use_my_angles = qfalse, qboolean bBindChilds = qfalse);
virtual void bind(Entity *master, qboolean use_my_angles = qfalse);
virtual void unbind(void);
virtual void glue(Entity *master, qboolean use_my_angles = qtrue, qboolean can_duck = qfalse);
virtual void unglue(void);
+7 -5
View File
@@ -63,11 +63,12 @@ gentity_t free_edicts;
int sv_numtraces = 0;
int sv_numpmtraces = 0;
int g_protocol = 0;
gentity_t *g_entities;
qboolean g_iInThinks = 0;
qboolean g_bBeforeThinks = qfalse;
static float g_fMsecPerClock = 0;
int g_protocol = 0;
target_game_e g_target_game = target_game_e::TG_INVALID;
gentity_t *g_entities;
qboolean g_iInThinks = 0;
qboolean g_bBeforeThinks = qfalse;
static float g_fMsecPerClock = 0;
usercmd_t *current_ucmd;
usereyes_t *current_eyeinfo;
@@ -240,6 +241,7 @@ void G_InitGame(int levelTime, int randomSeed)
G_Printf("gamedate: %s\n", __DATE__);
g_protocol = gi.Cvar_Get("com_protocol", "", 0)->integer;
g_target_game = (target_game_e)gi.Cvar_Get("com_target_game", "0", 0)->integer;
srand(randomSeed);
+1
View File
@@ -35,6 +35,7 @@ extern qboolean LoadingServer;
extern game_import_t gi;
extern game_export_t globals;
extern int g_protocol;
extern target_game_e g_target_game;
extern qboolean g_iInThinks;
extern qboolean g_bBeforeThinks;
+2
View File
@@ -264,6 +264,7 @@ cvar_t *sv_scriptfiles;
cvar_t *sv_maxbots;
cvar_t *sv_numbots;
cvar_t *sv_minPlayers;
cvar_t *g_rankedserver;
cvar_t *g_spectatefollow_firstperson;
@@ -600,6 +601,7 @@ void CVAR_Init(void)
sv_scriptfiles = gi.Cvar_Get("sv_scriptfiles", "0", 0);
sv_maxbots = gi.Cvar_Get("sv_maxbots", "0", CVAR_LATCH);
sv_numbots = gi.Cvar_Get("sv_numbots", "0", CVAR_LATCH);
sv_minPlayers = gi.Cvar_Get("sv_minPlayers", "0", 0);
g_rankedserver = gi.Cvar_Get("g_rankedserver", "0", 0);
g_spectatefollow_firstperson = gi.Cvar_Get("g_spectatefollow_firstperson", "0", 0);
+2 -1
View File
@@ -268,7 +268,8 @@ extern cvar_t* g_obituarylocation;
extern cvar_t *sv_scriptfiles;
extern cvar_t *sv_maxbots;
extern cvar_t * sv_numbots;
extern cvar_t *sv_numbots;
extern cvar_t *sv_minPlayers;
extern cvar_t *g_rankedserver;
extern cvar_t *g_spectatefollow_firstperson;
+8 -2
View File
@@ -885,7 +885,7 @@ void ScriptThreadLabel::Execute(Listener *listener, Event *ev)
}
}
void ScriptThreadLabel::Execute(const SafePtr<Listener>& listener, const SafePtr<Listener>& param)
void ScriptThreadLabel::Execute(Listener* pSelf, const SafePtr<Listener>& listener, const SafePtr<Listener>& param)
{
if (!m_Script) {
return;
@@ -896,7 +896,7 @@ void ScriptThreadLabel::Execute(const SafePtr<Listener>& listener, const SafePtr
params[0].setListenerValue(listener);
params[1].setListenerValue(param);
ScriptClass *scriptClass = new ScriptClass(m_Script, listener);
ScriptClass *scriptClass = new ScriptClass(m_Script, pSelf);
ScriptThread *thread = Director.CreateScriptThread(scriptClass, m_Label);
if (thread) {
@@ -904,6 +904,12 @@ void ScriptThreadLabel::Execute(const SafePtr<Listener>& listener, const SafePtr
}
}
void ScriptThreadLabel::Clear()
{
m_Script = NULL;
m_Label = STRING_EMPTY;
}
void ScriptThreadLabel::Set(const char *label)
{
str script;
+2 -1
View File
@@ -163,8 +163,9 @@ public:
void Execute(Listener *listener = NULL);
void Execute(Listener *listener, Event &ev);
void Execute(Listener *listener, Event *ev);
void Execute(const SafePtr<Listener> &listener, const SafePtr<Listener> &param);
void Execute(Listener* pSelf, const SafePtr<Listener> &listener, const SafePtr<Listener> &param);
void Clear();
void Set(const char *label);
void Set(const_str label);
void SetScript(const ScriptVariable& label);
+2 -2
View File
@@ -53,7 +53,7 @@ CLASS_DECLARATION( Weapon, InventoryItem, NULL )
InventoryItem::InventoryItem()
{
entflags |= EF_INVENTORYITEM;
entflags |= ECF_INVENTORYITEM;
if ( LoadingSavegame )
{
@@ -65,7 +65,7 @@ InventoryItem::InventoryItem()
InventoryItem::~InventoryItem()
{
entflags &= ~EF_INVENTORYITEM;
entflags &= ~ECF_INVENTORYITEM;
}
void InventoryItem::ActivateItem
+2 -2
View File
@@ -341,7 +341,7 @@ Item::Item()
{
str fullname;
entflags |= EF_ITEM;
entflags |= ECF_ITEM;
AddWaitTill(STRING_PICKUP);
@@ -403,7 +403,7 @@ Item::~Item()
owner = NULL;
}
entflags &= ~EF_ITEM;
entflags &= ~ECF_ITEM;
}
void Item::RemoveFromOwner(void)
+122 -77
View File
@@ -616,67 +616,93 @@ Event EV_Level_IgnoreClock
EV_NORMAL
);
//
// Added in OPM
//
Event EV_Level_SetForceTeamObjectiveLocation
(
"force_team_objective",
EV_DEFAULT,
"i",
"force",
"Whether or not to force using a separate objective location for each team.\n"
"1 (forced on TOW/Liberation match): different location for each team\n"
"0 (default): teams use same location on non-TOW/non-Liberation match\n",
EV_SETTER
);
Event EV_Level_GetForceTeamObjectiveLocation
(
"force_team_objective",
EV_DEFAULT,
NULL,
NULL,
"Return 1 if each team has a separate objective location",
EV_GETTER
);
extern Event EV_Entity_Start;
CLASS_DECLARATION(Listener, Level, NULL) {
{&EV_Level_GetTime, &Level::GetTime },
{&EV_Level_GetTotalSecrets, &Level::GetTotalSecrets },
{&EV_Level_GetFoundSecrets, &Level::GetFoundSecrets },
{&EV_Level_PreSpawnSentient, &Level::PreSpawnSentient },
{&EV_Level_GetAlarm, &Level::GetAlarm },
{&EV_Level_SetAlarm, &Level::SetAlarm },
{&EV_Level_SetNoDropHealth, &Level::SetNoDropHealth },
{&EV_Level_SetNoDropWeapons, &Level::SetNoDropWeapons },
{&EV_Level_GetRoundStarted, &Level::EventGetRoundStarted },
{&EV_Level_GetLoopProtection, &Level::GetLoopProtection },
{&EV_Level_SetLoopProtection, &Level::SetLoopProtection },
{&EV_Level_GetPapersLevel, &Level::GetPapersLevel },
{&EV_Level_SetPapersLevel, &Level::SetPapersLevel },
{&EV_Level_GetDMRespawning, &Level::EventGetDMRespawning },
{&EV_Level_SetDMRespawning, &Level::EventSetDMRespawning },
{&EV_Level_SetDMRespawning2, &Level::EventSetDMRespawning },
{&EV_Level_GetDMRoundLimit, &Level::EventGetDMRoundLimit },
{&EV_Level_SetDMRoundLimit, &Level::EventSetDMRoundLimit },
{&EV_Level_SetDMRoundLimit2, &Level::EventSetDMRoundLimit },
{&EV_Level_GetClockSide, &Level::EventGetClockSide },
{&EV_Level_SetClockSide, &Level::EventSetClockSide },
{&EV_Level_SetClockSide2, &Level::EventSetClockSide },
{&EV_Level_GetBombPlantTeam, &Level::EventGetBombPlantTeam },
{&EV_Level_SetBombPlantTeam, &Level::EventSetBombPlantTeam },
{&EV_Level_SetBombPlantTeam2, &Level::EventSetBombPlantTeam },
{&EV_Level_GetTargetsToDestroy, &Level::EventGetTargetsToDestroy},
{&EV_Level_SetTargetsToDestroy, &Level::EventSetTargetsToDestroy},
{&EV_Level_SetTargetsToDestroy2, &Level::EventSetTargetsToDestroy},
{&EV_Level_GetTargetsDestroyed, &Level::EventGetTargetsDestroyed},
{&EV_Level_SetTargetsDestroyed, &Level::EventSetTargetsDestroyed},
{&EV_Level_SetTargetsDestroyed2, &Level::EventSetTargetsDestroyed},
{&EV_Level_GetBombsPlanted, &Level::EventGetBombsPlanted },
{&EV_Level_SetBombsPlanted, &Level::EventSetBombsPlanted },
{&EV_Level_SetBombsPlanted2, &Level::EventSetBombsPlanted },
{&EV_Level_GetRoundBased, &Level::EventGetRoundBased },
{&EV_Level_GetObjectiveBased, &Level::EventGetObjectiveBased },
{&EV_Level_Rain_Density_Set, &Level::EventRainDensitySet },
{&EV_Level_Rain_Density_Get, &Level::EventRainDensityGet },
{&EV_Level_Rain_Speed_Set, &Level::EventRainSpeedSet },
{&EV_Level_Rain_Speed_Get, &Level::EventRainSpeedGet },
{&EV_Level_Rain_Speed_Vary_Set, &Level::EventRainSpeedVarySet },
{&EV_Level_Rain_Speed_Vary_Get, &Level::EventRainSpeedVaryGet },
{&EV_Level_Rain_Slant_Set, &Level::EventRainSlantSet },
{&EV_Level_Rain_Slant_Get, &Level::EventRainSlantGet },
{&EV_Level_Rain_Length_Set, &Level::EventRainLengthSet },
{&EV_Level_Rain_Length_Get, &Level::EventRainLengthGet },
{&EV_Level_Rain_Min_Dist_Set, &Level::EventRainMin_DistSet },
{&EV_Level_Rain_Min_Dist_Get, &Level::EventRainMin_DistGet },
{&EV_Level_Rain_Width_Set, &Level::EventRainWidthSet },
{&EV_Level_Rain_Width_Get, &Level::EventRainWidthGet },
{&EV_Level_Rain_Shader_Set, &Level::EventRainShaderSet },
{&EV_Level_Rain_Shader_Get, &Level::EventRainShaderGet },
{&EV_Level_Rain_NumShaders_Set, &Level::EventRainShaderSet },
{&EV_Level_Rain_NumShaders_Get, &Level::EventRainShaderGet },
{&EV_Level_AddBadPlace, &Level::EventAddBadPlace },
{&EV_Level_RemoveBadPlace, &Level::EventRemoveBadPlace },
{&EV_Level_IgnoreClock, &Level::EventIgnoreClock },
{NULL, NULL }
{&EV_Level_GetTime, &Level::GetTime },
{&EV_Level_GetTotalSecrets, &Level::GetTotalSecrets },
{&EV_Level_GetFoundSecrets, &Level::GetFoundSecrets },
{&EV_Level_PreSpawnSentient, &Level::PreSpawnSentient },
{&EV_Level_GetAlarm, &Level::GetAlarm },
{&EV_Level_SetAlarm, &Level::SetAlarm },
{&EV_Level_SetNoDropHealth, &Level::SetNoDropHealth },
{&EV_Level_SetNoDropWeapons, &Level::SetNoDropWeapons },
{&EV_Level_GetRoundStarted, &Level::EventGetRoundStarted },
{&EV_Level_GetLoopProtection, &Level::GetLoopProtection },
{&EV_Level_SetLoopProtection, &Level::SetLoopProtection },
{&EV_Level_GetPapersLevel, &Level::GetPapersLevel },
{&EV_Level_SetPapersLevel, &Level::SetPapersLevel },
{&EV_Level_GetDMRespawning, &Level::EventGetDMRespawning },
{&EV_Level_SetDMRespawning, &Level::EventSetDMRespawning },
{&EV_Level_SetDMRespawning2, &Level::EventSetDMRespawning },
{&EV_Level_GetDMRoundLimit, &Level::EventGetDMRoundLimit },
{&EV_Level_SetDMRoundLimit, &Level::EventSetDMRoundLimit },
{&EV_Level_SetDMRoundLimit2, &Level::EventSetDMRoundLimit },
{&EV_Level_GetClockSide, &Level::EventGetClockSide },
{&EV_Level_SetClockSide, &Level::EventSetClockSide },
{&EV_Level_SetClockSide2, &Level::EventSetClockSide },
{&EV_Level_GetBombPlantTeam, &Level::EventGetBombPlantTeam },
{&EV_Level_SetBombPlantTeam, &Level::EventSetBombPlantTeam },
{&EV_Level_SetBombPlantTeam2, &Level::EventSetBombPlantTeam },
{&EV_Level_GetTargetsToDestroy, &Level::EventGetTargetsToDestroy },
{&EV_Level_SetTargetsToDestroy, &Level::EventSetTargetsToDestroy },
{&EV_Level_SetTargetsToDestroy2, &Level::EventSetTargetsToDestroy },
{&EV_Level_GetTargetsDestroyed, &Level::EventGetTargetsDestroyed },
{&EV_Level_SetTargetsDestroyed, &Level::EventSetTargetsDestroyed },
{&EV_Level_SetTargetsDestroyed2, &Level::EventSetTargetsDestroyed },
{&EV_Level_GetBombsPlanted, &Level::EventGetBombsPlanted },
{&EV_Level_SetBombsPlanted, &Level::EventSetBombsPlanted },
{&EV_Level_SetBombsPlanted2, &Level::EventSetBombsPlanted },
{&EV_Level_GetRoundBased, &Level::EventGetRoundBased },
{&EV_Level_GetObjectiveBased, &Level::EventGetObjectiveBased },
{&EV_Level_Rain_Density_Set, &Level::EventRainDensitySet },
{&EV_Level_Rain_Density_Get, &Level::EventRainDensityGet },
{&EV_Level_Rain_Speed_Set, &Level::EventRainSpeedSet },
{&EV_Level_Rain_Speed_Get, &Level::EventRainSpeedGet },
{&EV_Level_Rain_Speed_Vary_Set, &Level::EventRainSpeedVarySet },
{&EV_Level_Rain_Speed_Vary_Get, &Level::EventRainSpeedVaryGet },
{&EV_Level_Rain_Slant_Set, &Level::EventRainSlantSet },
{&EV_Level_Rain_Slant_Get, &Level::EventRainSlantGet },
{&EV_Level_Rain_Length_Set, &Level::EventRainLengthSet },
{&EV_Level_Rain_Length_Get, &Level::EventRainLengthGet },
{&EV_Level_Rain_Min_Dist_Set, &Level::EventRainMin_DistSet },
{&EV_Level_Rain_Min_Dist_Get, &Level::EventRainMin_DistGet },
{&EV_Level_Rain_Width_Set, &Level::EventRainWidthSet },
{&EV_Level_Rain_Width_Get, &Level::EventRainWidthGet },
{&EV_Level_Rain_Shader_Set, &Level::EventRainShaderSet },
{&EV_Level_Rain_Shader_Get, &Level::EventRainShaderGet },
{&EV_Level_Rain_NumShaders_Set, &Level::EventRainShaderSet },
{&EV_Level_Rain_NumShaders_Get, &Level::EventRainShaderGet },
{&EV_Level_AddBadPlace, &Level::EventAddBadPlace },
{&EV_Level_RemoveBadPlace, &Level::EventRemoveBadPlace },
{&EV_Level_IgnoreClock, &Level::EventIgnoreClock },
{&EV_Level_SetForceTeamObjectiveLocation, &Level::SetForceTeamObjectiveLocation},
{&EV_Level_GetForceTeamObjectiveLocation, &Level::GetForceTeamObjectiveLocation},
{NULL, NULL }
};
void Level::GetTime(Event *ev)
@@ -779,9 +805,10 @@ void Level::Init(void)
m_letterbox_time = -1.0f;
m_vObjectiveLocation = vec_zero;
m_vAlliedObjectiveLocation = vec_zero;
m_vAxisObjectiveLocation = vec_zero;
m_vObjectiveLocation = vec_zero;
m_vAlliedObjectiveLocation = vec_zero;
m_vAxisObjectiveLocation = vec_zero;
m_bForceTeamObjectiveLocation = false;
svsEndTime = 0;
@@ -1164,7 +1191,8 @@ void Level::SpawnEntities(char *entities, int svsTime)
gi.LoadResource("*148a");
// Single-player check added in OPM
// Added in OPM
// Check for single-player before pre-creating a player instance
if (game.maxclients == 1 && g_gametype->integer == GT_SINGLE_PLAYER) {
spawn_entnum = 0;
new Player;
@@ -2589,15 +2617,18 @@ void Level::Archive(Archiver& arc)
arc.ArchiveFloat(&m_fLandmarkXDistMax);
}
void WriteStatS(FILE* pFile, const char* value) {
void WriteStatS(FILE *pFile, const char *value)
{
fprintf(pFile, "%s", value);
}
void WriteStatI(FILE* pFile, int value) {
void WriteStatI(FILE *pFile, int value)
{
fprintf(pFile, "%d", value);
}
void WriteStatF(FILE* pFile, float value) {
void WriteStatF(FILE *pFile, float value)
{
fprintf(pFile, "%.2f", value);
}
@@ -2609,22 +2640,26 @@ void Level::OpenActorStats()
return;
}
filename = "aistats_" + mapname + ".csv";
filename = "aistats_" + mapname + ".csv";
m_pAIStats = fopen(filename, "wt");
if (m_pAIStats) {
fprintf((FILE*)m_pAIStats, "targetname,weapon,grenade ammo,health,accuracy,hearing,sight,fov,mindist,maxdist,leash,sound awareness,noticescale,enemyshare,grenade aware,model\n");
fprintf(
(FILE *)m_pAIStats,
"targetname,weapon,grenade ammo,health,accuracy,hearing,sight,fov,mindist,maxdist,leash,sound "
"awareness,noticescale,enemyshare,grenade aware,model\n"
);
}
}
void Level::WriteActorStats(Actor* actor)
void Level::WriteActorStats(Actor *actor)
{
const char* name;
str itemName;
Weapon* weapon;
Ammo* ammo;
int ammoAmount;
FILE* pFile;
const char *name;
str itemName;
Weapon *weapon;
Ammo *ammo;
int ammoAmount;
FILE *pFile;
if (!g_aistats->integer) {
return;
@@ -2634,12 +2669,12 @@ void Level::WriteActorStats(Actor* actor)
OpenActorStats();
}
pFile = (FILE*)m_pAIStats;
pFile = (FILE *)m_pAIStats;
if (!pFile) {
return;
}
name = actor->TargetName().c_str();
name = actor->TargetName().c_str();
itemName = "none";
weapon = actor->GetActiveWeapon(WEAPON_MAIN);
@@ -2648,7 +2683,7 @@ void Level::WriteActorStats(Actor* actor)
}
ammoAmount = 0;
ammo = actor->FindAmmoByName("grenade");
ammo = actor->FindAmmoByName("grenade");
if (ammo) {
ammoAmount = ammo->getAmount();
}
@@ -2674,6 +2709,16 @@ void Level::WriteActorStats(Actor* actor)
fprintf(pFile, "\n");
}
void Level::SetForceTeamObjectiveLocation(Event *ev)
{
m_bForceTeamObjectiveLocation = ev->GetBoolean(1);
}
void Level::GetForceTeamObjectiveLocation(Event *ev)
{
ev->AddInteger(g_gametype->integer >= GT_TOW || m_bForceTeamObjectiveLocation);
}
badplace_t::badplace_t()
: m_fLifespan(FLT_MAX)
, m_iTeamSide(TEAM_ALLIES)
+23 -13
View File
@@ -195,11 +195,11 @@ public:
int m_numArenas;
// Voting variables
int m_voteTime;
int m_nextVoteTime;
int m_voteYes;
int m_voteNo;
int m_numVoters;
int m_voteTime;
int m_nextVoteTime;
int m_voteYes;
int m_voteNo;
int m_numVoters;
// Added in 2.0
str m_voteString;
str m_voteName;
@@ -228,6 +228,10 @@ public:
Vector m_vObjectiveLocation;
Vector m_vAlliedObjectiveLocation; // Added in 2.0
Vector m_vAxisObjectiveLocation; // Added in 2.0
// Added in OPM
// Forces axis/allied objectives location to be used
// even if the gametype is not TOW
bool m_bForceTeamObjectiveLocation;
// Current level state
bool spawning;
@@ -280,8 +284,8 @@ public:
void AddLandmarkOrigin(const Vector& origin);
void AddLandmarkName(const str& name, const Vector& origin);
void FreeLandmarks();
str GetDynamicDMLocations(const Vector &origin);
str GetDMLocation(const Vector &origin);
str GetDynamicDMLocations(const Vector& origin);
str GetDMLocation(const Vector& origin);
//====
void PreSpawnSentient(Event *ev);
void ServerSpawned();
@@ -354,11 +358,11 @@ public:
void EventRainNumShadersGet(Event *ev);
//====
// Added in 2.0
void EventAddBadPlace(Event *ev);
void EventRemoveBadPlace(Event *ev);
void EventIgnoreClock(Event *ev);
void UpdateBadPlaces();
int GetNearestBadPlace(const Vector& org, float radius, int team) const;
void EventAddBadPlace(Event *ev);
void EventRemoveBadPlace(Event *ev);
void EventIgnoreClock(Event *ev);
void UpdateBadPlaces();
int GetNearestBadPlace(const Vector& org, float radius, int team) const;
//====
str GetRandomHeadModel(const char *model);
str GetRandomHeadSkin(const char *model);
@@ -371,7 +375,13 @@ public:
void DoEarthquakes(void);
void OpenActorStats();
void WriteActorStats(Actor* actor);
void WriteActorStats(Actor *actor);
//====
// Added in OPM
void SetForceTeamObjectiveLocation(Event *ev);
void GetForceTeamObjectiveLocation(Event *ev);
//====
void Archive(Archiver& arc) override;
};
+3 -3
View File
@@ -1960,7 +1960,7 @@ CLASS_DECLARATION(SimpleArchivedEntity, Waypoint, "info_waypoint") {
Waypoint::Waypoint()
{
entflags |= EF_WAYPOINT;
entflags |= ECF_WAYPOINT;
}
CLASS_DECLARATION(SimpleArchivedEntity, TempWaypoint, NULL) {
@@ -1969,7 +1969,7 @@ CLASS_DECLARATION(SimpleArchivedEntity, TempWaypoint, NULL) {
TempWaypoint::TempWaypoint()
{
entflags |= EF_TEMPWAYPOINT;
entflags |= ECF_TEMPWAYPOINT;
}
/*****************************************************************************/
@@ -1988,7 +1988,7 @@ CLASS_DECLARATION(Waypoint, VehiclePoint, "info_vehiclepoint") {
VehiclePoint::VehiclePoint()
{
entflags |= EF_VEHICLEPOINT;
entflags |= ECF_VEHICLEPOINT;
spawnflags = 0;
}
+2 -2
View File
@@ -1166,7 +1166,7 @@ void PathNode::operator delete(void *ptr)
PathNode::PathNode()
{
entflags |= EF_PATHNODE;
entflags |= ECF_PATHNODE;
findCount = 0;
pLastClaimer = NULL;
numChildren = 0;
@@ -1186,7 +1186,7 @@ PathNode::PathNode()
PathNode::~PathNode()
{
entflags &= ~EF_PATHNODE;
entflags &= ~ECF_PATHNODE;
}
void PathNode::Remove(Event *ev)
+319 -199
View File
File diff suppressed because it is too large. Load diff
+17 -4
View File
@@ -350,7 +350,7 @@ public:
bool m_bFrozen; // if player is frozen
bool animDoneVM;
float speed_multiplier[MAX_SPEED_MULTIPLIERS];
Event *m_pKilledEvent;
ScriptThreadLabel m_killedLabel;
con_map<str, vma_t> vmalist;
str m_sVMAcurrent;
str m_sVMcurrent;
@@ -514,6 +514,7 @@ public:
void InitWeapons(void);
void InitView(void);
void InitModel(void);
void InitModelFps(void); // Added in openmohaa
void InitState(void);
void InitHealth(void);
void InitInventory(void);
@@ -1014,6 +1015,7 @@ inline void Player::Archive(Archiver& arc)
arc.ArchiveInteger(&buttons);
arc.ArchiveInteger(&new_buttons);
arc.ArchiveInteger(&server_new_buttons);
arc.ArchiveFloat(&respawn_time);
arc.ArchiveInteger(&last_attack_button);
@@ -1053,6 +1055,8 @@ inline void Player::Archive(Archiver& arc)
arc.ArchiveBool(&take_pain);
arc.ArchiveInteger(&nextpaintime);
arc.ArchiveFloat(&m_fHealRate);
arc.ArchiveBool(&knockdown);
arc.ArchiveBool(&canfall);
arc.ArchiveBool(&falling);
@@ -1157,17 +1161,27 @@ inline void Player::Archive(Archiver& arc)
if (arc.Loading()) {
UpdateWeapons();
InitModelFps();
}
//
// Added in OPM
//
arc.ArchiveBool(&m_bFrozen);
arc.ArchiveBool(&animDoneVM);
arc.ArchiveFloat(&m_fVMAtime);
for (int i = 0; i < MAX_SPEED_MULTIPLIERS; i++) {
arc.ArchiveFloat(&speed_multiplier[i]);
}
}
inline Camera *Player::CurrentCamera(void)
{
return camera;
}
inline void Player::CameraCut(void)
{
//
// toggle the camera cut bit
@@ -1177,7 +1191,6 @@ inline void Player::CameraCut(void)
}
inline void Player::CameraCut(Camera *ent)
{
if (ent == camera) {
// if the camera we are currently looking through cut, than toggle the cut bits
+216 -39
View File
@@ -25,6 +25,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "player.h"
#include "g_phys.h"
#include "portableturret.h"
extern Event EV_Player_AnimLoop_Torso;
extern Event EV_Player_AnimLoop_Legs;
@@ -32,7 +33,7 @@ extern Event EV_Player_AnimLoop_Legs;
void Player::EndAnim_Legs(Event *ev)
{
animdone_Legs = true;
if (IsRepeatType(m_iPartSlot[legs])) {
SetAnimDoneEvent(EV_Player_AnimLoop_Legs, m_iPartSlot[legs]);
}
@@ -51,7 +52,7 @@ void Player::EndAnim_Torso(Event *ev)
EvaluateState();
}
void Player::EndAnim_Pain(Event* ev)
void Player::EndAnim_Pain(Event *ev)
{
animdone_Pain = true;
}
@@ -166,15 +167,173 @@ int Player::CurrentPartAnim(bodypart_t part) const
void Player::AdjustAnimBlends(void)
{
int iPartSlot;
int iOldPartSlot;
float fWeightTotal;
int iPartSlot;
int iOldPartSlot;
float fWeightTotal;
qboolean playTurretAnim = false;
if (movetype == MOVETYPE_PORTABLE_TURRET) {
PortableTurret *turret = static_cast<PortableTurret *>(m_pTurret.Pointer());
if (turret->IsReloading()) {
if (partAnim[legs] != "mg42tripod_reload") {
SetPartAnim("mg42tripod_reload", legs);
StopAnimating(m_iPartSlot[torso]);
StopAnimating(m_iPartSlot[torso] ^ 1);
partAnim[torso] = "";
}
} else if (turret->IsSettingUp()) {
if (partAnim[legs] != "mg42tripod_setup") {
SetPartAnim("mg42tripod_setup", legs);
StopAnimating(m_iPartSlot[torso]);
StopAnimating(m_iPartSlot[torso] ^ 1);
partAnim[torso] = "";
}
} else if (turret->IsPackingUp()) {
if (partAnim[legs] != "mg42tripod_packup") {
SetPartAnim("mg42tripod_packup", legs);
StopAnimating(m_iPartSlot[torso]);
StopAnimating(m_iPartSlot[torso] ^ 1);
partAnim[torso] = "";
}
} else {
playTurretAnim = true;
}
}
if (playTurretAnim) {
PortableTurret *turret = static_cast<PortableTurret *>(m_pTurret.Pointer());
if (partAnim[legs] != "mg42tripod_aim") {
StopPartAnimating(legs);
}
if (partAnim[torso] != "mg42tripod_aim") {
StopPartAnimating(torso);
}
partAnim[legs] = "mg42tripod_aim";
partAnim[torso] = "mg42tripod_aim";
float pitch, yaw;
float legsPitchAngle, torsoPitchAngle;
float pitchAlpha, yawAlpha;
float legsYawAngle, torsoYawAngle;
float weight;
int animNum;
str vertLegsStr, vertTorsoStr;
str horzLegsStr, horzTorsoStr;
str anim;
pitch = AngleSubtract(turret->GetGroundPitch(), turret->angles[0]);
yaw = AngleSubtract(turret->GetStartYaw(), turret->angles[1]);
if (pitch >= 0) {
legsPitchAngle = 0.0;
torsoPitchAngle = 15.0;
vertLegsStr = "_straight";
vertTorsoStr = "_up15";
} else {
legsPitchAngle = -15.0;
torsoPitchAngle = 0.0;
vertLegsStr = "_down15";
vertTorsoStr = "_straight";
}
pitchAlpha = (pitch - legsPitchAngle) / (torsoPitchAngle - legsPitchAngle);
pitchAlpha = Q_clamp_float(pitchAlpha, 0, 1);
if (yaw < -20) {
legsYawAngle = -40.0;
torsoYawAngle = -20.0;
horzLegsStr = "_left40";
horzTorsoStr = "_left20";
} else if (yaw < 0) {
legsYawAngle = -20.0;
torsoYawAngle = 0.0;
horzLegsStr = "_left20";
horzTorsoStr = "_straight";
} else if (yaw <= 20) {
legsYawAngle = 0.0;
torsoYawAngle = 20.0;
horzLegsStr = "_straight";
horzTorsoStr = "_right20";
} else {
legsYawAngle = 20.0;
torsoYawAngle = 40.0;
horzLegsStr = "_right20";
horzTorsoStr = "_right40";
}
yawAlpha = (yaw - legsYawAngle) / (torsoYawAngle - legsYawAngle);
yawAlpha = Q_clamp_float(yawAlpha, 0, 1);
anim = "mg42tripod_aim" + horzLegsStr + vertLegsStr;
weight = (1 - pitchAlpha) * (1 - yawAlpha);
animNum = gi.Anim_NumForName(edict->tiki, anim.c_str());
if (animNum == -1) {
gi.DPrintf("^~^~^ Warning: Can't find player animation '%s'.\n", anim.c_str());
anim = "mg42tripod_aim_straight_straight";
animNum = gi.Anim_NumForName(edict->tiki, anim.c_str());
}
if (animNum == CurrentAnim(0)) {
SetWeight(0, weight);
} else {
NewAnim(animNum, 0, weight);
}
anim = "mg42tripod_aim" + horzLegsStr + vertTorsoStr;
weight = (1.0 - yawAlpha) * pitchAlpha;
animNum = gi.Anim_NumForName(edict->tiki, anim.c_str());
if (animNum == -1) {
gi.DPrintf("^~^~^ Warning: Can't find player animation '%s'.\n", anim.c_str());
anim = "mg42tripod_aim_straight_straight";
animNum = gi.Anim_NumForName(edict->tiki, anim.c_str());
}
if (animNum == CurrentAnim(1)) {
SetWeight(1, weight);
} else {
NewAnim(animNum, 1, weight);
}
anim = "mg42tripod_aim" + horzTorsoStr + vertTorsoStr;
weight = pitchAlpha * yawAlpha;
animNum = gi.Anim_NumForName(edict->tiki, anim.c_str());
if (animNum == -1) {
gi.DPrintf("^~^~^ Warning: Can't find player animation '%s'.\n", anim.c_str());
anim = "mg42tripod_aim_straight_straight";
animNum = gi.Anim_NumForName(edict->tiki, anim.c_str());
}
if (animNum == CurrentAnim(2)) {
SetWeight(2, weight);
} else {
NewAnim(animNum, 2, weight);
}
anim = "mg42tripod_aim" + horzTorsoStr + vertTorsoStr;
weight = (1.0 - pitchAlpha) * yawAlpha;
animNum = gi.Anim_NumForName(edict->tiki, anim.c_str());
if (animNum == -1) {
gi.DPrintf("^~^~^ Warning: Can't find player animation '%s'.\n", anim.c_str());
anim = "mg42tripod_aim_straight_straight";
animNum = gi.Anim_NumForName(edict->tiki, anim.c_str());
}
if (animNum == CurrentAnim(3)) {
SetWeight(3, weight);
} else {
NewAnim(animNum, 3, weight);
}
}
if (deadflag == DEAD_DEAD) {
if (m_fPainBlend) {
StopAnimating(ANIMSLOT_PAIN);
edict->s.frameInfo[ANIMSLOT_PAIN].weight = 0;
m_fPainBlend = 0;
SetWeight(ANIMSLOT_PAIN, 0);
m_fPainBlend = 0;
animdone_Pain = false;
}
return;
@@ -184,44 +343,56 @@ void Player::AdjustAnimBlends(void)
iOldPartSlot = m_iPartSlot[legs] ^ 1;
if (m_fPartBlends[legs] <= 0.0f) {
if (partOldAnim[legs] == "") {
goto __blend_torso;
}
if (partOldAnim[legs] != "") {
StopAnimating(iOldPartSlot);
StopAnimating(iOldPartSlot);
if (partAnim[legs] == "") {
SetWeight(iPartSlot, 0.0);
} else {
SetWeight(iPartSlot, 1.0);
}
} else {
if (partAnim[legs] == "") {
SetWeight(iPartSlot, 0.0);
} else {
SetWeight(iPartSlot, 1.0);
}
}
} else {
m_fPartBlends[legs] = m_fPartBlends[legs] - level.frametime * partBlendMult[legs];
m_fPartBlends[legs] -= level.frametime * partBlendMult[legs];
if (m_fPartBlends[legs] >= 0.01f) {
if (partOldAnim[legs] != "") {
edict->s.frameInfo[iOldPartSlot].weight = m_fPartBlends[legs];
SetWeight(iOldPartSlot, m_fPartBlends[legs]);
}
if (partAnim[legs] != "") {
edict->s.frameInfo[iPartSlot].weight = 1.0f - m_fPartBlends[legs];
SetWeight(iPartSlot, 1.0f - m_fPartBlends[legs]);
}
} else {
m_fPartBlends[legs] = 0.0f;
StopAnimating(iOldPartSlot);
partOldAnim[legs] = "";
goto __blend_torso;
if (partAnim[legs] == "") {
SetWeight(iPartSlot, 0.0);
} else {
SetWeight(iPartSlot, 1.0);
}
}
m_fPartBlends[legs] = 0.0f;
StopAnimating(iOldPartSlot);
partOldAnim[legs] = "";
}
if (partAnim[legs] != "") {
edict->s.frameInfo[iPartSlot].weight = 1.0f;
} else {
edict->s.frameInfo[iPartSlot].weight = 0.0f;
}
__blend_torso:
iPartSlot = m_iPartSlot[torso];
iOldPartSlot = m_iPartSlot[torso] ^ 1;
if (m_fPartBlends[torso] <= 0.0f) {
if (partOldAnim[torso] != "") {
StopAnimating(iOldPartSlot);
partOldAnim[torso] = "";
if (partAnim[torso] == "") {
SetWeight(iPartSlot, 0.0);
} else {
SetWeight(iPartSlot, 1.0);
}
}
} else {
m_fPartBlends[torso] = m_fPartBlends[torso] - level.frametime * partBlendMult[torso];
@@ -229,11 +400,11 @@ __blend_torso:
fWeightTotal = 0.0f;
if (partOldAnim[torso] != "") {
edict->s.frameInfo[iOldPartSlot].weight = m_fPartBlends[torso];
SetWeight(iOldPartSlot, m_fPartBlends[torso]);
fWeightTotal += m_fPartBlends[torso];
}
if (partAnim[torso] != "") {
edict->s.frameInfo[iPartSlot].weight = 1.0f - m_fPartBlends[torso];
SetWeight(iPartSlot, m_fPartBlends[torso]);
fWeightTotal += 1.0f - m_fPartBlends[torso];
}
@@ -241,9 +412,15 @@ __blend_torso:
} else {
m_fPartBlends[torso] = 0.0f;
StopAnimating(iOldPartSlot);
partOldAnim[torso] = "";
edict->s.frameInfo[iPartSlot].weight = partAnim[torso] != "" ? 1.0f : 0.0f;
edict->s.actionWeight = partAnim[torso] != "" ? 1.0f : 0.0f;
partOldAnim[torso] = "";
if (partAnim[torso] == "") {
SetWeight(iPartSlot, 0.0);
edict->s.actionWeight = 0.0;
} else {
SetWeight(iPartSlot, 1.0);
edict->s.actionWeight = 1.0;
}
}
}
@@ -251,24 +428,24 @@ __blend_torso:
if (m_sPainAnim == "") {
StopAnimating(ANIMSLOT_PAIN);
edict->s.frameInfo[ANIMSLOT_PAIN].weight = 0;
m_fPainBlend = 0;
animdone_Pain = false;
m_fPainBlend = 0;
animdone_Pain = false;
} else if (animdone_Pain) {
m_fPainBlend -= level.frametime * (10.0 / 3.0);
if (m_fPainBlend < 0.01f) {
StopAnimating(ANIMSLOT_PAIN);
edict->s.frameInfo[ANIMSLOT_PAIN].weight = 0;
m_fPainBlend = 0;
animdone_Pain = false;
m_fPainBlend = 0;
animdone_Pain = false;
}
}
if (m_fPainBlend) {
int i;
int i;
float w;
edict->s.frameInfo[ANIMSLOT_PAIN].weight = m_fPainBlend;
w = 1.0 - m_fPainBlend * 0.5;
w = 1.0 - m_fPainBlend * 0.5;
for (i = 0; i < ANIMSLOT_PAIN; i++) {
if (edict->s.frameInfo[i].weight) {
@@ -336,7 +513,7 @@ void Player::PlayerAnimDelta(float *vDelta)
}
}
void Player::EventTestAnim(Event* ev)
void Player::EventTestAnim(Event *ev)
{
// FIXME: unimplemented
}
+52 -71
View File
@@ -21,79 +21,61 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// player_combat.cpp: Player combat system and combat utility functions
//
//
#include "player.h"
#include "weaputils.h"
static Entity *FindClosestEntityInRadius
(
Vector origin,
Vector forward,
float fov,
float maxdist
)
static Entity *FindClosestEntityInRadius(Vector origin, Vector forward, float fov, float maxdist)
{
float dist, dot;
float fovdot = cos(fov * 0.5 * M_PI / 180.0);
Entity *ent;
Entity *bestent = NULL;
int bestdist = 999999;
qboolean valid_entity;
{
float dist,dot;
float fovdot = cos( fov * 0.5 * M_PI / 180.0 );
Entity *ent;
Entity *bestent=NULL;
int bestdist = 999999;
qboolean valid_entity;
// Find closest enemy in radius
ent = findradius(NULL, origin, maxdist);
// Find closest enemy in radius
ent = findradius( NULL, origin, maxdist );
while (ent) {
valid_entity = false;
while( ent )
{
valid_entity = false;
if (ent->flags & FL_AUTOAIM) {
valid_entity = true;
}
if( ent->flags & FL_AUTOAIM )
{
valid_entity = true;
}
if (valid_entity) {
// Check to see if the enemy is closest to us
Vector delta = (ent->centroid) - origin;
if ( valid_entity )
{
// Check to see if the enemy is closest to us
Vector delta = ( ent->centroid ) - origin;
dist = delta.length();
dist = delta.length();
if (dist < bestdist) {
delta.normalize();
if ( dist < bestdist )
{
delta.normalize();
// It's close, now check to see if it's in our FOV.
dot = DotProduct(forward, delta);
// It's close, now check to see if it's in our FOV.
dot = DotProduct( forward, delta );
if ( dot > fovdot )
{
trace_t trace;
// Do a trace to see if we can get to it
trace = G_Trace( origin,
vec_zero,
vec_zero,
ent->centroid,
NULL,
MASK_OPAQUE,
false,
"FindClosestEntityInRadius" );
if ( ( trace.ent && trace.entityNum == ent->entnum ) || ( trace.fraction == 1 ) )
{
// dir = delta;
bestent = ent;
bestdist = dist;
}
}
if (dot > fovdot) {
trace_t trace;
// Do a trace to see if we can get to it
trace = G_Trace(
origin, vec_zero, vec_zero, ent->centroid, NULL, MASK_OPAQUE, false, "FindClosestEntityInRadius"
);
if ((trace.ent && trace.entityNum == ent->entnum) || (trace.fraction == 1)) {
// dir = delta;
bestent = ent;
bestdist = dist;
}
}
}
}
ent = findradius( ent, origin, maxdist );
}
return bestent;
}
}
ent = findradius(ent, origin, maxdist);
}
return bestent;
}
Vector Player::GunTarget(bool bNoCollision, const vec3_t position, const vec3_t forward)
{
@@ -181,7 +163,7 @@ void Player::EventCorrectWeaponAttachments(Event *ev)
iTagLeft = gi.Tag_NumForName(edict->tiki, "tag_weapon_left");
iNumChildren = numchildren;
for (int i = 0; i < iNumChildren; i++) {
for (int i = 0; i < MAX_MODEL_CHILDREN && iNumChildren; i++) {
iChild = children[i];
if (iChild == ENTITYNUM_NONE) {
@@ -194,18 +176,17 @@ void Player::EventCorrectWeaponAttachments(Event *ev)
}
if (pChild->edict->s.tag_num == iTagLeft || pChild->edict->s.tag_num == iTagRight) {
if (pChild->IsSubclassOfWeapon()) {
if (pChild->edict->s.tag_num == iTagLeft) {
iUseAngles = edict->s.attach_use_angles;
vOffset = edict->s.attach_offset;
// reattach to the right tag
detach();
attach(entnum, iTagRight, iUseAngles, vOffset);
}
} else {
if (!pChild->IsSubclassOfWeapon()) {
// Remove entities like ammoclip
pChild->PostEvent(EV_Remove, 0);
iNumChildren--;
} else if (pChild->edict->s.tag_num == iTagLeft) {
iUseAngles = pChild->edict->s.attach_use_angles;
vOffset = pChild->edict->s.attach_offset;
// reattach to the right tag
pChild->detach();
pChild->attach(entnum, iTagRight, iUseAngles, vOffset);
}
}
}
+3 -1
View File
@@ -403,7 +403,7 @@ qboolean Player::CondAbleToDefuse(Conditional& condition)
}
Vector vForward, vRight, vUp;
AngleVectors(m_vViewPos, vForward, vRight, vUp);
AngleVectors(m_vViewAng, vForward, vRight, vUp);
maxrange = weapon->GetMaxRange();
@@ -570,6 +570,8 @@ qboolean Player::CondMinChargeTime(Conditional& condition)
if (hand != WEAPON_ERROR) {
weap = GetActiveWeapon(hand);
// Fixed in 2.0.
// Make sure the active weapon is valid
if (weap) {
float charge_time = weap->GetMinChargeTime(FIRE_PRIMARY);
if (charge_time) {
+1 -1
View File
@@ -95,7 +95,7 @@ void Player::WhatIs(Event *ev)
animname = NULL;
if (gi.modeltiki(ent->model)) {
animname = gi.Anim_NameForNum(ent->edict->tiki, ent->edict->s.frameInfo[0].index & ANIM_MASK);
animname = gi.Anim_NameForNum(ent->edict->tiki, ent->edict->s.frameInfo[0].index);
}
if (!animname) {
+1 -1
View File
@@ -44,7 +44,7 @@ PlayerBot::botfunc_t PlayerBot::botfuncs[MAX_BOT_FUNCTIONS];
PlayerBot::PlayerBot()
{
entflags |= EF_BOT;
entflags |= ECF_BOT;
if (LoadingSavegame) {
return;
+41 -26
View File
@@ -403,7 +403,7 @@ const char *ScriptMaster::ConstStrings[] = {
"both",
"runandshoot",
//
// Openmohaa additions
// Added in OPM
//
"respawn",
"viewmodelanim_done"
@@ -925,44 +925,59 @@ void ScriptMaster::ArchiveString(Archiver& arc, const_str& s)
void ScriptMaster::Archive(Archiver& arc)
{
ScriptClass *scr;
ScriptVM *m_current;
ScriptThread *m_thread;
int numClasses;
int numThreads;
int i, j;
int count;
int i, j;
ScriptClass *c;
int num;
ScriptVM *scriptVM;
ScriptVM *prevScriptVM;
if (arc.Saving()) {
numClasses = (int)ScriptClass_allocator.Count();
arc.ArchiveInteger(&numClasses);
count = (int)ScriptClass_allocator.Count();
arc.ArchiveInteger(&count);
MEM_BlockAlloc_enum<ScriptClass> en = ScriptClass_allocator;
for (scr = en.NextElement(); scr != NULL; scr = en.NextElement()) {
scr->ArchiveInternal(arc);
for (c = en.NextElement(); c != NULL; c = en.NextElement()) {
c->ArchiveInternal(arc);
numThreads = 0;
for (m_current = scr->m_Threads; m_current != NULL; m_current = m_current->next) {
numThreads++;
num = 0;
for (scriptVM = c->m_Threads; scriptVM != NULL; scriptVM = scriptVM->next) {
num++;
}
arc.ArchiveInteger(&numThreads);
arc.ArchiveInteger(&num);
for (m_current = scr->m_Threads; m_current != NULL; m_current = m_current->next) {
m_current->m_Thread->ArchiveInternal(arc);
for (scriptVM = c->m_Threads; scriptVM != NULL; scriptVM = scriptVM->next) {
scriptVM->m_Thread->ArchiveInternal(arc);
}
}
} else {
arc.ArchiveInteger(&numClasses);
arc.ArchiveInteger(&count);
for (i = 0; i < numClasses; i++) {
scr = new ScriptClass();
scr->ArchiveInternal(arc);
for (i = 0; i < count; i++) {
c = new ScriptClass();
c->ArchiveInternal(arc);
arc.ArchiveInteger(&numThreads);
arc.ArchiveInteger(&num);
for (j = 0; j < numThreads; j++) {
m_thread = new ScriptThread(scr, NULL);
m_thread->ArchiveInternal(arc);
c->m_Threads = NULL;
prevScriptVM = NULL;
for (j = 0; j < num; j++) {
scriptVM = new ScriptVM;
scriptVM->m_Thread = new ScriptThread;
scriptVM->m_Thread->m_ScriptVM = scriptVM;
scriptVM->m_ScriptClass = c;
scriptVM->next = NULL;
if (prevScriptVM) {
prevScriptVM->next = scriptVM;
} else {
c->m_Threads = scriptVM;
}
prevScriptVM = scriptVM;
scriptVM->m_Thread->ArchiveInternal(arc);
}
}
}
@@ -1184,7 +1199,7 @@ void ScriptMaster::PrintThread(int iThreadNum)
int i = 0;
for (entry = en.NextElement(); entry != NULL; entry = en.NextElement()) {
str& name = Director.GetString(entry->key);
str& name = Director.GetString(entry->GetKey());
if (i > 0) {
status += ", ";
+107 -75
View File
@@ -465,6 +465,15 @@ Event EV_ScriptSlave_FollowPath
"normalangles, loop, and a number specifying the start time.",
EV_NORMAL
);
Event EV_ScriptSlave_FollowPath_RelativeYaw
(
"path_relativeyaw",
EV_DEFAULT,
"f",
"relativeYaw",
"Makes the script slave follow the specified path with a yaw offset,",
EV_NORMAL
);
Event EV_ScriptSlave_EndPath
(
"endpath",
@@ -584,72 +593,83 @@ Event EV_ScriptSlave_ModifyFlyPath
EV_NORMAL
);
CLASS_DECLARATION(Mover, ScriptSlave, "script_object") {
{&EV_Bind, &ScriptSlave::BindEvent },
{&EV_Unbind, &ScriptSlave::EventUnbind },
{&EV_ScriptSlave_DoMove, &ScriptSlave::DoMove },
{&EV_ScriptSlave_WaitMove, &ScriptSlave::WaitMove },
{&EV_ScriptSlave_Angles, &ScriptSlave::SetAnglesEvent },
{&EV_SetAngle, &ScriptSlave::SetAngleEvent },
{&EV_Model, &ScriptSlave::SetModelEvent },
{&EV_ScriptSlave_Trigger, &ScriptSlave::TriggerEvent },
{&EV_ScriptSlave_Next, &ScriptSlave::GotoNextWaypoint },
{&EV_ScriptSlave_JumpTo, &ScriptSlave::JumpTo },
{&EV_ScriptSlave_MoveTo, &ScriptSlave::MoveToEvent },
{&EV_ScriptSlave_Speed, &ScriptSlave::SetSpeed },
{&EV_ScriptSlave_Time, &ScriptSlave::SetTime },
{&EV_ScriptSlave_MoveUp, &ScriptSlave::MoveUp },
{&EV_ScriptSlave_MoveDown, &ScriptSlave::MoveDown },
{&EV_ScriptSlave_MoveNorth, &ScriptSlave::MoveNorth },
{&EV_ScriptSlave_MoveSouth, &ScriptSlave::MoveSouth },
{&EV_ScriptSlave_MoveEast, &ScriptSlave::MoveEast },
{&EV_ScriptSlave_MoveWest, &ScriptSlave::MoveWest },
{&EV_ScriptSlave_MoveForward, &ScriptSlave::MoveForward },
{&EV_ScriptSlave_MoveBackward, &ScriptSlave::MoveBackward },
{&EV_ScriptSlave_MoveLeft, &ScriptSlave::MoveLeft },
{&EV_ScriptSlave_MoveRight, &ScriptSlave::MoveRight },
{&EV_ScriptSlave_RotateXDownTo, &ScriptSlave::RotateXdownto },
{&EV_ScriptSlave_RotateYDownTo, &ScriptSlave::RotateYdownto },
{&EV_ScriptSlave_RotateZDownTo, &ScriptSlave::RotateZdownto },
{&EV_ScriptSlave_RotateXUpTo, &ScriptSlave::RotateXupto },
{&EV_ScriptSlave_RotateYUpTo, &ScriptSlave::RotateYupto },
{&EV_ScriptSlave_RotateZUpTo, &ScriptSlave::RotateZupto },
{&EV_ScriptSlave_RotateXDown, &ScriptSlave::RotateXdown },
{&EV_ScriptSlave_RotateYDown, &ScriptSlave::RotateYdown },
{&EV_ScriptSlave_RotateZDown, &ScriptSlave::RotateZdown },
{&EV_ScriptSlave_RotateXUp, &ScriptSlave::RotateXup },
{&EV_ScriptSlave_RotateYUp, &ScriptSlave::RotateYup },
{&EV_ScriptSlave_RotateZUp, &ScriptSlave::RotateZup },
{&EV_ScriptSlave_RotateX, &ScriptSlave::RotateX },
{&EV_ScriptSlave_RotateY, &ScriptSlave::RotateY },
{&EV_ScriptSlave_RotateZ, &ScriptSlave::RotateZ },
{&EV_ScriptSlave_RotateAxisDownTo, &ScriptSlave::RotateAxisdownto },
{&EV_ScriptSlave_RotateAxisUpTo, &ScriptSlave::RotateAxisupto },
{&EV_ScriptSlave_RotateAxisDown, &ScriptSlave::RotateAxisdown },
{&EV_ScriptSlave_RotateAxisUp, &ScriptSlave::RotateAxisup },
{&EV_ScriptSlave_RotateAxis, &ScriptSlave::RotateZ },
{&EV_ScriptSlave_SetDamage, &ScriptSlave::SetDamage },
{&EV_ScriptSlave_SetMeansOfDeath, &ScriptSlave::SetMeansOfDeath },
{&EV_ScriptSlave_SetDamageSpawn, &ScriptSlave::SetDamage },
{&EV_ScriptSlave_FollowPath, &ScriptSlave::FollowPath },
{&EV_ScriptSlave_EndPath, &ScriptSlave::EndPath },
{&EV_ScriptSlave_FollowingPath, &ScriptSlave::FollowingPath },
{&EV_ScriptSlave_MoveDone, &ScriptSlave::MoveEnd },
{&EV_Damage, &ScriptSlave::DamageFunc },
{&EV_ScriptSlave_RotateDownTo, &ScriptSlave::Rotatedownto },
{&EV_ScriptSlave_RotateUpTo, &ScriptSlave::Rotateupto },
{&EV_ScriptSlave_RotateTo, &ScriptSlave::Rotateto },
{&EV_ScriptSlave_Explode, &ScriptSlave::Explode },
{&EV_ScriptSlave_NotShootable, &ScriptSlave::NotShootable },
{&EV_ScriptSlave_OpenAreaPortal, &ScriptSlave::OpenPortal },
{&EV_ScriptSlave_CloseAreaPortal, &ScriptSlave::ClosePortal },
{&EV_ScriptSlave_PhysicsOn, &ScriptSlave::PhysicsOn },
{&EV_ScriptSlave_PhysicsOff, &ScriptSlave::PhysicsOff },
{&EV_ScriptSlave_PhysicsVelocity, &ScriptSlave::PhysicsVelocity },
{&EV_ScriptSlave_FlyPath, &ScriptSlave::EventFlyPath },
{&EV_ScriptSlave_ModifyFlyPath, &ScriptSlave::EventModifyFlyPath},
Event EV_ScriptSlave_NormalAngles
(
"normalangles",
EV_DEFAULT,
"b",
"bUseNormalAngles",
"Sets the object to use normal angles when travelling on a spline path",
EV_NORMAL
);
{NULL, NULL }
CLASS_DECLARATION(Mover, ScriptSlave, "script_object") {
{&EV_Bind, &ScriptSlave::BindEvent },
{&EV_Unbind, &ScriptSlave::EventUnbind },
{&EV_ScriptSlave_DoMove, &ScriptSlave::DoMove },
{&EV_ScriptSlave_WaitMove, &ScriptSlave::WaitMove },
{&EV_ScriptSlave_Angles, &ScriptSlave::SetAnglesEvent },
{&EV_SetAngle, &ScriptSlave::SetAngleEvent },
{&EV_Model, &ScriptSlave::SetModelEvent },
{&EV_ScriptSlave_Trigger, &ScriptSlave::TriggerEvent },
{&EV_ScriptSlave_Next, &ScriptSlave::GotoNextWaypoint },
{&EV_ScriptSlave_JumpTo, &ScriptSlave::JumpTo },
{&EV_ScriptSlave_MoveTo, &ScriptSlave::MoveToEvent },
{&EV_ScriptSlave_Speed, &ScriptSlave::SetSpeed },
{&EV_ScriptSlave_Time, &ScriptSlave::SetTime },
{&EV_ScriptSlave_MoveUp, &ScriptSlave::MoveUp },
{&EV_ScriptSlave_MoveDown, &ScriptSlave::MoveDown },
{&EV_ScriptSlave_MoveNorth, &ScriptSlave::MoveNorth },
{&EV_ScriptSlave_MoveSouth, &ScriptSlave::MoveSouth },
{&EV_ScriptSlave_MoveEast, &ScriptSlave::MoveEast },
{&EV_ScriptSlave_MoveWest, &ScriptSlave::MoveWest },
{&EV_ScriptSlave_MoveForward, &ScriptSlave::MoveForward },
{&EV_ScriptSlave_MoveBackward, &ScriptSlave::MoveBackward },
{&EV_ScriptSlave_MoveLeft, &ScriptSlave::MoveLeft },
{&EV_ScriptSlave_MoveRight, &ScriptSlave::MoveRight },
{&EV_ScriptSlave_RotateXDownTo, &ScriptSlave::RotateXdownto },
{&EV_ScriptSlave_RotateYDownTo, &ScriptSlave::RotateYdownto },
{&EV_ScriptSlave_RotateZDownTo, &ScriptSlave::RotateZdownto },
{&EV_ScriptSlave_RotateXUpTo, &ScriptSlave::RotateXupto },
{&EV_ScriptSlave_RotateYUpTo, &ScriptSlave::RotateYupto },
{&EV_ScriptSlave_RotateZUpTo, &ScriptSlave::RotateZupto },
{&EV_ScriptSlave_RotateXDown, &ScriptSlave::RotateXdown },
{&EV_ScriptSlave_RotateYDown, &ScriptSlave::RotateYdown },
{&EV_ScriptSlave_RotateZDown, &ScriptSlave::RotateZdown },
{&EV_ScriptSlave_RotateXUp, &ScriptSlave::RotateXup },
{&EV_ScriptSlave_RotateYUp, &ScriptSlave::RotateYup },
{&EV_ScriptSlave_RotateZUp, &ScriptSlave::RotateZup },
{&EV_ScriptSlave_RotateX, &ScriptSlave::RotateX },
{&EV_ScriptSlave_RotateY, &ScriptSlave::RotateY },
{&EV_ScriptSlave_RotateZ, &ScriptSlave::RotateZ },
{&EV_ScriptSlave_RotateAxisDownTo, &ScriptSlave::RotateAxisdownto },
{&EV_ScriptSlave_RotateAxisUpTo, &ScriptSlave::RotateAxisupto },
{&EV_ScriptSlave_RotateAxisDown, &ScriptSlave::RotateAxisdown },
{&EV_ScriptSlave_RotateAxisUp, &ScriptSlave::RotateAxisup },
{&EV_ScriptSlave_RotateAxis, &ScriptSlave::RotateZ },
{&EV_ScriptSlave_SetDamage, &ScriptSlave::SetDamage },
{&EV_ScriptSlave_SetMeansOfDeath, &ScriptSlave::SetMeansOfDeath },
{&EV_ScriptSlave_SetDamageSpawn, &ScriptSlave::SetDamage },
{&EV_ScriptSlave_FollowPath, &ScriptSlave::FollowPath },
{&EV_ScriptSlave_FollowPath_RelativeYaw, &ScriptSlave::FollowPathRelativeYaw},
{&EV_ScriptSlave_EndPath, &ScriptSlave::EndPath },
{&EV_ScriptSlave_FollowingPath, &ScriptSlave::FollowingPath },
{&EV_ScriptSlave_MoveDone, &ScriptSlave::MoveEnd },
{&EV_Damage, &ScriptSlave::DamageFunc },
{&EV_ScriptSlave_RotateDownTo, &ScriptSlave::Rotatedownto },
{&EV_ScriptSlave_RotateUpTo, &ScriptSlave::Rotateupto },
{&EV_ScriptSlave_RotateTo, &ScriptSlave::Rotateto },
{&EV_ScriptSlave_Explode, &ScriptSlave::Explode },
{&EV_ScriptSlave_NotShootable, &ScriptSlave::NotShootable },
{&EV_ScriptSlave_OpenAreaPortal, &ScriptSlave::OpenPortal },
{&EV_ScriptSlave_CloseAreaPortal, &ScriptSlave::ClosePortal },
{&EV_ScriptSlave_PhysicsOn, &ScriptSlave::PhysicsOn },
{&EV_ScriptSlave_PhysicsOff, &ScriptSlave::PhysicsOff },
{&EV_ScriptSlave_PhysicsVelocity, &ScriptSlave::PhysicsVelocity },
{&EV_ScriptSlave_FlyPath, &ScriptSlave::EventFlyPath },
{&EV_ScriptSlave_ModifyFlyPath, &ScriptSlave::EventModifyFlyPath },
{&EV_ScriptSlave_NormalAngles, &ScriptSlave::EventNormalAngles },
{NULL, NULL }
};
cvar_t *g_showflypath;
@@ -689,16 +709,17 @@ ScriptSlave::ScriptSlave()
edict->s.renderfx = RF_ALWAYSDRAW;
}
splinePath = NULL;
m_pCurPath = NULL;
m_iCurNode = 0;
m_fLookAhead = 0;
m_fCurSpeed = 0;
m_fIdealSpeed = 0;
m_fIdealAccel = 0;
m_fIdealDistance = 100;
splineangles = false;
attack_finished = 0;
splinePath = NULL;
m_pCurPath = NULL;
m_iCurNode = 0;
m_fLookAhead = 0;
m_fCurSpeed = 0;
m_fIdealSpeed = 0;
m_fIdealAccel = 0;
m_fIdealDistance = 100;
splineangles = false;
m_fFollowRelativeYaw = 0;
attack_finished = 0;
setSolidType(SOLID_NOT);
@@ -1367,6 +1388,11 @@ void ScriptSlave::FollowPath(Event *ev)
}
}
void ScriptSlave::FollowPathRelativeYaw(Event *ev)
{
m_fFollowRelativeYaw = ev->GetFloat(1);
}
void ScriptSlave::EndPath(Event *ev)
{
if (!splinePath) {
@@ -1723,6 +1749,12 @@ void ScriptSlave::EventModifyFlyPath(Event *ev)
}
}
void ScriptSlave::EventNormalAngles(Event *ev)
{
splineangles = !ev->GetBoolean(1);
ignoreangles = false;
}
void ScriptSlave::SetupPath(cSpline<4, 512> *pPath, SimpleEntity *se)
{
str name;
+13
View File
@@ -77,6 +77,7 @@ public:
qboolean splineangles;
qboolean ignoreangles;
qboolean ignorevelocity;
float m_fFollowRelativeYaw;
qboolean moving; // is the script object currently moving?
protected:
@@ -138,6 +139,7 @@ protected:
void SetDamage(Event *ev);
void SetMeansOfDeath(Event *ev);
void FollowPath(Event *ev);
void FollowPathRelativeYaw(Event *ev); // Added in 2.0
void EndPath(Event *ev);
void FollowingPath(Event *ev);
void CreatePath(SplinePath *path, splinetype_t type);
@@ -151,6 +153,7 @@ protected:
void DamageFunc(Event *ev);
void EventFlyPath(Event *ev);
void EventModifyFlyPath(Event *ev);
void EventNormalAngles(Event *ev); // Added in 2.0
void SetupPath(cSpline<4, 512> *pPath, SimpleEntity *se);
void Archive(Archiver& arc) override;
@@ -220,6 +223,16 @@ inline void ScriptSlave::Archive(Archiver& arc)
m_pCurPath = NULL;
}
}
arc.ArchiveInteger(&m_iCurNode);
arc.ArchiveFloat(&m_fCurSpeed);
arc.ArchiveFloat(&m_fIdealSpeed);
arc.ArchiveVector(&m_vIdealPosition);
arc.ArchiveVector(&m_vIdealDir);
arc.ArchiveFloat(&m_fIdealAccel);
arc.ArchiveFloat(&m_fIdealDistance);
arc.ArchiveFloat(&m_fLookAhead);
arc.ArchiveFloat(&m_fFollowRelativeYaw);
}
class ScriptModel : public ScriptSlave
+14 -7
View File
@@ -841,7 +841,7 @@ Event EV_ScriptThread_PlayMovie // Added in 2.0
(
"PlayMovie",
EV_DEFAULT,
"sI",
"s",
"name",
"Play a Movie..."
);
@@ -1173,7 +1173,7 @@ Event EV_ScriptThread_RegisterCommand
);
//
// Openmohaa additions
// Added in OPM
//
Event EV_ScriptThread_CancelWaiting
(
@@ -3576,13 +3576,20 @@ void ScriptThread::Angles_PointAt(Event *ev)
void ScriptThread::EventIsAlive(Event *ev)
{
Entity *ent = ev->GetEntity(1);
Entity* ent;
if (ent) {
ev->AddInteger(!ent->IsDead());
} else {
ev->AddInteger(0);
if (!ev->IsEntityAt(1)) {
ev->AddInteger(false);
return;
}
ent = ev->GetEntity(1);
if (!ent) {
ev->AddInteger(false);
return;
}
ev->AddInteger(ent->health > 0);
}
void ScriptThread::EventPopmenu(Event *ev)
+8 -3
View File
@@ -567,7 +567,7 @@ Event EV_Sentient_GetForceDropWeapon
);
//
// Openmohaa additions
// Added in OPM
//
Event EV_Sentient_GetNewActiveWeap
(
@@ -693,7 +693,7 @@ Sentient::Sentient()
: m_bIsAnimal(false)
{
SentientList.AddObject((Sentient *)this);
entflags |= EF_SENTIENT;
entflags |= ECF_SENTIENT;
m_bOvercookDied = false;
@@ -824,7 +824,7 @@ Sentient::~Sentient()
SentientList.RemoveObject((Sentient *)this);
FreeInventory();
entflags &= ~EF_SENTIENT;
entflags &= ~ECF_SENTIENT;
}
void Sentient::Link()
@@ -2128,6 +2128,11 @@ void Sentient::Archive(Archiver& arc)
Holster(true);
}
}
//
// Added in OPM
//
arc.ArchiveInteger(&iNextLandTime);
}
static bool IsItemName(const char *name)
+3
View File
@@ -219,6 +219,9 @@ public:
bool m_bFootOnGround_Right;
bool m_bFootOnGround_Left;
//
// Added in OPM
//
int iNextLandTime;
CLASS_PROTOTYPE(Sentient);
+58 -30
View File
@@ -214,7 +214,7 @@ void Sentient::WeaponKnockedFromHands(void)
bool Sentient::CanSee(Entity *ent, float fov, float vision_distance, bool bNoEnts)
{
vec2_t delta;
int mask;
int mask;
VectorSub2D(ent->centroid, centroid, delta);
@@ -237,16 +237,28 @@ bool Sentient::CanSee(Entity *ent, float fov, float vision_distance, bool bNoEnt
}
if (ent->IsSubclassOfSentient()) {
return G_SightTrace(EyePosition(), vec_zero, vec_zero, static_cast<Sentient*>(ent)->EyePosition(), this, ent, mask, qfalse, "Sentient::CanSee 1");
return G_SightTrace(
EyePosition(),
vec_zero,
vec_zero,
static_cast<Sentient *>(ent)->EyePosition(),
this,
ent,
mask,
qfalse,
"Sentient::CanSee 1"
);
} else {
return G_SightTrace(EyePosition(), vec_zero, vec_zero, ent->centroid, this, ent, mask, qfalse, "Sentient::CanSee 2");
return G_SightTrace(
EyePosition(), vec_zero, vec_zero, ent->centroid, this, ent, mask, qfalse, "Sentient::CanSee 2"
);
}
}
bool Sentient::CanSee(const Vector& org, float fov, float vision_distance, bool bNoEnts)
{
vec2_t delta;
int mask;
int mask;
VectorSub2D(org, centroid, delta);
@@ -323,7 +335,7 @@ void Sentient::ChargeWeapon(weaponhand_t hand, firemode_t mode)
return;
}
if (hand > MAX_ACTIVE_WEAPONS) {
if (hand >= MAX_ACTIVE_WEAPONS) {
warning(
"Sentient::ChargeWeapon",
"Weapon hand number \"%d\" is out of bounds of 0 to MAX_ACTIVE_WEAPONS:%d\n",
@@ -494,7 +506,7 @@ void Sentient::StopFireWeapon(Event *ev)
number = WeaponHandNameToNum(side);
}
if ((number > MAX_ACTIVE_WEAPONS) || (number < 0)) {
if ((number >= MAX_ACTIVE_WEAPONS) || (number < 0)) {
warning(
"Sentient::StopFireWeapon",
"Weapon number \"%d\" is out of bounds of 0 to MAX_ACTIVE_WEAPONS:%d\n",
@@ -521,7 +533,7 @@ void Sentient::ReleaseFireWeapon(int number, firemode_t mode)
charge_start_time = 0;
if ((number > MAX_ACTIVE_WEAPONS) || (number < 0)) {
if ((number >= MAX_ACTIVE_WEAPONS) || (number < 0)) {
warning(
"Sentient::FireWeapon",
"Weapon number \"%d\" is out of bounds of 0 to MAX_ACTIVE_WEAPONS:%d\n",
@@ -623,7 +635,7 @@ void Sentient::AttachAllActiveWeapons(void)
}
}
if (this->isSubclassOf(Player)) {
if (this->IsSubclassOfPlayer()) {
Player *player = (Player *)this;
player->UpdateWeapons();
}
@@ -664,7 +676,7 @@ int Sentient::NumWeapons(void)
void Sentient::ChangeWeapon(Weapon *weapon, weaponhand_t hand)
{
if ((hand > MAX_ACTIVE_WEAPONS) || (hand < 0)) {
if ((hand >= MAX_ACTIVE_WEAPONS) || (hand < 0)) {
warning(
"Sentient::ChangeWeapon",
"Weapon hand number \"%d\" is out of bounds of 0 to MAX_ACTIVE_WEAPONS:%d\n",
@@ -691,27 +703,33 @@ void Sentient::DeactivateWeapon(weaponhand_t hand)
return;
}
if (!(activeWeaponList[hand]->GetWeaponClass() & WEAPON_CLASS_ANY_ITEM)) {
// Set the last active weapon only if the weapon is not an item
lastActiveWeapon.weapon = activeWeaponList[hand];
lastActiveWeapon.hand = hand;
}
activeWeaponList[hand]->AttachToHolster(hand);
activeWeaponList[hand]->SetPutAway(false);
activeWeaponList[hand]->NewAnim("putaway");
activeWeaponList[hand]->SetWeaponAnim("putaway");
// Check the player's inventory and detach any weapons that are already attached to that spot
for (i = 1; i <= inventory.NumObjects(); i++) {
Item *item = (Item *)G_GetEntity(inventory.ObjectAt(i));
if (activeWeaponList[hand]->GetCurrentAttachToTag().length() > 0) {
for (i = 1; i <= inventory.NumObjects(); i++) {
Item *item = (Item *)G_GetEntity(inventory.ObjectAt(i));
if (item->IsSubclassOfWeapon()) {
Weapon *weap = (Weapon *)item;
if (item->IsSubclassOfWeapon()) {
Weapon *weap = (Weapon *)item;
if ((weap != activeWeaponList[hand])
&& (!str::cmp(weap->GetCurrentAttachToTag(), activeWeaponList[hand]->GetCurrentAttachToTag()))) {
weap->DetachFromOwner();
if ((weap != activeWeaponList[hand])
&& (!str::icmp(weap->GetCurrentAttachToTag(), activeWeaponList[hand]->GetCurrentAttachToTag()))) {
weap->DetachFromOwner();
}
}
}
}
lastActiveWeapon.weapon = activeWeaponList[hand];
lastActiveWeapon.hand = hand;
activeWeaponList[hand] = NULL;
activeWeaponList[hand] = NULL;
}
void Sentient::DeactivateWeapon(Weapon *weapon)
@@ -720,6 +738,12 @@ void Sentient::DeactivateWeapon(Weapon *weapon)
for (i = 0; i < MAX_ACTIVE_WEAPONS; i++) {
if (activeWeaponList[i] == weapon) {
if (activeWeaponList[i] && !(activeWeaponList[i]->GetWeaponClass() & WEAPON_CLASS_ANY_ITEM)) {
// Set the last active weapon only if the weapon is not an item
lastActiveWeapon.weapon = activeWeaponList[i];
lastActiveWeapon.hand = (weaponhand_t)i;
}
activeWeaponList[i]->DetachFromOwner();
activeWeaponList[i]->SetPutAway(false);
activeWeaponList[i] = NULL;
@@ -747,6 +771,7 @@ void Sentient::EventDeactivateWeapon(Event *ev)
void Sentient::ActivateWeapon(Weapon *weapon, weaponhand_t hand)
{
str holsterTag;
int i;
if (hand == WEAPON_ERROR) {
@@ -755,15 +780,18 @@ void Sentient::ActivateWeapon(Weapon *weapon, weaponhand_t hand)
}
activeWeaponList[hand] = weapon;
str holsterTag = weapon->GetHolsterTag();
if (str::cmp(holsterTag, "")) {
if (hand == WEAPON_MAIN) {
holsterTag = weapon->GetHolsterTag();
}
if (holsterTag.length() > 0) {
// Check the player's inventory and detach any weapons that are currently attached to that tag.
for (i = 1; i <= inventory.NumObjects(); i++) {
Item* item = (Item*)G_GetEntity(inventory.ObjectAt(i));
Item *item = (Item *)G_GetEntity(inventory.ObjectAt(i));
if (item->IsSubclassOfWeapon()) {
Weapon* weap = (Weapon*)item;
Weapon *weap = (Weapon *)item;
if ((!str::cmp(holsterTag, weap->GetCurrentAttachToTag()))) {
weap->DetachFromOwner();
@@ -772,7 +800,7 @@ void Sentient::ActivateWeapon(Weapon *weapon, weaponhand_t hand)
}
}
weapon->AttachToOwner(hand);
weapon->NewAnim("raise");
weapon->SetWeaponAnim("raise");
if (weapon == holsteredWeapon) {
holsteredWeapon = NULL;
@@ -909,7 +937,7 @@ Weapon *Sentient::NextWeapon(Weapon *weapon)
assert(item);
if (item->isSubclassOf(Weapon)) {
if (item->IsSubclassOfWeapon()) {
choice = (Weapon *)item;
if ((!choice->HasAmmo(FIRE_PRIMARY) && !choice->GetUseNoAmmo()) || !choice->AutoChange()) {
continue;
@@ -964,7 +992,7 @@ Weapon *Sentient::PreviousWeapon(Weapon *weapon)
assert(item);
if (item->isSubclassOf(Weapon)) {
if (item->IsSubclassOfWeapon()) {
choice = (Weapon *)item;
if ((!choice->HasAmmo(FIRE_PRIMARY) && !choice->GetUseNoAmmo()) || !choice->AutoChange()) {
continue;
@@ -993,7 +1021,7 @@ Weapon *Sentient::PreviousWeapon(Weapon *weapon)
Weapon *Sentient::GetActiveWeapon(weaponhand_t hand) const
{
if ((hand > MAX_ACTIVE_WEAPONS) || (hand < 0)) {
if ((hand >= MAX_ACTIVE_WEAPONS) || (hand < 0)) {
warning(
"Sentient::GetActiveWeapon",
"Weapon hand number \"%d\" is out of bounds of 0 to MAX_ACTIVE_WEAPONS:%d\n",
@@ -1168,8 +1196,8 @@ void Sentient::PutawayWeapon(Event *ev)
weapon = GetActiveWeapon(hand);
if (weapon->isSubclassOf(Weapon)) {
weapon->NewAnim("putaway");
if (weapon->IsSubclassOfWeapon()) {
weapon->SetWeaponAnim("putaway");
}
}
+22 -22
View File
@@ -253,112 +253,112 @@ SimpleEntity::~SimpleEntity()
int SimpleEntity::IsSubclassOfEntity(void) const
{
return (entflags & EF_ENTITY);
return (entflags & ECF_ENTITY);
}
int SimpleEntity::IsSubclassOfAnimate(void) const
{
return (entflags & EF_ANIMATE);
return (entflags & ECF_ANIMATE);
}
int SimpleEntity::IsSubclassOfSentient(void) const
{
return (entflags & EF_SENTIENT);
return (entflags & ECF_SENTIENT);
}
int SimpleEntity::IsSubclassOfPlayer(void) const
{
return (entflags & EF_PLAYER);
return (entflags & ECF_PLAYER);
}
int SimpleEntity::IsSubclassOfActor(void) const
{
return (entflags & EF_ACTOR);
return (entflags & ECF_ACTOR);
}
int SimpleEntity::IsSubclassOfItem(void) const
{
return (entflags & EF_ITEM);
return (entflags & ECF_ITEM);
}
int SimpleEntity::IsSubclassOfInventoryItem(void) const
{
return (entflags & EF_INVENTORYITEM);
return (entflags & ECF_INVENTORYITEM);
}
int SimpleEntity::IsSubclassOfWeapon(void) const
{
return (entflags & EF_WEAPON);
return (entflags & ECF_WEAPON);
}
int SimpleEntity::IsSubclassOfProjectile(void) const
{
return (entflags & EF_PROJECTILE);
return (entflags & ECF_PROJECTILE);
}
int SimpleEntity::IsSubclassOfDoor(void) const
{
return (entflags & EF_DOOR);
return (entflags & ECF_DOOR);
}
int SimpleEntity::IsSubclassOfCamera(void) const
{
return (entflags & EF_CAMERA);
return (entflags & ECF_CAMERA);
}
int SimpleEntity::IsSubclassOfVehicle(void) const
{
return (entflags & EF_VEHICLE);
return (entflags & ECF_VEHICLE);
}
int SimpleEntity::IsSubclassOfVehicleTank(void) const
{
return (entflags & EF_VEHICLETANK);
return (entflags & ECF_VEHICLETANK);
}
int SimpleEntity::IsSubclassOfVehicleTurretGun(void) const
{
return (entflags & EF_VEHICLETURRET);
return (entflags & ECF_VEHICLETURRET);
}
int SimpleEntity::IsSubclassOfTurretGun(void) const
{
return (entflags & EF_TURRET);
return (entflags & ECF_TURRET);
}
int SimpleEntity::IsSubclassOfPathNode(void) const
{
return (entflags & EF_PATHNODE);
return (entflags & ECF_PATHNODE);
}
int SimpleEntity::IsSubclassOfWaypoint(void) const
{
return (entflags & EF_WAYPOINT);
return (entflags & ECF_WAYPOINT);
}
int SimpleEntity::IsSubclassOfTempWaypoint(void) const
{
return (entflags & EF_TEMPWAYPOINT);
return (entflags & ECF_TEMPWAYPOINT);
}
int SimpleEntity::IsSubclassOfVehiclePoint(void) const
{
return (entflags & EF_VEHICLEPOINT);
return (entflags & ECF_VEHICLEPOINT);
}
int SimpleEntity::IsSubclassOfSplinePath(void) const
{
return (entflags & EF_SPLINEPATH);
return (entflags & ECF_SPLINEPATH);
}
int SimpleEntity::IsSubclassOfCrateObject(void) const
{
return (entflags & EF_CRATEOBJECT);
return (entflags & ECF_CRATEOBJECT);
}
int SimpleEntity::IsSubclassOfBot(void) const
{
return (entflags & EF_BOT);
return (entflags & ECF_BOT);
}
void SimpleEntity::SetTargetName(str targetname)
Loaded 100 of 171 files, more files were not shown because too many files have changed in this diff. Show more