Compare commits

...
1704 Commits
Author SHA1 Message Date
smallmodel 586da44c30 Remove what's Working documentation as everything is implemented 2024-11-24 18:03:15 +01:00
smallmodel 3956e03557 Use Ubuntu 22.04 as the runner OS for linux, to use a lower GLIBC version 2024-11-24 16:31:38 +01:00
ysdragon 8d0b7b77c6 Check for libc and link against execinfo lib for musl libc 2024-11-24 16:04:30 +01:00
ysdragon 23ad991743 Use nullptr instead 2024-11-24 16:04:30 +01:00
smallmodel 4493b2c42e Prevent integer overflow when interpolating verts 2024-11-24 15:58:18 +01:00
smallmodel 8b6b1597d7 Check for bHitPerson in MV0, MV1 and MV2
This checks if the sentient being hit is dead, and skip it when moving the vehicle so the vehicle doesn't get stuck for when a sentient is dying
2024-11-23 22:58:51 +01:00
smallmodel dddedba721 Update getting_started_running.md 2024-11-23 21:14:42 +01:00
smallmodel be34870a18 Copy the channel origin to the sound entity origin when loading
If the channel had a valid entity at the time of saving, make sure to restore the origin
2024-11-23 21:12:58 +01:00
smallmodel 4d4b9288c6 Don't update the streamed channel if the source status AL_INITIAL
This can occur when starting a new sound without playing it, which can happen when reloading the sound system while all sounds are paused (game paused)
2024-11-23 18:42:27 +01:00
smallmodel fc9be91124 Update OpenAL to 1.24.0
PowerPC will remain on 1.23.1 until the compile issue is resolved
2024-11-23 17:24:05 +01:00
smallmodel 0d24c620fb Update GCC to version 14 2024-11-23 16:08:25 +01:00
smallmodel 89140f775e Archive entities at the order they were created
This fixes an issue where turrets would Think() before the base they are mounted on (like tanks), which means the turret would set its origin before the base (tank) does. This issue also occurs on the original game
2024-11-23 15:19:05 +01:00
smallmodel de6718b511 Include a new section on how to obtain demos online 2024-11-22 21:03:54 +01:00
smallmodel 5c094f9c8a More clarity 2024-11-22 20:57:26 +01:00
smallmodel e2f4d8cd6b Use explicit constants when checking g_gametype 2024-11-22 19:44:53 +01:00
smallmodel 04da76167c Set the correct face mode for when the AI is facing a entity that allows AI to face
This fixes a mistake where AI would turn away from the player if the player approaches too much
2024-11-22 18:52:36 +01:00
smallmodel 90639cee36 Fix incorrect effect being spawned for MakeEffect CGM 2024-11-22 18:18:27 +01:00
smallmodel ecfdcca4d5 Update README 2024-11-21 22:07:11 +01:00
smallmodel 3790f057e1 Fix an infinite loop in BulletAttack
This would be caused by an entity that is inside another entity, like 2 actors at the same location
2024-11-21 20:41:57 +01:00
smallmodel 44d8adcfb0 Set the eyePos when loading from save
Server uses the playerState's vEyePos as the position, to add entities to snapshots, so make sure it's initialized before the next snapshot is sent
2024-11-21 20:26:12 +01:00
smallmodel 64f877ae80 Use the correct convention for installing the project
On Win32:
- Binaries and libraries will be installed by default in <PREFIX>/bin
- The prefix is set to `Program Files/openmohaa` by default

On Unix:
- Binaries and libraries will be installed by default in <PREFIX>/lib/openmohaa
- Shared data will be installed in <PREFIX>/share/applications, <PREFIX>/share/metainfo and <PREFIX>/share/icons
- The prefix is set to `/usr/local` by default
2024-11-21 19:49:43 +01:00
smallmodel 2ce8450a7e Use fprintf to stderr 2024-11-21 01:14:08 +01:00
smallmodel 7e7b3ab280 Fix PDB files mistakenly not included 2024-11-21 00:13:37 +01:00
smallmodel 48c2d026e6 Fix ActorPath not archiving path properly
It was mistakenly archiving the first path multiple times instead of the whole path array. This lead to AI strangely moving after loading from save
2024-11-20 23:32:37 +01:00
smallmodel ad825f5114 Reimplement noise functions 2024-11-20 23:02:22 +01:00
smallmodel 120a486aea Use CMake installation directory
This removes the use of the DESTINATION parameter from install() command and instead rely on default values.
The shared build action file was modified to package installed files in a single folder
2024-11-20 22:50:49 +01:00
Joey Riches 864cdf1fc6 CMake: Add uninstall target
https://gitlab.kitware.com/cmake/community/-/wikis/FAQ#can-i-do-make-uninstall-with-cmake

Useful when for testing system-wide installation with linux
2024-11-20 18:01:30 +01:00
Joey Riches f1c12e0649 misc: Add linux assets
Add a .desktop file, this is used by application launchers in order to
find and execute applications, this should be installed to
`/usr/share/applications/org.openmoh.openmohaa.desktop`.

Add appstream metainfo, this provides metainfo that is used by Software
Centers for discoverability, this should be installed to
`/usr/share/metainfo/org.openmoh.openmohaa.metainfo.xml`.

This will open the door to getting OpenMoHAA packaged up by various
linux distros.
2024-11-20 16:40:01 +01:00
smallmodel 58d8a73269 Don't abort() on interrupt or on program termination 2024-11-20 12:46:04 +01:00
smallmodel c788d57c52 Use abort() rather than doing a segfault 2024-11-19 23:15:01 +01:00
smallmodel 50eda4156a Don't remove the weapon if it has no start ammo
Instead, prevent sentients from picking up weapons if they get no ammo from it and they already have that weapon. Instead, just let the weapon be picked up as a new weapon
2024-11-19 22:44:04 +01:00
smallmodel 1e609a4b2f Ignore bullet tracers in 1.11 and below
Before 2.0, the tracer frequency is set on almost all weapons. This has some artifacts on multiplayer, the tracer doesn't look adjusted in first-person view
2024-11-19 22:24:50 +01:00
smallmodel a0e2162dd7 Fix 1.11 servers filtered out 2024-11-19 22:16:55 +01:00
smallmodel 01dfbcdbfe Properly print the backtrace and generate a core dump on both Windows/Unix 2024-11-19 21:45:49 +01:00
smallmodel 862af012cb Fix infinite loop while getting the number of lines in objectives 2024-11-19 20:26:23 +01:00
smallmodel d83374d38c Set the default compass scale to 0.5 for the base game 2024-11-19 19:44:55 +01:00
smallmodel 05e14f6364 Adjust the objectives menu accordingly depending on the game message box which depends on the compass scale 2024-11-19 19:41:46 +01:00
smallmodel 6bc621462c Use CL_FontStringWidth instead of uie.FontStringWidth 2024-11-19 19:17:16 +01:00
smallmodel acb08b89f7 Fix constant for screenOrg 2024-11-18 22:03:58 +01:00
smallmodel 2107523eda Use MAX_CLIENTS - 1 instead of 63 2024-11-18 21:57:02 +01:00
smallmodel 2662174eba Fix radar clients not blinking when talking 2024-11-18 21:22:50 +01:00
smallmodel 59d03ff6f0 Return a virtual scale with the correct ratio if scale variable is set
This prevents the widget from being stretched out on widescreen, currently only the compass uses scalecvar
2024-11-18 21:13:43 +01:00
smallmodel 05d304dfc3 Set ignoredFiles only if ignore_files was specified
This fixes a crash that would occur due to a NULL string
2024-11-18 20:38:03 +01:00
smallmodel 614ed6e632 Use the vartree for flags, rather than copying the flags to a signed int value 2024-11-18 19:47:54 +01:00
smallmodel eb938c872d Make varnode endian-independant
This fixes terrain rendering incorrectly on big-endian architectures by using bit operation. The `flags` field in the union always matched the first byte of the variance float value instead of the least significant byte
2024-11-18 19:44:00 +01:00
smallmodel 46e1aa979b Use ARRAY_LEN instead of sizeof 2024-11-18 18:46:14 +01:00
smallmodel ec5acb4d98 Fix bad glDepthRange 2024-11-17 22:59:49 +01:00
smallmodel b237222761 Update features.md 2024-11-17 22:27:20 +01:00
smallmodel 652df1a5af Prevent players with SVF_NOCLIENT to use objects 2024-11-17 22:10:03 +01:00
smallmodel 69621335db Put the target extension version in the version string 2024-11-17 21:31:45 +01:00
smallmodel 7b58fbec8a Fix comparison operator for char 2024-11-17 21:25:54 +01:00
smallmodel aeb8aa8e55 Don't send a voice chat message if the entity is not sent to clients 2024-11-17 20:28:03 +01:00
smallmodel e74e113199 Fix voice message always being sent to enemies in team message 2024-11-17 20:26:40 +01:00
smallmodel 953091cdc8 Move and rename macros to snd_local_new.h 2024-11-17 19:11:59 +01:00
smallmodel 5819145af8 Synchronize the entity time with the channel time when loading
This prevents the channel from stopping immediately during respatialization, the entity time may be updated quite some time after loading
2024-11-17 18:46:21 +01:00
smallmodel 154464cda1 Set the server huddraw elements on single-player mode
This fixes huddraw elements not being archived properly when the map starts
2024-11-17 18:26:00 +01:00
smallmodel 2342f08a79 Print the new damage when g_showbullettrace is turned on 2024-11-17 18:02:57 +01:00
smallmodel 16711a33ef Fix bulletthroughwood and bulletthroughmetal not being archived correctly
This caused issues on some single-player maps where bullet would go through walls
2024-11-17 18:02:35 +01:00
smallmodel cea0d95fee Set the pitch to default when setting a new SFX
This fixes channels having an incorrect pitch when starting the sound under some circumstances
2024-11-17 17:12:36 +01:00
smallmodel 989ec9574c Fix too high farVal for glDepthRange 2024-11-17 16:46:21 +01:00
smallmodel b0b82f0252 Fix incorrect start trace for Actor::DontFaceWall()
This fixes AI not turning from wall
2024-11-17 16:36:45 +01:00
smallmodel 80ddba1013 Fix constant string for "officer" disguise type
This fixes the officer think not working at all
2024-11-17 16:36:19 +01:00
smallmodel 23f776d3c7 Fix typo 2024-11-17 14:32:44 +01:00
smallmodel 880acf9120 Make com_target_game and com_target_demo write-protected (can only be set at startup) 2024-11-17 14:28:00 +01:00
smallmodel 598110477e Archive the m_bAlwaysAway variable 2024-11-16 22:35:55 +01:00
smallmodel ffdfbc3c7d Fix the bullet stopping after the first entity 2024-11-16 21:57:12 +01:00
smallmodel a7dc8b3493 Don't archive r_fastsky variable
This prevents this setting to be altered by mods forever
2024-11-16 21:36:56 +01:00
smallmodel 67d8cad64d Allow sound files from OS disk in pure mode 2024-11-16 21:34:19 +01:00
smallmodel b007842fb4 Fix pure checksums not matching the server 2024-11-16 21:32:53 +01:00
smallmodel 2c4b5fc9ba Rename the type variable to currentType so it doesn't take precedence over the type member
This fixes an issue where it was the type variable that was being set, rather than the type member
2024-11-16 20:07:26 +01:00
smallmodel e96a3f4f59 Use c_str() instead of accessing m_data
c_str() will always return a valid string even if empty
2024-11-16 19:27:48 +01:00
smallmodel 8eded28efc Fix the typename in the error message for incompatible types 2024-11-16 19:22:01 +01:00
smallmodel b68bb4cee7 Fix integer overflow in wait command that would cause infinite loop in stock scripts
It was causing a rare infinite loop in anim/stand.scr where it waits for 9999999 if the actor is unarmed and medic
2024-11-16 19:10:26 +01:00
smallmodel 824cfd789c Properly save and restore entity's children solidity 2024-11-16 18:19:45 +01:00
smallmodel a0b80a9096 Fix string not usable for targetname 2024-11-16 18:17:19 +01:00
smallmodel 857d25825b Remove tmvolume like other commands when shutting down OpenAL 2024-11-16 16:57:59 +01:00
smallmodel 735832829d Don't drop the weapon if it has no ammo 2024-11-16 00:29:44 +01:00
smallmodel 5703161166 Fix grenade dropping no ammo
This makes the weapon drop at least 1 ammo clip
2024-11-16 00:29:13 +01:00
smallmodel d85455e9ec Don't export referenced paks if download is disabled on the server 2024-11-15 21:00:20 +01:00
smallmodel f6c9de4286 Use com_basegame instead of BASEGAME macro 2024-11-15 20:58:46 +01:00
smallmodel a598cbf0dc Update running documentation 2024-11-14 20:25:26 +01:00
smallmodel 67b285924c Prefix OpenAL with debug prints 2024-11-14 19:49:22 +01:00
smallmodel 0c206beb45 Expect a SimpleEntity rather than an Entity
The specified path in FollowPath can be a Waypoint which is a subclass of SimpleEntity
2024-11-14 19:46:16 +01:00
smallmodel 9a6472210c Use a separate user-data location for the demo version 2024-11-13 23:15:31 +01:00
smallmodel 7576d1241d Add hardware requirements for non-x86 architectures 2024-11-13 21:49:43 +01:00
smallmodel fb2f3bddaa Fix the intermission screen (mission failed/success) not hiding immediately on the base game 2024-11-13 20:01:05 +01:00
smallmodel 96ca9c20e4 Rework fade sequence and make it work 2024-11-13 19:40:31 +01:00
smallmodel d01fa33e46 Use 0.31 for Breakthrough demo
This makes the Breakthrough demo client compatible with Breakthrough demo servers
2024-11-13 00:07:07 +01:00
smallmodel ab84a6ea58 Add support for the demo version of the game
This allows the demo version of the game to be used, both for playing on demo servers, or for hosting a demo server
2024-11-12 23:09:37 +01:00
smallmodel b0a683c188 Don't localize if the localization hasn't been initialized 2024-11-12 23:09:32 +01:00
smallmodel e5ef61c5d2 Abort decal loading if a shader cannot be found while loading 2024-11-12 23:00:38 +01:00
smallmodel 02af9a763d Better support for older BSP versions 2024-11-12 20:56:26 +01:00
smallmodel 132903a843 Use different fields for protocol version 6 and 8 2024-11-12 20:56:02 +01:00
smallmodel fe862badf6 Add printdeathmsg from moh 2.0 and above 2024-11-12 18:37:17 +01:00
smallmodel 1ad5964c2f Implement stoploopsound from moh 2.0 and above 2024-11-12 18:21:24 +01:00
smallmodel 851a16e18c Fix the bullet tracer scale 2024-11-12 00:09:29 +01:00
smallmodel 763a79cb74 Fix angle when in turret 2024-11-11 23:48:39 +01:00
smallmodel c9ccb0efaf Check for Sentient instead of Player 2024-11-11 23:48:19 +01:00
smallmodel 9e060d11b6 Allow user-created variables 2024-11-11 20:58:37 +01:00
smallmodel 50fdbaf152 Use CVAR_RESETSTRING instead of CVAR_SERVER_CREATED 2024-11-11 20:36:03 +01:00
smallmodel ccca958ec5 Get the grid1 on each iteration in case it has been reallocated
This fixes a very rare crash that would occur when loading a world map
2024-11-11 19:48:49 +01:00
smallmodel dd37ba2741 Properly archive clients 2024-11-11 19:06:05 +01:00
smallmodel 81b49236a5 Use proper types for playerState_t structure 2024-11-11 19:00:36 +01:00
smallmodel 894e1d7d66 Properly cleanup the existing owner from targets 2024-11-11 18:37:29 +01:00
smallmodel 9d83d58756 Create path only if the target is a SplinePath 2024-11-11 18:28:56 +01:00
smallmodel 54b9a0c340 Fix incorrect SKB offsets 2024-11-11 18:28:42 +01:00
smallmodel 2cf380c15d Add scale field for skel header 2024-11-11 18:12:50 +01:00
smallmodel d400d8927d Fix archive data between 64-bit and 32-bit architectures 2024-11-11 17:52:24 +01:00
smallmodel fef30ff3d5 Clear the splinepath entity flag when destroying 2024-11-11 17:35:41 +01:00
smallmodel 4023c9d863 Fix isOpen event, must return true if it's not closed 2024-11-11 16:40:43 +01:00
smallmodel 7bcb91bbb5 Don't allocate the mark if the number of allocated polys is insufficient
There was a very rare occurrence where it would hang trying to find a free mark poly, when the number of specified polys was more than the number of allocated polys. This bug also occurs in the original game
2024-11-11 15:14:20 +01:00
smallmodel 5edee7d12e Add tmvolume from Spearhead and Breakthrough 2024-11-11 14:24:57 +01:00
smallmodel 51c7e27bc1 Fix the switch label not being archived 2024-11-11 14:05:14 +01:00
smallmodel f400190531 Fix the switch label called incorrectly for VehicleTurretGunTandem 2024-11-11 14:04:51 +01:00
smallmodel 8732e368b6 Clear the last command angles when loading 2024-11-11 13:49:33 +01:00
smallmodel 7e4da514f6 Update features.md 2024-11-10 22:14:03 +01:00
smallmodel 9a55939b42 Fix weapon selection 2024-11-10 22:10:34 +01:00
smallmodel cd89d2c0b4 Don't execute reloadmap if the server is not running 2024-11-10 22:10:24 +01:00
smallmodel 661b08a7fa Don't set g_shownpc to 1 when developer is set 2024-11-10 21:47:58 +01:00
smallmodel d27f928e2d Update features.md 2024-11-10 20:58:46 +01:00
smallmodel 079555e43a Fix VehicleTurretGun sound 2024-11-10 19:29:33 +01:00
smallmodel fcc4e94655 Continue traveling if the bullet trace goes backwards 2024-11-10 19:02:59 +01:00
smallmodel c5721f8a2c Fix variable name starting with multiple consecutive numbers 2024-11-10 17:55:54 +01:00
smallmodel e5acee55ea Restore old behavior of "angle" event of the ScriptOrigin class on previous versions (below 2.30) 2024-11-10 17:42:37 +01:00
smallmodel d3f3b9b51c Don't allow lean in single-player in the base game 2024-11-10 17:01:56 +01:00
smallmodel 48e9db8966 Don't reload the state table when archiving
This fixes multiple issues where the player could end on an incorrect move type after loading from save, like getting out of the ladder
2024-11-10 16:50:23 +01:00
smallmodel 67486f1e49 Clear the player velocity on intermission 2024-11-10 16:17:03 +01:00
smallmodel 923a6de394 Clear the velocity when both walking and frozen 2024-11-10 16:07:55 +01:00
smallmodel de0e4954f8 Call G_MoveClientToIntermission() instead of setting the immobile flag 2024-11-10 15:53:06 +01:00
smallmodel 1ef1bad9ae Add network profiling tool from Spearhead and Breakthrough
Profiling can be enabled with `cl_netprofile` and `sv_netprofile`, the overlay can be shown using `cl_netprofileoverlay` and `sv_netprofileoverlay` and the server can dump network profile using the `netprofiledump` command
2024-11-09 21:38:16 +01:00
smallmodel 23a035e2ca Use a default value for maxlen and bVirtualScale for Print 2024-11-09 19:38:15 +01:00
smallmodel ec73268f94 Reorder methods 2024-11-09 19:21:24 +01:00
smallmodel 2b06cc690e Add reloadmap server command from Breakthrough 2024-11-09 16:03:08 +01:00
smallmodel 7afc2427ac Finish DrawBoundingBox() entity implementation 2024-11-09 15:51:27 +01:00
smallmodel f3bbcba4f0 Set blue horizontal lines for debug bbox 2024-11-09 15:16:46 +01:00
smallmodel 0dca08a66a Fix actor position on a turret 2024-11-09 14:35:52 +01:00
smallmodel f646151ce2 Set medium difficulty by default 2024-11-09 13:27:24 +01:00
smallmodel 2e0e5db260 Implement bindweap 2024-11-09 00:27:42 +01:00
smallmodel f34aad03cd Add script owner implementation 2024-11-09 00:18:59 +01:00
smallmodel 332d209f62 Check if the turret's vehicle entity is valid 2024-11-08 22:31:49 +01:00
smallmodel 888e35466b Drop error if the Script cannot load the file 2024-11-08 22:28:33 +01:00
smallmodel 1f69fce10e Don't check for CONTENTS_BBOX on the base game for large bullets passing through entities
Some mods have tanks with mounted turrets and this would cause issues as the bullet would hit the tank instead
2024-11-08 22:06:51 +01:00
smallmodel ac3eb58671 Return 4 from getconnstate even if it's deprecated 2024-11-08 21:46:25 +01:00
smallmodel 14f3e2faf9 Add a comment about driver solidity 2024-11-08 21:26:23 +01:00
smallmodel a528e916c2 Add the owner when starting a thread from trigger_multipleall if the activator is a projectile 2024-11-08 21:26:09 +01:00
smallmodel e6f83bc1d6 Fix the exit position for the base game 2024-11-08 20:46:45 +01:00
smallmodel 841a8d2b4a Remove clientState_t from g_local.h (shouldn't be defined here) 2024-11-08 20:37:22 +01:00
smallmodel a51c250a31 Add ScriptDeprecated macros 2024-11-08 19:33:15 +01:00
smallmodel c2291e92c4 Add Anim_AngularDelta 2024-11-08 19:32:53 +01:00
smallmodel b8cc3313b1 Check for valid tiki in PF functions 2024-11-08 19:26:37 +01:00
smallmodel d1fca3e499 Check for valid skeletor 2024-11-08 19:24:07 +01:00
smallmodel 66b882346f Clear the animation delta when the animation is invalid 2024-11-08 19:13:56 +01:00
smallmodel b38fedb18c Make the vehicle path drive from TurretMove
This fixes the issue where the AB41 can't be controlled
2024-11-07 20:23:24 +01:00
smallmodel e6559c6ae6 Fire the turret only when attackleft is pressed 2024-11-07 20:02:49 +01:00
smallmodel 772aad79d7 Disable cubemap-based lighting due to rendering artifacts/bugs occurring 2024-11-07 19:37:12 +01:00
smallmodel 3e84dbe6ac Initialize skipFade 2024-11-06 18:53:43 +01:00
smallmodel 381f2b02f5 Add a paragraph about which release should be downloaded 2024-11-05 22:53:54 +01:00
smallmodel f347102ecb Add the skipFade parameter in bsptransition so the fade can be skipped
Useful for scripts that are using fadeout during cinematics and then transitioning to the nextmap, like in e2l2 where vehicles explode at the end of the mission
2024-11-05 22:37:33 +01:00
smallmodel f5d2fdbcad Return an empty string if the channel is neither playing nor paused
It was only checking if the channel was playing. This was an issue because, in the main menu the music is paused, which means saving from main menu would not save the music filename
2024-11-05 22:16:15 +01:00
smallmodel ab037f1890 Properly center the window 2024-11-05 22:03:43 +01:00
smallmodel a933c78d93 Explosions must not kill the window immediately 2024-11-05 22:02:30 +01:00
smallmodel d08f539e6d Correctly initialize the window object 2024-11-05 22:02:08 +01:00
smallmodel caea6e6bba Return a reference to a const str for the result of Target() 2024-11-05 21:58:19 +01:00
smallmodel 6970e2d00c Properly check entity sight against passOwnerNum 2024-11-05 21:48:43 +01:00
smallmodel af084542c4 Don't set the leadside 2024-11-05 21:48:14 +01:00
smallmodel 9f728580b6 Fix Y normal for the output color from cube being mistakenly used twice
This improves the overall lighting from cubemap
2024-11-05 20:31:56 +01:00
smallmodel c25d0b668a Only check if m_bVisible is non-zero 2024-11-05 20:30:30 +01:00
smallmodel 1e29fd7d2b Refactor SetScript/SetThread 2024-11-05 19:52:13 +01:00
smallmodel 67f822d492 Process label of type 'none'
A none variable should be considered valid, it will just clear the label
2024-11-05 18:43:28 +01:00
smallmodel effbbd6c62 Support long subtitles 2024-11-05 01:14:21 +01:00
smallmodel db802d1a4c Update the running documentation 2024-11-04 22:56:06 +01:00
smallmodel fba40370af Only create launchers for the standalone game 2024-11-04 22:52:49 +01:00
smallmodel fc0ca18632 Add missing QUAKED comments 2024-11-04 21:32:16 +01:00
smallmodel 059b0ba34f Override respondTo method for TriggerEntity
This makes TriggerEntity respond to any object that is a subclass of Entity. This is useful for scripts wanting script_model to touch triggers for cinematic purposes (for example, the bike crash gag at the end of e2l2)
2024-11-04 21:22:09 +01:00
smallmodel e833b08a8e Fix G_GetAngle returning the wrong angle (was flipped) 2024-11-04 20:37:28 +01:00
smallmodel afc431c413 Add a basic launcher 2024-11-04 01:00:53 +01:00
smallmodel 81e407a924 Add EXE_EXT 2024-11-03 21:45:27 +01:00
smallmodel 1f232efdf3 Add the push velocity when jumping from a valid ground entity 2024-11-03 20:34:49 +01:00
smallmodel 94e1830895 Don't jump when on top of another sentient 2024-11-03 20:32:17 +01:00
smallmodel 406f804ef8 Don't jump when inside a vehicle or turret 2024-11-03 20:30:37 +01:00
smallmodel 437f20dfb9 Set the view angles when archiving 2024-11-03 20:21:01 +01:00
smallmodel ff4438bce9 Properly load the statemap file and get the pain conditions when archiving 2024-11-03 20:12:14 +01:00
smallmodel 5cb343730b Rename Conditions to m_conditions 2024-11-03 20:06:31 +01:00
smallmodel dacaaa2cef Add missing variables from archive 2024-11-03 20:02:55 +01:00
smallmodel 2e6e20cf09 Set the m_bHasJumped value when jumping 2024-11-03 20:01:21 +01:00
smallmodel 2da379bade Fix typo for nodropweapons 2024-11-03 19:30:56 +01:00
smallmodel cf8f755f6c Make comment more clear 2024-11-03 19:23:11 +01:00
smallmodel 8114003c84 Add screenshot/levelshot allowed stuff commands 2024-11-03 18:54:34 +01:00
smallmodel bb47ba468c Fix game.skill and game.detail missing getters 2024-11-03 18:51:27 +01:00
smallmodel b97c47ab32 Cast to clock_t before left-shift 2024-11-03 18:40:18 +01:00
smallmodel 9042ea320c Refactor UI_RegisterLoadResource 2024-11-03 18:38:12 +01:00
smallmodel 98e725ef7b Fix EV_StatsUpdater_UpdateStats missing parameter declaration 2024-11-03 18:28:00 +01:00
smallmodel 05b2d3529e Implement UI_EndLoadResource 2024-11-03 18:27:41 +01:00
smallmodel 00dbc74269 Use MAX_WEAPON_ANIM_SLOTS instead of a constant 2024-11-03 15:36:55 +01:00
smallmodel 8addeedf5e Fix event parameters being incorrectly archived 2024-11-03 15:33:14 +01:00
smallmodel bc834b021c Use and draw the marker material when specified
This is used by the fuse stopwatch hud
2024-11-03 15:09:47 +01:00
smallmodel 6bac4bd57a Add assertions to check for valid squad mates 2024-11-03 15:09:27 +01:00
smallmodel 51324aa8e9 Archive the ProjectileTarget ID
The ID was missing during save, this caused issues with projectile generators when looking for a local target
2024-11-03 01:51:17 +01:00
smallmodel 7d1d92980a Disable the charge life when set to 0 2024-11-03 01:40:34 +01:00
smallmodel 3d42197f50 Initialize the minlife field 2024-11-03 01:26:30 +01:00
smallmodel 8a774c02dc Call G_BeginIntermission() instead of G_MissionFailed() when calling missionfailed 2024-11-03 00:41:26 +01:00
smallmodel a644e8a09c Check for GT_SINGLE_PLAYER instead of 0 2024-11-03 00:40:59 +01:00
smallmodel 6f51427c7c Add a function to count the number of valid clients 2024-11-03 00:34:33 +01:00
smallmodel 62bcf58d83 Call G_RestartLevelWithDelay instead in G_MissionFailed 2024-11-03 00:33:33 +01:00
smallmodel f40f206161 Don't add the owner velocity by default
This fixes an issue where AI would throw grenades incorrectly
2024-11-03 00:21:27 +01:00
smallmodel 1235f42143 Set the grenade mode when tossing a grenade with the specified speed 2024-11-03 00:20:47 +01:00
smallmodel 1016bfa1ad Fix calcgrenadetoss2 not pointing to the correct method 2024-11-03 00:19:31 +01:00
smallmodel f9ce111784 Set the targetname for projectiles 2024-11-02 22:38:45 +01:00
smallmodel 4c057faf73 Add a newline for warnings 2024-11-02 21:51:19 +01:00
smallmodel 4f16179c09 getmins/getmaxs are getters instead of returns 2024-11-02 21:46:55 +01:00
smallmodel 6991c9f9f7 Fix save comment not having the proper string 2024-11-02 21:22:24 +01:00
smallmodel 6e6dac0b74 Proper formatting 2024-11-02 20:56:32 +01:00
smallmodel 23f9c1a1e6 Only set the effect angles from the supplied angles if the spawnthing doesn't have angle set 2024-11-02 20:14:30 +01:00
smallmodel e4b2c863d8 Fix angles not being set correctly from the base 2024-11-02 20:13:23 +01:00
smallmodel ae16994289 Fix amplitude mistakenly being set instead of the base 2024-11-02 19:46:32 +01:00
smallmodel b8b17bb0c9 Implement VSS wind 2024-11-02 19:12:09 +01:00
smallmodel 3098fc98d3 Don't change the velocity for VSS, this was a mistake 2024-11-02 19:01:05 +01:00
smallmodel f3ecfd04da Use macro flags rather than constant values 2024-11-02 18:41:56 +01:00
smallmodel 0796fab24b Fix VSS sources not lerping at all 2024-11-02 18:06:56 +01:00
smallmodel 0fda31b430 Fix radial velocity/circle effects not properly applying 2024-11-02 17:52:33 +01:00
smallmodel 84a2b4be76 Use cg_effect_physicsrate instead of a constant value 2024-11-02 17:51:44 +01:00
smallmodel 5269fbb1fa Don't set the accel flag for swarm FX 2024-11-02 17:26:08 +01:00
smallmodel f23dfa091e Fix wrong flag used for checking for PMF_NO_HUD 2024-11-02 13:48:03 +01:00
smallmodel 32c3964474 Fix the source line having the entire file 2024-11-01 00:11:09 +01:00
smallmodel 6ff92f0a7e Process the ubersound folder differently depending on the target version
- On 1.11 and below, the ubersound folder is parsed either only in dedicated server mode or in client-only mode
- On 2.0 and above, alias are cleared and the ubersound folder is always parsed in multiplayer on both client and server
2024-10-31 23:57:18 +01:00
smallmodel c795b2390e Add a ScriptMaster constructor 2024-10-31 23:55:12 +01:00
smallmodel ce7005103c Handle the case where a vector is given for the face command 2024-10-31 23:51:36 +01:00
smallmodel 1a18878f26 Parse unary operators last when calling events 2024-10-31 22:16:20 +01:00
smallmodel 1e036a7689 Clear the torso and legs state when the movement type is set to portable turret 2024-10-31 19:49:05 +01:00
smallmodel 858b27b809 Handle the case where the legs or the torso state is NULL 2024-10-31 19:48:30 +01:00
smallmodel b4841a878b Only set the first found mark time and alpha fade 2024-10-31 19:37:42 +01:00
smallmodel 4565b6a9a8 Add cg_addhud and cg_removehud as whitelisted stuff commands 2024-10-31 01:45:37 +01:00
smallmodel 9ffb407d11 Fix incorrect/uninitialized token returned when there is a macro 2024-10-31 01:31:41 +01:00
smallmodel 0f3ffa267a Parse const array elements properly 2024-10-31 01:22:38 +01:00
smallmodel 74c8aa95f5 Properly ignore single-digits 2024-10-30 23:21:14 +01:00
smallmodel 4853235d86 Don't parse the token as a variable if the identifier only contains number
This fixes an issue where floats would be parsed as a variable after brackets
2024-10-30 22:42:55 +01:00
smallmodel 0d01ea939d Fix whole script file being printed sometimes on error 2024-10-30 21:25:15 +01:00
smallmodel 5ba6c006c2 Fix compile error 2024-10-30 00:23:42 +01:00
smallmodel 22e7d1e2e4 Only put animation definitions that exist, rather than setting a NULL animation definition
This fixes issues when searching animations by name
2024-10-29 22:27:22 +01:00
smallmodel c650af7b55 Fix stack corruption due to an improper assignment to the alias 2024-10-29 21:37:31 +01:00
smallmodel 2ce5e498ab Use CurrentScriptThread() when getting the current script class
So if the current thread is NULL, it will properly throw an exception
2024-10-29 21:11:44 +01:00
smallmodel d3212c55a0 Properly parse and cache ubersounds, and don't cache resources that must be always loaded to avoid filling up sound indexes 2024-10-29 21:02:16 +01:00
smallmodel becf9f5d8c Cache the source position to improve the source search time
This greatly reduces the time to compile big scripts
2024-10-29 20:26:51 +01:00
smallmodel 9cd8133068 Fix the directory prefix when using filters for FS_ListFilteredFiles 2024-10-29 20:25:25 +01:00
smallmodel 48fa5c0ce6 Parse all scr files inside the ubersound folder 2024-10-28 23:29:04 +01:00
smallmodel 6fc7199719 Register server sounds in multiplayer 2024-10-28 23:28:05 +01:00
smallmodel 9e04f94625 Check if the entity is valid after processing pending events during spawn 2024-10-28 23:14:46 +01:00
smallmodel c9b844b9ea Count the number of loaded anims and don't return a valid animation definition if there are no loaded animations 2024-10-28 22:57:52 +01:00
smallmodel 497058d7f4 Make the driver nonsolid while moving 2024-10-28 22:30:52 +01:00
smallmodel a509dd4692 Fix vehicle exit position when targeting the base game
The base game always uses, when specified, the exit position
2024-10-28 22:25:49 +01:00
smallmodel 8fdfffab36 Keep the mouse cursor position when the client disconnects 2024-10-28 21:13:47 +01:00
smallmodel aa118bceb3 Set the door speed based on the door type 2024-10-28 20:59:58 +01:00
smallmodel 4da50a78d5 Merge pull request #483 from smallmodel/marks_fix
Fix mark fragments being randomly culled or missing, especially on moving brush models
2024-10-28 20:59:28 +01:00
smallmodel 4d27a6daa3 Fix incorrect vert dist 2024-10-28 20:55:03 +01:00
smallmodel b6f8997a01 Make the mark object local to the entity 2024-10-28 20:47:01 +01:00
smallmodel 568efd4742 Fix the link to the build branch 2024-10-28 19:05:16 +01:00
smallmodel bf68808eae Set the skel index for each updated entity so poses only update when needed
This fixes poses being updated even if they don't need update (no frame changed), which resulted in some performance loss and some rare accuracy issues when AI fire weapons
2024-10-28 00:55:37 +01:00
smallmodel 5cbd2dd988 Use true/false rather than qtrue/qfalse 2024-10-28 00:45:21 +01:00
smallmodel 92b4ae2702 Use ANIM_WEIGHT_NONE instead of 0 2024-10-27 22:16:04 +01:00
smallmodel a8cdf0b5ad Don't update the upper animation if the think state is attack/grenade/killed/pain 2024-10-27 21:48:13 +01:00
smallmodel e8dfa0206b Use a macro constant for movement/action skan blend frames 2024-10-27 21:39:16 +01:00
smallmodel afe1ba47cf Decrease the time tolerance between frames to make animations smoother 2024-10-27 19:37:56 +01:00
smallmodel 2afa9adceb Add a link to mp-navigation for bots 2024-10-27 18:19:58 +01:00
smallmodel ef32200c8d Target older macOS versions 2024-10-27 17:45:23 +01:00
smallmodel dae7795478 Add NDEBUG compile definition on non-debug builds 2024-10-27 17:45:20 +01:00
smallmodel 7c96b68623 Specify the home directory location for macOS 2024-10-27 15:16:01 +01:00
smallmodel 558e69dba8 Archive the vehicle name
This was missing and this allows the torso state to the modheight to set the bounding box height. Before that, it did not recognize the turret so the modheight was still set to stand. It caused issues when trying to get out a vehicle turret, like the flak88 in e1l1 (the player wasn't able to get out of the turret)
2024-10-27 14:27:44 +01:00
smallmodel da7cd03f09 Increase packed animation time precision
This tries to fix some client commands replaying
2024-10-27 13:42:42 +01:00
smallmodel 6934e5cff8 Check for valid target list in GetScriptTarget() 2024-10-27 12:16:19 +01:00
smallmodel c7cdde7bc2 Check if the target list is valid before adding the entity 2024-10-26 22:42:21 +02:00
smallmodel 940ac789b9 Change the current fov only if the fov is currently the selected fov
This prevents the player from modifying the fov while zooming
2024-10-26 22:42:18 +02:00
smallmodel 3d46bae1d0 Stop the triggered music when the server is restarted 2024-10-26 15:07:47 +02:00
smallmodel 16bedf7e86 Warp the sample offset for small streams so it doesn't get past the stream size 2024-10-26 15:07:09 +02:00
KevDoy 2ee531511b Add: Instructions for installing GOG binaries on *nix 2024-10-26 14:58:34 +02:00
smallmodel 0ad5222946 Use the correct stopwatch for explosives 2024-10-26 13:34:33 +02:00
smallmodel 2b4aef4ea6 Add a newline to Cmd_Stuff
Next commands weren't correctly appended
2024-10-26 13:28:49 +02:00
smallmodel 679cf4b7ec Correctly remove "prespawn"/"spawn" waittill when loading from save 2024-10-26 13:27:32 +02:00
smallmodel a993b8d352 Specify "Fixed" instead of "Added" as it's a bug that was fixed 2024-10-26 00:34:50 +02:00
smallmodel b7403347bb Ignore the first responder if it's disabled so the UI doesn't get blocked by it 2024-10-26 00:30:42 +02:00
smallmodel bf978256e9 Add changes from upstream, like pipefile, random number seed 2024-10-25 22:33:02 +02:00
smallmodel 9bd25e9734 Combine mouse movement events in event queue 2024-10-25 22:08:24 +02:00
smallmodel e7499cca04 Also halt the secondary server list if it exists, when canceling refresh 2024-10-25 22:07:23 +02:00
smallmodel e2d6156b5a Apply the hidden visibility for all functions only on macOS
The backtrace still prints the name of functions regardless of the visibility on macOS
2024-10-25 22:01:49 +02:00
smallmodel 31cb6216c9 Use a volatile variable to prevent the function from being entirely optimized 2024-10-25 21:06:30 +02:00
smallmodel e75f5bbbfc Version number typo 2024-10-25 21:01:01 +02:00
smallmodel 69cc87212a Bumped the version number to 0.80.0 due to the number of changes and the completeness 2024-10-25 20:49:23 +02:00
smallmodel 3c1500002b Implement the destructor for the World class to free up the target list 2024-10-25 20:44:00 +02:00
smallmodel b2287f3d83 Avoid using nextSnap if the prediction is disabled in the next snap
This prevent blinking issues like flashing arms
2024-10-24 21:56:44 +02:00
smallmodel 005a278210 Use CF_CAMERA_ANGLES_TURRETMODE 2024-10-24 21:08:52 +02:00
smallmodel 976e2ae022 Remove useless GetSentientOwner() 2024-10-24 21:08:44 +02:00
smallmodel 8fe87e1067 Handle turret camera flags which has no interpolation 2024-10-24 21:08:26 +02:00
smallmodel d142ded9ad Add RF_FRAMELERP flag to ref entity 2024-10-24 21:08:04 +02:00
smallmodel 090f362bb6 Declare g_allowvote as a serverinfo variable 2024-10-23 23:10:22 +02:00
smallmodel ff3c25cc07 Add cg_allowvote 2024-10-23 23:09:39 +02:00
smallmodel ed22a51a72 Only allow breakthrough clients when targeting mohaab 2024-10-23 22:22:09 +02:00
smallmodel 9e0c11a970 Reset scoreboard values like the objective and the picture when initializing a new game 2024-10-23 21:04:23 +02:00
smallmodel edb52a8448 Properly move items in the map rotation list 2024-10-23 20:52:22 +02:00
smallmodel afb08e0ea9 Prevent adding duplicate maps in the rotation list 2024-10-23 20:49:00 +02:00
smallmodel 8758ba6cb1 Fix the map not starting after applying the rotation list 2024-10-23 20:42:03 +02:00
smallmodel e6a9968d23 Remove useless assertion 2024-10-23 20:25:17 +02:00
smallmodel fcd2d2e668 Use the correct weapon selection menu 2024-10-23 20:15:29 +02:00
smallmodel 991c8869d1 Properly draw circles 2024-10-23 20:10:34 +02:00
smallmodel aef9dc1704 Add feature to show static models culling with r_showcull 2024-10-23 20:07:17 +02:00
smallmodel 848cf7ac01 Fix AddPointToBounds not properly setting the max bounds 2024-10-23 20:03:07 +02:00
smallmodel de1d3b6ef4 Don't reset the client structure on single-player 2024-10-22 22:36:46 +02:00
smallmodel 29f8ff8d71 Set the new frame radius
This fixes an issue when culling static models as it uses the radius and the radius wasn't initialized
2024-10-22 22:26:55 +02:00
smallmodel b641a1040c Fix incorrect cull point height (should be squared) 2024-10-22 22:25:59 +02:00
smallmodel 83acdeb16e Allow activation of the game menu so it can be focused 2024-10-22 22:06:19 +02:00
smallmodel aa2d73a1c8 Correctly copy frame bounds 2024-10-22 21:56:35 +02:00
smallmodel b7a643aa59 Fix AI wrongly aiming at the wrong direction 2024-10-22 21:51:03 +02:00
smallmodel 3d454c90cb Rework the target list, use a container instead of an hash set so the target list gets archived correctly
This fixes an issue when loading from a save. A variable referencing target list container would have random entities in it, which would cause errors and crashes when trying to do an action on the array of entities
2024-10-22 20:05:53 +02:00
smallmodel 590b3f5cbb Fix class ID for throbbing box classes 2024-10-22 00:48:11 +02:00
smallmodel f87e6d5938 Fix barrel jitter
This fixes barrel objects improperly jittering back and forth, sometimes forever
2024-10-21 22:12:13 +02:00
smallmodel 901e81cdf5 Format barrels source file 2024-10-21 21:59:12 +02:00
smallmodel d2ed2f5e95 Correct the gamma with the proper destination resolution when resampling 2024-10-21 21:37:08 +02:00
smallmodel c580ccdee1 Only print a warning instead of dropping when the next snapshot is out of range 2024-10-21 21:26:07 +02:00
smallmodel 8ecbe1dd79 Set the script origin local angles and angles when setting the angle
This fixes the issue where a ScriptOrigin would rotate in the wrong direction
2024-10-21 20:27:52 +02:00
smallmodel 64696c7645 Return the angle using the forward vector 2024-10-21 20:24:47 +02:00
smallmodel ff0dcbd786 Add G_GetAngle 2024-10-21 20:24:33 +02:00
smallmodel a3e5d62c96 Increase the precision of the delta animation time 2024-10-21 19:54:25 +02:00
smallmodel 267e2f4b15 Add a workaround against inactivity timer for mods that handle spectating 2024-10-21 19:25:52 +02:00
smallmodel d52bf52e6a Add BUTTON_ANY flag when moving mouse 2024-10-21 19:22:54 +02:00
smallmodel f5391bbfa0 Use BUTTON_ANY to check for input rather than BUTTON_MOUSE 2024-10-21 19:03:19 +02:00
smallmodel a218106c8b Reset the number of songs when freeing all songs
This fixes an issue where songs from previous maps get played on maps without a music file
2024-10-21 18:40:42 +02:00
smallmodel 8f54f4b806 When loading from save, set the edict model directly rather than loading and resetting animations 2024-10-20 23:25:42 +02:00
smallmodel 78b2637c66 Don't replay animation for new snapshot entities
This prevent cannons effects from replaying due to it being shown when the player exits the cannon
2024-10-20 23:18:00 +02:00
smallmodel 4b25e24a13 Fix issues when using turret while charging a grenade or using the mine detector 2024-10-20 22:42:44 +02:00
smallmodel aa0c704655 Instead of resetting the state, prevent using the turret if the player is charging 2024-10-20 22:42:05 +02:00
smallmodel 4da099d15c Add GetChargeFraction() 2024-10-20 22:41:21 +02:00
smallmodel 0bb11d76bd Remove accidental print 2024-10-20 22:22:36 +02:00
smallmodel c146452570 Attempt to fix animation time going back and forth 2024-10-20 22:21:27 +02:00
smallmodel ed05983a57 Use ceiling for the packed anim time
This is an attempt to fix an issue where the animation time would deviate from 1 bit and would go back and forth
2024-10-20 22:19:57 +02:00
smallmodel 909dc96c2f Use a separate CG_InterpolateAnimParms function for animation 2024-10-20 22:18:40 +02:00
smallmodel 863a6293e7 Don't draw the lensflare in UI 2024-10-20 19:12:42 +02:00
smallmodel 7a49f6fc8b Fix the fuse stopwatch 2024-10-20 18:55:27 +02:00
smallmodel c1433a6d9e Use the correct stopwatch type for when the sticky bomb gets wet 2024-10-20 18:54:36 +02:00
smallmodel 374b8b9ae7 Add fuse stopwatch 2024-10-20 18:52:50 +02:00
smallmodel e2f5c80afc Stop charging the weapon when using turret 2024-10-20 18:46:23 +02:00
smallmodel 29911380d1 Use the weapon owner rather than the last successful hit entity 2024-10-20 01:00:55 +02:00
smallmodel 405a4bfe28 Fix debug line delay not working properly 2024-10-20 00:55:08 +02:00
smallmodel 87e41f0c21 Set the model before anything else 2024-10-19 22:44:07 +02:00
smallmodel dce2bcca7c Initialize bModelSet 2024-10-19 22:41:32 +02:00
smallmodel 00421a7666 Process client events with the correct order
Effects that are using commanddelay were not working at all, this fixes the processing of delayed events so they get processed sequentially and at the correct time
2024-10-19 22:38:46 +02:00
smallmodel fd426926e9 Set all alpha color channel in the current static model to prevent vertices from hiding randomly 2024-10-19 21:54:08 +02:00
smallmodel d83634f8a2 Allow to specify a model when spawning an entity 2024-10-19 21:40:23 +02:00
smallmodel 6efac1c0f7 Don't set animation 2024-10-19 21:27:03 +02:00
smallmodel 3a68ca7f4b Handle static shader data and entity surface values for when deforming vertexes 2024-10-19 20:45:50 +02:00
smallmodel 8898919fd3 Correctly parse lightingSpecular parameters 2024-10-19 20:45:24 +02:00
smallmodel 40834380cf Check if the snap is valid before getting the client number 2024-10-19 20:39:57 +02:00
smallmodel 18abf3854d Use normals for deform vertexes
This fixes the issue where some ocean shaders would look inconsistent
2024-10-19 20:33:57 +02:00
smallmodel 6d0b4f8cb7 Fix PVS sound overflow 2024-10-18 23:50:52 +02:00
smallmodel fc1f795e83 Use ULightGreen color on SH/BT for dm messages 2024-10-18 23:19:09 +02:00
smallmodel ef09f136d4 Fix sound indexes not erased correctly 2024-10-18 23:15:59 +02:00
smallmodel 6136bbd019 Set g_netoptimize to 1 when spawning server 2024-10-18 23:05:53 +02:00
smallmodel 5136aa4886 Properly handle and delete unused non visible entity sounds to free up sound indexes 2024-10-18 23:01:27 +02:00
smallmodel 1a3122bef3 Fix pointer to integer warning 2024-10-18 22:14:45 +02:00
smallmodel 23d7db814c Use an unsigned integer for the column size
This fixes compile warnings
2024-10-18 22:03:41 +02:00
smallmodel 3174ca5da9 Explicitly mark overridden methods 2024-10-18 22:02:27 +02:00
smallmodel 6a107419e3 Only change the maxclients when the map is different
It fixes an issue where on restart, only the number of snapshot entities was changed without the memory being reallocated for it
2024-10-18 20:26:27 +02:00
smallmodel 6d69a8033f Initialize the radar 2024-10-18 20:12:47 +02:00
smallmodel bb9ccdd3b9 Make the bot move slowly when aiming with a semi-auto to improve the spread of their weapon 2024-10-18 20:03:39 +02:00
smallmodel 5b3ce85695 Add a method to get the spread factor 2024-10-18 19:52:49 +02:00
KevDoyandsmallmodel 84c5bfa777 Add Open MoHAA Text Logos
Add a logo and update the README file to use the new logo

---------

Co-authored-by: smallmodel <15067410+smallmodel@users.noreply.github.com>
2024-10-18 19:26:01 +02:00
smallmodel d9166478e5 Set the weapon animation back to idle when finished animating
This fixes an issue that also occur in OG, where some weapons would constantly replay the same sounds (often reload/rechamber) when the weapon entity is removed then added to the client snapshot
2024-10-17 17:50:33 +02:00
smallmodel 373fe45b50 Add an example for using bots 2024-10-17 16:33:26 +02:00
smallmodel cd83091101 Update the ubuntu version for publishing tags 2024-10-17 16:00:06 +02:00
smallmodel 631abd2b0f Update section about bots 2024-10-17 15:59:03 +02:00
smallmodel 02df233205 Refactor UploadCompressed 2024-10-17 15:17:20 +02:00
Jesse Mitchell 11e9d0f9ba [macOS / Compiler Fix] Alter offset for Mouse Buttons
Fix the mouse buttons code and alter how the mouseButton check works
2024-10-17 01:24:22 +02:00
smallmodel 35fea91268 Download and install ninja on Windows, from the official ninja-build GitHub repository
This greatly reduces the compile time on Windows
2024-10-16 22:33:08 +02:00
smallmodel 6f3d79ae1b Use multi-config generators and specify the build type in the --config when using the cmake command instead of using CMAKE_BUILD_TYPE. Also build third-party libraries in Release mode 2024-10-16 22:04:33 +02:00
smallmodel 32da07ea80 Cache Linux apt packages
This avoid overloading servers by downloading the same set of packages multiple times
2024-10-16 20:35:19 +02:00
smallmodel e9a76f933b Cast to int32 rather than uint32 when writing the packed velocity
This fixes an issue where the integer could overflow, on some platforms like ARM the integer would be 0
2024-10-16 19:52:47 +02:00
smallmodel 6b6adf1147 Copy second and third triangles, this was forgotten 2024-10-16 18:28:41 +02:00
smallmodel 6413e770e1 Update compiling doc 2024-10-15 23:46:21 +02:00
smallmodel 7d1067108b Swap the archive type on big endian architectures 2024-10-15 23:38:39 +02:00
smallmodel e00ebda641 Disable compression for big endian systems 2024-10-15 23:33:00 +02:00
smallmodel 2b6fc0602a Avoid misaligned memory access 2024-10-15 23:18:14 +02:00
smallmodel 53c09b5342 Correctly swap skeletons for CPUs that don't support misaligned memory access 2024-10-15 23:10:04 +02:00
smallmodel d78d8abb9f Correctly load SKB models on big endian architectures 2024-10-15 23:07:58 +02:00
smallmodel f6b459b408 Correctly copy long/short taking into account memory overlaps 2024-10-15 22:49:23 +02:00
smallmodel 581585a47c Prevent clearing the event command list if the event system is not initialized
This fixes the issue where the game could crash (especially in optimized release) due to a memory corruption, because the event command list was deconstructed earlier
2024-10-15 20:52:53 +02:00
smallmodel ddbdcc91dd Don't use an offset for the reverse table 2024-10-15 19:22:54 +02:00
smallmodel 8f8b75e0aa Set symbols visibility to hidden by default
This fixes an issue where shared libraries would use functions from in the executable because they have the same name, which would cause memory corruption
2024-10-14 20:36:06 +02:00
smallmodel 2e673a6bc9 Delete posted events when canceling 2024-10-13 23:49:52 +02:00
smallmodel 8c2b92d151 Remove player from turret when deleted 2024-10-13 23:22:13 +02:00
smallmodel 032fb9b5ba Make sure to delete all conditional objects
This fixes the issue where memory would be leaked by conditionals
2024-10-13 22:09:38 +02:00
smallmodel b1c5d6c62a Increase the backtrace size to 64 2024-10-13 11:32:20 +02:00
smallmodel 037af5d728 Don't access the removed node 2024-10-13 11:32:11 +02:00
Leszek Godlewski 61a2b6a837 Don't call into the OAL channel in S_OPENAL_GetMusicFilename if QAL init failed
Prevent a crash upon vid_restart
2024-10-13 00:25:17 +02:00
smallmodel 13698a9590 MINS and MAXS must be signed values 2024-10-12 01:16:31 +02:00
smallmodel 4f2907ef77 Remove LADDER_HAND_HEIGHT (useless) 2024-10-12 01:16:04 +02:00
smallmodel 8667d11c52 Prevent SV_DropClient() from being called recursively if the client is dropped by a kick or timeout and has too many reliable commands 2024-10-11 22:55:24 +02:00
smallmodel 24309095ff Rework bot save/load:
- Only save and restore the userinfo
- Restore bots when the server spawns
- Read client session data like real players
2024-10-11 22:54:40 +02:00
smallmodel d5a90ded17 Add a comment about primary weapon selection on map change 2024-10-11 21:51:52 +02:00
smallmodel 9d744367ac Add firstTime parameter for bots 2024-10-11 21:46:49 +02:00
smallmodel 46a46a9536 Remove unnecessary code 2024-10-10 22:29:17 +02:00
smallmodel 224c1df553 Test against entities with BSP solidity when testing client visibility 2024-10-10 21:38:51 +02:00
smallmodel bcea5af30f Remove unused sound index that were used for non visible players 2024-10-10 21:22:59 +02:00
smallmodel 211ce09c0b Don't create sound index for non visible players if net optimization is disabled 2024-10-10 21:22:35 +02:00
smallmodel 1e41a2595d Leave 1 second minimum between each call to RefindPath() 2024-10-10 20:27:52 +02:00
smallmodel 36a080b3a9 Call InitModelList() once
This fixes an issue where the model list would get initialized each frame
2024-10-10 20:11:12 +02:00
smallmodel a3050f6c64 Avoid using too much performance to update the loading screen, especially on low-end PCs 2024-10-10 19:48:23 +02:00
smallmodel be5deddc1d Make indexes and coordinates 16-bytes aligned 2024-10-10 19:10:12 +02:00
smallmodel 36f9bdb88c Use intptr_t instead of size_t because intptr_t can hold a pointer which is not always the case for size_t 2024-10-10 19:07:20 +02:00
smallmodel 1a33e9a15b Add BotRotation class to handle bot turning 2024-10-09 21:21:19 +02:00
smallmodel 4157a49c7e Remove useless include 2024-10-09 21:21:13 +02:00
smallmodel f27be7314e Add a BotMovement class for managing bot movements 2024-10-09 20:46:39 +02:00
smallmodel a425038fa6 Set macOS rpath to @executable_path 2024-10-09 19:38:32 +02:00
smallmodel 0b07858bfc Refactor PlayerBot to use a separate controller class, alongside classes that manage bots 2024-10-08 22:17:22 +02:00
smallmodel 7dbf1d7bf5 Add a method to get the ladder 2024-10-08 21:52:49 +02:00
smallmodel 34c44ab2cf Add a method to get the max fire movement 2024-10-08 21:52:43 +02:00
smallmodel 5ec106642d Fix node cover mask 2024-10-08 21:00:01 +02:00
smallmodel dcd9ce91a8 Use the raw integer value of the squared distance when comparing nodes 2024-10-08 20:42:22 +02:00
smallmodel a05fbfe69b Fix incorrect value of AI_CONCEALMENT_MASK 2024-10-08 20:38:34 +02:00
smallmodel feb76f4fb4 Allow entities other than SimpleActor for finding covers and sniper nodes 2024-10-08 20:31:50 +02:00
smallmodel d467b68187 Add node editing support, with a way to dynamically load, remove and modify nodes while editing 2024-10-08 20:25:33 +02:00
smallmodel de18fa2860 Refactor Entity::FovCheck 2024-10-08 20:14:10 +02:00
smallmodel 58f6c719a9 Add code to select current node in view and draw it for editing later 2024-10-08 01:14:40 +02:00
smallmodel b2fa21a111 Format navigation source file 2024-10-07 23:52:39 +02:00
smallmodel f94099e350 Don't link nodes that can't be reached with an high fall height 2024-10-07 23:49:39 +02:00
smallmodel e2f11879d5 MAXS_Z is 94 2024-10-07 23:05:37 +02:00
Sébastien Noel aa15b3ea7f Allow to build against system libs instead of bundled copy 2024-10-07 20:51:23 +02:00
smallmodel 1624d10a01 Don't check for bots for smoothclients 2024-10-07 00:51:01 +02:00
smallmodel 0d53adf9bd Rework bot spawning
- Add a sv_sharedbots to specify if real client slots should be used
- Removed m_bSpawnBot from level, bots are spawned directly in G_BotBegin instead
- sv_numbots can be used to directly configure the number of bots to spawn
- Fix the way bots spawn/unspawn on-demand
- Documented g_bot functions
2024-10-06 22:57:39 +02:00
smallmodel 295c267c31 Automatically join a team if the bot was put in spectator, and automatically select a primary weapon if none was selected 2024-10-06 22:57:31 +02:00
smallmodel d4b3f7378e Don't update the new path check time when there is a new move 2024-10-06 22:29:55 +02:00
smallmodel a503e18966 Make the bot move to the enemy only if it was seen 2024-10-06 22:29:29 +02:00
smallmodel b1f7d641fc Use game.maxclients for the maximum number of bots 2024-10-06 21:44:10 +02:00
smallmodel 5019d1e4f9 Spawn bots after the server has spawned 2024-10-06 21:43:42 +02:00
smallmodel 2aa0205872 Clear client persistent to avoid leaking data 2024-10-06 21:01:05 +02:00
smallmodel a7befa8882 When a client disconnects, delete the entity on the next frame if the function is called while in thinks 2024-10-06 21:00:40 +02:00
smallmodel a5058c7bab Call Delete() instead of deleting the item as it could cause issues if the item is being deleted while iterating over edicts 2024-10-06 19:57:03 +02:00
smallmodel f5558d106e Don't set the last radar time if the entity number is above the max number of clients 2024-10-06 19:19:44 +02:00
smallmodel d19328230c Allow more bots to be spawned alongside the minimum number of players 2024-10-06 18:50:42 +02:00
smallmodel b77464386c Count actual clients that aren't spectating 2024-10-06 18:46:23 +02:00
smallmodel 9119319429 Avoid unbalancing teams when removing bots 2024-10-06 18:46:02 +02:00
smallmodel d3d85fded0 Add TEAM_MAX 2024-10-06 18:37:31 +02:00
smallmodel 9b9642df8f Add a very tiny offset off the facing dir as a workaround the 1 bit difference between 32-bit and 64-bit
In 64-bit, some windings are off by 1 bit (float values) compared to 32-bit, which causes issue on some maps like `dm/mp_stadt_dm` where the player would get stuck climbing up because of the blocking patch at the top
2024-10-06 17:33:48 +02:00
smallmodel e564a97b05 Check if the delta is exactly 16 2024-10-06 17:31:02 +02:00
smallmodel a150cb5c6e Also check for liberation game type when the team is dead 2024-10-06 16:58:20 +02:00
smallmodel afd7943b62 Fix incorrect teams and controllers for TOW objectives 2024-10-06 15:20:45 +02:00
smallmodel 09eb130b6d Update curiosity and MoveDone() 2024-10-06 14:24:32 +02:00
smallmodel 5869ba06bc Update the attack time when moving 2024-10-06 01:13:12 +02:00
smallmodel b6c2638c1b Make curiosity random 2024-10-06 01:01:03 +02:00
smallmodel 16b0f0d625 Use random() in CuriousSound() 2024-10-06 00:53:31 +02:00
smallmodel 9293930628 Make bots jump off ladder
They don't support ladders yet
2024-10-05 23:59:32 +02:00
smallmodel 46935b165c Fix MoveDone() not checking for height, also return false when temporarily getting away 2024-10-05 23:57:02 +02:00
smallmodel c0dd08f6e0 Set an higher firing sound in MP 2024-10-05 21:24:45 +02:00
smallmodel 1fde1647e8 Use the proper enum for BroadcastAIEvent 2024-10-05 21:24:29 +02:00
smallmodel 7ef006ccca Fix nodes improperly connecting to other nodes that are below the ground 2024-10-05 21:15:37 +02:00
smallmodel fd69d6b42c Allow the bot to get out if stuck while falling 2024-10-05 20:46:16 +02:00
smallmodel 627f66fb5b Add basic pathnode editing feature 2024-10-05 20:45:56 +02:00
smallmodel 8451c11916 Add a feature to dynamically create a master class for development 2024-10-05 20:17:11 +02:00
smallmodel 6bbbbcfb05 Allow spawning a simple entity 2024-10-05 20:15:50 +02:00
smallmodel 63465278a5 When there is no free player start spot, try to find a random player s tart one 2024-10-05 20:15:40 +02:00
smallmodel 2980771deb Fix path node connection, use the target node num 2024-10-05 20:13:03 +02:00
smallmodel 1169b84c2f Make sure the entity is valid before checking for the bad place team 2024-10-05 20:12:37 +02:00
smallmodel 355491a950 Reduce the bot attack time to avoid the bot getting stuck 2024-10-05 14:47:09 +02:00
smallmodel 7caa0adbab Toggle use button and don't use if the door is open 2024-10-05 14:46:44 +02:00
smallmodel 8acc51c489 Correctly add/remove bots 2024-10-05 13:54:53 +02:00
smallmodel 732fd98593 Make the bot strafe when attacking 2024-10-05 13:43:09 +02:00
smallmodel 21a610d22c Fix NoticeEvent ignoring other players on FFA 2024-10-05 11:56:08 +02:00
smallmodel a379e6efbf Don't use Ninja on Windows because of chocolatey servers causing troubles 2024-10-05 00:39:23 +02:00
smallmodel b1e1b6cc68 Properly aim at the last enemy position with some randomness applied 2024-10-04 22:10:51 +02:00
smallmodel da86e0ce34 Fix bot incorrectly jumping 2024-10-04 21:23:49 +02:00
smallmodel 6ca12eb0de Fix bot sometimes being stuck respawning between team spawn intervals 2024-10-04 20:27:28 +02:00
smallmodel a25442368b Make the bot jump more to avoid getting stuck 2024-10-04 20:25:05 +02:00
smallmodel e7e95d47a5 Prevent others from picking up the health item if their future health will be full 2024-10-04 19:59:09 +02:00
smallmodel 292fe8eab4 Stop moving if there is a maximum fire movement so the weapon can be fired 2024-10-04 19:48:09 +02:00
smallmodel 272a401189 Make the bot jump even if the path is not valid to get out of spawns with no path nodes 2024-10-04 19:03:33 +02:00
smallmodel 592e3f47e9 Handle curiosity sounds better by getting the owner of concerned entities and ignoring team mates 2024-10-03 22:54:25 +02:00
smallmodel cabf1a9043 Make AI path more random 2024-10-03 22:23:46 +02:00
smallmodel e623541861 Improve the way bots turn, make it smoother 2024-10-03 21:57:29 +02:00
smallmodel b74b6f8c1d Use the last attacker origin instead of the last death position 2024-10-03 21:33:12 +02:00
smallmodel 11abdd451f Fix incorrect dir for PathSearch::FindPathAway 2024-10-03 21:27:30 +02:00
smallmodel 1c3596b1f9 Add more conditions to check for valid enemies when attacking 2024-10-03 20:45:23 +02:00
smallmodel 1e73333fbe Make bot path more random when idle 2024-10-03 20:22:54 +02:00
smallmodel 6eb49f567a Made tempaway path better 2024-10-03 20:10:33 +02:00
smallmodel 0120e7e4a5 Add liberation messages 2024-10-03 19:06:03 +02:00
smallmodel 10e4d3db11 Check if the activeItem is within the configstring range to avoid leaking data 2024-10-03 19:05:56 +02:00
smallmodel 0b34d2dbb8 Fix ammo bits being incorrect 2024-10-02 23:04:30 +02:00
smallmodel be1ef1de0e Try respawning when the player should respawn
This fixes an issue where bots wouldn't respawn with `sv_team_spawn_interval` set
2024-10-02 22:18:07 +02:00
smallmodel ef45c988c6 Fix player spectating often not spectating the next alive player 2024-10-02 22:16:58 +02:00
smallmodel 3ecdee1b89 Make bots play a taunt when they get a kill 2024-10-02 21:54:56 +02:00
smallmodel c7561b1f6d Send the GotKill event to the attacker when killed 2024-10-02 21:50:59 +02:00
smallmodel 50a3df8dff Fix the instant message maximum number on AA and SH/BT 2024-10-02 21:49:20 +02:00
smallmodel dfde4a58de Improve bot movements
- Do random movements if the path cannot be found
- Reset the movement if the bot is really blocked
- Set an higher fall height
2024-10-02 21:29:38 +02:00
smallmodel 090ba308d8 Clear bot buttons after spawning
This fixes a rare occurrence where the bot would fire and reload after spawning
2024-10-02 20:14:24 +02:00
smallmodel e01e989c22 Check if the snap is valid when notifying for hit/kill
The game would crash otherwise, this is also an issue in the original game
2024-10-02 20:10:29 +02:00
smallmodel a9b4af98fc Make bots use random player models 2024-10-02 19:42:03 +02:00
smallmodel 30f5442728 Limit bot vision distance to the farplane 2024-10-02 19:41:25 +02:00
smallmodel 123ca2812a Define and use DEFAULT_SFX_NUMBER_PLAYING 2024-10-02 19:02:20 +02:00
smallmodel 95435ea512 Improve bot movement
- The bot will immediately move upon spawning
- If blocked, the block will move randomly to get out
- There is now only 1/5 chance the bot will go to the location where they died
2024-10-02 18:34:45 +02:00
smallmodel db625baadd Set the healrate to 0 (instant) by default on protocol 8 and below (vanilla AA) 2024-10-02 18:12:10 +02:00
smallmodel 200a80aa02 Automatically choose a primary weapon for bots 2024-10-02 17:02:59 +02:00
smallmodel 0472a93c3f Ignore kills when telefragging
This fixes an issue (that also occur on OG) where telefrags would also count towards teamkills
2024-10-02 17:02:48 +02:00
smallmodel 9b70e646dc Add "auto" to automatically choose a primary weapon 2024-10-02 16:52:22 +02:00
smallmodel 388ab210a7 Fix incorrect obituary hit location 2024-10-02 16:42:10 +02:00
smallmodel 15e8a71249 Fix bot userinfo accumulating with previous bot userinfo 2024-10-02 15:59:41 +02:00
smallmodel dfd04f0d41 Reset the player state when using a turret
This prevents the player from using the turret + hold their weapon to crouch and become impossible to hit
2024-10-02 14:50:11 +02:00
smallmodel 88ac49c0c9 Set the correct flag when the player is using a turret 2024-10-02 14:35:37 +02:00
smallmodel 7d6ff3e6a4 Format bg source files 2024-10-02 14:09:36 +02:00
smallmodel c68fbfacb9 Set the EF_PLAYER_IN_MENU flag when the player is talking 2024-10-02 14:09:27 +02:00
smallmodel 8e51c7ca3b Fix VEHICLE_TYPE state condition not returning the vehicle type
This fixes player lacking animation when using heavy weapons like the granatwerfer
2024-10-02 14:09:07 +02:00
smallmodel 33064f8392 Set a default minimum delay between text messages 2024-10-02 13:31:45 +02:00
smallmodel 40141465b5 Add a section about flood protection 2024-10-02 13:29:58 +02:00
smallmodel 13d855c2e7 Use Cmd_Argv() to check for dmmessage 2024-10-02 13:07:04 +02:00
smallmodel 2f8b6a2009 Satisfy stufftext tests 2024-10-02 12:27:57 +02:00
smallmodel 23e56e767f Increase sphere light limit
Some servers have a lot of objects in maps, causing all spheres to be used
2024-10-02 12:18:58 +02:00
smallmodel ce5b954c4d Use the target game version when sending the version to the server, instead of the global project version
The non-dedicated server version of MOH: Breakthrough (standalone executable) rejects clients that have a version of 2.30 or below, or a version of 2.50 or above (0.1 difference), which prevents playing LAN sessions of Breakthrough. To solve this issue, the client now sends a version value that is within the allowed version range for the target game
2024-10-01 23:36:05 +02:00
smallmodel a0c20663a0 Don't make the player not solid in a vehicle slot
This fixes player not taking hits from explosions
2024-10-01 23:25:01 +02:00
smallmodel 56f850b59d Don't add the same world surface more than once
This fixes an issue where shaders like water, ocean would look strange or completely black, due to them blending against each other multiple times
2024-10-01 20:51:56 +02:00
smallmodel 253d4e2c4d Fix jammed door message printed on the first client 2024-10-01 20:26:17 +02:00
smallmodel 6fef42d6e0 Localize the jammed door message 2024-10-01 20:25:51 +02:00
smallmodel d6a00a5984 Fix IsOpen event not being used
Some multiplayer and single-player scripts rely on it
2024-10-01 20:24:12 +02:00
smallmodel 26a1e24e3a Fix TIKI_ParseAnimations incorrectly swallowing the full animation file when the map doesn't match
This fixes missing animations
2024-10-01 19:53:33 +02:00
smallmodel 6103efa8cc Don't set the entity angles immediately during glue
The game expects objects to glue and keep their initial angles/origin
2024-10-01 19:03:17 +02:00
smallmodel 9a7ba0786c Set the correct number of bits for the large bullet flag in 2.0 and above
This fixes the issue where there the client (in spearhead protocol mode) would read 2 bits instead of the 1 bit the server sent, which would cause a parse error
2024-10-01 18:52:39 +02:00
smallmodel 935efaeb3a Fix sound event being posted with incorrect arguments
The argument wouldn't contain "wait" when necessary, which would cause scripts to be stuck forever waiting for sound to be done
2024-10-01 18:09:56 +02:00
smallmodel 020a6d8b66 Fix stupid compile error mistake 2024-09-30 22:39:33 +02:00
smallmodel 9dea8fc41e Fix wrong pointer type passed to strncmp 2024-09-30 21:59:14 +02:00
smallmodel 3a7e249edf Refactored svflags and use the correct entity server flags 2024-09-30 19:58:41 +02:00
smallmodel c406aaf74f Add a feature that prevents teams from being uneven 2024-09-29 19:00:19 +02:00
smallmodel 83938471ca Set the blue component of the temp model entity
This fixes particles having an incorrect color sometimes
2024-09-29 15:41:35 +02:00
smallmodel db6ff8901b Set the render effect of skyportal and skyentity when adding them to the snapshot
This fixes the issue where some entities like effects would be visible through the sky
2024-09-29 15:27:54 +02:00
smallmodel 737ee3af64 Specify the compiler to use globally for macOS 2024-09-29 14:46:42 +02:00
smallmodel 9ea40f31e4 Clear all entities on registration 2024-09-29 13:30:56 +02:00
smallmodel 27bd6f4b1c Merge pull request #379 from smallmodel/me/throbbingbox
Fix the destroyed model of specific throbbing boxes
2024-09-29 13:09:09 +02:00
smallmodel b9e9137f90 Fix the spelling for the default explosive sound 2024-09-29 13:03:10 +02:00
smallmodel bee0bbbe90 Initialize the effect and destroyed model for the specific ThrobbingBox explosive classes 2024-09-29 13:02:56 +02:00
smallmodel 277ca0c951 Handle bigger offsets in sample_ms_offset()
This fixes an issue where when the offset was big enough, the value would overflow and start again from 0
2024-09-29 12:34:07 +02:00
smallmodel 8aa059dd21 When paused, keep in sync with the server time (#371)
This fixes an issue where a temporary lag would occur when starting a single-player map, or when pausing/unpausing the game
2024-09-29 00:10:52 +02:00
smallmodel c39bdd246a Correctly load DDS file on bigendian architectures 2024-09-28 20:56:55 +02:00
smallmodel 9823af9159 Fix light grid offsets endianness 2024-09-28 20:45:04 +02:00
smallmodel 9ee0e0a3c9 Correctly copy data on big-endian (#365) 2024-09-28 20:09:42 +02:00
smallmodel bf184fb719 Use #pragma once instead of #ifndef 2024-09-27 20:19:11 +02:00
smallmodel 94f308c50f Draw a black outline for game messages and death messages when targeting mohta or mohtt 2024-09-27 20:01:48 +02:00
smallmodel bfa0ef64ec Fix the letterbox not transitioning smoothly
This fixes the letterbox being shown immediately
2024-09-27 19:35:30 +02:00
smallmodel 98fc0a8cb9 Fix the letterbox not correctly rendering
When a letterbox was active, it was covering the entire screen
2024-09-27 19:33:39 +02:00
smallmodel facabc09f5 Don't set the label shader if the specified material name is considered empty (#364)
For labels linking to a variable for the shader, this prevents the label from still being rendered, drawing the tiled square grid (notexture)
2024-09-27 18:30:03 +02:00
smallmodel 51afcd7b96 Fix loading screen being incorrectly displayed
This fixes an issue where some part of the loading screen would not be drawn correctly, due to the screen being updated recursively through UI_Update()
2024-09-27 17:59:03 +02:00
smallmodel 340f1bb287 Put chat first in game and add a statement for disabling text messages 2024-09-26 22:13:33 +02:00
smallmodel 40c8479448 Update server configuration documentation 2024-09-26 20:48:26 +02:00
smallmodel 27e2063bf9 Add server configuration documentation 2024-09-26 20:30:37 +02:00
smallmodel e43f0a9285 Add a new feature to enable/disable instant messages and text chat with a variable to set the minimum delay between messages 2024-09-26 19:29:56 +02:00
smallmodel a977cbdd26 Update README 2024-09-26 19:27:11 +02:00
smallmodel dbc536c6c2 Fix voice chat time not working on FFA 2024-09-26 19:10:01 +02:00
smallmodel 97c9075503 Fix a small mistake in normal calculations for MM_ClipVelocity2D
Same error as commit c76dda1523. This fixes an issue where AI would run too slowly, like the crate guy in the intro of e1l1, the crate guy was too slow that it ran through the intro vehicle
2024-09-26 18:20:25 +02:00
smallmodel 290e45062d Set the server time before calling ge->RunFrame() in SV_SpawnServer()
This fixes an issue where some scripts wouldn't be initialized in time, like those that set AI animations. For example this caused an issue with the plane passenger in e2l1, where the animation would get reset due to a very specific chain of events
2024-09-26 01:18:11 +02:00
smallmodel fc6bffe683 Don't post event when loading save game 2024-09-26 01:01:27 +02:00
smallmodel 1fb8327ca9 Don't let the frame msec go below 0 2024-09-25 22:14:27 +02:00
smallmodel 36208de902 Fix spawn time delta 2024-09-25 22:12:29 +02:00
smallmodel 5403577642 Fix the return value of FS_Seek
It returns a negative value on failure, so handle that properly
2024-09-25 21:04:55 +02:00
smallmodel c76dda1523 Fix a small mistake in normal calculations for MM_ClipVelocity
This leaded to some occasional errors in AI movement, like in e3l2 where the medic gets stuck while going down the stairs
2024-09-25 20:22:42 +02:00
smallmodel b5034e5b12 Fix the m_iSaySlot being mistakenly used for the weight cross blend, the specified slot parameter must be used instead
This fixes #266 where some AIs would lack speech animation
2024-09-25 20:04:58 +02:00
smallmodel b039333922 Call AnimName() to get the current animation name 2024-09-25 19:48:06 +02:00
smallmodel b504e0d109 Call CurrentAnim() to retrieve the animation index 2024-09-25 19:47:43 +02:00
smallmodel 0692b9dcdb Fix events sometimes not being posted to entities
Fixes #253
2024-09-25 19:41:21 +02:00
smallmodel 085b72154f Use a more modern implementation of minizip from ioquake3 2024-09-24 22:25:33 +02:00
smallmodel 4f99c0fa98 Merge branch 'me_main' 2024-09-24 20:11:44 +02:00
smallmodel b38b71eb44 Small mistake fix 2024-09-24 20:11:34 +02:00
smallmodel 639da1a4b8 Remove unused variables 2024-09-24 20:09:39 +02:00
smallmodel f2d27aae3f Update getting_started_running.md 2024-09-24 20:06:37 +02:00
smallmodel 931876ac77 Remove lidbad-0.15.1b 2024-09-24 20:03:30 +02:00
smallmodel e5f62a9188 Update features.md 2024-09-24 20:02:41 +02:00
smallmodel 3fb699979c Fix small equality mistake (expected assignment) 2024-09-23 22:44:11 +02:00
smallmodel 85f15a1f28 Delete spawnthings when their last temp model is freed
This fixes:
- Losing FPS in a match with a lot of players, due to a massive amount of emitters getting spawned every time a weapon fires
- Memory leaks due to emitters staying in memory forever after being spawned
2024-09-23 19:29:07 +02:00
smallmodel 758017b638 If the temp model being removed is the head one, use its sibling 2024-09-23 19:16:31 +02:00
smallmodel 724d1db9b8 Properly clear parents of orphaned entities 2024-09-22 21:38:35 +02:00
smallmodel 00421fbee6 Fix the link to the branch build workflow 2024-09-22 20:18:40 +02:00
smallmodel 2510bab41f Change the order of the target os for more clarity 2024-09-22 20:16:51 +02:00
smallmodel c6675f2013 Remove special features code to avoid any confusion 2024-09-22 20:06:31 +02:00
smallmodel 1fd6c2bd52 Merge pull request #360 from pryon/UINotepad-fixes
UINotepad fixes and improvements
2024-09-22 19:35:52 +02:00
smallmodel 8f355fe188 Add Voip code from ioq3 2024-09-22 16:50:44 +02:00
smallmodel dbd10a281b call CL_ShutdownInput() 2024-09-22 16:39:30 +02:00
smallmodel d57ea3695b Add VOIP code for cl_input 2024-09-22 16:38:00 +02:00
smallmodel 8dd74b7789 Get rid of the code that sends next fragments from clients 2024-09-22 16:35:12 +02:00
smallmodel 36c00f146d Improve gamepad support 2024-09-22 16:19:55 +02:00
SmileTheory aba9f25744 Fix frame_msec possibly being zero in cl_input.c.
This fixes a mouse freezing bug.
2024-09-22 16:14:01 +02:00
smallmodel dacfa6ae55 Made common source file a C file as it should be 2024-09-22 16:03:02 +02:00
smallmodel f53fba082a Improve memory for debugging purposes 2024-09-22 15:45:29 +02:00
smallmodel 764b95f617 Set a better name for binaries to properly distinguish the name of the architecture 2024-09-22 14:56:02 +02:00
smallmodel 3237b3564e Update getting started running 2024-09-22 14:23:51 +02:00
Zack Middleton 985731f543 Fix command line variables not being set correctly
+seta, +sets, and +setu were ignored because Com_AddStartupCommands
thought Com_StartupVariable handled it.

+set didn't allow value to be multiple tokens which due to Unix shell
unintuitively removing quotes causes the variable to only be set to
the first token. This could be worked around by escaping quotes

    ioq3ded +set g_motd \"hello world\"

but it doesn't match behavior of other start up commands (which now
includes seta, sets, and setu) that use all tokens.
2024-09-22 13:47:55 +02:00
Thilo Schulz 7c28efe9cd Fix bug where Com_StartupVariable would set CVAR_USER_CREATED on already existing cvars 2024-09-22 13:36:23 +02:00
smallmodel 5b567f4cba Fix music volume not restored when the map restarts after the intermission 2024-09-22 01:39:40 +02:00
smallmodel 78918eb59d Correctly process statements with a semicolon 2024-09-22 01:23:23 +02:00
smallmodel 1848506f09 Properly pass the size of the path buffer into Q_strncpyz 2024-09-21 23:09:16 +02:00
smallmodel ce0004a296 Use unsafe version of strcpy as the buffer length is unknown 2024-09-21 23:08:52 +02:00
smallmodel e85d3f2a19 Pass the correct size to Q_strncpyz 2024-09-21 22:50:53 +02:00
smallmodel 4e5a0a30bf Fix subtitle being incorrect due to the size of the pointer (and not the size of the string) being passed to Q_strncpyz 2024-09-21 21:09:12 +02:00
pryon 9ab37e54b4 Fix CodeQL printf argument type warning 2024-09-21 20:59:27 +02:00
smallmodel 0bd15172b1 Use Ninja generator for faster builds and set compiler/flags in environment variables directly to reduce copy-pasted parameters 2024-09-21 20:34:45 +02:00
pryon fe0e5c1d9c Fix bug when multiple lines are joined together after copy-pasting text 2024-09-21 20:08:11 +02:00
pryon 5128d88722 Fix bug when deleting multiple lines doesn't actually remove everything selected 2024-09-21 20:04:57 +02:00
pryon 173ca3e58e Fix assertion failures on str operations 2024-09-21 20:02:58 +02:00
pryon 2a13fca737 Fix an off-by-one bug when selection points are determined 2024-09-21 20:01:03 +02:00
pryon b3a9f4423b Fix crash when saving a file with no contents or with no name 2024-09-21 19:52:20 +02:00
pryon 62c24826e6 Silence some localization error console spam messages
This helps to reduce the number of `LOCALIZATION ERROR` messages in the console for strings that couldn't be translated anyway
2024-09-21 19:49:43 +02:00
pryon a3d2c2c044 Properly free uipopup_describe instances 2024-09-21 19:46:32 +02:00
pryon 72409622ef Stop activating controls when their vertical scrollbar is hovered over
This fixes the annoyance of open windows (console, notepad) losing focus just by simply moving the mouse around
2024-09-21 19:43:18 +02:00
pryon c8a2de8235 Implement FS_FileTime for proper retrieval of file date/size info in FilePicker 2024-09-21 19:37:50 +02:00
pryon 6b91846b0c Reimplement Sys_ListFiles and Sys_ListFilteredFiles
They had several bugs, like showing the current and parent directory entires twice, not seeing files but only directories, etc.
2024-09-21 19:36:13 +02:00
pryon 92190220aa Implement clipboard functionality 2024-09-21 19:32:23 +02:00
smallmodel 705d30d125 Add ninja/cmake/clang to the list of packages to install 2024-09-21 19:18:35 +02:00
pryon c316dc7b00 Fix incorrect line width calculation when tabs are present 2024-09-21 19:17:25 +02:00
smallmodel 529dc29d08 Remove CMake parallel build setting 2024-09-21 19:15:26 +02:00
smallmodel 91e760bf5f Use a more recent version of ubuntu image for linux 2024-09-21 18:50:10 +02:00
smallmodel 61e24499bf Cross-compile macOS binaries with single hosted runner image 2024-09-21 18:44:23 +02:00
smallmodel 75621651e5 Add arm64 to valid OSX architectures 2024-09-21 18:30:37 +02:00
smallmodel 3973b95746 Build MacOS binaries from GitHub Action 2024-09-20 23:09:07 +02:00
smallmodel f9d264058b Use safe version of sprintf and strcpy 2024-09-20 23:08:53 +02:00
smallmodel a69d9d4483 Fix compilation errors for MacOS, and add support for MacOS 2024-09-20 21:31:27 +02:00
smallmodel 8b19d00086 Remove the last OpenAL linking as it's already linked before 2024-09-20 21:29:15 +02:00
smallmodel 1156d4f881 Replaced (u)int64_t with long long to avoid constructor conflicts with some compilers 2024-09-20 21:28:36 +02:00
smallmodel 08c5186426 Use stdlib.h as malloc.h is deprecated 2024-09-20 21:27:53 +02:00
smallmodel 61b4a817f3 Move alloca include directive to q_platform.h due to difference between platforms 2024-09-20 20:52:41 +02:00
smallmodel 13710904ba Update getting started installation 2024-09-20 18:45:15 +02:00
smallmodel 015ebb650e Clean up ClassDef class 2024-09-19 22:50:33 +02:00
smallmodel 17d623bf85 Add more clarity + check the length of the const_str enumeration and the length of the const string array to make sure they both match 2024-09-19 21:23:19 +02:00
smallmodel 0049348de5 Update features documentation 2024-09-19 21:06:22 +02:00
smallmodel 20d11f5f97 Add max_amount parameter to the EV_Sentient_GiveAmmo documentation 2024-09-19 21:02:04 +02:00
smallmodel 047a7bb949 Deprecate r_forceClampToEdge in favor of automatic detection
This avoids setting the variable manually to fix sky seams and weird graphical artifacts. Now, it's detected automatically
2024-09-19 21:00:22 +02:00
smallmodel 52c79f7f77 Make crates correctly fall 2024-09-19 20:49:33 +02:00
smallmodel c97bc2e977 Add more clarity in crateobject.cpp 2024-09-19 20:38:31 +02:00
smallmodel 78d564cc04 Fix CrateThink stopping when it shouldn't 2024-09-19 20:34:04 +02:00
smallmodel e27c0716c4 Allow more stufftext commands when the local server is running
Those stufftext commands are primarily used by single-player maps and briefings
2024-09-19 20:14:15 +02:00
smallmodel 35d037daff small detail change 2024-09-19 20:00:53 +02:00
smallmodel f055162ac0 Adjust the quick message DM console rectangle to avoid seeing characters 2024-09-19 19:46:27 +02:00
smallmodel f2e32c737b Fix the gap in the console between the bottom line and the text 2024-09-19 19:46:07 +02:00
smallmodel 205709271b Add fixes from upstream ioq3 2024-09-19 19:24:31 +02:00
smallmodel 3e70a9fab8 Fix mistakes that lead to compilation errors 2024-09-19 19:19:58 +02:00
smallmodel 733c6c96f0 Merge pull request #359 from twolife/spelling
Fix a few typos
2024-09-19 17:44:08 +02:00
Sébastien Noel a010e648ee Fix a few typos 2024-09-19 10:52:47 +02:00
smallmodel 1c7b561aa9 Filter stufftext commands
This works by allowing the stufftext server command to be executed if the statement only contains whitelisted commands and variables
2024-09-18 23:51:39 +02:00
smallmodel 75a71d35ec Avoid calling isspace with a character that has a value below 0 2024-09-18 23:04:01 +02:00
smallmodel 7c0f0672bd Add r_vidmode1024 and r_vidmodemax so the display resolution can be changed in Spearhead and Breakthrough 2024-09-18 22:59:30 +02:00
smallmodel 8fc6b6e3c3 Correctly handle quick message and message mode for the chat window
This fixes the chat window not being put in quick message mode at all when intended, now it also correctly handle team/private message modes
2024-09-18 22:14:16 +02:00
smallmodel 6c2c8ca2b7 Don't archive s_openaldevice and s_openaldriver 2024-09-18 22:10:33 +02:00
smallmodel 1b6bdd07e7 Disable function keys for UI
This fixes the issue where menus like the message mode can't be toggled
2024-09-18 21:51:35 +02:00
smallmodel 539688dd3d Reduced the delay to 33 ms (30 fps) to update the loading bar
This makes the loading bar smoother
2024-09-18 20:56:13 +02:00
smallmodel 08e09c3b4c Avoid setting variables with the same value
This prevents the console from being spammed with constant variable change when `developer` is set to 2
2024-09-18 20:55:02 +02:00
smallmodel 4259053c7e Expose methods for basic DMA (when OpenAL is unavailable) 2024-09-18 20:49:38 +02:00
smallmodel c221cfd493 Reorganize workflows and use multiple environments for different release stages 2024-09-18 20:33:30 +02:00
smallmodel 41298b53d4 Add PRODUCT_VERSION_STAGE variable to define the stage of the software through builds 2024-09-18 18:13:57 +02:00
smallmodel ddcd05adc6 Cancel other CodeQL actions on newer pushes 2024-09-18 17:10:25 +02:00
smallmodel a28cd64c7a Update implementation documentation again 2024-09-18 00:30:38 +02:00
smallmodel 38e62fef18 Update the implementation documentation with the current state 2024-09-18 00:26:51 +02:00
smallmodel 3f139f463b Remove stub print 2024-09-18 00:19:05 +02:00
smallmodel 0597191319 Implement SkelVec3::IsUnit 2024-09-18 00:18:08 +02:00
smallmodel f4c8b0c21f Initialize the cube build info
This should fix lighting being too dark or incorrect in some places
2024-09-17 22:22:42 +02:00
smallmodel bba7031f3d Add more clarity to code 2024-09-17 22:20:20 +02:00
smallmodel 4785913e02 compare_light_intensities should compare intensity as integers directly 2024-09-17 21:31:50 +02:00
smallmodel a6808d1f6a Fix incorrect light color for point lights and spot lights, also handle negative point light intensity
This fixes lighting from sphere being computed incorrectly for entities, making entities often look black or having strange lighting color
2024-09-17 21:27:14 +02:00
smallmodel 7188e9832a Fix leaf iteration 2024-09-17 20:51:00 +02:00
smallmodel 0cce0c81fb Prevent world values from being overridden by entities 2024-09-17 20:32:39 +02:00
smallmodel a60baa03e0 Add MAX_SPHERE_LIGHTS 2024-09-17 20:06:35 +02:00
smallmodel b0c8dafb33 Correctly compute colors for static model in vertex lit texture 2024-09-17 20:02:37 +02:00
smallmodel b672fc8b29 Add #if, #if_not and #else shader statements 2024-09-17 20:00:24 +02:00
smallmodel eac69f659f For dot/oneminusdot, shader needs normal 2024-09-17 20:00:00 +02:00
smallmodel d9ab65154c Fix incorrect lighting grid blend 2024-09-17 00:27:01 +02:00
smallmodel c120aed8bb Fix incorrect static model grid lighting 2024-09-16 22:11:58 +02:00
smallmodel ecdbe3d959 Don't check lightmap for RB_StageIteratorVertexLitTextureUnfogged to be used 2024-09-16 22:01:04 +02:00
smallmodel 96d10fb8b0 Mark r_light_nolight as cheat 2024-09-16 20:50:02 +02:00
smallmodel 2ab826268d Clear the legs state during the torso evaluation when the movecontrol is not legs
The legs state won't be stuck anymore waiting for an empty animation. This could happen under special circumstances, when the torso evaluation sets the movecontrol to non-legs (clears the legs anim) and then back to legs in subsequent iterations.
Fixes #105, the issue cannot be exploited anymore for land-sharking
2024-09-16 20:20:19 +02:00
smallmodel c3e3f368e0 use cheats rather than sv_cheats to check if the client is connected to a cheat server 2024-09-16 18:59:36 +02:00
smallmodel f35582489d Fix support for british, russian and italian voices in Spearhead and Breakthrough 2024-09-16 18:09:56 +02:00
smallmodel 9acea3484d Play zing sounds only if the location if the zing is valid
This fixes a potential crash where uninitialized position would be passed to the sound system
2024-09-16 17:39:15 +02:00
smallmodel a72da9b73e Fix incorrect terrain height for poly
This caused decals to float in the air when they were placed on the terrain
2024-09-15 23:49:42 +02:00
smallmodel df53d35967 Fix real dynamic lighting algorithm for both terrain and patch
This fixes #356 where real dynamic lighting would look completely wrong, making it look like there are graphical artifacts on surfaces
2024-09-15 21:23:17 +02:00
smallmodel e5e7421d3c Fix terrain lightmap when there is a dynamic light map
This fixes terrain having a completely wrong lightmap texture coordinates for dynamic lighting
2024-09-15 21:21:38 +02:00
smallmodel 6ff25d00fc Use lightmap offset for grid surface when a dlightmap is specified 2024-09-15 21:15:01 +02:00
smallmodel 4a5b0b3105 Fix y lightmap position when allocating a new lightmap block
See the issue with dynamic lights: #356
2024-09-15 19:39:22 +02:00
smallmodel d05d964432 Fix NaN lmapStep for terrain patches 2024-09-15 19:34:25 +02:00
smallmodel daa4a67b49 Reuse dlightmap in R_CheckDlightSurface and R_CheckDlightTerrain 2024-09-15 19:34:06 +02:00
smallmodel 9c0224911c Reset the number of dynamic lights when calculating the real terrain lighting
This fixes a crash that can occur when there is only the terrain that can be lit with dlights
2024-09-15 12:02:05 +02:00
smallmodel ef5759cff5 Don't execute commands during the intro 2024-09-15 01:21:20 +02:00
smallmodel 77292fb9ab First person spectator fix (not working yet) 2024-09-15 01:21:17 +02:00
smallmodel 6fb9ab078e Implement RE_DrawBackground_DrawPixels 2024-09-15 01:12:00 +02:00
smallmodel 844a72e0f3 Add DrawPixels and PixelZoom 2024-09-15 01:11:52 +02:00
smallmodel 46e9046629 Implement VehicleHalfTrack 2024-09-15 01:03:37 +02:00
smallmodel e5af60787e Partially implement GetZone/IsInZone 2024-09-15 00:42:35 +02:00
smallmodel 4b0696a187 Implement remaining methods of ClientGameCommandManager 2024-09-15 00:42:22 +02:00
smallmodel a6377fedab Remove useless code 2024-09-14 23:36:19 +02:00
smallmodel 2f884e6d55 Call Key_GetCatcher/Key_SetCatcher instead of modifying the variable directly 2024-09-14 23:32:24 +02:00
smallmodel 28f8c65771 Key_SetCatcher() must use cls.keyCatchers 2024-09-14 23:30:30 +02:00
smallmodel b509ef5ab4 Deactivate the mouse only when loading 2024-09-14 23:29:30 +02:00
smallmodel 9f48dabaec Play the game's intro when starting 2024-09-14 22:59:27 +02:00
smallmodel 5b0224ae3c Implement support for playing movies
Videos like briefings and intro are now played correctly
2024-09-14 22:58:43 +02:00
smallmodel c3ef267d6d Implement movie audio in OpenAL code 2024-09-14 21:55:15 +02:00
smallmodel fe9b298705 Export cl_movieaudio 2024-09-14 21:53:19 +02:00
smallmodel 0b106cf47e Print errors only when developer mode is set 2024-09-14 13:21:08 +02:00
smallmodel 9b417c9b26 Add EV_Client_ForceFeedback (unused) 2024-09-14 13:20:55 +02:00
smallmodel 37d5458c4c Partially implement cinematic support for reading RoQ files (no audio yet) 2024-09-13 23:00:31 +02:00
smallmodel 77d48cb104 Don't call UI_ClearBackground in cinematic mode 2024-09-13 22:58:37 +02:00
smallmodel a25200741a Finis the loading screen if it's the default 2024-09-13 22:23:53 +02:00
smallmodel d04a32920a Fix an incorrect parameter value passed to FS_Read when reading the DCL file 2024-09-13 21:49:45 +02:00
smallmodel 792b676c11 Set the number of brush models
The level marks system depends on the number of brush models and leafs, having a number that doesn't match what was saved would cause a crash
2024-09-13 21:47:57 +02:00
smallmodel 690a7a7557 Format cl_ui file 2024-09-13 21:36:23 +02:00
smallmodel e128c93ad9 Declare CL_FinishedStartStage 2024-09-13 21:25:41 +02:00
smallmodel 39add5ccec Fix incorrect parsing of music volumes 2024-09-13 20:01:01 +02:00
smallmodel a1a89cba34 Allow dynamic adjustment for the size of status columns in SVC_Status 2024-09-13 19:50:29 +02:00
smallmodel 2d696cf500 Also use the port when connecting to a server 2024-09-13 19:07:06 +02:00
smallmodel 45fe0bc8b7 Add an IP column
See #353 where servers would appear twice
2024-09-13 19:06:38 +02:00
smallmodel 9fc4c67187 Fix a crash when insep is 0 2024-09-13 19:05:30 +02:00
smallmodel 34aeab5f77 Fix the game type string being empty
(see #353 for the game type)
2024-09-13 18:34:43 +02:00
smallmodel b510452260 Remove useless comment 2024-09-12 23:48:46 +02:00
smallmodel 89b8d5a67b Use source files in renderercommon 2024-09-12 23:46:13 +02:00
smallmodel 500e3a3b2c Add support for JPEG screenshots 2024-09-12 23:33:39 +02:00
smallmodel 47e575ed9a define USE_INTERNAL_JPEG for compatible JPEG struct size 2024-09-12 23:33:21 +02:00
smallmodel 10b30d74e7 Implement sample_volume() 2024-09-12 22:23:27 +02:00
smallmodel 1ba4c6b7ad Remove useless comment 2024-09-12 22:18:09 +02:00
smallmodel eb899be95e Implement RE_GetGraphicsInfo 2024-09-12 21:40:07 +02:00
smallmodel 6d993af419 Fix compiler warning 2024-09-12 21:09:07 +02:00
smallmodel a136cccbe1 Implement R_CraterTerrain 2024-09-12 21:02:04 +02:00
smallmodel 2b43ebfca4 Add ter_crater command 2024-09-12 20:43:24 +02:00
smallmodel 06f4980ee1 Implement ghost textures with particles 2024-09-12 20:09:05 +02:00
smallmodel 6cdf5b7b7e Process .gst files 2024-09-12 19:44:36 +02:00
smallmodel 117b9a5579 Add declarations for GHOST functions 2024-09-12 19:42:41 +02:00
smallmodel 9475be8f6f Remove entityNumIndexes/staticModelNumIndexes from declaration as it causes compilation issue on some compilers 2024-09-11 23:41:47 +02:00
smallmodel 41ca1797f9 Implement basic GHOST methods and functions 2024-09-11 23:21:50 +02:00
smallmodel e56ae3d266 Update features.md 2024-09-11 21:07:55 +02:00
smallmodel 735ffaf80b Implement swipe 2024-09-11 19:57:45 +02:00
smallmodel ed52d1c648 Implement R_FastDlightTerrain 2024-09-11 19:19:38 +02:00
smallmodel 78fa90c59b Move RB_StaticMesh to tr_model.cpp for info world tris 2024-09-11 19:03:41 +02:00
smallmodel 548a3efe5a Implement R_InfoWorldTris_f and R_PrintInfoWorldtris 2024-09-11 18:57:50 +02:00
smallmodel 18a12eeba3 Fix loop breaking instead of continuing 2024-09-11 18:51:05 +02:00
smallmodel 83d486ceeb Add missing declarations 2024-09-11 18:48:47 +02:00
smallmodel d898c0f995 Implement R_PrintInfoStaticModels 2024-09-11 18:45:17 +02:00
smallmodel 02faf6f8c1 Implement R_Sky_ChangeFrustum 2024-09-11 18:27:19 +02:00
smallmodel 3478bbddf2 Implement RB_ComputeShadowVolume 2024-09-11 18:02:39 +02:00
smallmodel fd1ee31e1e Remove useless comment 2024-09-11 17:56:26 +02:00
smallmodel 4a565f0985 Declare R_GetLightingGridValueFast 2024-09-11 00:23:43 +02:00
smallmodel c68f23cdaf Fix compilation warnings 2024-09-11 00:21:31 +02:00
smallmodel e386eb00ef Implement all lighting functions 2024-09-11 00:12:13 +02:00
smallmodel 662d048bf4 Implement R_AddLightGridSurfacesToScene 2024-09-10 20:42:05 +02:00
smallmodel d9e3cc2188 Add a way to draw the skeleton for debugging purposes 2024-09-10 20:16:56 +02:00
smallmodel a586f13af8 Remove CL_GamespyServers_f as there is an existing implementation 2024-09-10 19:58:28 +02:00
smallmodel 37820c1673 Generate QKey 2024-09-10 19:57:25 +02:00
smallmodel 8a2e4ca470 Add Com_RandomBytes and Com_IsVoipTarget 2024-09-10 19:54:25 +02:00
smallmodel 3a5da64c6f Make radar clients speak on mohaas/mohaab 2024-09-10 19:50:43 +02:00
smallmodel 9c018a2330 Implement CGM_FENCEPOST 2024-09-10 19:40:53 +02:00
smallmodel 0840cdd83a Restore the old behavior where the bullet would hit all entities in sight. Only works when targeting mohaa version 1.x
Fixes #348. Since 2.0, bullet trace stops after the first hit entity even if it's a trigger, which can be an issue on some SP maps.
2024-09-10 19:01:34 +02:00
smallmodel e972747969 Update documentation
This adds an example for using fs_homepath
2024-09-09 23:59:06 +02:00
smallmodel e151c6eb15 Update documentation 2024-09-09 23:38:37 +02:00
smallmodel 603444a69f Fix an issue where the remaining time would reach 0:00 and the match would never end
See #287, this occurred when the fraglimit was defined.
2024-09-09 22:25:54 +02:00
smallmodel 999e0fd721 Implement test emitter 2024-09-09 21:48:40 +02:00
smallmodel 47131dec44 Fix wrong special effects count 2024-09-09 21:43:20 +02:00
smallmodel 6adad053d9 Explicitly disable looping when setting the sample loop count to a value other than 0
This fixes a rare occurrence where some sounds would loop forever
2024-09-09 00:15:39 +02:00
smallmodel 725561b655 Fix the usage of memory, strings, constant and parameters 2024-09-08 23:54:47 +02:00
smallmodel b84fbf452e Pass a vec4_t to GL_SetFogColor() rather than a vec3_t 2024-09-08 23:49:48 +02:00
smallmodel eb7af2bce9 Implement basic test emitter functions 2024-09-08 23:33:55 +02:00
smallmodel 7c57c4b131 Fix wrong secondary ammo type being picked up 2024-09-08 20:20:58 +02:00
smallmodel 4460466cb3 Implement RE_SetRenderTime 2024-09-08 19:43:37 +02:00
smallmodel eea19d733d Add R_UpdateGhostTextures (unimplemented) 2024-09-08 19:43:29 +02:00
smallmodel abc97dcab3 Implement R_AddTerrainMarkSurfaces and RE_AddTerrainMarkToScene 2024-09-08 19:40:00 +02:00
smallmodel 065c791a10 Implement CG_ResetEffectCommandCvars 2024-09-08 19:29:40 +02:00
smallmodel 6b902e7f5d Remove "unimplemented" comment 2024-09-08 18:49:45 +02:00
smallmodel df0cb87b35 Implement CG_AddLightShow (cg_acidtrip) 2024-09-08 18:48:15 +02:00
smallmodel 0b9687fea4 Implement functions for printing content types, surface properties and surface types 2024-09-08 18:39:39 +02:00
smallmodel 99fbe092bc Use correct names for surface flags 2024-09-08 18:34:02 +02:00
smallmodel 7a7849ae83 Remove comment 2024-09-08 18:25:10 +02:00
smallmodel 47830bb330 Update version number 2024-09-08 18:24:59 +02:00
smallmodel 0dfb1a3a2a Use Com_DPrintf for TIKI/alias warnings/errors
This prevent the console from getting spammed with developer errors in production
2024-09-08 18:22:12 +02:00
smallmodel e2e1ab0275 Fix status command column length breaking some programs 2024-09-08 18:09:54 +02:00
smallmodel 4249cacf2f Support token dollar in variable name
This fixes mods like trapshooting not working because of a '$' in a variable name
2024-09-08 18:03:43 +02:00
smallmodel 4e3ec52673 Fix a crash due to NULL string being appended 2024-09-08 18:02:57 +02:00
smallmodel 98991a4a7a Fix file ordering with uppercase/lowercase file names 2024-09-08 17:59:30 +02:00
smallmodel bca6d656b6 Fix bad verts value passed to CG_AddFragmentToScene 2024-09-08 17:53:35 +02:00
smallmodel ffc3580d43 Implement CG_CheckCaptureKey 2024-09-08 16:31:19 +02:00
smallmodel c18cdc78ea Fix Cgame key catching 2024-09-08 15:48:46 +02:00
smallmodel 77ecc73631 Implement lens flare / sun flares
Some maps like mohdm1 have a sun flares, now when you look up the sky towards the sun direction, you will see the flare of the sun
2024-09-08 15:31:18 +02:00
smallmodel 3834f51d74 Fix GetNamedWidget() always returning the last valid widget
This is problematic when doing different logic when a widget doesn't exist, for example when loading a map, if the continue button doesn't exist then the game should continue automatically
2024-09-08 15:06:43 +02:00
smallmodel 86ddec3f76 Clear the world to prevent crashes 2024-09-08 14:59:10 +02:00
smallmodel 4d12bcb184 Export s_sun 2024-09-08 00:52:03 +02:00
smallmodel 7d93723382 Update getting started doc 2024-09-07 23:58:56 +02:00
smallmodel 8e1a52bbb7 Implement VIS debugging 2024-09-07 23:58:50 +02:00
smallmodel cd9b1a741f Match CG_PermanentMark parameters
This fixes #355
2024-09-07 23:57:17 +02:00
smallmodel cefe331e0c Remove useless surface flags 2024-09-07 23:51:52 +02:00
smallmodel 14d1fae54a Implement all treadmark functions 2024-09-06 22:10:22 +02:00
smallmodel a1601be7a6 Implement code to make tread mark decals 2024-09-05 23:54:01 +02:00
smallmodel a2ebeb11e3 Update features.md 2024-09-05 23:10:50 +02:00
smallmodel b7f0f32878 Fix DCL signature on big-endian architectures 2024-09-05 01:14:42 +02:00
smallmodel 58e39add5b Implemented treadmarks update functions 2024-09-05 01:04:53 +02:00
smallmodel 61725c95df Add MASK_TREADMARKS 2024-09-05 00:43:36 +02:00
smallmodel 71a1df661a Fix current mark's alpha component not updating properly 2024-09-04 21:54:49 +02:00
smallmodel 9eed0eab5f Implement CG_PermanentMark 2024-09-04 21:51:42 +02:00
smallmodel e42b6fe0a9 Fix current mark not updating if it has a rotation 2024-09-04 21:51:16 +02:00
smallmodel b1e640ad1d Implement CG_PermanentMark 2024-09-04 21:41:16 +02:00
smallmodel 2fc091fdf7 Skip loading if the file length is less than the dcl header length 2024-09-04 20:56:41 +02:00
smallmodel 47ba241e7d Fix file being closed but still used afterwards 2024-09-04 20:50:22 +02:00
smallmodel c0d37c504a Fix infinite loop in R_TerrainHeightForPoly 2024-09-04 20:46:10 +02:00
smallmodel 1e0195f6e3 Add variables that will be used in unimplemented functions 2024-09-04 20:29:29 +02:00
smallmodel e806c1ddf1 Move MAX_MARK values to tr_types_new.h 2024-09-04 20:23:20 +02:00
smallmodel 78f0072c59 Update the SFX datasize when downsampling
This fixes #349 where the size of the AL buffer didn't match the real downsampled size, which would cause AL to read way past of end of the data buffer
2024-09-04 20:12:46 +02:00
smallmodel 1022ce531a Fix AL buffers having sound data past end of the sound buffer 2024-09-04 20:10:56 +02:00
smallmodel 7f08a7bca8 Remove register keyword as it's deprecated since C++17 2024-09-04 20:10:21 +02:00
smallmodel 4123bef60d Implement R_ApplyLevelDecal 2024-09-04 20:05:48 +02:00
smallmodel c6464efa07 Implement level mark loading and updating 2024-09-04 00:02:07 +02:00
smallmodel 0a9075748e Fix OpenAL binary name on ARM64 2024-09-02 20:38:38 +02:00
smallmodel 3733761696 Fix the reloading sound in 2.0, the behavior is different in 2.0 and 2.30 2024-09-02 19:52:32 +02:00
smallmodel cde7cbc3a3 Implement G_ClientDrawTags 2024-09-02 19:52:32 +02:00
smallmodel e927da56cf Fix GetTagPositionAndOrientation() returning wrong tag axis and position 2024-09-02 19:52:31 +02:00
smallmodel 3b8bffe39c Fix variable misspelling 2024-09-02 19:52:31 +02:00
smallmodel 19da377064 Implement G_ObfuscationForSmokeSprites
This is used so the player can throw a smoke grenade and hide behind it for AI
2024-09-02 19:52:30 +02:00
smallmodel 4d1380b5c4 Implement G_ClientDoBlends and FindIntermissionPoint 2024-09-02 19:52:30 +02:00
smallmodel 25c2904d66 Implement RE_MapVersion and RE_PrintBSPFileSizes 2024-09-02 19:52:30 +02:00
smallmodel 53565663d9 Add old welcome code (commented out) for when a player becomes spectator 2024-09-02 01:01:55 +02:00
smallmodel 76f0e17987 Fix bullet trace end being out of bounds, causing clients to have a strange bullet trace 2024-09-02 00:42:29 +02:00
smallmodel 5052449e38 Fix invisible bullet tracers 2024-09-02 00:25:07 +02:00
smallmodel a539da3200 Clear velocity and avelocity in MoveDone
This fixes objects rotating forever like the radio tower in m1l3a
2024-09-02 00:06:12 +02:00
smallmodel fb875501f0 Fix UI library forcing latched variables
This caused issues when setting render variables
2024-09-01 23:34:57 +02:00
smallmodel 89d805ab92 Fix the FireDelay always returning for FIRE_PRIMARY 2024-09-01 20:42:19 +02:00
smallmodel 7852929da3 Fix the music replaying when loading from save after it ended 2024-09-01 20:38:11 +02:00
smallmodel 595e6fcb8b Fix AI firing forever in mohaa 2024-09-01 20:36:54 +02:00
smallmodel a9792bd4c3 Add comments above all actor.cpp methods 2024-09-01 20:21:44 +02:00
smallmodel c19bc7e7a2 Add comments about new additions from 2.0 and above 2024-09-01 20:04:10 +02:00
smallmodel 3e980ed371 Unset the script goal once the AI reached the point 2024-09-01 19:38:05 +02:00
smallmodel a9a7c7fdb8 Adjust area portal when closing before broadcasting ai events 2024-09-01 18:49:41 +02:00
smallmodel 5baf5bccf2 Notify scripts when door has closed/opened 2024-09-01 18:43:38 +02:00
smallmodel 981d72ac5a Add assertions to check for invalid path distance 2024-09-01 18:28:01 +02:00
smallmodel a9b8cdce64 Only print the long word error in debug mode 2024-09-01 18:10:16 +02:00
smallmodel f3222fc36a Set AI angles only if they don't have an enemy, otherwise let the AI set their angles
This prevented actors from attacking correctly because the AI cover target state expects the AI to 100% stare at the enemy and the vehicle would keep changing the AI angles
2024-09-01 17:16:09 +02:00
smallmodel e5aee8d206 Fix the MG42 fire delay being too slow by default for AIs 2024-09-01 16:51:41 +02:00
smallmodel 96d16bcbc1 Correctly check the max yaw offset in AI_CanTarget()
This caused AI to exit turrets immediately
2024-09-01 16:46:24 +02:00
smallmodel 010a5ffc74 Mark entities as missing until they are received
This fixes a bug where the plane sound in t1l1 would stop immediately because the entity isn't received at this point
2024-09-01 16:21:56 +02:00
smallmodel bed9bbbd05 Update classes documentation 2024-08-31 22:13:21 +02:00
smallmodel 5cc168111c Fix class not dumping properly 2024-08-31 22:10:44 +02:00
smallmodel bdec6aab07 Fix calls to class dumping functions 2024-08-31 22:09:50 +02:00
smallmodel 56cbab8661 Fix NumEventCommands() returning an incorrect result 2024-08-31 21:42:07 +02:00
smallmodel 29c3bece4e Prevent players to use developer commands like lod or view 2024-08-31 21:32:55 +02:00
smallmodel dc24a4a067 Stop spawning if there is no entity 0 (could only happen in multiplayer) 2024-08-31 21:32:42 +02:00
smallmodel c4683e2417 Don't execute entity events from the console if the client isn't running
This prevent the server from executing console commands for the first player
2024-08-31 21:18:35 +02:00
smallmodel 11f5870a8b Add ioq3 server fixes and improvement
- Add a rate limit to protect against DoS attacks
- Better IPv6 support
2024-08-31 21:04:10 +02:00
smallmodel 9de71e3529 Correctly check if the AI either can see or can shoot to find the enemy
The AI would get stuck trying to cover otherwise
2024-08-31 18:06:02 +02:00
smallmodel 81866d96e0 Make flesh impacts properly work 2024-08-31 18:02:07 +02:00
smallmodel 70fcc70348 Fix AI turret placement
The AI was too much off from the turret
2024-08-31 17:34:10 +02:00
smallmodel 1911f04079 Fix strange AI turret target angles
The turret sometimes turned extremely fast or ignored the max yaw offset
2024-08-31 17:22:28 +02:00
smallmodel b7288ba3f4 Don't affect the frameMsec with timescale as it causes issues with physics (like vehicles) 2024-08-31 16:50:10 +02:00
smallmodel be655e2b9c Fix the height of huddraw elements not being archived properly
A wrong variable was specified
2024-08-31 16:38:58 +02:00
smallmodel 915269e017 Fix the actor stuck targeting an enemy with really low threat (behind walls, not visible)
This fixes the actor being stuck aiming even if the player is near them
2024-08-31 16:24:59 +02:00
smallmodel 6071b5303c Remove useless NET_Sleep and make sure frameMsec doesn't go below 1 2024-08-31 16:18:28 +02:00
smallmodel e59a24ded3 Fix actors enemy not being able to be set if enemy switch is disabled 2024-08-31 16:17:37 +02:00
smallmodel 2239efa439 Fix sample_offset() returning a wrong value with looping sounds
The returned offset will now be the correct when the stream has been re-read from the beginning due to the sound looping
2024-08-30 21:12:39 +02:00
smallmodel 99fcec9f26 Initialize bStartedGame 2024-08-30 18:56:01 +02:00
smallmodel 2fe4e85543 Fix path goal end anim script never reaching
The end anim script should be executed below a certain speed (1/4 below normal speed).
This fixes a bug in e3l4 where the game would never continue past the first bunker. The actor would get stuck after collecting supplies for the first bunker at the beginning because it stopped too far away from the target origin
2024-08-30 00:44:14 +02:00
smallmodel 68f2635c06 Should be DotProduct2D 2024-08-29 23:31:46 +02:00
smallmodel 0147677412 Calculate sr/cr only if right or up is specified 2024-08-29 21:37:10 +02:00
smallmodel 89133bf05d Fix looping sounds not stopped when stopping all sounds
This fixes an issue where some random looping sound (like footsteps) would be heard after restarting or when loading a saved game
2024-08-29 19:29:16 +02:00
smallmodel 7a0a671f18 Use the correct value when comparing the sound awareness multiplied by the range factor 2024-08-28 00:41:53 +02:00
smallmodel c7d1f42edb Use centroid when broadcasting new AI event 2024-08-28 00:40:57 +02:00
smallmodel 2b9d31fe7f Normalize angles to fix interpolation issues on client
See #342
2024-08-27 15:24:31 +02:00
smallmodel 1f71bb714d Fix sounds unexpectedly getting marked as streamed when they are not
This fixes #345 where a crash occurred because of a NULL buffer, as streamed sounds don't have a memory buffer
2024-08-27 12:47:58 +02:00
smallmodel 6b21f7e92e Fix the turret firedelay behavior on mohaa base 2024-08-27 01:34:51 +02:00
smallmodel 8b5074b6ac Fix Dot/Texcoords calc
This caused some shaders such as headlights beam on the opeltruck being weirdly rendered
2024-08-27 01:07:51 +02:00
smallmodel 7f7d797fce Fix vehicles getting blocked by sentients dying 2024-08-27 00:36:03 +02:00
smallmodel 0b3aad5ad2 Fix entnum comparison (must be greater than or equal to the squadmate's entnum) 2024-08-27 00:09:13 +02:00
smallmodel ad88215b85 Cleaned up actor_runandshoot.cpp 2024-08-26 23:45:41 +02:00
smallmodel ccb1465e17 Use a raw pointer instead of the str object
Original game checks for the NUL character using the line buffer (`c_str()`) directly instead of the str object's operator[], as this would cause an assertion failure because the str's length ignore the NUL character
2024-08-26 23:09:55 +02:00
smallmodel fde4d8d54f Update README and bug report 2024-08-26 22:11:14 +02:00
smallmodel 37db2e8acc Update issue templates 2024-08-26 22:04:30 +02:00
smallmodel 9413eb0d58 Update issue templates 2024-08-26 21:58:10 +02:00
smallmodel 06d2eaf409 Fix doors opening and closing indefinitely by actors 2024-08-26 19:04:49 +02:00
smallmodel 444ce284ae Spawn a trigger field even if the TOGGLE flag is set
This fixes Actors not being able to open doors
2024-08-26 18:55:10 +02:00
smallmodel a150c1b18b Fix animation delta repeating when getting delta of the same frame
This fixes actors moving too much and strangely
2024-08-26 18:18:20 +02:00
smallmodel 194e898d90 Ignore bad SFX for 3D loop sounds 2024-08-26 13:22:40 +02:00
smallmodel 0b1a20dcff Properly save and restore sound position, also fix loopsounds not playing properly 2024-08-26 01:29:42 +02:00
smallmodel 93e7561cb3 Fix Actor::EventSoundDone() using the wrong parameter for the sfxName, causing the SoundDone event to be sent immediately 2024-08-26 01:05:58 +02:00
smallmodel 6ab654264b Cleaned up Entity::ProcessSoundEvent() 2024-08-26 01:05:13 +02:00
smallmodel 7023184892 Fix subdivisions endianness
See #332
2024-08-26 00:45:21 +02:00
smallmodel 07f13d1ae9 Force the soundtrack to be sent again 2024-08-26 00:08:29 +02:00
smallmodel ac22b1cfbf Use an higher fragment size when sending a message to the loopback 2024-08-25 23:41:03 +02:00
smallmodel e70cdfb898 Improve code readability 2024-08-25 22:01:03 +02:00
smallmodel 022181fcfd Remove processed buffers after half of the queued buffers has been processed 2024-08-25 16:49:24 +02:00
smallmodel e021289d36 Fix the turret setting incorrect angles 2024-08-24 19:23:11 +02:00
smallmodel 91b80a8e21 Fix the sound system not restarting when modifying the speaker type to 0 2024-08-24 19:19:55 +02:00
smallmodel 322ca2b42e Fix the loop protection not working when multiple scripts are executed
This fix will apply the protection globally
2024-08-24 18:50:04 +02:00
smallmodel d399ffd609 Set the correct sound velocity 2024-08-24 18:18:20 +02:00
smallmodel bf2626f804 Set the pitch before playing the sound 2024-08-24 17:53:13 +02:00
smallmodel 00f27ac02d Fix improper sound distance values 2024-08-24 17:35:35 +02:00
smallmodel 5134aed352 Mark the functions as inline to optimize function calls 2024-08-24 17:35:02 +02:00
smallmodel b457a84ed9 Fix AL_DISTANCE_MODEL value type, it must be an integer 2024-08-24 16:39:43 +02:00
smallmodel 8188d46ee7 Fix SetLittleLong() writing past end of bytes buffer
(even though the union was still 4-bytes because of the integer)
2024-08-24 15:10:12 +02:00
smallmodel d64e88451f Fix compiler warnings
Note that in Dismiss(), checking for `this` is not necessary (original code was generated by the compiler)
2024-08-24 15:08:42 +02:00
smallmodel c70c578194 Ignore ALC_OUTPUT_MODE_SOFT if unavailable 2024-08-24 14:51:58 +02:00
smallmodel 54ceff5107 Process the value of s_speaker_type 2024-08-24 14:25:25 +02:00
smallmodel 3b94904ea8 Update getting started 2024-08-24 12:01:37 +02:00
smallmodel 1c8b4a1922 Update the documentation to reflect the current state of the project 2024-08-24 01:03:36 +02:00
smallmodel 32b0b2dfac Fix camera angles changing too much when switching between linked turrets 2024-08-24 00:40:23 +02:00
smallmodel 6506577787 Add shader flags with tcMod rotate
This fixes vehicle wheels rotating forever. Wheels now rotate consistently depending on the vehicle speed
2024-08-24 00:35:39 +02:00
smallmodel 56775399d3 Fix 3D sounds not being attached to an entity when specified 2024-08-23 23:38:52 +02:00
smallmodel d6d40975e5 Add more file debug print 2024-08-23 23:32:46 +02:00
smallmodel e3936f52a2 Move Com_SwapSaveStruct to a better place 2024-08-23 22:39:14 +02:00
smallmodel 53d5dd1e40 Differentiate saves from mohaa, mohta and mohtt
Fixes #339 where Spearhead and Breakthrough would also display saves from mohaa
2024-08-23 22:25:43 +02:00
smallmodel b2ef0fd6e3 Swap the save game struct on big endian architectures 2024-08-23 21:09:12 +02:00
smallmodel 8832fbe55d Fix entities loopsound incorrectly having the streamed value at the end of the name, causing some sounds unable to load 2024-08-23 21:03:02 +02:00
smallmodel b5ffe756d6 Fix buffers unnecessarily being unqueued after source has stopped 2024-08-23 20:38:41 +02:00
smallmodel 01a0173a2f Take all branches into account for GitHub actions 2024-08-23 19:52:30 +02:00
smallmodel 7bebb2adab Statically link the CRT runtime in soft-oal 2024-08-23 19:51:47 +02:00
smallmodel 8c41576daa Remove assertion as sounds can be streamed at any time 2024-08-23 12:13:17 +02:00
smallmodel a529b37f25 Show some AL errors on developer mode only 2024-08-23 12:07:28 +02:00
smallmodel f84ed6b794 Fix crash when loading from save, caused by incorrect client-game state size
Closes #343
2024-08-23 11:48:50 +02:00
smallmodel 9526a92fc1 Use same parameters as oal to build OpenAL 2024-08-22 17:13:43 +02:00
smallmodel 5e60b89a0d Fix linux compile error 2024-08-22 16:13:03 +02:00
smallmodel e46625a52c Added more verbosity 2024-08-22 15:39:28 +02:00
smallmodel 037cb0f5cb Fix OpenAL64.dll name on Win32 and Win64 2024-08-22 15:18:20 +02:00
smallmodel f67a7c6621 List available devices and use Generic Software if Generic Hardware is the default 2024-08-22 13:30:04 +02:00
smallmodel 4839a2026b Fix string casting 2024-08-22 12:43:18 +02:00
smallmodel 219dbbb5b7 Open the default device by passing in the default device name instead of NULL 2024-08-22 12:39:14 +02:00
smallmodel d78de51bc2 Bump version number 2024-08-21 19:02:23 +02:00
smallmodel faa50352e0 Remove explicit USE_SOUND_NEW as OpenAL is the default 2024-08-21 18:53:57 +02:00
smallmodel f2b49f7ccb Fix wrong parameters 2024-08-21 18:48:16 +02:00
smallmodel 13911b051a Use OpenAL by default 2024-08-21 18:35:06 +02:00
smallmodel 694167d352 Merge pull request #341 from runlevel5/fix-compilation-errors
Fix compilation error [WIP]
2024-08-20 17:02:20 +02:00
Trung Lê 3b2e4ff9c1 Revert to original code 2024-08-21 00:18:38 +10:00
Trung Lê 16e0dc17a8 Add implicit conversion from const-qualified pointer types to non-const-qualified var 2024-08-21 00:13:04 +10:00
Trung Lê 1f4b7718e8 Refactoring gameExport_s::ReadLevel() and gameExport_s::WriteLevel() 2024-08-20 23:41:43 +10:00
smallmodel 8c59d6020e Backported ioquake3 fixes for https://www.cvedetails.com/cve/CVE-2017-11721/ (Buffer overflow) 2024-08-18 13:35:59 +02:00
smallmodel 377b0896c2 Fix drivable vehicle not having the death waittill after loading from save
This caused some vehicles to be destroyed immediately after being handled from script (like the halftrack in t2l1)
2024-08-18 12:03:01 +02:00
smallmodel a399fdf6cf Removed useless comments 2024-08-17 21:07:25 +02:00
smallmodel 783c24d6f7 Fix sound never playing from entities that are not sent to clients 2024-08-17 17:24:17 +02:00
smallmodel 1254146223 Fix streamed sound stopping before end 2024-08-17 11:09:35 +02:00
smallmodel f776d842d1 Don't load sound immediately if they must be streamed
This removes more hiccups
2024-08-14 19:08:20 +02:00
smallmodel 74acf35a89 Merge branch 'main' into features/oal-streaming 2024-08-13 21:07:27 +02:00
smallmodel 81b8fe3f61 Use a pointer to an array instead of accessing the tiki mesh field directly to avoid loop badly optimized due to the compiler thinking there can be only 1 element
This fixes #337
2024-08-13 20:55:12 +02:00
smallmodel 679bfb90ea Fix accessing 8th leaves element before finishing the loop
This caused the 8th element to be taken into account when enabling optimizations with GCC (invalid pointer to the leaf)
2024-08-13 20:41:53 +02:00
smallmodel deb18c53b7 Implement streaming support for OpenAL
See #333, and #324
2024-08-12 20:26:17 +02:00
smallmodel bbb7aa3771 Updated CodeQL actions to use newer version of steps 2024-08-12 18:23:03 +02:00
smallmodel eb04e26823 Use the new libmad version as it seems stable enough 2024-08-09 20:33:59 +02:00
smallmodel 3af24ee0ea Exclude new sound CPP files directly when not using the new sound system instead of using #ifdef 2024-08-09 20:30:35 +02:00
smallmodel 513fe7773f Don't append a '\' at the beginning during autocompletion 2024-08-08 20:44:00 +02:00
smallmodel 9150d1cc44 Fix lighting grid being incorrect
It fixes #321 where impacts like bullets would have an incorrect color (like red, green...)
2024-08-08 20:31:19 +02:00
smallmodel e19b72647e Use qglGenTextures to guarantee the uniqueness of the texture number 2024-08-08 19:07:09 +02:00
smallmodel d809975882 Use Q_snprintf because itoa is non-standard 2024-08-07 22:27:02 +02:00
smallmodel 7b92d99afa Fix compile error 2024-08-07 22:24:52 +02:00
smallmodel b463c905cf Free up unused images
This fixes #93 where the game would hit `MAX_DRAWIMAGES` after loading a few maps
2024-08-07 21:11:16 +02:00
smallmodel 7f8a0c9931 Fix the image texture number not properly matching the image
It caused issues with textures being messed up sometimes, after multiple maps were loaded
2024-08-07 21:10:04 +02:00
smallmodel 53d812666c Remove FIXME section 2024-08-07 21:02:48 +02:00
smallmodel 7b59f07181 Allow precaching image manually with r_precacheimages 2024-08-07 20:01:38 +02:00
smallmodel d22dea5e8e Count renderer memory 2024-08-07 19:57:09 +02:00
smallmodel 8817467216 Implement trace obfuscation 2024-08-06 22:58:16 +02:00
smallmodel 236afa7c3f Implement obfuscation mapping setup
The implementation reads all obfuscation csv and return a list of visual obfuscations
2024-08-06 20:21:00 +02:00
smallmodel cd6ec5e3a7 Fix streamed sound, use 2D instead with properly implemented panning 2024-08-06 18:43:15 +02:00
smallmodel 434aaf3eaf Initialize last animation time 2024-08-05 23:41:17 +02:00
smallmodel 5b80ea20c7 Fix filename case sensitivity on Linux
This fixes #334 where some sounds wouldn't play because some scripts reference sounds without respecting the case
2024-08-05 21:11:49 +02:00
smallmodel 1d60405eaa Fix heap corruption when taking screenshots with non-standard resolutions like 1366x768 2024-08-05 19:48:23 +02:00
smallmodel 64f4f59165 Fix vid_restart and snd_restart resetting the sound system (experimental sound system only)
This fixes #335 where one of those commands would clear all active sounds as well as the triggered music, and the soundtrack
2024-08-05 19:21:38 +02:00
smallmodel 192f9ac514 Added S_CurrentSoundtrack() 2024-08-05 19:14:30 +02:00
smallmodel 279b1413ec Clear the active music when stopping the triggered music 2024-08-05 19:09:29 +02:00
smallmodel 9c5297882c Renamed CHANNEL_FLAG_PLAYABLE to CHANNEL_FLAG_PLAY_DEFERRED 2024-08-05 18:49:41 +02:00
smallmodel a6d508d791 Fix sounds replaying when unpausing
This caused some sounds to play again when saving
2024-08-05 18:49:16 +02:00
smallmodel 6b3402c631 Fix actor accuracy being crazy, killing the player easily 2024-08-05 18:43:56 +02:00
smallmodel d5da32b8a9 Fix AI damage 2024-08-05 18:43:40 +02:00
smallmodel 39b3ed3d44 Fix part blend mult being incorrectly archived
This may have been the cause of animations not properly playing and the player being unable to climb on ladders
2024-08-03 18:40:27 +02:00
smallmodel f8b97405ff Fix infinite loop in DownSampleWav when s_khz is less than 44 kHz
This fixes #330 where `s_khz` below 44 (the usual sample rate of mohaa wav files) would cause an infinite loop due to improper usage of the `ii` variable in the loop where another variable would be accidentally incremented instead
2024-07-30 20:59:48 +02:00
smallmodel 1d4fe357c8 Fix ShaderForShaderNum incorrectly swapping the shader num 2024-07-29 21:39:24 +02:00
smallmodel c7900b6048 Fix static model index endianness 2024-07-29 21:13:18 +02:00
smallmodel 6e3f959684 Fix header version incorrectly parsed 2024-07-29 20:32:21 +02:00
smallmodel eb9a3b1bbf R_UnpackTerraPatch: no need to get little-endian values as values are already swapped by R_SwapTerraPatch
See #332
2024-07-29 19:04:29 +02:00
smallmodel 391450f090 Swap bsp header on big-endian architectures
See #332 where the lump's offset and length are incorrect on big-endian architectures
2024-07-29 19:03:26 +02:00
smallmodel f804476fbc Add soft-oal to the build 2024-07-28 19:55:20 +02:00
smallmodel 60e4fa7005 Handle shader picmip and fix shaders not rendered properly with force32bit (alpha channel was ignored) 2024-07-28 19:25:24 +02:00
smallmodel c13f9dc9a8 Increase MAX_IMAGE_ANIMATIONS
This fixes emitters not playing correctly
2024-07-28 19:12:08 +02:00
smallmodel f213943b2d Fix RB_SetGL2D 2024-07-28 19:02:06 +02:00
smallmodel 5159a534bb Fix animated images playing at the same time for all entities 2024-07-28 19:01:34 +02:00
smallmodel c7a4e705cb Fix libmad still producing shared libraries 2024-07-28 18:51:15 +02:00
smallmodel 864ea08393 Fix special characters not being handled properly
This fixes characters (signed character below 0) being replaced by '?' in UI text elements, like in the console
2024-07-27 23:41:12 +02:00
smallmodel ebfb6d1846 Fix inwardsphere not being used
This fixes emitters looking incorrect, like `animate/adamspark.tik`, for the explosion of electric panels
2024-07-27 23:20:30 +02:00
smallmodel 6b89ec615a Set damage angles only for mohaa 1.0-1.11 2024-07-27 19:45:18 +02:00
smallmodel af432e6d3f Allow pain if the current time is above the allowed next pain time 2024-07-27 19:37:05 +02:00
smallmodel 44c17409a7 Allow pain if the player dies 2024-07-27 19:33:39 +02:00
smallmodel 0f48c39bc1 Add more resilience against null entity in G_FixEntityPosition 2024-07-27 19:05:45 +02:00
smallmodel 572e6652cc Fix followpath not working under special circumstances
This fixes an issue where some planes (like the final bomber plane in t3l2) would not fly and look stuck
2024-07-27 19:05:05 +02:00
smallmodel fecb601fc4 Clear velocity only if it's not ignored 2024-07-27 18:17:10 +02:00
smallmodel 7b238e9d34 Set new orders appropriately 2024-07-27 18:13:31 +02:00
smallmodel 73c8ff11b3 Call CurrentScriptThread() to get the current script, so it can throw an exception if the current thread is NULL 2024-07-27 18:03:41 +02:00
smallmodel 682dc89067 Add ignorevelocity argument for followpath 2024-07-27 17:54:48 +02:00
smallmodel ee514710c5 Add Emscripten implementation from ioquake3 upstream 2024-07-26 23:57:50 +02:00
James Darpinian 2d15696a5e Add .vscode and baseq3 to gitignore 2024-07-26 23:03:40 +02:00
Alan Zhao 769d06b0f0 Use nanosleep(2) instead of usleep(3)
usleep(3) was declared obsolete in POSIX.1-2001 and removed in
POSIX.1-2008 and nanosleep(2) was recommended to be used instead.
2024-07-26 23:03:09 +02:00
smallmodel dcb0369e10 Fix actions deprecation warnings 2024-07-26 22:08:46 +02:00
smallmodel 1b35d3ce05 Fix angular delta being wrong
This fixes animated characters being sometimes badly positioned, like actors in the plane in t1l1
2024-07-25 21:46:33 +02:00
smallmodel 31d254cb9f Use ceil() and set the delta appropriately if time1 is after team2 2024-07-25 21:43:19 +02:00
smallmodel bf4780bbdb From now, load streamed sound into memory as deferred loading is currently unsupported 2024-07-25 19:49:34 +02:00
smallmodel 5af8e127f8 Added NULL sound flag 2024-07-25 19:04:08 +02:00
smallmodel 016e062fef Fix UIReggedMaterial::ReregisterMaterial and UIReggedMaterial::GetMaterial
ReregisterMaterial() must register the material if it was registered before, and GetMaterial() must register the material if it hasn't been registered and return it
2024-07-24 21:10:46 +02:00
smallmodel c093122764 Made code C++ compatible so UI_LoadResource() can be used 2024-07-24 20:07:22 +02:00
smallmodel 11ec6270da Made OpenAL package required 2024-07-24 19:57:22 +02:00
smallmodel 81df55310b Fix medals always being awarded
This fixes #316
2024-07-23 19:53:40 +02:00
smallmodel e5fb85ad08 Fix material not refreshing when it already has a shader.
This fixes #329 where the material (matching quick.tga) would be loaded only once without being able to change
2024-07-23 19:06:48 +02:00
smallmodel c5ef60040a Fix sounds not being resumed properly after loading from save 2024-07-22 20:44:00 +02:00
smallmodel 757b4849f8 Add a fix to load the music from save
This commit implements code to get/set sample offset in an OpenAL channel and saves the music filename/offset into the file. This only works by using the experimental sound system, so it partially fixes #327
2024-07-22 20:13:03 +02:00
smallmodel 2198bdec21 Added stub variables and functions for loading 2024-07-22 19:15:52 +02:00
smallmodel 8bd377ce85 Fix the save system taking a screenshot of the whole UI menu instead of just the 3D view
This fixes #328 where the save would have a screenshot of the save menu
2024-07-22 19:00:50 +02:00
smallmodel 89eae68318 Fixed parameter mistake
(Why didn't you tell anything about that, MSVC?)
2024-07-20 22:09:03 +02:00
smallmodel d1e94f3934 Fix saveshot not executed when saving
This fixes #273 where the loadsave menu wouldn't show the screenshot
2024-07-20 16:07:02 +02:00
smallmodel fc0a995c66 Added code to save image with custom resolution to a file 2024-07-20 16:04:04 +02:00
smallmodel eee0eaac4a Process the "!" (not) syntax for enabledcvar
This fixes #265 where the mine detector icon wouldn't appear because it wants SP mode
2024-07-17 23:55:11 +02:00
smallmodel 535da856a4 When returning a cvar value, use the latched string if present 2024-07-17 23:43:00 +02:00
smallmodel 422bf647a7 Save the client-game state into the archive file (feature from moh spearhead 2.0)
This saves cgame data such as emitters and vss sources
2024-07-15 23:45:32 +02:00
smallmodel 93cd470659 Fix broken cgame state saving 2024-07-15 23:44:11 +02:00
smallmodel 81b86d61da Fix read-only cvar being improperly archived
This caused cvars like `paused` being wrongly restored. If the `paused` value is 1 or above, like when saving from the menu, the game would get stuck loading the level because it's paused, no frame could be executed.
It also fixes cvars like `sv_fps`, `g_playermodel` not being archived when they should.
Fixes #326
2024-07-15 20:39:22 +02:00
smallmodel eac8580f64 Add libmad 0.16.4
This new version introduces patches against crashes and exploits. CMake is also fully supported and platforms are properly detected so architecture specific optimizations are used.

To use it, USE_SOUND_NEW must be non-zero when configuring the project
2024-07-11 23:04:04 +02:00
smallmodel d56498e622 Adds CHANNEL_NONE case statement even if there is nothing to do 2024-07-11 22:04:03 +02:00
smallmodel 551fccb761 Fixes wrong handle being compared for uniqueness
This should fix invisible models (fixes #322)
2024-07-02 22:47:41 +02:00
smallmodel 5317b8424f Prevents the player from walking
This fixes #275
2024-07-02 22:16:13 +02:00
smallmodel 5816391e9b Fixes loopsound not properly working (not playing, or not being 3D) 2024-07-02 20:25:08 +02:00
smallmodel 543c00037a Implements sample playback rate 2024-07-02 20:10:54 +02:00
smallmodel d5f435ee90 Makes loops work as they should 2024-07-02 20:01:01 +02:00
smallmodel 02e2e92d36 Uses linear sound distance model 2024-07-02 19:30:29 +02:00
smallmodel 040f8db0ef Fixes wrong sound volume and pitch 2024-07-02 19:10:48 +02:00
smallmodel 14927df9fa Moves MAX_SUBTITLES to `q_shared.h| 2024-07-02 19:03:27 +02:00
smallmodel dca9709b12 Fixes MASK_PLAYERSOLID incorrectly using CONTENTS_WEAPONCLIP instead of CONTENTS_PLAYERCLIP for invisible player collision
This fixes #317, fixes #319 and fixes #320 where the player would bypass clip/playerclip
2024-07-02 18:51:53 +02:00
smallmodel d6571820fe Fixes g_pVert/g_pTris being freed even when they are NULL 2024-07-02 18:46:27 +02:00
smallmodel a0d3333ebb Fixes chan->bufferdata not being set to NULL when released 2024-07-02 18:45:51 +02:00
smallmodel 9615fafc1e Fixes incorrect usage of DotProduct result in an integer 2024-07-01 19:03:21 +02:00
smallmodel 5fc2425f3a Set the mindist/maxdist for 3D sounds 2024-07-01 18:52:04 +02:00
smallmodel 63445c4fc1 Added a note to use the experimental openal-based sound system 2024-07-01 18:20:22 +02:00
smallmodel eefe8ee2d1 Allow 3D / pan with streamed or MP3 sounds 2024-07-01 18:17:04 +02:00
smallmodel edb1cb0ebe Renamed SFX_FLAG_NO_DATA to SFX_FLAG_STREAMED 2024-07-01 18:05:24 +02:00
smallmodel 140242a761 Fixes MP3 files like dialog improperly working 2024-07-01 18:00:20 +02:00
smallmodel ae13be0c37 Fixes OpenAL errors 2024-07-01 17:39:47 +02:00
smallmodel 74ff3b920e Fixes OpenAL 2D origin 2024-07-01 17:39:32 +02:00
smallmodel 2cd6b981f1 Puts the volume gain constant in a variable 2024-07-01 16:46:54 +02:00
smallmodel f866dcbcfc Adds triggered music support
This allows the main menu music to play, as well as single-player musics
2024-07-01 16:10:42 +02:00
smallmodel 0d394a7e67 Fixes strings printing on the same line 2024-07-01 14:15:58 +02:00
smallmodel 7059f32ecc Don't timeout if the client hosts the game 2024-07-01 01:09:39 +02:00
smallmodel 87baa69d7c Fixes incorrect lighting color normalization
This fixes #314 where mark colors would have their values warped back to 0, making holes blue
2024-07-01 00:20:33 +02:00
smallmodel 408c901342 Fixes skyboxSpeed using an integer rather than a float
This fixes #313 where the skybox would be misplaced
2024-07-01 00:19:50 +02:00
smallmodel d709dda87a Use shader's distance range instead of the portal range 2024-06-30 23:57:32 +02:00
smallmodel cda6225659 Adds a workaround against a bit that was lost on x86 with FP87.
This fixes #312 where a rounding error caused facets to be removed due to windings points being outside of the epsilon
2024-06-23 17:26:07 +02:00
smallmodel 563182c14c Added FloatRoundedBitError() (currently unused) 2024-06-23 17:25:23 +02:00
smallmodel 303ed30a38 Don't remove the facet is there is no border planeCM_PlaneEqual 2024-06-23 17:19:52 +02:00
smallmodel 0a6c745ffb Use VectorNormalize() instead of VectorNormalize2() 2024-06-23 17:10:58 +02:00
smallmodel 9d654faa3d As m_BlockedPaths is an array of pathway_ref, the proper delete call must be used 2024-06-23 00:24:20 +02:00
smallmodel 9407b64fe3 Q_strncpyz: don't copy if the src is the same as the dest 2024-06-23 00:18:22 +02:00
smallmodel 1f0f5764a8 Added PathInfo() constructor initialization 2024-06-22 21:41:28 +02:00
smallmodel 13197acb3a Uses a signed char instead of a char for opcode stack offset. On some platforms like ARM, char is unsigned by default
This fixes #311 where a memory corruption that occurred in ARM was caused because of insufficient ScriptVM stack size. The stack size was incorrectly calculated because the stack offset was using unsigned values instead of signed in ARM.
2024-06-22 19:18:08 +02:00
smallmodel 2f48ca6adb Adds assertion check to check if top stack is out of bounds 2024-06-22 19:03:27 +02:00
smallmodel 01d938b5ba Fixes some variables being uninitialized 2024-06-22 19:03:04 +02:00
smallmodel 186d7a12e5 typo 2024-06-22 16:51:20 +02:00
smallmodel 5192d36f81 Fixes gametype incorrectly checked in G_InitWorldSession 2024-06-22 16:43:03 +02:00
smallmodel dfb6c37c9e Don't copy the server name if it's from the same string address 2024-06-22 16:42:39 +02:00
smallmodel cb208b9ad2 Initialize the message buffer to avoid leaking private data 2024-06-22 16:39:26 +02:00
smallmodel e4d20c3fa1 Initialize explosion flash 2024-06-22 16:39:08 +02:00
smallmodel 0b747bf1c5 Use memmove rather than strcpy for removing key values 2024-06-22 16:39:00 +02:00
smallmodel e207715b5e Initialize m_iLastTiresUpdate 2024-06-22 16:12:29 +02:00
smallmodel bef1b456e1 Initialize all Ammo members 2024-06-22 16:11:03 +02:00
smallmodel 11349f9ad5 Fixes the source pos access for ENUM_if_statement (out of bounds index) 2024-06-22 16:08:33 +02:00
smallmodel 2a485a6b69 Fixes the endianness when loading LOD from file 2024-06-22 15:34:38 +02:00
smallmodel f41e92de6e Fixes possible memory corruption when generating a LOD curve 2024-06-22 15:34:00 +02:00
smallmodel 835c0b0d9a Adds constants for LOD curve values 2024-06-22 15:30:59 +02:00
smallmodel d9dc34f06d Checks for AGEN_TIKI_DIST_FADE and AGEN_ONE_MINUS_TIKI_DIST_FADE for static models 2024-06-21 22:02:59 +02:00
smallmodel 907ff36018 Fixes r_showstaticbboxes freezing the game 2024-06-21 21:49:13 +02:00
smallmodel 64626a767c Fixes entities not being rendered after number 1023
This fixes #310 where some static models would not be rendered, making it look like there are invisible walls.
2024-06-21 21:48:55 +02:00
smallmodel a7df73073d Adds a condition to check if static model poly can be rendered 2024-06-21 20:54:14 +02:00
smallmodel 40492daecd Avoid creating a new sound index when there is no active client 2024-06-16 23:20:30 +02:00
smallmodel a5691d7779 Allows clients to join a single-player game 2024-06-16 20:48:34 +02:00
smallmodel d1ecd4a3c8 Don't initialize client persistant data during autosave 2024-06-16 18:19:11 +02:00
smallmodel 5482b31c66 Reads the sv_privatePassword value 2024-06-16 18:18:14 +02:00
smallmodel 15f2f6c798 Renamed g_session functions 2024-06-16 18:16:14 +02:00
smallmodel 46b3f4eb5e Adds differentMap parameter for G_ClientConnect, it clears the selected DM weapon.
On each map change, the player gets asked for the primary weapon like in 2.0 and above
2024-06-16 18:14:26 +02:00
smallmodel f5aadbb788 If the loopSound has no origin, make it local
This should fix #309
2024-06-15 16:38:02 +02:00
smallmodel bbb54ea36d Uses LoopSounds() parameters instead of just the alias 2024-06-15 16:33:02 +02:00
smallmodel d7a5eb5d2f Use LEVEL_WIDE_MIN_DIST instead of 10000 constant 2024-06-15 16:26:35 +02:00
smallmodel cc716c3fa4 Don't process loopsound yet when spawning 2024-06-15 16:22:34 +02:00
smallmodel 141574a0d7 Ignore mouse events when paused 2024-06-15 16:22:21 +02:00
smallmodel 2df8ed10d0 Improves timeout checking, properly show the timeout menu and shutdown the server 2024-06-15 14:56:30 +02:00
smallmodel 40e3977664 Continue using entities even when attached to a turret, in 1.11 and below for backwards compatibility!
Fixes #140 where the MG42 objective in m1l1 would not trigger
2024-06-15 00:16:29 +02:00
smallmodel 7ddee0100e Implements CG_BodyFallSound() 2024-06-14 22:24:55 +02:00
smallmodel 6b869c4c0d Use an enumeration instead of raw values 2024-06-14 21:39:54 +02:00
smallmodel 91497d8fa7 Implements Player::EventTestAnim() 2024-06-14 21:20:15 +02:00
smallmodel 85bf56ae03 Call SetWeight() rather than setting it manually 2024-06-14 21:19:04 +02:00
smallmodel 84d702838d Implemented Player::MeasureLandmineDistances()
This makes minedetector actually detect mines, especially on `e1l2`
2024-06-13 23:58:31 +02:00
smallmodel fd3a36f162 Fixed melee sometimes not making the hit sound 2024-06-13 23:30:19 +02:00
smallmodel 10e3192f85 Fixed MASK_PLAYERSOLID being wrong 2024-06-13 23:24:11 +02:00
smallmodel de874874e4 Use an enum for setup case rather than raw values 2024-06-13 23:11:28 +02:00
smallmodel 72e315bce1 Using an enum channelType_e rather than raw values for bone channel types 2024-06-13 23:04:33 +02:00
smallmodel 02ef85e390 Removed GetChannelTypeFromName(), was useless 2024-06-13 21:28:49 +02:00
smallmodel aeba0e0f6f Set the real limit of MAX_SKELETOR_CHANNELS 2024-06-13 21:26:59 +02:00
smallmodel f8fa944054 Some refactoring, + implemented SetLocalFromGlobal() 2024-06-13 21:26:51 +02:00
smallmodel 1d50fa088a Don't dealloc if there is no frame in the channel 2024-06-13 21:26:29 +02:00
smallmodel 546ded324e Made ChannelNames() method public 2024-06-13 21:25:45 +02:00
smallmodel 332a635031 Use MAX_GLOBAL_FROM_LOCAL 2024-06-13 21:25:02 +02:00
smallmodel de02c868a2 Fixed bullet tracers being incorrect
This should fix almost immobile bullet tracers on t1l1
2024-06-11 23:46:50 +02:00
smallmodel a74b966b7c Update fog when changing whether or not the terrain must be rendered 2024-06-11 23:44:02 +02:00
smallmodel ca4b1ebdee Don't render terrain when refdef.render_terrain is set to false 2024-06-11 23:37:45 +02:00
smallmodel 42c20ac008 Portal sky mustn't cause entity surface to be r-eadded
This fixes an issue where an entity would get re-added with a really lower LOD. Fixes #307
2024-06-11 23:35:18 +02:00
smallmodel a26e5b74c2 Use armhf and armel suffix to distinguish between ARM variants 2024-06-11 22:09:31 +02:00
smallmodel ee5faedaf9 Removed the value of LittleSwap/BigSwap on little-endian/big-endian 2024-06-11 21:25:38 +02:00
smallmodel 874b034698 Corrected some compilation warnings 2024-06-11 21:24:01 +02:00
smallmodel dfb2cb6bbf Fixed buffer overrun 2024-06-11 21:19:15 +02:00
smallmodel fb15f0f2b3 Fixed a tiny mistake that prevented morphs from working correctly
Actors now have a working dynamic facial expression (moving eyes/mouth/brown...)
2024-06-11 00:12:59 +02:00
smallmodel 4d231fbc50 Call LocalChannel instead of GetLocalFromGlobal 2024-06-11 00:05:28 +02:00
smallmodel dd85118a9c Don't pack channels when reading encoded frames from mohsh and above (they're already packed in the animation file) 2024-06-11 00:01:55 +02:00
smallmodel 531340627d Call LocalChannel() instead 2024-06-10 23:53:42 +02:00
smallmodel 6b6e5291dd Fixed EYES_up length 2024-06-10 23:40:50 +02:00
smallmodel 79b0e6998d Fixed implementations 2024-06-10 23:40:34 +02:00
smallmodel 445814b144 Fixed skeletor_c::ChannelNames return value 2024-06-10 22:15:10 +02:00
smallmodel ebb3173322 Added skeletorMorphCache_t as an alias to int 2024-06-10 22:06:47 +02:00
smallmodel c16f2029b1 Implemented skeletor_c::ChannelNames() 2024-06-10 22:06:35 +02:00
smallmodel abefdd772c DecodeFrameValue should only return a float value 2024-06-10 22:06:25 +02:00
smallmodel e550d244df Reimplemented skelChannelList_s::LocalChannel 2024-06-10 22:05:39 +02:00
smallmodel 84cc66ad48 Merge pull request #306 from pryon/UINotepad
Implement UINotepad
2024-06-10 18:31:34 +02:00
pryon fa5a97031d Fix assignment of a temporary to a non-const reference error on GCC 2024-06-10 14:43:40 +02:00
pryon 6e454cdfb3 Fix subtle bugs and refactor in UIWindowManager 2024-06-10 14:26:38 +02:00
pryon 52f43a3aa6 Document OPM fix for center-justified UINotepad statusbar 2024-06-10 14:25:30 +02:00
pryon 907aa21ba8 Fix UIPopupMenu crashes caused by dereferencing already freed instance 2024-06-10 14:24:39 +02:00
pryon ac01ad6751 Take over va() memory safety fix from ioquake3 2024-06-10 14:19:29 +02:00
pryon c84702b490 Fix file picker crash on AA 2024-06-10 14:18:49 +02:00
pryon edd2a9d8f6 UIMultiLineEdit::Draw documentation 2024-06-10 14:17:35 +02:00
pryon a19c7afce0 Add placeholders for handling clipboard operations in UIMultiLineEdit
Actual clipboard functionality will be added later
2024-06-10 14:15:06 +02:00
pryon 849f1ee7d1 Fix several bugs in UIMultiLineEdit
These are necessary so that UINotepad can actually be used for editing text
2024-06-10 14:13:21 +02:00
pryon c60c2c09e1 Fix incorrect TAB character width calculation and refactor logic 2024-06-10 14:06:30 +02:00
pryon 3254b3f044 Send SE_CHAR events (CharEvent) for ENTER, TAB and ESCAPE keys
So that UINotepad registers them as valid keypresses when typing
2024-06-10 14:04:55 +02:00
pryon 9a35d34fc3 Implement UINotepad
Also fix several original game bugs within, some cosmetical, some memory corrupting
2024-06-10 14:02:10 +02:00
pryon 4da5e26cdc Move CTRL macro to q_shared.h 2024-06-10 13:59:10 +02:00
smallmodel 8a28ad0c36 Fixed explosion effects on protocol below 2.0 2024-06-09 20:16:14 +02:00
smallmodel e08b2fe382 Added cg_target_game 2024-06-09 20:10:30 +02:00
smallmodel 8b16e94829 Fixed grenade bounce sound overly playing 2024-06-09 19:56:41 +02:00
smallmodel 618223f01b Ignore NumShaders in protocol version 8 and below 2024-06-09 19:32:15 +02:00
smallmodel 13c63d3e1f Fixed wrong condition with msg broadcast visibility 2024-06-09 18:51:39 +02:00
smallmodel 8e0aa5185b Fixed CGM endianness 2024-06-09 18:48:22 +02:00
smallmodel 2b01f092b3 Fixed german model always being set to german_wehrmacht_soldier 2024-06-09 18:23:06 +02:00
smallmodel 1fd238567e Fixed animation loading endian 2024-06-09 17:55:57 +02:00
smallmodel cb59edc963 Handle script exceptions in G_ServerSpawned 2024-06-09 16:56:42 +02:00
smallmodel 0ce70b9f8f Improved/fixed archive support for big-endian platforms 2024-06-09 16:53:50 +02:00
smallmodel 57175cfa5c Simplified the decompression algorithm and fixed it for big-endian 2024-06-09 16:45:10 +02:00
smallmodel 8aacdcefb8 Fixed lz77 endianness 2024-06-09 14:14:11 +02:00
smallmodel 69766ae87a Added SwapValue 2024-06-09 13:19:31 +02:00
smallmodel d3d2082e41 Removed useless print 2024-06-09 13:08:01 +02:00
smallmodel de621f6acb Made short3 implementation endianness independant
This fixes scripts not working properly as script variables key are using short3
2024-06-09 00:59:23 +02:00
smallmodel a7c5067475 Fixed the execution of a method on the correct class 2024-06-09 00:07:11 +02:00
smallmodel 7282426736 Improved the networking code for big-endian architectures 2024-06-09 00:02:00 +02:00
smallmodel 0333fd86f8 MSG_DeltaNeeded_ver_15 was never called 2024-06-08 21:52:28 +02:00
smallmodel ab91ade685 Explicitly use signed char for patch xy because some platforms use unsigned char by default 2024-06-08 19:56:24 +02:00
smallmodel 005afcd53d Simplified CM_PickTerrainSquareMode 2024-06-08 19:20:27 +02:00
smallmodel c1604c0c8c Handle animation file endianness 2024-06-08 14:59:52 +02:00
smallmodel 5155c10136 Fixed scripts not working on big-endian architectures 2024-06-08 14:40:35 +02:00
smallmodel 28c6e3b398 Properly swap terrain patches for rendering on big-endian architectures 2024-06-08 12:48:36 +02:00
smallmodel 41244095b1 CMod_LoadTerrainIndexes: big-endian compatibility 2024-06-08 12:47:18 +02:00
smallmodel a5535fa789 Make sure to initialize the widget's command handler to NULL.
This should fix #305
2024-06-08 01:40:36 +02:00
smallmodel 6796a8b3fe Properly swap terrain patch values on big-endian systems 2024-06-08 01:08:58 +02:00
smallmodel 819dffcb86 Added MAX_TERRAIN_VARNODES 2024-06-08 01:05:47 +02:00
smallmodel b54db17069 Added unsigned swaps 2024-06-08 01:03:08 +02:00
smallmodel e27f2443e8 Fixed skel loading on big-endian systems 2024-06-08 00:53:39 +02:00
smallmodel a1e0bc5d7c Implemented TIKI_SwapSkel (used on Big-Endian systems) 2024-06-08 00:40:52 +02:00
smallmodel 28ea95b9ff Added scale field 2024-06-08 00:08:54 +02:00
smallmodel e3b9e48d8c Added TIKI_SKEL_LOD_INDEXES 2024-06-07 22:38:45 +02:00
smallmodel 026b6b2562 Ignore endianness on skd/skb header signature, as it's a string 2024-06-07 22:08:46 +02:00
smallmodel 0fa380ecff Correctly read the BSP checksum on big-endian systems 2024-06-07 22:01:24 +02:00
smallmodel ebd885f053 Fixed Subclient not having the correct client name 2024-06-07 20:36:55 +02:00
smallmodel 74ccb03e54 Reduced compilation warnings 2024-06-07 20:34:13 +02:00
smallmodel 50264c4968 Make sure to cast the float number to int when using it in the format specifier 2024-06-07 20:25:47 +02:00
smallmodel be222b64a1 Fixed one tiny instruction mistake that could cause issues with dynamic lights on terrains 2024-06-07 20:20:19 +02:00
smallmodel db7ae4ffef Properly clear the color values 2024-06-07 19:57:14 +02:00
smallmodel 884a76db4c Drop error instead of throwing an exception to meet non-throwing exception specification 2024-06-07 19:55:33 +02:00
smallmodel 18e5c6e714 Use unsigned format specifier to match MAX_VOTEOPTIONS_BUFFER_LENGTH's type 2024-06-07 19:49:51 +02:00
smallmodel 468341b7d0 Explicitly mark as override 2024-06-07 19:49:29 +02:00
smallmodel e03b976ffd Added missing header on scriptclass.cpp source file 2024-06-07 19:42:10 +02:00
smallmodel 34ea099d87 Define _FILE_OFFSET_BITS to 64 due to a bug in readdir() affecting 32-bit architectures
readdir() would return NULL, setting errno to EOVERFLOW, unable to load pk3 files
2024-06-06 22:18:23 +02:00
smallmodel 5f2827e2ab Added hardware requirements 2024-06-05 22:32:36 +02:00
smallmodel 1d887b4655 Fixed leaf light being incorrectly reassigned 2024-06-05 21:21:35 +02:00
smallmodel 6250380f61 Added PowerPC into the build system 2024-06-05 21:13:33 +02:00
smallmodel 6bb475abe7 Fixed PowerPC platform support with proper checks for endianness and ppc64 2024-06-05 21:13:06 +02:00
smallmodel 31ea951357 Fixed SkelMorphGetXyz implementation 2024-06-05 00:43:08 +02:00
smallmodel 091c8b4d12 Optimized channel data memory and performance (feature from moh 2.0 and above) 2024-06-05 00:40:43 +02:00
smallmodel c4523db991 Added GetBoneChannelType 2024-06-04 23:48:29 +02:00
smallmodel 2b66672d2d Added MAX_GLOBAL_FROM_LOCAL constant and implemented skelChannelList_s::GlobalChannel and skelChannelList_s::LocalChannel 2024-06-04 21:06:43 +02:00
smallmodel 77de0b78ba First test if the entity has morphs before proceeding to loop through vertices 2024-06-04 20:20:40 +02:00
smallmodel 0181fbcfa0 Use the weight's bone index if there is no morph 2024-06-04 19:52:32 +02:00
smallmodel e1f2433c36 Fixed sky portal rendering
This fixes #260
2024-06-03 21:36:58 +02:00
smallmodel c753dcafd8 SurfIsOffscreen: use raw surface values rather than tess values 2024-06-03 21:36:35 +02:00
smallmodel 57ac7d8c19 Removed code that is already present in CG_SetupFog() and CG_SetupPortalSky() 2024-06-03 21:36:12 +02:00
smallmodel d64ef13b79 Fixed script_skyorigin never being sent to clients 2024-06-03 21:34:48 +02:00
smallmodel 911e87c6ec physics_off: Don't reset the physics in 1.0 in Single-player mode
This fixes #303 in m4l2 where the player doesn't have their gun holstered in the truck
2024-06-03 20:29:41 +02:00
smallmodel b75c7b64f1 Still allow crouch when glued in 1.0 and in Single-player mode
This fixes #303 where the player is standing in the truck in m4l2
2024-06-03 20:28:39 +02:00
smallmodel 135b519dd8 Reduced actor's change of getting curious 2024-06-02 23:47:06 +02:00
smallmodel b7a0607d52 Using parameters that take the entity rather than raw values 2024-06-02 19:55:42 +02:00
smallmodel 2ee1a2099d Ignore map name case sensitivity when parsing map-specific animations 2024-06-02 19:46:14 +02:00
smallmodel 7fe7e74fe2 Replaced all stricmp calls with Q_stricmp 2024-06-02 19:44:06 +02:00
smallmodel 0a3a23af41 Using AI_EVENT_MAX to check for max ai events 2024-05-29 23:54:48 +02:00
smallmodel e89262ed3b Fixed TIKI_ParseAnimations improperly returning, even when a map was specified, causing parsing issues 2024-05-28 21:38:17 +02:00
smallmodel 21fda4cabd Removed redundant code 2024-05-28 21:31:28 +02:00
smallmodel a85694b548 Fixed incorrect method for EV_ScriptThread_Showmenu.
This fixes #302 where screen text with the mission date would never be shown.
2024-05-28 20:49:09 +02:00
smallmodel 16464c5a68 Removed zone events from entity
This fixes a conflict where some scripts would store stuff in a variable named `zone` in an entity
2024-05-27 23:28:12 +02:00
smallmodel 85c8769512 Fixed incorrect usage of the grid lighting
This fixes some entities being invisible when `r_fastentlight` is set to 1, due to the alpha color being 0 (cast from int to char for each color value). Fixes #299
2024-05-20 13:11:48 +02:00
smallmodel c3abbd9014 Added assertion checks 2024-05-20 13:10:12 +02:00
smallmodel 98239050d8 Correctly archive the active weapon (safe pointer)
This fixes the player sometimes being holstered after loading from a save (closes #270)
2024-05-12 23:55:11 +02:00
smallmodel dc7caf04a8 Fixed MoveTo not working on waypoints.
This fixes an issue where objects using waypoint (like elevators) would move at `(0 0 0)`. Closes #298
2024-05-12 23:40:11 +02:00
smallmodel db01f72adc Reimplemented ScriptVariable::entityValue
Some script events don't check if it's an actual entity, it would cause crashes.
E3L3 would crash after the player got out of the AB41: the AB41 was targetting a VehiclePoint and vehicles_thinkers.scr script set the `self.collisionent` to `self.target` which caused a crash as `VehiclePoint` doesn't inherit from `Entity`
2024-05-01 20:41:57 +02:00
smallmodel 170b4b0972 Fixed ScriptAimedStrafingGunfire aimTarget never set nor used
This fixes the gunfire incorrectly damaging things it shouldn't damage.

For example, the sniper3 balcony AI on e3l1:
The bomber caused this AI to fall before initialization (by damaging them when it shouldn't), the AI became nonsolid. After initialization, the AI had enemy enabled, however it remained nonsolid because of the balcony fall. It was constantly shooting at the player and it was unkillable because it was nonsolid.
The mission wasn't able to be completed because of this issue.
2024-05-01 20:18:52 +02:00
smallmodel ff6e81d44f Fixed CL_GetSnapshot sometimes wrongfully assigning parents multiple times and displaying errors
This should fix #170
2024-05-01 18:55:25 +02:00
smallmodel 88bc0e1e85 Reimplemented MSG_SetBroadcastVisible() and MSG_SetBroadcastAll() 2024-05-01 18:36:27 +02:00
smallmodel c5b46529b0 Check the client if it has a valid entity for MSG_SetBroadcastVisible() 2024-05-01 18:24:44 +02:00
smallmodel e5dbfba55e Fixed an issue where scripts would get compiled every time they are executed, causing a performance issue 2024-05-01 17:54:45 +02:00
smallmodel daa7aceecf Fixed sighttrace not properly passing entities
This fixes the issue where some scripts (like e2l3's BattleHouse) expect sighttrace to ignore entities (fixes #202)
2024-05-01 17:43:04 +02:00
smallmodel 35681e7a1f Added MASK_IGNORE_ENTS 2024-05-01 17:42:02 +02:00
smallmodel d4dfde3340 Trigger must not be effective when being damaged if it does not take damage
This fixes issue with vehicles damaging triggers by touching them (like the ClickItemTrigger on m5l3 with tanks)
2024-04-30 20:26:08 +02:00
smallmodel 05a6b43e08 Check for __APPLE__ to detect MacOS 2024-04-30 19:25:02 +02:00
smallmodel 16f775c78c Fixed ScriptSlave path with 2 equal points
This fixes the script slave moving infinitely and not sending movedone notifications as it would never advance to the next path. e3l4's outro is now fixed because of that (was stuck).
2024-04-29 23:42:05 +02:00
smallmodel af919dadca Simplified code for g_showflypath 2024-04-29 20:04:21 +02:00
smallmodel 41c322ec81 Refactored ScriptSlave::FollowingPath and ScriptSlave::SetupPath with bugfixes 2024-04-29 19:59:16 +02:00
smallmodel ac8c18250d If the actor is an american, always call ThinkHoldGun_TurretGun() without checking for enemy 2024-04-28 20:39:54 +02:00
smallmodel 4b05c400b2 Round to integer for vectoyaw()
This fixes Actor never finishing TurnTo as the DesiredYaw was set to a very precise value
2024-04-28 19:29:54 +02:00
smallmodel cc85d0c100 Bumped version number 2024-04-22 23:40:00 +02:00
smallmodel 56dce21538 Fixed an invalid access to lighting sphere leaves
It was causing crashes on some occasions
2024-04-22 23:39:07 +02:00
smallmodel 3cd5acf3aa Fixed issue with case-sensitive variables.
normal/return commands are case-insensitive
getter/setter commands are case-sensitive
2024-04-22 20:10:01 +02:00
smallmodel 48fc5a72b8 Fixed some setters and getters being inverted 2024-04-22 19:59:20 +02:00
smallmodel 26c3375112 When there is no enter_boneindex for turret slot, use the boneindex instead
This fixes #208
2024-04-22 18:28:56 +02:00
smallmodel e89543710c Check for max use angle when using the vehicle 2024-04-22 18:04:14 +02:00
smallmodel ee48193f15 Added notagaxis
Fixes #222
2024-04-22 17:21:26 +02:00
smallmodel 6d10ed27c5 Fixed preferred weapon not showing on stats screen
Fixes #271
2024-04-22 16:48:24 +02:00
smallmodel 19c68aa25d Ignore player collision if the actor is already nonsolid
This fixes #277 where the vehicle could get stuck due to the actor being solid afterwards
2024-04-21 20:33:31 +02:00
smallmodel 5ee7cb16bb for ANIM_MODE_SCRIPTED and ANIM_MODE_NOCLIP, set the yaw based on the angular delta 2024-04-21 20:28:54 +02:00
smallmodel 4630a1f386 Fixed wrong return values for Vehicle::EventCanUse
It fixes Modello being hardly usable on maps like e3l2
2024-04-21 19:40:33 +02:00
smallmodel 06dab5d8b0 Refactored ScriptThread::EventPointsWithinDist for more clarity 2024-04-21 19:39:39 +02:00
smallmodel 054201bea9 Fixed character assertion fail when the character was a value below 0 2024-04-21 19:07:08 +02:00
smallmodel f39a4c0bc7 Fixed projectile explosion origin.
This fixes exploder triggers sometimes never being triggered (fixes #294)
2024-04-21 17:47:39 +02:00
smallmodel 0e20d7e880 Fixed arm/arm64 binary loading on Windows
(fixes #295)
2024-04-14 23:03:46 +02:00
smallmodel 927f4bb4bd Marked overridden virtual methods 2024-04-11 00:30:00 +02:00
smallmodel f9901787b5 Removed "touch" unregistration 2024-04-11 00:26:45 +02:00
smallmodel 6731f56aea Fixed m_PrevCodePos usage 2024-04-10 23:42:09 +02:00
smallmodel d6870ecbee Added trigger_sideduse from 2.30 2024-04-10 21:44:03 +02:00
smallmodel eea8c42268 Added GetOwner event 2024-04-10 21:37:49 +02:00
smallmodel 99647e677a Do projectile vulnerability for vehicles 2024-04-10 00:22:35 +02:00
smallmodel a5d637dbb3 Added GetOwner() 2024-04-10 00:21:23 +02:00
smallmodel 048a973290 Added GetProjectileHitsRemaining 2024-04-10 00:20:32 +02:00
smallmodel fa80e0bd75 Implemented FencePost 2024-04-10 00:05:00 +02:00
smallmodel a23de7b361 Made Killed() a virtual method 2024-04-09 23:54:08 +02:00
smallmodel dc60cb45b2 Fixed scripts using syntax like $self 2024-04-09 23:22:54 +02:00
smallmodel 2bf1144a14 Removed unused source files 2024-04-09 22:41:41 +02:00
smallmodel ab5efa5a64 Fixed sentient being improperly attached/detached from/to the turret
This fixes #255
2024-04-09 00:12:02 +02:00
smallmodel ccc98e4c62 Implemented missing ThrobbingBox_Stickybomb() 2024-04-08 23:38:51 +02:00
smallmodel 52424f63f0 Make ThrowObject::Throw throws an exception when the owner and targetent is NULL, also use centroid if the target entity is not a sentient 2024-04-08 21:52:48 +02:00
smallmodel 881df7193b Fixed ThrowObject not usable when spawned from script.
This fixes #218
2024-04-08 21:47:24 +02:00
smallmodel e859bba61d Added a forgotten call to SetupNextCycle when turning on the projectile generator and fixed the uninitialized delay before beginning the cycle.
This fixes artillery system not working on t2l3, t2l4, e1l1... (fixes #224)
2024-04-08 21:33:59 +02:00
smallmodel e3beec985e When parsing and compiling a script, return the length in an output parameter instead so the method can return a boolean to indicate success.
This fixes #221 where a script with no code would fail.
2024-04-08 21:04:26 +02:00
smallmodel 9eec50d69f Fixed script model animation issues, especially when they're looping
This fixes #220.
2024-04-08 20:52:58 +02:00
smallmodel 5a8cc83e6e Fixed MM stepping
This fixes actors being slow and it also fixes actors going under the map
2024-03-31 22:52:30 +02:00
smallmodel 724aeb22ed Fixed MM_SlideMove() velocity clip and interaction 2024-03-31 22:15:19 +02:00
smallmodel 6fdc756b59 Set terrain rendering settings to max detail by default 2024-03-17 22:38:44 +01:00
smallmodel 25418b7857 Ammo name must be case-insensitive
This fixes some maps like t1l3 where the player would have a pistol with 6 bullets and no ammo
2024-03-06 23:49:37 +01:00
smallmodel b4de0b53e4 Special items must not be archived in persistent data 2024-03-06 19:43:37 +01:00
smallmodel cacf1ca1b7 Set the unarmed flag when archiving persistent data 2024-03-06 19:35:15 +01:00
smallmodel 98c61529b9 Archive the weapon clip amount in persistent data 2024-03-06 19:33:48 +01:00
smallmodel 6675a491be Fixed the model name when archiving persistant data
This fixes a crash when the next mission map is loaded and then saving/loading afterwards (fixes #237)
2024-03-06 19:29:07 +01:00
smallmodel b6485ad7db Configstring optimization so that there is only one occurence of a configstring index in pending server commands
This fixes configstring overflow in big maps like t1l2 (fixes #289)
2024-03-06 18:54:32 +01:00
smallmodel 9f5df368d1 Fixed infinite player team spectate 2024-03-05 23:30:25 +01:00
smallmodel e970e29953 Use a constant expression for clarity 2024-03-05 22:59:12 +01:00
smallmodel 9fb559bdb1 Added an assertion check for lastRadarTime 2024-03-05 22:52:19 +01:00
smallmodel 61e9146385 Moved con_set entry to the header file
This fixes compilation issue with GCC (fixes #288)
2024-03-05 18:30:31 +01:00
smallmodel 897c2322b9 Archive the target list
This fixes crashes related to scripts using entities by target name
2024-03-04 23:35:22 +01:00
smallmodel 7b8be9fed1 Added ArchiveObject() that accepts a SafePtr 2024-03-04 23:34:31 +01:00
smallmodel cebb351505 Added and implemented TargetList 2024-03-04 23:08:22 +01:00
smallmodel b4bce3431b Archive LightClass object pointer instead of a Class object pointer 2024-03-04 22:51:29 +01:00
smallmodel c6e3dfdbe6 Fixed velocity clip (sliding along plane)
This fixes the issue where vehicles would not be moving precisely where it should be moving (incorrect clipping of the velocity). For example, the minesweeper tank in e1l2 kept getting stuck because it didn't move appropriately (fixes #261)
2024-03-04 22:40:49 +01:00
smallmodel 22d2790735 Fixed vehicle stepping 2024-03-04 22:27:00 +01:00
smallmodel 5d3b76b249 Cleaned up SetMoveInfo() / SetCEMoveInfo() 2024-03-04 22:26:56 +01:00
smallmodel 7b07be1502 use double instead of float 2024-03-04 22:25:31 +01:00
smallmodel 3acb796b59 Call VectorNormalize() directly in Vector::normalize() 2024-03-04 20:07:06 +01:00
smallmodel 25bbc1793d Fixed AngleNormalize360 2024-03-04 20:06:35 +01:00
smallmodel 63456beeb0 Code clarity 2024-03-03 22:47:31 +01:00
smallmodel 2e32395cf2 VectorNormalize optimization 2024-03-03 19:51:56 +01:00
smallmodel d04ed0aace Made M_PI double 2024-03-03 19:46:32 +01:00
smallmodel 302f06f8d2 Clear the variable if the field cannot be found 2024-03-03 18:54:22 +01:00
smallmodel 4cf4ca2943 Fixed crash on pSoundAlias 2024-03-03 18:53:22 +01:00
smallmodel fe35e02ed4 Fixed weapon pickup logic, like player picking up the weapon indefinitely when reaching max ammo 2024-03-03 18:09:19 +01:00
smallmodel 5fa1b98d34 Fixed vert Z coord not matching average height
This caused issue where verts would never be merged. This should fix #232
2024-03-03 17:52:29 +01:00
smallmodel bebe117487 Formatted document 2024-03-03 17:34:01 +01:00
smallmodel 26495fe0f8 Refactored R_TerraTriNeighbor 2024-03-03 17:33:35 +01:00
smallmodel 4c4ac9f90e Added more assertions for consistency 2024-03-03 16:24:09 +01:00
smallmodel bf5fdb8f06 Fixed improper fence masks
This fixes #284, fixes #280
2024-03-02 15:29:25 +01:00
smallmodel 01e68fd5ee Fixed turret gun never being killed
This fixes #231
2024-03-02 15:29:08 +01:00
smallmodel e930b5481a Mark the trigger as dead after kill 2024-03-02 15:27:35 +01:00
smallmodel 9bd4d40f09 Formatted document 2024-03-02 15:00:56 +01:00
smallmodel 40035f4df3 Fixed multi-shaders snow 2024-03-02 14:23:32 +01:00
smallmodel a7b3fdd70b Added getConfigStringIdNormalized client game import to normalize config strings 2024-03-02 14:06:32 +01:00
smallmodel b77af7fced Implemented R_GetLightingForDecal 2024-03-01 22:59:06 +01:00
smallmodel 52c89f1de3 Fixed comparison operator 2024-03-01 22:31:33 +01:00
smallmodel e7cd70b8ee Enable cg_rain by default 2024-03-01 22:19:18 +01:00
smallmodel e06ee0f26a Bounce backwards check 2024-02-28 23:40:41 +01:00
smallmodel 76c9e4e048 Fixed pickup message appearing twice 2024-02-28 23:33:10 +01:00
smallmodel 06d8ddbfc7 Fixed AI firing multiple bullets when it should fire one
This fixes AI killing the player almost instantly
2024-02-28 22:56:05 +01:00
smallmodel 8b9840d37f Implemented Game::Archive() 2024-02-28 22:52:44 +01:00
smallmodel 960469be77 Implemented MakePrimitive() 2024-02-28 22:52:25 +01:00
smallmodel 77ef0f3579 Implemented game.detail and game.skill 2024-02-28 22:21:53 +01:00
smallmodel 07c840a4a9 Don't assert for NULL owner 2024-02-28 22:10:18 +01:00
smallmodel 35a8c4edfa g_droppeditemlife: make sure the value is non-null 2024-02-28 22:10:07 +01:00
smallmodel 36af9e6589 Fixed a very boring mistake ignored by MSVC 2024-02-27 00:02:20 +01:00
smallmodel ea14ab5664 Implemented special func 2024-02-26 23:25:39 +01:00
smallmodel 1ed8538745 Bounds check clarity 2024-02-26 20:23:31 +01:00
smallmodel 12e36b987a Use G_DebugRotatedBBox when drawing the entity's bounding box 2024-02-26 19:56:35 +01:00
smallmodel 8324c599de Implemented G_DebugRotatedBBox 2024-02-26 19:56:23 +01:00
smallmodel d972c85fba Formatted debuglines source file 2024-02-26 19:33:52 +01:00
smallmodel d8b9abe7f5 Fixed call to GunTarget()
It was specifying the position in the boolean parameter which lead to wrong results
2024-02-26 19:21:12 +01:00
smallmodel 4f868d9585 Fixed a collision bug with fence masks 2024-02-26 19:19:38 +01:00
smallmodel e27ac45f44 Don't load TGA without alpha for collision 2024-02-26 19:08:21 +01:00
smallmodel 58d0e43f78 Use MASK_USE instead of MASK_SOLID 2024-02-26 17:37:38 +01:00
smallmodel a6c1cbfd50 Added MASK_USE 2024-02-26 16:34:31 +01:00
smallmodel e32222884d Fixed DisguiseSalute never finishing animation 2024-02-26 15:53:38 +01:00
smallmodel 49a7a1f8ff minimum visibility is 0.999 and not 1.0 2024-02-26 15:53:17 +01:00
smallmodel e5275c0f05 Fixed MASK_TRANSITION being wrong 2024-02-25 21:26:08 +01:00
smallmodel c391605f61 Fixed AI attacking the disguised player
This fixes #203
2024-02-25 20:10:02 +01:00
smallmodel 73c9e6f1d8 Ignore disabled ennemies 2024-02-25 19:16:07 +01:00
smallmodel 2d6ac6f0be Fixed weapon melee AI broadcast 2024-02-25 19:15:41 +01:00
smallmodel 57870103a6 Fixed TriggerVehicle not responding to VehicleCollisionEntity 2024-02-25 18:54:42 +01:00
smallmodel 64604b5c44 Disable non-pvs sound in single-player
This fixes #267 where configstrings are full
2024-02-25 18:43:42 +01:00
smallmodel 9960884e3c Initialize watchFadeTime 2024-02-23 23:53:27 +01:00
smallmodel 593982d586 Added assertion test 2024-02-23 23:53:18 +01:00
smallmodel f229c1c5a8 Fixed player health in SP 2024-02-23 23:21:44 +01:00
smallmodel 35e9f9982c Preallocate arguments for sp/dm commands 2024-02-23 23:19:59 +01:00
smallmodel a0cb46d4a1 Formatting 2024-02-23 23:09:57 +01:00
smallmodel e8a48184b9 Set the ground entity number to the glue master 2024-02-23 23:09:29 +01:00
smallmodel d2aa26248f Don't allow ducking when physics are off
This fixes #251
2024-02-23 23:02:29 +01:00
smallmodel 0f1de72ae6 Initialize the ground entity number 2024-02-23 22:51:08 +01:00
smallmodel efaea69c09 Don't evaluate state when immobile 2024-02-23 21:12:38 +01:00
smallmodel a67dbff603 Reset state to STAND when the player has no physics 2024-02-23 21:12:23 +01:00
smallmodel 35e6435382 Reimplemented DropInventoryItems from 2.30 2024-02-22 23:12:04 +01:00
smallmodel 7a2735885f Send information about sentient's team
This fixes #259
2024-02-22 22:50:36 +01:00
smallmodel cc721a3db6 Lexer fixes for integer
This fixes map loading issues (fixes #258)
2024-02-22 21:36:31 +01:00
smallmodel 1a5cac2c6a Implemented all parm methods
This fixes, #249 and fixes #217
2024-02-22 20:44:15 +01:00
smallmodel ef08f1c8f3 Fixed turret fire issues 2024-02-22 20:21:53 +01:00
smallmodel 8919890dbe Fixed entity collision for vehicles
This fixes vehicle not properly handling damage triggers (fixes #223, fixes #240)
2024-02-22 19:59:28 +01:00
smallmodel cf6335d180 Fixed VehicleTouched not handling damage properly if there is no driver 2024-02-22 18:29:31 +01:00
smallmodel a86a707e4a Added more variables to initialize 2024-02-22 18:29:16 +01:00
smallmodel 9d61993878 Archive name_index 2024-02-21 20:59:41 +01:00
smallmodel 6eb20a3524 Added PostSpawn for ammo
This fixed ammo being spawned in the air without falling (fixes #244)
2024-02-21 20:59:28 +01:00
smallmodel 7314543c88 Fixed snow bullet hit effect
This fixes #246
2024-02-21 20:17:01 +01:00
smallmodel bb4b10d752 Use result from Cvar_InfoString_Big for CS_SYSTEMINFO 2024-02-21 20:13:24 +01:00
smallmodel 416c568c51 Make CVAR_ROM variables appear first in info strings 2024-02-21 20:13:08 +01:00
smallmodel 65d3a51a17 Use '\n' instead of 10 2024-02-21 20:12:14 +01:00
smallmodel e55f5902d5 Avoid using constant values 2024-02-21 20:12:05 +01:00
smallmodel b0180383df Fixed FFA scores
This fixes #242
2024-02-21 19:37:49 +01:00
smallmodel 61f0fc665f Fixed MG42 reload anim name 2024-02-20 23:29:47 +01:00
smallmodel b0c1d79132 Fixed AI mg42 fire delay 2024-02-20 23:29:38 +01:00
smallmodel 7945c2ca66 Fixed target's m_Team accidentally being overwritten
This causes NPC to look invulnerable (fixes #238)
2024-02-20 22:57:02 +01:00
smallmodel 8b2b1a9a47 S_AddLoopingSound: ignore null sfx handle 2024-02-20 22:42:54 +01:00
smallmodel b76f9a9a6c Fixed skel_entity_cache initialization 2024-02-20 22:42:34 +01:00
smallmodel 8af5da5fca tiki assert check 2024-02-20 20:45:05 +01:00
smallmodel cbe6d85bcd Added multiple cache per entity 2024-02-20 20:44:55 +01:00
smallmodel 6b6e2c947c Fixed vNorm not being initializing causing crashes on rare occasions
This should fix #169
2024-02-20 19:53:08 +01:00
smallmodel 66fcc2cd14 Cleaned up VSS_AddRepulsion 2024-02-20 19:52:11 +01:00
smallmodel af829772f9 Cleaned up VSS_CalcRepulsionForces and fixed vss index 2024-02-20 18:54:59 +01:00
smallmodel 7b6a558fe5 Check for valid turret gun in P_UserAim
When the player dies, it gets detached from turret can would cause crash (#216)
2024-02-19 23:41:57 +01:00
smallmodel 4122ee4168 Fixed RunAndShoot state crash due to NULL moving patrol node
(#214)
2024-02-19 23:25:39 +01:00
smallmodel b77f62ab58 Load/Save SimpleArchivedEntity
This fixes #213 where elevator wouldn't go up because of missing waypoint
2024-02-19 23:23:15 +01:00
smallmodel 783bf1b63c Archive ignorevelocity member 2024-02-19 23:22:53 +01:00
smallmodel a0728b4a8a Using MASK_CLICKITEM mask for ClickItemAttack 2024-02-19 23:10:14 +01:00
smallmodel ea6e865cc8 Added MASK_CLICKITEM 2024-02-19 19:59:14 +01:00
smallmodel 1da4113110 Added FuncLadder archive method
This fixes bug where ladder would get unusable after loading from save game (see #211)
2024-02-19 19:36:46 +01:00
smallmodel 7956746b65 Fixed inward sphere argument: the argument should be optional
See #209
2024-02-19 19:34:11 +01:00
smallmodel 10a8d13ade Added missing variables to archive 2024-02-18 23:27:15 +01:00
smallmodel 65b47a2b3a Fixed AnimDone never being called
This fixes maps like e1l2 never starting because it waits for an anim to finish
2024-02-18 21:54:18 +01:00
smallmodel 46cc00d669 Set m_fMaxSpeed 2024-02-18 21:53:33 +01:00
smallmodel 5521cf9ab3 Fixed m_fMaxSpeed being always set to 250 2024-02-18 20:10:18 +01:00
smallmodel a770df1e0b Fixed path not found spam 2024-02-18 15:47:07 +01:00
smallmodel 03943a23ac Fixed badplace and run and shoot think never working 2024-02-17 20:10:00 +01:00
smallmodel 685dc0336a Corrected loop ordering 2024-02-17 00:05:39 +01:00
smallmodel 776012fedf Health must have a targetname by default in 2.0 and above 2024-02-16 23:52:25 +01:00
smallmodel 6ba9f2655c Call PostSpawn after constructing the health instance 2024-02-16 23:51:34 +01:00
smallmodel 8a3b62e93f Fixed targetname error 2024-02-16 23:50:57 +01:00
smallmodel bd999a6d9c Fixed Trace's pass_entities parameter (didn't properly ignore entities) 2024-02-15 23:48:23 +01:00
smallmodel f46078965d info_null must inherits from Listener instead of Entity
This fixes Level::AllocEdict issues on some maps that use it a lot (like t2l4) #206
2024-02-15 21:15:37 +01:00
smallmodel 60f6bb17e3 Fixed AI parameters not fixing AI parameters 2024-02-15 20:40:55 +01:00
smallmodel fdf1dac618 Wrong condition for SetDesiredYawDest (should set only if values are non-zero) 2024-02-15 20:23:50 +01:00
smallmodel 373a35acf0 Fixed target trigger being triggered by itself 2024-02-15 20:23:17 +01:00
smallmodel abfdac59ba Make aiMaxDeviation only supported on 2.0 and above 2024-02-15 00:21:01 +01:00
smallmodel efc1354dcb Fixed entity monitoring always used 2024-02-14 20:58:19 +01:00
smallmodel c9f2603692 Don't suppress below 2.0 2024-02-14 20:48:11 +01:00
smallmodel aab24260e2 FriendlyInLineOfFire should return false below 2.0 2024-02-14 20:47:54 +01:00
smallmodel e450156bf7 Fixed path goal movement 2024-02-14 20:46:43 +01:00
smallmodel 1533c02a41 Fixed cover hide 2024-02-14 20:32:57 +01:00
smallmodel c4855029a9 Fixed motion facing 2024-02-14 20:32:40 +01:00
smallmodel 4fa457118f Fixed CanMovePathWithLeash() not returning the correct result 2024-02-14 20:06:35 +01:00
smallmodel 33b403d6eb Fixed MASK_CANSEE 2024-02-14 19:58:29 +01:00
smallmodel a5c6654dcb Fixed m_fMaxDistanceSquared initialization value 2024-02-14 19:22:19 +01:00
smallmodel 07ec6adecb Fixed ViewJitter never being removed 2024-02-14 18:40:34 +01:00
smallmodel ceb901e9ca Fixed disconnected menu not being pushed properly 2024-02-14 18:32:06 +01:00
smallmodel 651b86b066 Added comment for more clarity 2024-02-13 18:23:23 +01:00
smallmodel a4003dd61c Only execute anim/suppress.scr if targeting 2.0 and above 2024-02-13 18:16:52 +01:00
smallmodel 5e461786f9 Added a comment about FriendlyInLineOfFire 2024-02-13 18:15:54 +01:00
smallmodel 45108c6f4b Fixed curious' finished animation global function
This fixes AI being permanently stuck in a curious animation
2024-02-13 17:38:11 +01:00
smallmodel bc0d373dcd Fixed AI getting blocked because of an obstacle 2024-02-13 17:37:28 +01:00
smallmodel 0f37a8f6ea Fixed m_fLeashSquared initialization 2024-02-13 16:42:54 +01:00
smallmodel 03ceaf82ce Fixed AngleMod() being inaccurate
This caused issues with Actor never finishing turning (because it expected the desired yaw to be at the exact same angle rounded by 0.001)
2024-02-13 16:23:47 +01:00
smallmodel 1e5e5e24f6 Fixed entity monitoring never printing 2024-02-13 16:23:06 +01:00
smallmodel eb993dbd43 Fixed grenade toss location and wall facing 2024-02-13 16:22:56 +01:00
smallmodel 4f5abb3412 Fixed int conversion when printing the awareness 2024-02-13 16:22:39 +01:00
smallmodel 6418d79d76 Call PostThink() in Think_Alarm() 2024-02-13 16:22:18 +01:00
smallmodel 796a3a711f Fixed animation delta over time 2024-02-13 01:01:51 +01:00
smallmodel 0ef743d945 Forgot newline 2024-02-13 01:01:39 +01:00
smallmodel 7c33f98ae9 Use m_fFollowRelativeYaw 2024-02-13 00:57:37 +01:00
smallmodel 51ba1e2951 Properly use identity / identitylighting when cgen isn't explicitly specified 2024-02-12 23:47:07 +01:00
smallmodel 0b16d599d5 Added UseCount for image_t 2024-02-12 22:11:15 +01:00
smallmodel 3b2223ad22 image validity check 2024-02-12 22:11:00 +01:00
smallmodel 186583148a Use proper values for GL_TEXTURE_WRAP_S and GL_TEXTURE_WRAP_T 2024-02-12 22:10:00 +01:00
smallmodel 5475624b7f Added DDS support + handle compressed textures correctly 2024-02-12 20:19:33 +01:00
smallmodel d5be69239a Added GL 1.3 functions 2024-02-12 20:18:52 +01:00
smallmodel 304645d720 Ignore CGEN_BAD stages 2024-02-12 19:50:32 +01:00
smallmodel 0591152f99 Added ifCvar / ifCvarnot support 2024-02-12 17:18:51 +01:00
smallmodel 74e8a38c00 When idle, limit the turret's pitch to the max idle pitch 2024-02-12 16:59:20 +01:00
smallmodel 5cadab46ab Fixed fence mask being incorrectly specified as transparent rather than opaque 2024-02-12 16:49:27 +01:00
smallmodel 1577927d99 Ignore collision if the brush has a trace content and the trace content wasn't specified in the trace flags 2024-02-12 16:48:58 +01:00
smallmodel 5a0aeb2f88 Fixed last fire time being incorrectly set in the future 2024-02-12 15:12:55 +01:00
smallmodel 7a1f7773bf Use sin/cos instead of sinf/cosf (accuracy) 2024-02-12 15:05:33 +01:00
smallmodel b0e597cf55 Fixed vehicle collision orientation 2024-02-12 15:02:55 +01:00
smallmodel c40d073d7a Refactored CM_CheckTerrainTriSphere 2024-02-12 14:17:04 +01:00
smallmodel dd8b3f607a Fixed terrain tri sphere collision not returning correct results with small objects 2024-02-12 13:36:56 +01:00
smallmodel 5cc599984d Fixed bullet hit effect for glass 2024-02-12 00:29:52 +01:00
smallmodel b95b8c4c20 Fixed water bullet effect 2024-02-12 00:17:30 +01:00
smallmodel 3e190ca4b3 Added MASK_SHOT_FLUID (there are so many masks) 2024-02-12 00:02:28 +01:00
smallmodel 3853d1ef39 Properly map the CGM message depending on the protocol version 2024-02-11 23:38:24 +01:00
smallmodel bf700186d0 Fixed bounce velocity reduction 2024-02-11 23:31:26 +01:00
smallmodel ca7cacfdcc Add a debug line when bouncing if enabled (for AI) 2024-02-11 23:27:21 +01:00
smallmodel b893f4f89f Properly stop if on ground 2024-02-11 23:20:52 +01:00
smallmodel 109686aca2 Reduce the velocity when bouncing 2024-02-11 23:14:08 +01:00
smallmodel 6840df4eca backoff value should be 1.4 for bounce and 1.6 for Gib 2024-02-11 23:11:11 +01:00
smallmodel ed3f212bd8 Also check for slide with bounce movetype 2024-02-11 23:10:21 +01:00
smallmodel e1f2a51f2b Only move angles if there is an angular velocity 2024-02-11 23:07:32 +01:00
smallmodel d3870309fb Fixed MASK_MONSTERSOLID 2024-02-11 22:56:44 +01:00
smallmodel 1fa2031f11 When a player is inside a vehicle, use the vehicle's health for the health stat 2024-02-08 20:41:33 +01:00
smallmodel 1d765125c7 Fixed facets and planes being badly initialized 2024-02-08 20:35:11 +01:00
smallmodel 5aa70d91f3 Fixed patch subdivisions 2024-02-07 23:44:59 +01:00
smallmodel f018c2c15a Ignore shaders for surface starting with the name "material" 2024-02-07 23:36:04 +01:00
smallmodel 1b8ad12b25 Call RefreshMaterial() instead of ReregisterMaterial() 2024-02-07 23:33:12 +01:00
smallmodel 078aa01895 Reimplemented RefreshMaterial() 2024-02-07 23:33:02 +01:00
smallmodel f0aad4bb21 Don't mark the driver slot as unused by default 2024-02-07 22:51:50 +01:00
smallmodel 8fe054b063 Fixed door open direction 2024-02-06 23:32:33 +01:00
smallmodel ac63e6c627 Rotate the client when blocked, and make sure the checked's velocity doesn't reach the push move speed 2024-02-06 23:31:48 +01:00
smallmodel 434a48af7d Initialize m_iNumShotsFired 2024-02-06 22:57:37 +01:00
smallmodel c5dcf96717 Implemented all RB_Calc functions 2024-02-06 22:54:48 +01:00
smallmodel 84791c42bc Implemented RB_CalcSunReflectionTexCoords 2024-02-06 22:23:26 +01:00
smallmodel e032a1a627 Implemented all tcMod values 2024-02-06 22:16:20 +01:00
smallmodel 1f2b5dcc86 Added and fixed all missing tcMod parameters 2024-02-06 20:07:39 +01:00
smallmodel 8bd30ffb22 Added rate tmod variable 2024-02-06 19:59:14 +01:00
smallmodel fbf67fccc3 Added TMOD enum values from AA 1.11 2024-02-06 19:55:21 +01:00
smallmodel b848ee0fac Added rotateStart and rotateCoef for rotate tcMod 2024-02-06 19:48:55 +01:00
smallmodel 4a39e5411f Fixed patch collision in position test 2024-02-05 23:46:43 +01:00
smallmodel 336ba6181e Don't allocate planes / facets if there are none 2024-02-05 23:25:41 +01:00
smallmodel c9aedf242d Fixed scoreboard sending incorrect data for spectators 2024-02-05 21:03:10 +01:00
smallmodel 500c70016f Don't crossblend with new weapons 2024-02-05 20:13:23 +01:00
smallmodel cf1dbf07c7 Corrected MASK_CLICK tracemask (especially for patches surface) 2024-02-04 20:46:05 +01:00
smallmodel 13ec3435b4 Fixed rain num shaders 2024-02-04 19:36:56 +01:00
smallmodel fce0f7b357 Better rain handlijng 2024-02-04 19:36:34 +01:00
smallmodel 0fabdc8c44 Added current objective index 2024-02-04 19:25:03 +01:00
smallmodel 2174f2ff85 For "delete" and "remove", use Listener::ScriptRemove 2024-02-04 19:09:08 +01:00
smallmodel ac40373c09 Use RemoveVehicleSoundEntities() to remove sound entities 2024-02-04 19:08:37 +01:00
smallmodel d5908bd75c Fixed frag grenade spelling in SP 2024-02-04 16:30:31 +01:00
smallmodel 8cf3be3526 If in thinks, don't delete the object immediately 2024-02-04 16:30:22 +01:00
smallmodel 0290fa3351 Set default animation on the attached model if the tag was not found 2024-02-04 16:30:02 +01:00
smallmodel 937f3993ec Removed unusable FX in 1.11 and below 2024-02-04 16:10:49 +01:00
smallmodel d501285057 Play pain animation only in 2.0 and above 2024-02-04 15:47:48 +01:00
smallmodel 0ed92943de Fixed commands not being executed properly on a specific type of array of listeners 2024-02-03 23:22:06 +01:00
smallmodel 56044dd8f8 HideMouse doesn't take parameters 2024-02-03 23:19:55 +01:00
smallmodel e8109076f4 Assign shaders to surfaces that don't have a shader assigned 2024-02-03 23:03:41 +01:00
smallmodel 0a31ab7558 Use the correct view model animation for the kar98 mortar 2024-02-03 21:23:59 +01:00
smallmodel e73be7ef5c Smoke grenades don't exist in vanilla Allied Assault 2024-02-03 21:19:04 +01:00
smallmodel aa209e0aaf Fixed plane distance not being copied correctly with terrain square mode 5 or 6 2024-02-03 21:09:26 +01:00
smallmodel 570dddddd8 Formatted cm_terrain source files 2024-02-03 21:07:49 +01:00
smallmodel 534176423e Fixed trace error with Vehicle Hit(MV2) 2024-02-02 23:05:55 +01:00
smallmodel ca2c2fb8fe Use floating-point operation in CalculateBoxPoints() 2024-02-02 23:05:18 +01:00
smallmodel 4388b7b187 AI_ThinkActive() must be used if the owner is an Actor 2024-02-02 19:26:11 +01:00
smallmodel 368f94ce3b Fixed spline improperly returning the number of points when appending 2024-02-02 19:23:09 +01:00
smallmodel e7fd0f7419 Merge pull request #138 from ysdragon/dev
Fixed compilation using Clang 16+
2024-01-31 20:43:30 +01:00
DraGoN 92f7c3633f Fixed compilation using Clang 16+ 2024-01-30 22:54:13 +00:00
smallmodel bf27caa61e Fixed vehicle lacking gravity 2024-01-29 22:55:48 +01:00
smallmodel 808916029e Formatted scriptthread source file 2024-01-29 00:03:51 +01:00
smallmodel 5f3ee10bc0 Fixed Linux compilation error because of stupid CL accepting anything 2024-01-29 00:01:39 +01:00
smallmodel 45f50cfe25 Fixed array variable being case-sensitive 2024-01-28 23:53:02 +01:00
smallmodel 42c0605abf Fixed game message printing possible random characters if the string is empty 2024-01-28 23:33:59 +01:00
smallmodel f83839e01b Fixed crash with WhatIs command if the entity doesn't have a model 2024-01-28 23:32:43 +01:00
smallmodel 24dbc1ce4e Use C vectors 2024-01-28 23:29:56 +01:00
smallmodel d8505eff2b Fixed label parameters being incorrectly case-sensitive 2024-01-28 23:17:00 +01:00
smallmodel bca71ade85 Added automatic addition of idle animation when there is none (from 2.30 code) 2024-01-28 23:16:47 +01:00
smallmodel 7518d7b418 Reworked FS_CanonicalFilename 2024-01-28 20:41:17 +01:00
smallmodel 3f8aeac7e6 Exported WriteSkelmodel 2024-01-28 20:27:58 +01:00
smallmodel c4a9a87929 Added TIKI_AddDefaultIdleAnim 2024-01-28 20:24:17 +01:00
smallmodel 7eca455795 Set the idle skelmodel and increase the number of skels 2024-01-28 20:24:04 +01:00
smallmodel cb9ac23b23 Added TIKI_AllocAnim 2024-01-28 20:23:05 +01:00
smallmodel 4a66a41f91 Added idle skel and number of skeletons 2024-01-28 20:19:14 +01:00
smallmodel 665c35d089 Added TIKI array max values 2024-01-28 20:18:09 +01:00
smallmodel 0a634c633b Fixed crash when loading MP3 in OpenAL 2024-01-28 19:41:31 +01:00
smallmodel eb70b30e7a Fixed an issue with the lexer (space before thhe dot) 2024-01-28 19:40:32 +01:00
smallmodel 8d188073b4 When pushing a menu, the max motion time must be taken from the head menu 2024-01-27 21:26:37 +01:00
smallmodel ceea855c6f Also play Widget motion if there is a fade sequence 2024-01-27 21:26:11 +01:00
smallmodel 9b7f192dce Corrected marks not working on entities like doors 2024-01-27 21:14:13 +01:00
smallmodel 23a866f6f8 Implemented R_GetInlineModelBounds 2024-01-27 20:53:17 +01:00
smallmodel 946a7a406c Fixed client not quitting when dedicated is set to 1 2024-01-27 20:45:56 +01:00
smallmodel e209290073 Fixed cSpline using wrong positions 2024-01-25 21:55:21 +01:00
smallmodel 2c441ee541 Fixed vehicle sound entity using bad sound prefix 2024-01-25 21:55:03 +01:00
smallmodel dd768ec9ef Formatted VehicleSoundEntity source files 2024-01-25 21:54:44 +01:00
smallmodel adaeaea596 Fixed other code that makes the game crash when length is 0 2024-01-25 19:48:34 +01:00
smallmodel 5a44740592 Fixed invalid event name causing crashes 2024-01-24 21:52:22 +01:00
smallmodel 97a0bd90ec Set default values for sv_invulnerabletime and sv_team_spawn_interval depending on the target protocol 2024-01-24 20:37:43 +01:00
smallmodel 92ee1d9caf Reset location print after sending it 2024-01-24 20:19:22 +01:00
smallmodel 9ab28dc7da Fixed objective maps appearing twice 2024-01-23 22:42:27 +01:00
smallmodel 840501c8dd Fixed waffenss skin name 2024-01-23 00:04:41 +01:00
smallmodel ef4b79b1f5 Fixed pm_flags being wrong on Allied Assault 2024-01-22 23:53:25 +01:00
smallmodel b6b35079ef Fixed crouch height bounding box 2024-01-22 23:53:13 +01:00
smallmodel b8e8aead93 Fixed issues with multiple consecutive dollars
This fixes the issue with scripts, like `m6l1c` that accidentally use double dollars for targetnames, like `$$player`
2024-01-22 22:20:25 +01:00
smallmodel dd378db4d0 Avoid the use of fabs() for dot product 2024-01-22 00:08:27 +01:00
smallmodel cc048f5099 Fixed some sounds being improperly replaced 2024-01-21 23:50:15 +01:00
smallmodel ac02afaae6 Don't spam the console with OpenAL errors 2024-01-21 23:48:49 +01:00
smallmodel bff58ae615 Removed trace.startsolid check 2024-01-21 23:30:48 +01:00
smallmodel 748934edcd Fixed incorrect box in brush testing 2024-01-21 23:30:38 +01:00
smallmodel d9fb375812 Fixed collision issues due to steps 2024-01-21 20:46:15 +01:00
smallmodel 55582a85ab Fixed entityNum callback 2024-01-18 20:39:04 +01:00
smallmodel 9255c5259d Fixed spawnpoint issues 2024-01-18 20:23:41 +01:00
smallmodel f1e2a45520 Don't crash if the length is 0 2024-01-18 20:05:57 +01:00
smallmodel cb9e69238c Initialize buffer to 0 (integer) 2024-01-17 23:15:38 +01:00
smallmodel 56b2971dee Fixed AL positioning and volume 2024-01-17 20:44:32 +01:00
smallmodel ad917d96c8 Use roundf() for more clarity 2024-01-17 19:33:07 +01:00
smallmodel 1fd7bd3fa5 Fixed MP3 loading and improperly configured channels 2024-01-16 20:54:41 +01:00
smallmodel 1234bd89c7 Fixed wrong configstring for the soundtrack 2024-01-16 20:54:10 +01:00
smallmodel 187ee87f10 Make sure to initialize new sound system 2024-01-16 20:28:13 +01:00
smallmodel 5ae88b816d Initialize pSoundAlias to NULL 2024-01-16 20:27:56 +01:00
smallmodel 3418691f88 Added S_NeedFullRestart and S_ReLoad 2024-01-16 20:27:43 +01:00
smallmodel 4e8a51db81 Fixed Wav not loading properly 2024-01-16 20:27:32 +01:00
smallmodel 2629ef17c3 Made snd_codec c++ aware 2024-01-16 20:27:20 +01:00
smallmodel 9b63625c2b Add snd_codec 2024-01-16 20:27:10 +01:00
smallmodel 970d72cf07 Implemented snd_openal_new.cpp 2024-01-15 23:04:25 +01:00
smallmodel d88870bc04 Added more exports 2024-01-15 23:04:13 +01:00
smallmodel 9b35e13923 Added qalGetSourceiv / qalGetBufferfv 2024-01-15 23:04:01 +01:00
smallmodel 032eb11cfb Implemented various methods 2024-01-12 00:04:36 +01:00
smallmodel 9ea7b77231 Added channel flags and loopsound flags 2024-01-12 00:04:20 +01:00
smallmodel 318dc18891 Added MAX_OPENAL_POSITION_CHANNELS 2024-01-10 23:03:03 +01:00
smallmodel 8d327cd0a0 Added more SFX flags and exports 2024-01-10 23:02:30 +01:00
smallmodel d3de937ee0 Added FS_CorrectCase 2024-01-10 19:45:53 +01:00
smallmodel 3be1673eb9 Added boolean sound DMA variables 2024-01-10 19:32:44 +01:00
smallmodel 13f23ace76 Added macros for more clarity 2024-01-09 23:30:29 +01:00
smallmodel 26c50f15dc Added s_volume and sfx exports + added load_sfx_info() declaration 2024-01-09 23:28:28 +01:00
smallmodel 46aa58d0cd Made qal.h C++ aware 2024-01-09 23:28:01 +01:00
smallmodel aac9dd40de Add USE_OPENAL=1 definition when USE_SOUND_NEW is defined 2024-01-09 23:27:51 +01:00
smallmodel 71dba1b7dc Added snd_info.cpp 2024-01-08 23:25:48 +01:00
smallmodel 8b85e4e075 Export number_of_sfx_infos and sfx_infos 2024-01-08 23:25:41 +01:00
smallmodel 028489d673 Implemented snd_mem_new.c 2024-01-08 23:15:12 +01:00
smallmodel 5c4c14a17d Added SFX flags 2024-01-08 23:15:09 +01:00
smallmodel 2e10a96d11 Crosshair must always be shown in 1.11 and below regardless of the property 2024-01-08 23:05:21 +01:00
smallmodel 09ad42ba47 Fixed players not being able to use while firing, below 2.0 2024-01-08 22:56:26 +01:00
smallmodel 88ccaee5cc Implemented C++ sound DMA 2024-01-08 20:07:26 +01:00
smallmodel e936a0b995 Added more declarations 2024-01-08 20:03:25 +01:00
smallmodel ff5b0b7607 Added snd_mem_new.c 2024-01-08 19:43:47 +01:00
smallmodel edd2fd5e63 Renamed aarch64 to arm64 2024-01-08 18:37:33 +01:00
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
623 changed files with 88820 additions and 81784 deletions

No files matched your search

+39
View File
@@ -0,0 +1,39 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots (OPTIONAL)**
If applicable, add screenshots to help explain your problem.
**Logs**
- Paste the output of the console window in a text file, and attach the text file.
- If applicable (`logfile` set to 2), attach the `qconsole.log` file. On Windows, it can be found in **%APPDATA%\...\qconsole.log** and on Linux, it can be found on the home directory **~/.openmohaa/.../qconsole.log**.
**Version information (please complete the following information):**
- OS: [e.g. `Debian`]
- OS Version [e.g `12`]
- OpenMoHAA Version: [e.g `0.70.0-alpha+0.0b1a20dcf win_msvc64-x86_64-debug`, can be found below **Common Initialization** in the console, or by typing `version`]
**Dump (OPTIONAL)**
You can include a core dump generated by the OS (`.dmp` file). If you compiled OpenMoHAA yourself, also add all output openmohaa binaries (except libopenal and libSDL).
**Additional context (OPTIONAL)**
Add any other context about the problem here.
+17
View File
@@ -0,0 +1,17 @@
name: Build branch
on:
push:
branches:
- '**'
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build-all:
uses: ./.github/workflows/shared-build.yml
with:
environment: "testing"
-192
View File
@@ -1,192 +0,0 @@
name: Build
on:
push:
pull_request:
workflow_call:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: RelWithDebInfo
jobs:
build-platform-linux:
strategy:
matrix:
architecture: [
{name: 'amd64', triple: 'x86_64-linux-gnu'},
{name: 'i686', triple: 'i686-linux-gnu'},
{name: 'aarch64', triple: 'aarch64-linux-gnu'},
{name: 'armhf', triple: 'arm-linux-gnueabihf'}
]
name: "Building for platform linux-${{matrix.architecture.name}}"
runs-on: ubuntu-22.04
steps:
- name: Settings
working-directory: ${{github.workspace}}
run: |
echo "CMAKE_BUILD_PARALLEL_LEVEL=$(($(nproc) * 16))" >> $GITHUB_ENV
# echo "CMAKE_GENERATOR=Ninja" >> $GITHUB_ENV
- name: Install required packages
run: |
sudo apt update && sudo apt install -y flex bison
- name: Install required cross-platform packages (${{ matrix.architecture.triple }})
if: matrix.architecture.name != 'amd64'
run: sudo apt install -y gcc-12-${{ matrix.architecture.triple }} g++-12-${{ matrix.architecture.triple }}
# Setup SDL
- name: Set up SDL
id: sdl
uses: libsdl-org/setup-sdl@main
with:
version: sdl2-latest
build-type: Release
cmake-arguments: "-DCMAKE_C_COMPILER=clang
-DCMAKE_CXX_COMPILER=clang++
-DCMAKE_C_FLAGS=--target=${{ matrix.architecture.triple }}
-DCMAKE_CXX_FLAGS=--target=${{ matrix.architecture.triple }}"
- uses: actions/checkout@v3
with:
path: 'source'
- name: CMake Settings
run: |
echo "CMAKE_PARAM=--log-level=VERBOSE \
-DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} \
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/install' \
-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
-DCMAKE_C_FLAGS=--target=${{ matrix.architecture.triple }} \
-DCMAKE_CXX_FLAGS=--target=${{ matrix.architecture.triple }} \
-DGIT_REVISION_BUILD_NUMBER=${{ github.run_number }}" >> $GITHUB_ENV
- name: Configure CMake
working-directory: ${{github.workspace}}
run: |
cmake -B ./build ${{ env.CMAKE_PARAM }} ./source
- name: Build
working-directory: ${{github.workspace}}
run: |
cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
- name: Test
working-directory: ${{github.workspace}}
# Execute tests defined by the CMake configuration.
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
run: |
cd "${{github.workspace}}/build"
ctest -C ${{env.BUILD_TYPE}}
- name: Install
working-directory: ${{github.workspace}}
# Install to the directory defined in CMAKE_INSTALL_PREFIX
run: |
cmake --install ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
cp '${{steps.sdl.outputs.prefix}}/lib/libSDL2.so' '${{github.workspace}}/install'
- uses: actions/upload-artifact@v3
with:
name: out-linux-${{matrix.architecture.name}}
if-no-files-found: error
path:
${{github.workspace}}/install
build-platform-windows:
strategy:
matrix:
architecture: [
{name: 'x64', config: 'x64' },
{name: 'x86', config: 'Win32' },
{name: 'arm64', config: 'ARM64' }
]
name: "Building for platform windows-${{matrix.architecture.name}}"
runs-on: windows-2022
steps:
- name: Settings
working-directory: ${{github.workspace}}
run: |
echo "CMAKE_BUILD_PARALLEL_LEVEL=$((Get-CimInstance Win32_ComputerSystem).NumberOfLogicalProcessors * 16)" >> $GITHUB_ENV
# Setup SDL
- name: Set up SDL
id: sdl
uses: libsdl-org/setup-sdl@main
with:
version: sdl2-latest
build-type: Release
cmake-arguments: "-A ${{ matrix.architecture.config }}"
- name: Install Flex/Bison
working-directory: ${{github.workspace}}
run: |
mkdir thirdparties && cd thirdparties
git clone --depth 1 --single-branch --branch v2.5.25 https://github.com/lexxmark/winflexbison.git
cmake -B winflexbison-build -DCMAKE_INSTALL_PREFIX='${{github.workspace}}/thirdparties/winflexbison-install' ./winflexbison
cmake --build winflexbison-build --config Release --parallel
cmake --install winflexbison-build
- uses: actions/checkout@v3
with:
path: 'source'
- name: CMake Settings
run: |
echo "CMAKE_PARAM=-A ${{ matrix.architecture.config }} `
--log-level=VERBOSE `
-DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} `
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/install' `
-DGIT_REVISION_BUILD_NUMBER=${{ github.run_number }} `
-DBISON_EXECUTABLE='${{github.workspace}}/thirdparties/winflexbison-install/win_bison.exe' `
-DFLEX_EXECUTABLE='${{github.workspace}}/thirdparties/winflexbison-install/win_flex.exe'".Replace("`r", "").Replace("`n", "") >> $env:GITHUB_ENV
- name: Configure CMake
working-directory: ${{github.workspace}}
run: |
cmake -B ./build ${{ env.CMAKE_PARAM }} ./source
- name: Build
working-directory: ${{github.workspace}}
run: |
cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
- name: Test
working-directory: ${{github.workspace}}
# Execute tests defined by the CMake configuration.
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
run: |
cd "${{github.workspace}}/build"
ctest -C ${{env.BUILD_TYPE}}
- name: Install
working-directory: ${{github.workspace}}
# Install to the directory defined in CMAKE_INSTALL_PREFIX
run: |
cmake --install ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
Copy-Item '${{steps.sdl.outputs.prefix}}/bin/*.dll' -Destination '${{github.workspace}}/install'
- uses: actions/upload-artifact@v3
with:
name: out-windows-${{matrix.architecture.name}}
if-no-files-found: error
path: |
${{github.workspace}}/install
!${{github.workspace}}/install/**/*.pdb
- uses: actions/upload-artifact@v3
with:
name: out-windows-${{matrix.architecture.name}}-pdb
if-no-files-found: error
path: |
${{github.workspace}}/install
@@ -20,6 +20,10 @@ on:
schedule:
- cron: '42 8 * * 1'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
analyze:
name: Analyze
@@ -41,7 +45,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4
# Setup SDL
- name: Set up SDL
@@ -52,7 +56,7 @@ jobs:
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
@@ -66,7 +70,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2
uses: github/codeql-action/autobuild@v3
# ℹ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
@@ -79,6 +83,6 @@ jobs:
# ./location_of_script_within_repo/buildscript.sh
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
uses: github/codeql-action/analyze@v3
with:
category: "/language:${{matrix.language}}"
+477
View File
@@ -0,0 +1,477 @@
name: Shared build workflow
on:
workflow_call:
inputs:
environment:
required: true
type: string
env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: RelWithDebInfo
RELEASE_STAGE: ${{ vars.RELEASE_STAGE || 'unstable' }}
jobs:
##########################
#
# Linux
# Ubuntu 22.04
#
# Using this version instead of 24.04 to use a lower GLIBC version (2.34)
##########################
build-platform-linux:
strategy:
matrix:
architecture: [
{name: 'amd64', triple: 'x86_64-linux-gnu'},
{name: 'i686', triple: 'i686-linux-gnu'},
{name: 'arm64', triple: 'aarch64-linux-gnu'},
{name: 'armhf', triple: 'arm-linux-gnueabihf'},
{name: 'powerpc', triple: 'powerpc-linux-gnu'},
{name: 'ppc64', triple: 'powerpc64-linux-gnu'},
{name: 'ppc64el', triple: 'powerpc64le-linux-gnu'}
]
name: "Building for platform linux-${{matrix.architecture.name}}"
runs-on: "ubuntu-22.04"
environment: ${{ inputs.environment }}
steps:
###
# Packages
###
- uses: awalsh128/cache-apt-pkgs-action@latest
name: Install required packages
with:
packages: flex bison ninja-build cmake clang libpulse-dev portaudio19-dev libasound2-dev libjack-dev libpipewire-0.3-dev qtbase5-dev libdbus-1-dev
version: "0.1"
- uses: awalsh128/cache-apt-pkgs-action@latest
name: Install required cross-platform packages (${{ matrix.architecture.triple }})
if: matrix.architecture.name != 'amd64'
with:
packages: gcc-12-${{ matrix.architecture.triple }} g++-12-${{ matrix.architecture.triple }}
version: "0.1"
- name: Settings
working-directory: ${{github.workspace}}
run: |
echo "CMAKE_GENERATOR=Ninja Multi-Config" >> $GITHUB_ENV
echo "CC=clang" >> $GITHUB_ENV
echo "CXX=clang++" >> $GITHUB_ENV
echo "CFLAGS='--target=${{ matrix.architecture.triple }}'" >> $GITHUB_ENV
echo "CXXFLAGS='--target=${{ matrix.architecture.triple }}'" >> $GITHUB_ENV
# Temporary workaround for PowerPC as the 1.24.0 version doesn't check for altivec
# Will use older versions until a new tag is created with this issue resolved
if [ ${{ matrix.architecture.name }} != 'powerpc' ] && [ ${{ matrix.architecture.name }} != 'ppc64' ] && [ ${{ matrix.architecture.name }} != 'ppc64el' ]; then
echo "OPENAL_REF=1.24.0" >> $GITHUB_ENV
else
echo "OPENAL_REF=1.23.1" >> $GITHUB_ENV
fi
###
# SDL
###
# Setup SDL
- name: Set up SDL
id: sdl
uses: libsdl-org/setup-sdl@main
with:
version: 2-latest
build-type: Release
# Workaround for when changing the runner OS version
cmake-arguments: "-DCACHE_OS_VERSION=Ubuntu_22.04"
###
# OpenAL
###
# soft-oal setup
- name: Checkout soft-oal
uses: actions/checkout@v4
with:
repository: 'kcat/openal-soft'
path: 'thirdparties/soft-oal'
ref: ${{ env.OPENAL_REF }}
- name: Configure and install soft-oal
working-directory: ${{github.workspace}}/thirdparties/soft-oal
run: |
cmake -B ./build \
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/thirdparties/soft-oal/install'
cmake --build ./build --config Release --parallel
cmake --install ./build --config Release
###
# Project
###
- uses: actions/checkout@v4
with:
path: 'source'
- name: CMake Settings
run: |
echo "CMAKE_PARAM=--log-level=VERBOSE \
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/install' \
-DOPENAL_LIBRARY='${{github.workspace}}/thirdparties/soft-oal' \
-DOPENAL_INCLUDE_DIR='${{github.workspace}}/thirdparties/soft-oal/include' \
-DGIT_REVISION_BUILD_NUMBER=${{ github.run_number }} \
-DPRODUCT_VERSION_STAGE='${{ env.RELEASE_STAGE }}'" >> $GITHUB_ENV
- name: Configure CMake
working-directory: ${{github.workspace}}
run: |
cmake -B ./build ${{ env.CMAKE_PARAM }} ./source
- name: Build
working-directory: ${{github.workspace}}
run: |
cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel
- name: Test
working-directory: ${{github.workspace}}
# Execute tests defined by the CMake configuration.
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
run: |
cd "${{github.workspace}}/build"
ctest -C ${{env.BUILD_TYPE}}
- name: Install
working-directory: ${{github.workspace}}
# Install to the directory defined in CMAKE_INSTALL_PREFIX
run: |
cmake --install ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
# Copy libraries
mkdir ${{github.workspace}}/package
cp -l ${{steps.sdl.outputs.prefix}}/lib/libSDL2-2.0.so.0 '${{github.workspace}}/package/'
cp -l ${{github.workspace}}/thirdparties/soft-oal/install/lib/libopenal.so.1 '${{github.workspace}}/package/'
if [ -d ${{github.workspace}}/install/bin ]; then cp -r ${{github.workspace}}/install/bin/openmohaa/. '${{github.workspace}}/package'; fi
if [ -d ${{github.workspace}}/install/lib ]; then cp -r ${{github.workspace}}/install/lib/openmohaa/. '${{github.workspace}}/package'; fi
###
# Artifacts
###
- uses: actions/upload-artifact@v4
with:
name: out-linux-${{matrix.architecture.name}}
if-no-files-found: error
path:
${{github.workspace}}/package
##########################
#
# Microsoft Windows
# Windows Server 2022
#
##########################
build-platform-windows:
strategy:
matrix:
architecture: [
{name: 'x64', config: 'x64', toolset: 'x64' },
{name: 'x86', config: 'Win32', toolset: 'x64_x86' },
{name: 'arm64', config: 'ARM64', toolset: 'x64_arm64' }
]
name: "Building for platform windows-${{matrix.architecture.name}}"
runs-on: "windows-2022"
environment: ${{ inputs.environment }}
steps:
###
# Packages
###
#
# Commented out for now, chocolatey servers started complaining about too many requests
#
#- name: Install required packages
# run: |
# choco install -y ninja
- name: Install required packages
run: |
$DownloadPath="$($env:USERPROFILE)\Downloads"
Invoke-WebRequest "https://github.com/ninja-build/ninja/releases/download/v1.12.1/ninja-win.zip" -OutFile "$DownloadPath\ninja-win.zip"
Expand-Archive -Path "$DownloadPath\ninja-win.zip" -DestinationPath "$($env:PROGRAMFILES)\ninja"
echo "$($env:PROGRAMFILES)\ninja" >> $GITHUB_PATH
- name: Install Flex/Bison
working-directory: ${{github.workspace}}
run: |
mkdir thirdparties && cd thirdparties
git clone --depth 1 --single-branch --branch v2.5.25 https://github.com/lexxmark/winflexbison.git
cmake -B winflexbison-build -DCMAKE_INSTALL_PREFIX='${{github.workspace}}/thirdparties/winflexbison-install' ./winflexbison
cmake --build winflexbison-build --config Release --parallel
cmake --install winflexbison-build --config Release
- name: Settings
working-directory: ${{github.workspace}}
run: |
echo "CMAKE_GENERATOR=Ninja Multi-Config" >> $env:GITHUB_ENV
echo "CC=cl.exe" >> $env:GITHUB_ENV
echo "CXX=cl.exe" >> $env:GITHUB_ENV
pushd "$($env:PROGRAMFILES)\Microsoft Visual Studio\*\*\VC\Auxiliary\Build"
cmd /c "vcvarsall.bat ${{ matrix.architecture.toolset }} & set" | ForEach-Object {
if ($_ -match "=") {
# Split into key=value
$var = $_.split("=", 2);
echo "$($var[0])=$($var[1])" >> $env:GITHUB_ENV
}
}
popd
###
# SDL
###
# Setup SDL
- name: Set up SDL
id: sdl
uses: libsdl-org/setup-sdl@main
with:
version: 2-latest
build-type: Release
cmake-arguments: ""
###
# OpenAL
###
# soft-oal setup
- name: Checkout soft-oal
uses: actions/checkout@v4
with:
repository: 'kcat/openal-soft'
path: 'thirdparties/soft-oal'
ref: '1.24.0'
# soft-oal build
# Statically link the CRT runtime into OAL as a workaround to prevent crashes
- name: Configure and install soft-oal
working-directory: ${{github.workspace}}/thirdparties/soft-oal
run: |
cmake -B ./build `
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/thirdparties/soft-oal/install' `
-DALSOFT_BUILD_ROUTER=OFF `
-DALSOFT_REQUIRE_WINMM=ON `
-DALSOFT_REQUIRE_DSOUND=ON `
-DALSOFT_REQUIRE_WASAPI=ON `
-DCMAKE_C_FLAGS_RELEASE="/MT /O2 /Ob2 /DNDEBUG" `
-DCMAKE_CXX_FLAGS_RELEASE="/MT /O2 /Ob2 /DNDEBUG" `
-DCMAKE_C_FLAGS_MINSIZEREL="/MT /O2 /Ob2 /DNDEBUG" `
-DCMAKE_CXX_FLAGS_MINSIZEREL="/MT /O1 /Ob1 /DNDEBUG" `
-DCMAKE_C_FLAGS_RELWITHDEBINFO="/MT /Zi /O2 /Ob1 /DNDEBUG" `
-DCMAKE_CXX_FLAGS_RELWITHDEBINFO="/MT /Zi /O2 /Ob1 /DNDEBUG"
cmake --build ./build --config Release --parallel
cmake --install ./build --config Release
# Unfortunately soft-oal produces a binary called OpenAL32 even in 64-bit
if (("x64", "ARM64") -icontains "${{ matrix.architecture.config }}") { Rename-Item -Path '.\install\bin\OpenAL32.dll' -NewName 'OpenAL64.dll' }
###
# Project
###
- uses: actions/checkout@v4
with:
path: 'source'
- name: CMake Settings
run: |
echo "CMAKE_PARAM= `
--log-level=VERBOSE `
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/install' `
-DGIT_REVISION_BUILD_NUMBER=${{ github.run_number }} `
-DBISON_EXECUTABLE='${{github.workspace}}/thirdparties/winflexbison-install/win_bison.exe' `
-DOPENAL_LIBRARY='${{github.workspace}}/thirdparties/soft-oal' `
-DOPENAL_INCLUDE_DIR='${{github.workspace}}/thirdparties/soft-oal/include' `
-DFLEX_EXECUTABLE='${{github.workspace}}/thirdparties/winflexbison-install/win_flex.exe' `
-DPRODUCT_VERSION_STAGE='${{ env.RELEASE_STAGE }}'".Replace("`r", "").Replace("`n", "") >> $env:GITHUB_ENV
- name: Configure CMake
working-directory: ${{github.workspace}}
run: |
cmake -B ./build ${{ env.CMAKE_PARAM }} ./source
- name: Build
working-directory: ${{github.workspace}}
run: |
cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel
- name: Test
working-directory: ${{github.workspace}}
# Execute tests defined by the CMake configuration.
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
run: |
cd "${{github.workspace}}/build"
ctest -C ${{env.BUILD_TYPE}}
- name: Install
working-directory: ${{github.workspace}}
# Install to the directory defined in CMAKE_INSTALL_PREFIX
run: |
cmake --install ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
New-Item -ItemType Directory '${{github.workspace}}/package'
Copy-Item '${{steps.sdl.outputs.prefix}}/bin/*.dll' -Destination '${{github.workspace}}/package'
Copy-Item '${{github.workspace}}/thirdparties/soft-oal/install/bin/*.dll' -Destination '${{github.workspace}}/package'
if (Test-Path ${{github.workspace}}/install/bin) { Copy-Item '${{github.workspace}}/install/bin/*' -Include '*.dll','*.exe','*.pdb' -Destination '${{github.workspace}}/package' }
if (Test-Path ${{github.workspace}}/install/lib) { Copy-Item '${{github.workspace}}/install/lib/*' -Include '*.dll','*.exe','*.pdb' -Destination '${{github.workspace}}/package' }
###
# Artifact
###
- uses: actions/upload-artifact@v4
with:
name: out-windows-${{matrix.architecture.name}}
if-no-files-found: error
path: |
${{github.workspace}}/package
!${{github.workspace}}/package/**/*.pdb
- uses: actions/upload-artifact@v4
with:
name: out-windows-${{matrix.architecture.name}}-pdb
if-no-files-found: error
path: |
${{github.workspace}}/package
##########################
#
# Apple macOS
# macOS 14
#
# This version is used as the OS, as older versions are slower.
##########################
build-platform-macos:
strategy:
matrix:
architecture: [
{name: 'x86_64', triple: 'x86_64-apple-macos10.8'},
{name: 'arm64', triple: 'arm64-apple-macos11'}
]
name: "Building for platform macos-${{matrix.architecture.name}}"
runs-on: "macos-14"
environment: ${{inputs.environment}}
steps:
###
# Packages
###
# Install required packages
# Paths on x86_64 and ARM64 are different for homebrew
- name: Install required packages
run: |
brew update && brew install git flex bison ninja cmake llvm ninja
- name: Settings
working-directory: ${{github.workspace}}
run: |
echo "CMAKE_GENERATOR=Ninja Multi-Config" >> $GITHUB_ENV
echo "CC=clang" >> $GITHUB_ENV
echo "CXX=clang++" >> $GITHUB_ENV
echo "MACOSX_DEPLOYMENT_TARGET=10.15" >> $GITHUB_ENV
###
# SDL
###
# Setup SDL
- name: Set up SDL
id: sdl
uses: libsdl-org/setup-sdl@main
with:
version: 2-latest
build-type: Release
cmake-arguments: "-DCMAKE_OSX_ARCHITECTURES=${{ matrix.architecture.name }}
-DCMAKE_VERBOSE_MAKEFILE=on"
###
# OpenAL
###
# soft-oal setup
# Use GCC instead of Clang because of missing SSE intrinsics
# It also doesn't enable altivec support on PowerPC by default
- name: Checkout soft-oal
uses: actions/checkout@v4
with:
repository: 'kcat/openal-soft'
path: 'thirdparties/soft-oal'
ref: '1.24.0'
- name: Configure and install soft-oal
working-directory: ${{github.workspace}}/thirdparties/soft-oal
run: |
cmake -B ./build \
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/thirdparties/soft-oal/install' \
-DCMAKE_OSX_ARCHITECTURES=${{ matrix.architecture.name }} \
-DCMAKE_VERBOSE_MAKEFILE=on
cmake --build ./build --config Release --parallel
cmake --install ./build --config Release
###
# Project
###
- uses: actions/checkout@v4
with:
path: 'source'
- name: CMake Settings
run: |
echo "CMAKE_PARAM=--log-level=VERBOSE \
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/install' \
-DCMAKE_VERBOSE_MAKEFILE=on \
-DCMAKE_OSX_ARCHITECTURES=${{ matrix.architecture.name }} \
-DOPENAL_LIBRARY='${{github.workspace}}/thirdparties/soft-oal/install' \
-DOPENAL_INCLUDE_DIR='${{github.workspace}}/thirdparties/soft-oal/install/include/AL' \
-DGIT_REVISION_BUILD_NUMBER=${{ github.run_number }} \
-DPRODUCT_VERSION_STAGE='${{ env.RELEASE_STAGE }}'" >> $GITHUB_ENV
- name: Configure CMake
working-directory: ${{github.workspace}}
run: |
cmake -B ./build ${{ env.CMAKE_PARAM }} ./source
- name: Build
working-directory: ${{github.workspace}}
run: |
cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel
- name: Test
working-directory: ${{github.workspace}}
# Execute tests defined by the CMake configuration.
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
run: |
cd "${{github.workspace}}/build"
ctest -C ${{env.BUILD_TYPE}}
- name: Install
working-directory: ${{github.workspace}}
# Install to the directory defined in CMAKE_INSTALL_PREFIX
run: |
cmake --install ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
# Create hard-link and copy symbolic links
mkdir ${{github.workspace}}/package
cp -l ${{steps.sdl.outputs.prefix}}/lib/libSDL2-2.0.0.dylib '${{github.workspace}}/package/'
cp -l ${{github.workspace}}/thirdparties/soft-oal/install/lib/libopenal.1.dylib '${{github.workspace}}/package/'
if [ -d ${{github.workspace}}/install/bin ]; then cp -r ${{github.workspace}}/install/bin/openmohaa/. '${{github.workspace}}/package'; fi
if [ -d ${{github.workspace}}/install/lib ]; then cp -r ${{github.workspace}}/install/lib/openmohaa/. '${{github.workspace}}/package'; fi
###
# Artifacts
###
- uses: actions/upload-artifact@v4
with:
name: out-macos-${{matrix.architecture.name}}
if-no-files-found: error
path:
${{github.workspace}}/package
@@ -6,7 +6,7 @@ on:
- "v*.*.*"
env:
RELEASE_TYPE: ${{ vars.RELEASE_TYPE || 'test' }}
RELEASE_STAGE: ${{ vars.RELEASE_STAGE || 'unstable' }}
RELEASE_IS_PRERELEASE: ${{ vars.RELEASE_IS_PRELEASE }}
permissions:
@@ -14,7 +14,9 @@ permissions:
jobs:
build-all:
uses: ./.github/workflows/build-cmake.yml
uses: ./.github/workflows/shared-build.yml
with:
environment: "release"
deploy_all:
strategy:
@@ -25,25 +27,30 @@ jobs:
target_os: [
'linux-amd64',
'linux-i686',
'linux-aarch64',
'linux-arm64',
'linux-armhf',
'linux-powerpc',
'linux-ppc64',
'linux-ppc64el',
'windows-x64',
'windows-x86',
'windows-x64-pdb',
'windows-x86',
'windows-x86-pdb',
'windows-arm64',
'windows-arm64-pdb'
'windows-arm64-pdb',
'macos-x86_64',
'macos-arm64'
]
runs-on: ubuntu-22.04
environment: release
runs-on: ubuntu-24.04
environment: "release"
needs: [build-all]
env:
RELEASE_NAME: ${{ github.event.repository.name }}-${{github.ref_name}}-${{matrix.target_os}}
steps:
- uses: actions/download-artifact@v3
- uses: actions/download-artifact@v4
with:
name: 'out-${{matrix.target_os}}'
path: ${{github.workspace}}/${{matrix.target_os}}
@@ -53,8 +60,8 @@ jobs:
run: zip -r ../${{ env.RELEASE_NAME }}.zip ./
- name: Release
uses: softprops/action-gh-release@v1
uses: softprops/action-gh-release@v2
with:
name: '${{github.ref_name}}-${{env.RELEASE_TYPE}}'
name: '${{github.ref_name}}-${{env.RELEASE_STAGE}}'
prerelease: ${{env.RELEASE_IS_PRERELEASE}}
files: ${{github.workspace}}/${{ env.RELEASE_NAME }}.zip
+4 -1
View File
@@ -5,6 +5,8 @@ Makefile.local
*.swp
*tags
*~
/.vscode/
/baseq3
# OS X
####################
@@ -44,5 +46,6 @@ profile
*.suo
.vs
out
code_unfinished/*
thirdparties/
code/parser/generated/*
+150 -25
View File
@@ -5,6 +5,14 @@ include(TargetArch.cmake)
target_architecture(TARGET_ARCH)
set(USE_INTERNAL_LIBS ON)
if(USE_SYSTEM_LIBS)
set(USE_INTERNAL_LIBS OFF)
endif()
option(USE_INTERNAL_JPEG "If set, use bundled libjpeg." ${USE_INTERNAL_LIBS})
option(USE_INTERNAL_MAD "If set, use bundled libmad." ${USE_INTERNAL_LIBS})
option(USE_INTERNAL_ZLIB "If set, use bundled zlib." ${USE_INTERNAL_LIBS})
if(TARGET_GAME_TYPE)
message(SEND_ERROR "TARGET_GAME_TYPE is now unsupported, it is now done at runtime.")
@@ -14,14 +22,35 @@ endif()
set(TARGET_BASE_GAME "./")
set(CMAKE_DEBUG_POSTFIX "-dbg")
#
# Microsoft compiler specific parameters
#
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()
#
# Clang and GCC specific parameters
#
if(CMAKE_C_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_C_COMPILER_ID STREQUAL "GNU" 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()
#
# Clang specific parameters
#
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
# Ignore warnings for code like 'assert("Assert string")'
add_compile_options(-Wno-pointer-bool-conversion)
endif()
#
# GCC specific parameters
#
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
# Add this option on gcc to prevent functions from having the STB_GNU_UNIQUE binding
# Otherwise, it would prevent libraries from being unloaded
@@ -39,6 +68,8 @@ ELSE()
set(TARGET_ARCH_SUFFIX ${TARGET_ARCH})
ENDIF()
set(TARGET_BIN_SUFFIX ".${TARGET_ARCH}")
message(STATUS "Architecture detected: ${TARGET_ARCH}, suffix set to ${TARGET_ARCH_SUFFIX}.")
IF(WIN32)
@@ -52,7 +83,7 @@ ELSE()
ENDIF()
IF(CMAKE_BUILD_TYPE MATCHES Debug)
add_definitions(-D_DEBUG)
add_compile_definitions(_DEBUG)
# NOTE: The following may mess up function importation
#if(UNIX)
@@ -60,18 +91,60 @@ IF(CMAKE_BUILD_TYPE MATCHES Debug)
# set(CMAKE_ENABLE_EXPORTS ON)
# message(STATUS "Enabling exports on Unix for backtrace")
#endif()
ELSE()
# Non-debug builds
add_compile_definitions(NDEBUG)
ENDIF()
# Common stuff
if(APPLE)
# macOS doesn't search the executable path by default
# so, locate libraries like SDL in the executable path
set(CMAKE_INSTALL_RPATH "@executable_path")
set(CMAKE_BUILD_WITH_INSTALL_RPATH ON)
if(CMAKE_C_COMPILER_ID MATCHES "Clang" OR CMAKE_C_COMPILER_ID STREQUAL "GNU")
# Set the visibility to hidden on macOS to prevent shared libraries from
# using functions in the executable
# it's ok to hide them because the backtrace on macOS will still print the name of the functions
add_compile_options(-fvisibility=hidden)
endif()
endif()
#
# Setup the installation directory
#
if(WIN32)
# By default, both DLLs and EXEs are in the same directory
set(CMAKE_DEFAULT_INSTALL_RUNTIME_DIR bin)
set(BIN_INSTALL_SUBDIR ".")
set(LIB_INSTALL_SUBDIR ".")
else()
# Unix
set(CMAKE_DEFAULT_INSTALL_RUNTIME_DIR lib)
set(BIN_INSTALL_SUBDIR ${CMAKE_PROJECT_NAME})
set(LIB_INSTALL_SUBDIR ${CMAKE_PROJECT_NAME})
endif()
# By default, put both binaries and shared libraries in the same directory
# the game uses internal shared libraries that must be in the same folder as the binaries
set(CMAKE_INSTALL_BINDIR ${CMAKE_DEFAULT_INSTALL_RUNTIME_DIR} CACHE PATH "Binary dir")
set(CMAKE_INSTALL_LIBDIR ${CMAKE_INSTALL_BINDIR} CACHE PATH "Library dir")
include(GNUInstallDirs)
#
# Common stuff
#
add_subdirectory("code/qcommon")
add_subdirectory("code/gamespy")
#
# Application
#
add_subdirectory("code/sys")
##
## Server app
##
add_subdirectory("code/server")
add_executable(omohaaded "code/null/null_client.c" "code/null/null_input.c" "code/null/null_snddma.c")
@@ -82,24 +155,26 @@ target_link_libraries(omohaaded PRIVATE omohserver)
target_link_libraries(omohaaded PRIVATE syslib)
target_link_libraries(omohaaded PRIVATE qcommon qcommon_standalone)
# Gamespy dependency
# Add the gamespy dependency
target_include_directories(omohaaded PUBLIC "code/qcommon" "code/script" "code/gamespy" "code/server")
set_target_properties(omohaaded PROPERTIES OUTPUT_NAME "omohaaded${TARGET_BASE_SUFFIX}${TARGET_ARCH_SUFFIX}")
set_target_properties(omohaaded PROPERTIES OUTPUT_NAME "omohaaded${TARGET_BIN_SUFFIX}")
set_target_properties(omohaaded PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
INSTALL(TARGETS omohaaded DESTINATION ${CMAKE_INSTALL_BINDIR}/${BIN_INSTALL_SUBDIR})
if (MSVC)
target_link_options(omohaaded PRIVATE "/MANIFEST:NO")
INSTALL(FILES $<TARGET_PDB_FILE:omohaaded> DESTINATION "./" OPTIONAL)
INSTALL(FILES $<TARGET_PDB_FILE:omohaaded> DESTINATION ${CMAKE_INSTALL_BINDIR}/${BIN_INSTALL_SUBDIR} OPTIONAL)
endif()
INSTALL(TARGETS omohaaded DESTINATION "./")
if (NOT BUILD_NO_CLIENT)
##
## Client app
##
add_subdirectory("code/client")
add_subdirectory("code/renderer")
add_subdirectory("code/sdl")
add_subdirectory("code/client")
#include("code/renderergl2/glsl/shaders.cmake")
#file(GLOB_RECURSE SOURCES_RENDERER "code/sdl/*.c" "code/renderercommon/*.c" "code/renderergl2/*.c" "code/renderergl2/*.cpp")
@@ -112,27 +187,77 @@ if (NOT BUILD_NO_CLIENT)
target_link_libraries(openmohaa PRIVATE omohclient)
target_link_libraries(openmohaa PRIVATE omohrenderer omohsdl)
target_link_libraries(openmohaa PRIVATE qcommon qcommon_standalone)
### Gamespy dependency
target_include_directories(openmohaa PUBLIC "code/qcommon" "code/script" "code/gamespy" "code/server" "code/client" "code/uilib" "code/jpeg-8c")
set_target_properties(openmohaa PROPERTIES OUTPUT_NAME "openmohaa${TARGET_BASE_SUFFIX}${TARGET_ARCH_SUFFIX}")
# Add the gamespy dependency
target_include_directories(openmohaa PUBLIC "code/qcommon" "code/script" "code/gamespy" "code/server" "code/client" "code/uilib")
set_target_properties(openmohaa PROPERTIES OUTPUT_NAME "openmohaa${TARGET_BIN_SUFFIX}")
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()
if(USE_INTERNAL_JPEG)
target_include_directories(openmohaa PUBLIC "code/jpeg-8c")
target_link_libraries(openmohaa PRIVATE jpeg8)
else()
find_package(JPEG REQUIRED)
target_include_directories(openmohaa PUBLIC ${JPEG_INCLUDE_DIRS})
target_link_libraries(openmohaa PRIVATE ${JPEG_LIBRARIES})
endif()
INSTALL(TARGETS openmohaa DESTINATION ${CMAKE_INSTALL_BINDIR}/${BIN_INSTALL_SUBDIR})
if (MSVC)
target_link_options(openmohaa PRIVATE "/MANIFEST:NO")
INSTALL(FILES $<TARGET_PDB_FILE:openmohaa> DESTINATION "./" OPTIONAL)
INSTALL(FILES $<TARGET_PDB_FILE:openmohaa> DESTINATION ${CMAKE_INSTALL_BINDIR}/${BIN_INSTALL_SUBDIR} OPTIONAL)
endif()
INSTALL(TARGETS openmohaa DESTINATION "./")
if(UNIX AND NOT APPLE)
#
# Desktop entries installation on Unix
#
set(TARGET_ARCH ${TARGET_BIN_SUFFIX})
# Configure the .desktop entries with the arch suffix
configure_file(
misc/linux/org.openmoh.openmohaa.desktop.in
${CMAKE_BINARY_DIR}/misc/linux/org.openmoh.openmohaa.desktop
@ONLY
)
configure_file(
misc/linux/org.openmoh.openmohaab.desktop.in
${CMAKE_BINARY_DIR}/misc/linux/org.openmoh.openmohaab.desktop
@ONLY
)
configure_file(
misc/linux/org.openmoh.openmohaas.desktop.in
${CMAKE_BINARY_DIR}/misc/linux/org.openmoh.openmohaas.desktop
@ONLY
)
# Install .desktop entries
install(FILES ${CMAKE_BINARY_DIR}/misc/linux/org.openmoh.openmohaa.desktop DESTINATION ${CMAKE_INSTALL_DATADIR}/applications)
install(FILES ${CMAKE_BINARY_DIR}/misc/linux/org.openmoh.openmohaab.desktop DESTINATION ${CMAKE_INSTALL_DATADIR}/applications)
install(FILES ${CMAKE_BINARY_DIR}/misc/linux/org.openmoh.openmohaas.desktop DESTINATION ${CMAKE_INSTALL_DATADIR}/applications)
install(FILES misc/linux/org.openmoh.openmohaa.metainfo.xml DESTINATION ${CMAKE_INSTALL_DATADIR}/metainfo)
install(FILES misc/openmohaa.svg DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/symbolic/apps/ RENAME org.openmoh.openmohaa.svg)
endif()
endif()
#
# Launcher
#
add_subdirectory(code/Launcher)
#
# uninstall target
#
if(NOT TARGET uninstall)
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
IMMEDIATE @ONLY)
add_custom_target(uninstall
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
endif()
+18 -161
View File
@@ -1,153 +1,45 @@
# OpenMoHAA
![Build](https://github.com/openmoh/openmohaa/actions/workflows/build-cmake.yml/badge.svg?branch=main) [![Release](https://img.shields.io/github/v/release/openmoh/openmohaa)](https://github.com/openmoh/openmohaa/releases) [![Downloads](https://img.shields.io/github/downloads/openmoh/openmohaa/total)](https://github.com/openmoh/openmohaa/releases)
[![Build](https://github.com/openmoh/openmohaa/actions/workflows/branches-build.yml/badge.svg?branch=main)](https://github.com/openmoh/openmohaa/actions/workflows/branches-build.yml) [![Release](https://img.shields.io/github/v/release/openmoh/openmohaa)](https://github.com/openmoh/openmohaa/releases) [![Downloads](https://img.shields.io/github/downloads/openmoh/openmohaa/total)](https://github.com/openmoh/openmohaa/releases)
![License](https://img.shields.io/github/license/openmoh/openmohaa) ![Commits](https://img.shields.io/github/commit-activity/t/openmoh/openmohaa)
![Discord](https://img.shields.io/discord/596049712579215361?logo=discord&logoColor=white&color=5865F2)
```
/ _ \ _ __ ___ _ __ | \/ |/ _ \| | | | / \ / \
| | | | '_ \ / _ \ '_ \| |\/| | | | | |_| | / _ \ / _ \
| |_| | |_) | __/ | | | | | | |_| | _ |/ ___ \ / ___ \
\___/| .__/ \___|_| |_|_| |_|\___/|_| |_/_/ \_\/_/ \_\
|_|
```
## 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.
![logo](misc/openmohaa-text-sm.png)
## 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).
The main goal of OpenMoHAA is to ensure the future and continuity of **Medal of Honor: Allied Assault** on all platforms/architectures by providing new patches/features. Thanks to the ioquake3 project and the F.A.K.K SDK, OpenMoHAA has already reached more than half of its goal: 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.
- [Downloading and installing OpenMoHAA](docs/getting_started_installation.md)
- [Running OpenMoHAA and using expansion assets](docs/getting_started_running.md)
- [Dedicated server configuration](docs/configuration/server.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
### Single-player
### Client
The entire single-player campaign should work (Allied Assault, Spearhead and Breakthrough). If you encounter any bug, please create a new [GitHub issue](https://github.com/openmoh/openmohaa/issues) describing them.
a) extract archive to your MOHAA installation directory.
### Multiplayer
-or-
The Multiplayer part is almost fully stable.
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.
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.
### Server
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.
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) |
- [List of 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 +51,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
+23 -9
View File
@@ -3,8 +3,12 @@ set(archdetect_c_code "
# error cmake_ARCH x86
#elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64)
# error cmake_ARCH x86_64
#elif defined(__ppc64__) || defined(__powerpc64__)
# error cmake_ARCH ppc64
#elif defined(__PPC64__) || defined(__ppc64__) || defined(__powerpc64__) || defined(_ARCH_PPC64)
# if __BIG_ENDIAN__
# error cmake_ARCH ppc64
# else
# error cmake_ARCH ppc64el
# endif
#elif defined(__ppc__) || defined(__ppc) || defined(__powerpc__)
# error cmake_ARCH ppc
#elif defined __s390__
@@ -19,10 +23,14 @@ set(archdetect_c_code "
# error cmake_ARCH alpha
#elif defined __sparc__
# error cmake_ARCH sparc
#elif defined __arm__ || defined (_M_ARM)
# error cmake_ARCH arm
#elif defined(__aarch64__) || defined(__ARM64__) || defined(_M_ARM64)
# error cmake_ARCH aarch64
# error cmake_ARCH arm64
#elif defined __arm__ || defined (_M_ARM)
# if defined(__ARM_PCS_VFP) && (__ARM_PCS_VFP)
# error cmake_ARCH armhf
# else
# error cmake_ARCH armel
# endif
#elif defined __cris__
# error cmake_ARCH cris
#elif defined __hppa__
@@ -63,12 +71,14 @@ function(target_architecture output_var)
foreach(osx_arch ${CMAKE_OSX_ARCHITECTURES})
if("${osx_arch}" STREQUAL "ppc" AND ppc_support)
set(osx_arch_ppc TRUE)
elseif("${osx_arch}" STREQUAL "ppc64" AND ppc_support)
set(osx_arch_ppc64 TRUE)
elseif("${osx_arch}" STREQUAL "i386")
set(osx_arch_i386 TRUE)
elseif("${osx_arch}" STREQUAL "x86_64")
set(osx_arch_x86_64 TRUE)
elseif("${osx_arch}" STREQUAL "ppc64" AND ppc_support)
set(osx_arch_ppc64 TRUE)
elseif("${osx_arch}" STREQUAL "arm64")
set(osx_arch_arm64 TRUE)
else()
message(FATAL_ERROR "Invalid OS X arch name: ${osx_arch}")
endif()
@@ -79,6 +89,10 @@ function(target_architecture output_var)
list(APPEND ARCH ppc)
endif()
if(osx_arch_ppc64)
list(APPEND ARCH ppc64)
endif()
if(osx_arch_i386)
list(APPEND ARCH i386)
endif()
@@ -87,8 +101,8 @@ function(target_architecture output_var)
list(APPEND ARCH x86_64)
endif()
if(osx_arch_ppc64)
list(APPEND ARCH ppc64)
if(osx_arch_arm64)
list(APPEND ARCH arm64)
endif()
else()
# figure out extension for the source file
+21
View File
@@ -0,0 +1,21 @@
if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt")
message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt")
endif()
file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files)
string(REGEX REPLACE "\n" ";" files "${files}")
foreach(file ${files})
message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
execute_process(
COMMAND "@CMAKE_COMMAND@" -E remove "$ENV{DESTDIR}${file}"
OUTPUT_VARIABLE rm_out
RESULT_VARIABLE rm_retval
)
if(NOT "${rm_retval}" STREQUAL 0)
message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
endif()
else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
endif()
endforeach()
+36
View File
@@ -0,0 +1,36 @@
project(Launcher)
set(LAUNCHER_SOURCES "${CMAKE_SOURCE_DIR}/code/Launcher/launch_main.cpp")
if (WIN32)
set(LAUNCHER_SOURCES ${LAUNCHER_SOURCES}
"${CMAKE_SOURCE_DIR}/code/Launcher/launch_win32.cpp"
"${CMAKE_SOURCE_DIR}/code/sys/win_resource.rc")
else()
set(LAUNCHER_SOURCES ${LAUNCHER_SOURCES}
"${CMAKE_SOURCE_DIR}/code/Launcher/launch_linux.cpp")
endif()
function (create_launcher name type)
if (NOT BUILD_NO_CLIENT)
add_executable(openmohaa_launcher_${name} ${LAUNCHER_SOURCES})
target_include_directories(openmohaa_launcher_${name} PUBLIC "../qcommon")
target_compile_definitions(openmohaa_launcher_${name} PRIVATE NO_RC_MANIFEST=1 TARGET_GAME=${type})
target_compile_features(openmohaa_launcher_${name} PRIVATE cxx_std_17)
set_target_properties(openmohaa_launcher_${name} PROPERTIES OUTPUT_NAME "launch_openmohaa_${name}${TARGET_BIN_SUFFIX}")
INSTALL(TARGETS openmohaa_launcher_${name} DESTINATION ${CMAKE_INSTALL_BINDIR}/${BIN_INSTALL_SUBDIR})
endif()
#add_executable(omohaaded_launcher_${name} ${LAUNCHER_SOURCES})
#target_include_directories(omohaaded_launcher_${name} PUBLIC "../qcommon")
#target_compile_definitions(omohaaded_launcher_${name} PRIVATE NO_RC_MANIFEST=1 TARGET_GAME=${type} DEDICATED=1)
#target_compile_features(omohaaded_launcher_${name} PRIVATE cxx_std_17)
#set_target_properties(omohaaded_launcher_${name} PROPERTIES OUTPUT_NAME "launch_omohaaded_${name}${TARGET_BIN_SUFFIX}")
#
#INSTALL(TARGETS omohaaded_launcher_${name} DESTINATION ${CMAKE_INSTALL_BINDIR}/${PROJECT_INSTALL_SUBDIR})
endfunction()
create_launcher(base 0)
create_launcher(spearhead 1)
create_launcher(breakthrough 2)
+32
View File
@@ -0,0 +1,32 @@
/*
===========================================================================
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
===========================================================================
*/
// launch.h: Base interface for starting programs
#include "q_platform.h"
#include <filesystem>
#include <string>
#include <vector>
std::filesystem::path GetProgramLocation();
void LaunchProgram(const std::filesystem::path& path, const std::vector<std::string>& argumentList);
+80
View File
@@ -0,0 +1,80 @@
/*
===========================================================================
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
===========================================================================
*/
// main.cpp: Windows implementation of the launcher
#include "launch.h"
#include <unistd.h>
#include <spawn.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <string>
#include <iostream>
extern "C" char** environ;
std::filesystem::path GetProgramLocation()
{
char path[FILENAME_MAX];
ssize_t count = readlink("/proc/self/exe", path, FILENAME_MAX);
return std::filesystem::path(std::string(path, (count > 0) ? count : 0)).parent_path();
}
void LaunchProgram(const std::filesystem::path& path, const std::vector<std::string>& argumentList)
{
pid_t pid;
std::string pathString = path.string();
size_t argCount = argumentList.size();
char** argv;
int status;
argv = new char*[argCount + 2];
argv[0] = (char*)pathString.c_str();
for (size_t i = 0; i < argCount; i++) {
argv[i + 1] = (char*)argumentList[i].c_str();
}
argv[argCount + 1] = NULL;
//status = posix_spawn(&pid, pathString.c_str(), NULL, NULL, argv, environ);
//delete[] argv;
//if (status != 0) {
// std::cout << "posix_spawn returned error: " << status << std::endl;
// return;
//}
//
// Using execve rather than posix_spawn
// This replaces the current process that is not needed anyway
//
status = execve(pathString.c_str(), argv, environ);
delete[] argv;
if (status == -1) {
std::cout << "posix_spawn returned error: " << errno << std::endl;
return;
}
waitpid(pid, NULL, 0);
}
+67
View File
@@ -0,0 +1,67 @@
/*
===========================================================================
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
===========================================================================
*/
// main.cpp: The launcher
#include "launch.h"
#include <iostream>
#include <string>
#include <vector>
const char* targetGameList[] =
{
"Base",
"Spearhead",
"Breakthrough"
};
int main(int argc, const char* argv[]) {
std::vector<std::string> argumentList;
#if !defined(DEDICATED) || !DEDICATED
const char* programName = "openmohaa" "." ARCH_STRING DLL_SUFFIX EXE_EXT;
#else
const char* programName = "omohaaded" "." ARCH_STRING DLL_SUFFIX EXE_EXT;
#endif
argumentList.push_back("+set");
argumentList.push_back("com_target_game");
argumentList.push_back(std::to_string(TARGET_GAME));
for (size_t i = 1; i < argc; i++) {
argumentList.push_back(argv[i]);
}
std::cout << "Using the target game: " << targetGameList[TARGET_GAME] << std::endl;
std::cout << std::endl;
std::cout << "Expected program name: " << programName << std::endl;
const std::filesystem::path programLocation = GetProgramLocation();
const std::filesystem::path programPath = programLocation / programName;
std::cout << "Program location: " << programLocation << std::endl;
std::cout << "Expected path: " << programPath << std::endl;
LaunchProgram(programPath, argumentList);
return 0;
}
+87
View File
@@ -0,0 +1,87 @@
/*
===========================================================================
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
===========================================================================
*/
// main.cpp: Windows implementation of the launcher
#include "launch.h"
#include <Windows.h>
#include <string>
#include <iostream>
std::filesystem::path GetProgramLocation()
{
wchar_t path[FILENAME_MAX] = { 0 };
GetModuleFileNameW(nullptr, path, FILENAME_MAX);
return std::filesystem::path(path).parent_path();
}
void LaunchProgram(const std::filesystem::path& path, const std::vector<std::string>& argumentList)
{
PROCESS_INFORMATION processInfo;
STARTUPINFOW startupInfo;
BOOL returnValue;
std::wstring osCommandLine;
std::wstring commandLine;
size_t argCount = argumentList.size();
memset(&processInfo, 0, sizeof(processInfo));
memset(&startupInfo, 0, sizeof(startupInfo));
startupInfo.cb = sizeof(startupInfo);
for (size_t i = 0; i < argCount; i++) {
commandLine += L"\"";
commandLine += std::wstring(argumentList[i].begin(), argumentList[i].end());
commandLine += L"\"";
if (i != argCount - 1) {
commandLine += L" ";
}
}
osCommandLine = path.wstring();
osCommandLine += L" ";
osCommandLine += commandLine;
returnValue = CreateProcessW(
path.wstring().c_str(),
(LPWSTR)osCommandLine.c_str(),
NULL,
NULL,
FALSE,
0,
NULL,
std::filesystem::current_path().wstring().c_str(),
&startupInfo,
&processInfo
);
if (!returnValue) {
std::cout << "Error in CreateProcess: " << GetLastError() << std::endl;
return;
}
WaitForSingleObject(processInfo.hProcess, INFINITE);
CloseHandle(processInfo.hProcess);
CloseHandle(processInfo.hThread);
}
+4 -1
View File
@@ -933,10 +933,13 @@ static void waitToApplyUpdates(void)
OS forcibly closes the pipe), we will unblock. Then we can loop on
kill() until the process is truly gone. */
int x = 0;
struct timespec req;
req.tv_sec = 0;
req.tv_nsec = 100000000;
read(3, &x, sizeof (x));
info("Pipe has closed, waiting for process to fully go away now.");
while (kill(options.waitforprocess, 0) == 0) {
usleep(100000);
nanosleep(&req, NULL);
}
#endif
}
+4 -9
View File
@@ -27,16 +27,11 @@ target_compile_features(cgame PUBLIC cxx_nullptr)
target_compile_features(cgame PUBLIC c_variadic_macros)
target_link_libraries(cgame PUBLIC qcommon)
set_target_properties(cgame PROPERTIES PREFIX "${TARGET_PLATFORM_PREFIX}")
set_target_properties(cgame PROPERTIES OUTPUT_NAME "cgame${TARGET_ARCH_SUFFIX}")
set_target_properties(cgame PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TARGET_BASE_GAME}")
set_target_properties(cgame PROPERTIES PREFIX "")
set_target_properties(cgame PROPERTIES OUTPUT_NAME "cgame${TARGET_BIN_SUFFIX}")
INSTALL(
TARGETS cgame
LIBRARY DESTINATION "${TARGET_BASE_GAME}"
RUNTIME DESTINATION "${TARGET_BASE_GAME}"
)
INSTALL(TARGETS cgame DESTINATION ${CMAKE_INSTALL_LIBDIR}/${LIB_INSTALL_SUBDIR})
if(MSVC)
INSTALL(FILES $<TARGET_PDB_FILE:cgame> DESTINATION "${TARGET_BASE_GAME}" OPTIONAL)
INSTALL(FILES $<TARGET_PDB_FILE:cgame> DESTINATION ${CMAKE_INSTALL_LIBDIR}/${LIB_INSTALL_SUBDIR} OPTIONAL)
endif()
+4 -4
View File
@@ -113,7 +113,7 @@ void CG_ArchiveModelHandle(MemArchiver& archiver, qhandle_t* handle)
if (tmp.length()) {
*handle = cgi.R_RegisterModel(tmp.c_str());
} else {
*handle = NULL;
*handle = (qhandle_t)0;
}
} else {
if (*handle) {
@@ -135,7 +135,7 @@ void CG_ArchiveShaderHandle(MemArchiver& archiver, qhandle_t* handle)
if (tmp.length()) {
*handle = cgi.R_RegisterShader(tmp.c_str());
} else {
*handle = NULL;
*handle = (qhandle_t)0;
}
} else {
if (*handle) {
@@ -163,7 +163,7 @@ void CG_ArchiveRefEntity(MemArchiver& archiver, refEntity_t* ref)
archiver.ArchiveVec3(ref->axis[2]);
archiver.ArchiveBoolean(&ref->nonNormalizedAxes);
archiver.ArchiveVec3(ref->origin);
archiver.ArchiveRaw(ref->frameInfo, 192);
archiver.ArchiveRaw(ref->frameInfo, sizeof(ref->frameInfo));
archiver.ArchiveFloat(&ref->actionWeight);
archiver.ArchiveShort(&ref->wasframe);
archiver.ArchiveFloat(&ref->scale);
@@ -171,7 +171,7 @@ void CG_ArchiveRefEntity(MemArchiver& archiver, refEntity_t* ref)
archiver.ArchiveInteger(&ref->skinNum);
CG_ArchiveShaderHandle(archiver, &ref->customShader);
archiver.ArchiveRaw(ref->shaderRGBA, 4);
archiver.ArchiveRaw(ref->shaderRGBA, sizeof(ref->shaderRGBA));
archiver.ArchiveFloat(ref->shaderTexCoord);
archiver.ArchiveFloat(&ref->shaderTexCoord[1]);
archiver.ArchiveFloat(&ref->shaderTime);
+206 -56
View File
@@ -196,7 +196,8 @@ Event EV_Client_SetColorVelocity
"rVel gVel bVel",
"Set the color velocity of the spawned dlight tempmodel"
);
Event EV_Client_SetRandomVelocity(
Event EV_Client_SetRandomVelocity
(
"randvel",
EV_DEFAULT,
"SfFSfFSfF",
@@ -210,7 +211,8 @@ Event EV_Client_SetRandomVelocity(
"without randomness.\n"
"This velocity is applied using the world axis"
);
Event EV_Client_SetRandomVelocityAlongAxis(
Event EV_Client_SetRandomVelocityAlongAxis
(
"randvelaxis",
EV_DEFAULT,
"SfFSfFSfF",
@@ -225,6 +227,14 @@ Event EV_Client_SetRandomVelocityAlongAxis(
"without randomness.\n"
"This velocity is applied using the parent axis"
);
Event EV_Client_NoTagAxis
(
"notagaxis",
EV_DEFAULT,
NULL,
NULL,
"Forces the effect to use the model's orientation for randvelaxis and offsetalongaxis"
);
Event EV_Client_SetAccel
(
"accel",
@@ -554,7 +564,16 @@ Event EV_Client_LoopSound
EV_DEFAULT,
"sFFf",
"soundName volume min_distance pitch",
"Play the specifed sound as a looping sound"
"Play the specified sound as a looping sound"
);
// Added in 2.0
Event EV_Client_StopLoopSound
(
"stoploopsound",
EV_DEFAULT,
NULL,
NULL,
"Stop the looping sound"
);
Event EV_Client_Cache
(
@@ -975,7 +994,7 @@ Event EV_Client_BounceDecal(
"maxamount temporary",
"Put a mark when the tempmodel bounces and hits a surface\n"
"maxamount = Max amount of decals to make when bouncing\n"
"temporary = specify 1 for a temporary mark that only appears for a short time, 0 for a decal that stays aroung "
"temporary = specify 1 for a temporary mark that only appears for a short time, 0 for a decal that stays around "
"longer (default is 0)\n"
);
Event EV_Client_SetDecalRadius
@@ -1075,6 +1094,15 @@ Event EV_Client_Print
"string",
"Prints a string."
);
// Added in 2.0
Event EV_Client_PrintDeathMsg
(
"printdeathmsg",
EV_DEFAULT,
"sssss",
"msg1, msg2, killer, victim, deathType",
"Prints a death message string. Used to allow death messages to appear in their correct language on client machines.."
);
Event EV_Client_SetVolumetric
(
"volumetric",
@@ -1112,7 +1140,7 @@ Event EV_Client_SetAlignStretch(
EV_DEFAULT,
"F",
"scaleMultiplier",
"Aligns the temp model to the direction of travel, and stretches it betwen the last and current positions.\n"
"Aligns the temp model to the direction of travel, and stretches it between the last and current positions.\n"
);
Event EV_Client_SetClampVelocity
(
@@ -1185,6 +1213,14 @@ Event EV_Client_SFXStartDelayed
"fDelay sCommand arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8",
"Used for adding commands to a special effect with a time delay"
);
Event EV_Client_PlayForceFeedback
(
"playforcefeedback",
EV_DEFAULT,
"s",
"effectname",
"Starts a force feedback effect."
);
EffectsEventQueueNode EffectsEventQueue;
@@ -1221,6 +1257,7 @@ CLASS_DECLARATION(Listener, ClientGameCommandManager, NULL) {
{&EV_Client_SetColorVelocity, &ClientGameCommandManager::SetAngularVelocity },
{&EV_Client_SetRandomVelocity, &ClientGameCommandManager::SetRandomVelocity },
{&EV_Client_SetRandomVelocityAlongAxis, &ClientGameCommandManager::SetRandomVelocityAlongAxis},
{&EV_Client_NoTagAxis, &ClientGameCommandManager::SetNoTagAxis },
{&EV_Client_SetAccel, &ClientGameCommandManager::SetAccel },
{&EV_Client_SetFriction, &ClientGameCommandManager::SetFriction },
{&EV_Client_SetSpin, &ClientGameCommandManager::SetSpin },
@@ -1250,6 +1287,7 @@ CLASS_DECLARATION(Listener, ClientGameCommandManager, NULL) {
{&EV_Client_StopSound, &ClientGameCommandManager::StopSound },
{&EV_Client_StopAliasChannel, &ClientGameCommandManager::StopAliasChannel },
{&EV_Client_LoopSound, &ClientGameCommandManager::LoopSound },
{&EV_Client_StopLoopSound, &ClientGameCommandManager::StopLoopSound },
{&EV_Client_Cache, &ClientGameCommandManager::Cache },
{&EV_Client_CacheImage, &ClientGameCommandManager::CacheImage },
{&EV_Client_CacheFont, &ClientGameCommandManager::CacheFont },
@@ -1312,6 +1350,7 @@ CLASS_DECLARATION(Listener, ClientGameCommandManager, NULL) {
{&EV_Client_SetClampVelocity, &ClientGameCommandManager::SetClampVel },
{&EV_Client_SetClampVelocityAxis, &ClientGameCommandManager::SetClampVelAxis },
{&EV_Client_Print, &ClientGameCommandManager::Print },
{&EV_Client_PrintDeathMsg, &ClientGameCommandManager::PrintDeathMsg },
{&EV_Client_EyeLimits, &ClientGameCommandManager::SetEyeLimits },
{&EV_Client_EyeMovement, &ClientGameCommandManager::SetEyeMovement },
{&EV_Client_SFXStart, &ClientGameCommandManager::StartSFX },
@@ -1383,9 +1422,11 @@ qboolean ClientGameCommandManager::PostEventForEntity(Event *ev, float fWait)
EffectsEventQueueNode *node;
int inttime;
if (!m_fEventWait || current_entity_number < 0) {
if (!str::icmp(ev->getName(), ")")) {
m_fEventWait = 0.0;
if (m_fEventWait < 0 || current_entity_number < 0) {
if (m_fEventWait != 0.0) {
if (!str::icmp(ev->getName(), ")")) {
m_fEventWait = 0.0;
}
}
delete ev;
@@ -1402,7 +1443,7 @@ qboolean ClientGameCommandManager::PostEventForEntity(Event *ev, float fWait)
event = EffectsEventQueue.next;
inttime = EVENT_msec + (fWait * 1000.0f + 0.5f);
while (event != &EffectsEventQueue && inttime > event->inttime) {
while (event != &EffectsEventQueue && inttime >= event->inttime) {
event = event->next;
}
@@ -1438,8 +1479,8 @@ void ClientGameCommandManager::SetBaseAndAmplitude(Event *ev, Vector& base, Vect
base[j] = ev->GetFloat(i++);
amplitude[j] = ev->GetFloat(i++);
} else {
base[j] = 0.0;
amplitude[j] = atof(org.c_str());
base[j] = atof(org.c_str());
amplitude[j] = 0.0;
}
}
}
@@ -1462,6 +1503,13 @@ void ClientGameCommandManager::Print(Event *ev)
}
}
void ClientGameCommandManager::PrintDeathMsg(Event* ev)
{
if (current_entity) {
cgi.DPrintf("%d:%s\n", current_entity->entityNumber, ev->GetString(1).c_str());
}
}
qboolean ClientGameCommandManager::IsBlockCommand(const str& name)
{
if (!str::icmp(name, "originspawn")) {
@@ -1541,7 +1589,6 @@ void ClientGameCommandManager::CommandDelay(Event *ev)
ev1->AddValue(ev->GetValue(i));
}
delay = ev->GetFloat(1) * 1000;
if (current_entity_number != -1) {
PostEventForEntity(ev1, fWait);
} else {
@@ -1551,6 +1598,16 @@ void ClientGameCommandManager::CommandDelay(Event *ev)
current_tiki->name
);
}
if (IsBlockCommand(eventName)) {
m_fEventWait = fWait;
} else {
m_fEventWait = 0;
}
if (current_entity_number == -1 && m_fEventWait > 0) {
m_fEventWait = -1;
}
}
void ClientGameCommandManager::StartSFX(Event *ev)
@@ -2157,7 +2214,9 @@ void ClientGameCommandManager::SetInwardSphere(Event *ev)
}
m_spawnthing->cgd.flags |= T_INWARDSPHERE;
m_spawnthing->sphereRadius = ev->GetFloat(1);
if (ev->NumArgs() > 0) {
m_spawnthing->sphereRadius = ev->GetFloat(1);
}
}
//=============
@@ -2586,7 +2645,9 @@ void ClientGameCommandManager::SetColorRange(Event *ev)
return;
}
// FIXME: unused stub??
//
// Unused
//
}
//=============
@@ -2666,6 +2727,15 @@ void ClientGameCommandManager::SetRandomVelocityAlongAxis(Event *ev)
SetRandomVelocity(ev);
}
void ClientGameCommandManager::SetNoTagAxis(Event* ev)
{
if (!m_spawnthing) {
return;
}
m_spawnthing->cgd.flags2 |= T2_NOTAGAXIS;
}
void ClientGameCommandManager::SetRadialVelocity(Event *ev)
{
if (!m_spawnthing) {
@@ -2803,7 +2873,9 @@ void ClientGameCommandManager::SetAccel(Event *ev)
m_spawnthing->cgd.accel[1] = ev->GetFloat(2);
m_spawnthing->cgd.accel[2] = ev->GetFloat(3);
m_spawnthing->cgd.flags2 |= T2_ACCEL;
if (!(m_spawnthing->cgd.flags & T_SWARM)) {
m_spawnthing->cgd.flags2 |= T2_ACCEL;
}
}
void ClientGameCommandManager::SetFriction(Event *ev)
@@ -3032,7 +3104,7 @@ spawnthing_t *ClientGameCommandManager::InitializeSpawnthing(spawnthing_t *sp)
sp->cgd.parent = -1;
sp->cgd.tiki = nullptr;
sp->cgd.lightstyle = -1;
sp->cgd.physicsRate = 10;
sp->cgd.physicsRate = cg_effect_physicsrate->integer;
sp->cgd.shadername = "beamshader";
sp->cgd.decal_orientation = 0;
sp->cgd.decal_radius = 10;
@@ -3851,7 +3923,7 @@ void ClientGameCommandManager::PlaySound(
} else {
if (debugSound->integer) {
Com_Printf(
"\nWARNING: OVERRIDE OVERRIDE OVERRIDESound %s had all its parm overriden by code.\n\n",
"\nWARNING: OVERRIDE OVERRIDE OVERRIDESound %s had all its parm overridden by code.\n\n",
sound_name.c_str()
);
}
@@ -3965,6 +4037,9 @@ void ClientGameCommandManager::StopSound(Event *ev)
cgi.S_StopSound(current_entity_number, channel);
}
//===============
// StopAliasChannel
//===============
void ClientGameCommandManager::StopAliasChannel(Event *ev)
{
str sound_name;
@@ -4060,6 +4135,54 @@ void ClientGameCommandManager::LoopSound(Event *ev)
current_centity->tikiLoopSoundFlags = 0;
}
//===============
// StopLoopSound
//===============
void ClientGameCommandManager::StopLoopSound(Event* ev)
{
if (!current_centity) {
cgi.DPrintf("CCM::StopLoopSound : StopLoopSound in %s without current_centity\n", cgi.TIKI_Name(current_tiki));
return;
}
Com_Printf("\n\nClientGameCommandManager::StopLoopSound\n\n");
current_centity->tikiLoopSound = NULL;
}
//===============
// CacheImageResource
//===============
void CacheImageResource(const char* stuff) {
str real_stuff;
char filename[1024];
if (cgi.fsDebug->integer == 2) {
Com_Printf("client cacheimage: %s\n", stuff);
}
Q_strncpyz(filename, stuff, sizeof(filename));
cgi.FS_CanonicalFilename(filename);
cgi.R_RegisterShaderNoMip(filename);
}
//===============
// CacheFontResource
//===============
void CacheFontResource(const char* stuff) {
str real_stuff;
char filename[1024];
if (cgi.fsDebug->integer == 2) {
Com_Printf("client cacheimage: %s\n", stuff);
}
Q_strncpyz(filename, stuff, sizeof(filename));
cgi.FS_CanonicalFilename(filename);
cgi.R_LoadFont(filename);
}
//===============
// CacheResource
//===============
@@ -4099,12 +4222,12 @@ void ClientGameCommandManager::Cache(Event *ev)
void ClientGameCommandManager::CacheImage(Event *ev)
{
// FIXME: stub
CacheImageResource(ev->GetString(1).c_str());
}
void ClientGameCommandManager::CacheFont(Event *ev)
{
// FIXME: stub
CacheFontResource(ev->GetString(1).c_str());
}
//===============
@@ -4112,15 +4235,16 @@ void ClientGameCommandManager::CacheFont(Event *ev)
//===============
void AliasResource(dtiki_t *pmdl, const char *alias, const char *realname, const char *parameters)
{
if (pmdl) {
if (!pmdl->a->alias_list) {
pmdl->a->alias_list = cgi.AliasList_New(pmdl->a->name);
}
cgi.Alias_ListAdd((AliasList_t *)pmdl->a->alias_list, alias, realname, parameters);
} else {
if (!pmdl) {
cgi.Alias_Add(alias, realname, parameters);
return;
}
if (!pmdl->a->alias_list) {
pmdl->a->alias_list = cgi.AliasList_New(pmdl->a->name);
}
cgi.Alias_ListAdd((AliasList_t*)pmdl->a->alias_list, alias, realname, parameters);
}
qboolean bLoadForMap(const char *psMapsBuffer, const char *name)
@@ -4181,19 +4305,32 @@ void ClientGameCommandManager::AliasCache(Event *ev)
psMapsBuffer = NULL;
for (i = 3; i <= ev->NumArgs(); i++) {
if (!strcmp(ev->GetToken(i).c_str(), "maps")) {
str s = ev->GetString(i);
if (!s.icmp("maps")) {
i++;
psMapsBuffer = ev->GetToken(i);
} else if (!strcmp(ev->GetToken(i).c_str(), "always")) {
bAlwaysLoaded = true;
} else {
strcat(parmbuffer, ev->GetToken(i));
strcat(parmbuffer, " ");
psMapsBuffer = (char *)ev->GetToken(i).c_str();
continue;
}
if (!s.icmp("always")) {
bAlwaysLoaded = true;
continue;
}
strcat(parmbuffer, s);
strcat(parmbuffer, " ");
}
if (bAlwaysLoaded || bLoadForMap(psMapsBuffer, ev->GetString(1))) {
if (bAlwaysLoaded) {
AliasResource(current_tiki, ev->GetString(1), ev->GetString(2), parmbuffer);
}
if (bLoadForMap(psMapsBuffer, ev->GetString(1))) {
if (!bAlwaysLoaded) {
AliasResource(current_tiki, ev->GetString(1), ev->GetString(2), parmbuffer);
}
CacheResource(ev->GetString(2));
}
}
@@ -4223,28 +4360,33 @@ void ClientGameCommandManager::Alias(Event *ev)
psMapsBuffer = NULL;
for (i = 3; i <= ev->NumArgs(); i++) {
if (!strcmp(ev->GetToken(i).c_str(), "maps")) {
str s = ev->GetString(i);
if (!s.icmp("maps")) {
i++;
psMapsBuffer = ev->GetToken(i);
} else if (!strcmp(ev->GetToken(i).c_str(), "always")) {
psMapsBuffer = (char *)ev->GetToken(i).c_str();
continue;
}
if (!s.icmp("always")) {
bAlwaysLoaded = true;
} else if (subtitle) {
strcat(parmbuffer, "\"");
strcat(parmbuffer, s);
strcat(parmbuffer, "\" ");
subtitle = 0;
} else {
subtitle = s.icmp("subtitle") == 0;
if (!subtitle) {
if (!Q_stricmp(ev->GetToken(i), "subtitle") || !Q_stricmp(ev->GetToken(i), "forcesubtitle")) {
subtitle = qtrue;
strcat(parmbuffer, ev->GetToken(i));
} else {
strcat(parmbuffer, ev->GetToken(i));
}
} else {
strcat(parmbuffer, "\"");
strcat(parmbuffer, ev->GetToken(i));
strcat(parmbuffer, "\"");
subtitle = qfalse;
subtitle = s.icmp("forcesubtitle") == 0;
}
strcat(parmbuffer, " ");
strcat(parmbuffer, s);
}
strcat(parmbuffer, " ");
}
if (bAlwaysLoaded || bLoadForMap(psMapsBuffer, ev->GetString(1))) {
@@ -4976,7 +5118,15 @@ bool ClientGameCommandManager::GetTagPositionAndOrientation(str tagname, orienta
//===============
void ClientGameCommandManager::RestartAllEmitters(void)
{
// FIXME: stub??
ctempmodel_t *p;
//
// FIXME: not sure if it's the right thing
//
for (p = m_active_tempmodels.prev; p != &m_active_tempmodels; p = p->next) {
p->cgd.createTime = cg.time;
}
}
//===============
@@ -5187,7 +5337,7 @@ void CG_ClientCommandDebugMessage(centity_t *cent, const char *fmt, ...)
char msg[1024];
va_start(argptr, fmt);
vsprintf(msg, fmt, argptr);
Q_vsnprintf(msg, sizeof(msg), fmt, argptr);
va_end(argptr);
if ((!cg_debugAnimWatch->integer) || ((cg_debugAnimWatch->integer - 1) == cent->currentState.number)) {
@@ -5342,7 +5492,7 @@ qboolean CG_Command_ProcessFile(const char *filename, qboolean quiet, dtiki_t *c
current_tiki = NULL;
// Update the loading screen
sprintf(tempName, "m%s", filename);
Com_sprintf(tempName, sizeof(tempName), "m%s", filename);
cgi.LoadResource(tempName);
bufstart = buffer;
@@ -5351,7 +5501,7 @@ qboolean CG_Command_ProcessFile(const char *filename, qboolean quiet, dtiki_t *c
Event *ev;
// grab each line as we go
strcpy(com_token, COM_ParseExt(&buffer, qtrue));
Q_strncpyz(com_token, COM_ParseExt(&buffer, qtrue), sizeof(com_token));
if (!com_token[0]) {
break;
}
@@ -5359,7 +5509,7 @@ qboolean CG_Command_ProcessFile(const char *filename, qboolean quiet, dtiki_t *c
if (!Q_stricmp(com_token, "end") || !Q_stricmp(com_token, "server")) {
// skip the line
while (1) {
strcpy(com_token, COM_ParseExt(&buffer, qfalse));
Q_strncpyz(com_token, COM_ParseExt(&buffer, qfalse), sizeof(com_token));
if (!com_token[0]) {
break;
}
@@ -5372,7 +5522,7 @@ qboolean CG_Command_ProcessFile(const char *filename, qboolean quiet, dtiki_t *c
// get the rest of the line
while (1) {
strcpy(com_token, COM_ParseExt(&buffer, qfalse));
Q_strncpyz(com_token, COM_ParseExt(&buffer, qfalse), sizeof(com_token));
if (!com_token[0]) {
break;
}
@@ -5384,7 +5534,7 @@ qboolean CG_Command_ProcessFile(const char *filename, qboolean quiet, dtiki_t *c
cgi.FS_FreeFile((void *)bufstart);
// Update the loading screen
sprintf(tempName, "o%s", filename);
Com_sprintf(tempName, sizeof(tempName), "o%s", filename);
cgi.LoadResource(tempName);
return qtrue;
+4
View File
@@ -113,6 +113,7 @@ TIKI file, similar to ScriptMaster in the server game dll.
#define T2_VARYCOLOR (1 << 20)
#define T2_SPIN (1 << 21)
#define T2_RELATIVEANGLES (1 << 22)
#define T2_NOTAGAXIS (1 << 23)
class spawnthing_t;
class specialeffect_t;
@@ -763,6 +764,7 @@ private:
void SpawnVSSSource(int count, int timealive);
void EventViewKick(Event *ev);
void Print(Event *ev);
void PrintDeathMsg(Event *ev); // Added in 2.0
void StartBlock(Event *ev);
void EndBlock(Event *ev);
void UpdateSpawnThing(spawnthing_t *ep);
@@ -788,6 +790,7 @@ private:
void SetScaleRate(Event *ev);
void SetRandomVelocity(Event *ev);
void SetRandomVelocityAlongAxis(Event *ev);
void SetNoTagAxis(Event *ev); // Added in 2.0
void SetAccel(Event *ev);
void SetFriction(Event *ev);
void SetSpin(Event *ev);
@@ -849,6 +852,7 @@ private:
void StopSound(Event *ev);
void StopAliasChannel(Event *ev);
void LoopSound(Event *ev);
void StopLoopSound(Event *ev); // Added in 2.0
void Cache(Event *ev);
void CacheImage(Event *ev);
void CacheFont(Event *ev);
+207 -57
View File
@@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2023 the OpenMoHAA team
Copyright (C) 2008-2024 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@@ -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);
@@ -159,17 +160,157 @@ baseshader_t *CG_GetShaderUnderCrosshair(qboolean bVerbose, trace_t *pRetTrace)
static void CG_PrintContentTypes(int iContentFlags)
{
// FIXME: unimplemented
if (iContentFlags & CONTENTS_SOLID) {
cgi.Printf(" solid");
}
if (iContentFlags & CONTENTS_LAVA) {
cgi.Printf(" lava");
}
if (iContentFlags & CONTENTS_SLIME) {
cgi.Printf(" slime");
}
if (iContentFlags & CONTENTS_WATER) {
cgi.Printf(" water");
}
if (iContentFlags & CONTENTS_FOG) {
cgi.Printf(" fog");
}
if (iContentFlags & CONTENTS_FENCE) {
cgi.Printf(" fence");
}
if (iContentFlags & CONTENTS_AREAPORTAL) {
cgi.Printf(" areaportal");
}
if (iContentFlags & CONTENTS_PLAYERCLIP) {
cgi.Printf(" playerclip");
}
if (iContentFlags & CONTENTS_VEHICLECLIP) {
cgi.Printf(" vehicleclip");
}
if (iContentFlags & CONTENTS_MONSTERCLIP) {
cgi.Printf(" monsterclip");
}
if (iContentFlags & CONTENTS_WEAPONCLIP) {
cgi.Printf(" weaponclip");
}
if (iContentFlags & CONTENTS_SHOOTONLY) {
cgi.Printf(" shootableonly");
}
if (iContentFlags & CONTENTS_ORIGIN) {
cgi.Printf(" origin");
}
if (iContentFlags & CONTENTS_TRANSLUCENT) {
cgi.Printf(" trans");
}
}
static void CG_PrintSurfaceProperties(int iSurfaceFlags)
{
// FIXME: unimplemented
if (iSurfaceFlags & SURF_NODAMAGE) {
cgi.Printf(" nodamage");
}
if (iSurfaceFlags & SURF_SLICK) {
cgi.Printf(" slick");
}
if (iSurfaceFlags & SURF_SKY) {
cgi.Printf(" sky");
}
if (iSurfaceFlags & SURF_LADDER) {
cgi.Printf(" ladder");
}
if (iSurfaceFlags & SURF_NOIMPACT) {
cgi.Printf(" noimpact");
}
if (iSurfaceFlags & SURF_NOMARKS) {
cgi.Printf(" nomarks");
}
if (iSurfaceFlags & SURF_CASTSHADOW) {
cgi.Printf(" castshadow");
}
if (iSurfaceFlags & SURF_NODRAW) {
cgi.Printf(" nodraw");
}
if (iSurfaceFlags & SURF_NOLIGHTMAP) {
cgi.Printf(" nolightmap");
}
if (iSurfaceFlags & SURF_ALPHASHADOW) {
cgi.Printf(" alphashadow");
}
if (iSurfaceFlags & SURF_NOSTEPS) {
cgi.Printf(" nofootsteps");
}
if (iSurfaceFlags & SURF_NONSOLID) {
cgi.Printf(" nonsolid");
}
if (iSurfaceFlags & SURF_OVERBRIGHT) {
cgi.Printf(" overbright");
}
if (iSurfaceFlags & SURF_BACKSIDE) {
cgi.Printf(" backside");
}
if (iSurfaceFlags & SURF_NODLIGHT) {
cgi.Printf(" nodlight");
}
if (iSurfaceFlags & SURF_HINT) {
cgi.Printf(" hint");
}
if (iSurfaceFlags & SURF_PATCH) {
cgi.Printf(" patch");
}
}
static void CG_PrintSurfaceType(int iSurfType)
{
// FIXME: unimplemented
switch (iSurfType & MASK_SURF_TYPE) {
case SURF_FOLIAGE:
cgi.Printf("foliage");
break;
case SURF_SNOW:
cgi.Printf("snow");
break;
case SURF_CARPET:
cgi.Printf("carpet");
break;
case SURF_SAND:
cgi.Printf("sand");
break;
case SURF_PUDDLE:
cgi.Printf("puddle");
break;
case SURF_GLASS:
cgi.Printf("glass");
break;
case SURF_GRAVEL:
cgi.Printf("gravel");
break;
case SURF_MUD:
cgi.Printf("mud");
break;
case SURF_DIRT:
cgi.Printf("dirt");
break;
case SURF_GRILL:
cgi.Printf("metal grill");
break;
case SURF_GRASS:
cgi.Printf("grass");
break;
case SURF_ROCK:
cgi.Printf("rock");
break;
case SURF_PAPER:
cgi.Printf("paper");
break;
case SURF_WOOD:
cgi.Printf("wood");
break;
case SURF_METAL:
cgi.Printf("metal");
break;
default:
cgi.Printf("!!*none specified*!!");
break;
}
}
void CG_GetCHShader(void)
@@ -215,9 +356,9 @@ void CG_EditCHShader(void)
pShader = CG_GetShaderUnderCrosshair(qfalse, NULL);
if (pShader) {
strcpy(name, "editspecificshader ");
strcat(name, pShader->shader);
strcat(name, "\n");
Q_strncpyz(name, "editspecificshader ", sizeof(name));
Q_strcat(name, sizeof(name), pShader->shader);
Q_strcat(name, sizeof(name), "\n");
cgi.AddCommand(name);
} else {
cgi.Printf("No surface selected\n");
@@ -339,56 +480,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 },
};
/*
+71 -37
View File
@@ -675,14 +675,17 @@ void CG_DrawObjectives()
{
float vColor[4];
float fX, fY;
int iNumObjectives;
float fObjectivesTop;
static float fWidth;
float fHeight;
int iNumLines[20];
int iTotalNumLines;
int i;
int ii;
int iCurrentObjective;
float fTimeDelta;
const char *pszLocalizedText;
const char *pszLine;
iTotalNumLines = 0;
for (i = CS_OBJECTIVES; i < CS_OBJECTIVES + MAX_OBJECTIVES; ++i) {
@@ -702,26 +705,30 @@ void CG_DrawObjectives()
return;
}
for (i = 0; i < MAX_OBJECTIVES; i++) {
if ((cg.Objectives[i].flags & 0xFFFFFFFE)) {
iNumLines[i] = 0;
// Added in 2.0
// Get the minimum Y value, it should be below the compass
fObjectivesTop = cgi.UI_GetObjectivesTop();
iNumObjectives = 0;
for (ii = 0; ii < MAX_STRING_CHARS; ii++) {
if (cg.Objectives[i].text[ii] == '\n') {
iTotalNumLines++;
iNumLines[i]++;
} else if (!cg.Objectives[i].text[ii]) {
iTotalNumLines++;
iNumLines[i]++;
break;
}
}
for (i = 0; i < MAX_OBJECTIVES; i++) {
if ((cg.Objectives[i].flags == OBJ_FLAG_NONE) || (cg.Objectives[i].flags & OBJ_FLAG_HIDDEN)) {
continue;
}
iNumObjectives++;
iNumLines[i] = 0;
pszLocalizedText = cgi.LV_ConvertString(cg.Objectives[i].text);
for (pszLine = strchr(pszLocalizedText, '\n'); pszLine; pszLine = strchr(pszLine + 1, '\n')) {
iNumLines[i]++;
}
iTotalNumLines += iNumLines[i];
}
fX = 25.0;
fY = 125.0;
fWidth = (float)(25 * iTotalNumLines + 155) + 5.0 - 130.0;
fY = fObjectivesTop + 5;
fWidth = (float)(iTotalNumLines * 12 + fObjectivesTop + iNumObjectives * 25 + 32) - fY;
vColor[2] = 0.2f;
vColor[1] = 0.2f;
vColor[0] = 0.2f;
@@ -730,7 +737,7 @@ void CG_DrawObjectives()
cgi.R_DrawStretchPic(fX, fY, 450.0, fWidth, 0.0, 0.0, 1.0, 1.0, cgs.media.objectivesBackShader);
fX = 30.0;
fY = 130.0;
fY = fObjectivesTop + 10;
vColor[0] = 1.0;
vColor[1] = 1.0;
vColor[2] = 1.0;
@@ -740,12 +747,12 @@ void CG_DrawObjectives()
fY = fY + 5.0;
cgi.R_DrawString(cgs.media.objectiveFont, "_______________________________________________________", fX, fY, -1, 0);
fHeight = 155.0;
fHeight = fObjectivesTop + 35;
for (i = 0; i < MAX_OBJECTIVES; ++i) {
qhandle_t hBoxShader;
if ((cg.Objectives[i].flags & OBJ_FLAG_HIDDEN) || !cg.Objectives[i].flags) {
if ((cg.Objectives[i].flags == OBJ_FLAG_NONE) || (cg.Objectives[i].flags & OBJ_FLAG_HIDDEN)) {
continue;
}
@@ -789,7 +796,7 @@ void CG_DrawObjectives()
cgi.R_SetColor(vColor);
cgi.R_DrawStretchPic(fX, fY, 16.0, 16.0, 0.0, 0.0, 1.0, 1.0, hBoxShader);
fHeight += 25 * iNumLines[i];
fHeight += iNumLines[i] * 12 + 25;
}
}
@@ -927,6 +934,8 @@ void CG_UpdateAttackerDisplay()
void CG_UpdateCountdown()
{
const char* message = "";
if (!cg.snap) {
return;
}
@@ -937,16 +946,24 @@ void CG_UpdateCountdown()
iSecondsLeft = (cgs.matchEndTime - cg.time) / 1000;
if (iSecondsLeft >= 0) {
iMinutesLeft = iSecondsLeft / 60;
cgi.Cvar_Set(
"ui_timemessage", va("%s %2i:%02i", cgi.LV_ConvertString("Time Left:"), iMinutesLeft, iSecondsLeft % 60)
);
message = va("%s %2i:%02i", cgi.LV_ConvertString("Time Left:"), iMinutesLeft, iSecondsLeft % 60);
} else if (!cgs.matchEndTime) {
cgi.Cvar_Set("ui_timemessage", "");
message = "";
}
} else {
// The match has not started yet
cgi.Cvar_Set("ui_timemessage", "Waiting For Players");
message = "Waiting For Players";
}
if (strcmp(ui_timemessage->string, message)) {
cgi.Cvar_Set("ui_timemessage", message);
}
}
static void CG_RemoveStopwatch() {
cgi.Cmd_Execute(EXEC_NOW, "ui_removehud hud_stopwatch\n");
cgi.Cmd_Execute(EXEC_NOW, "ui_removehud hud_fuse\n");
cgi.Cmd_Execute(EXEC_NOW, "ui_removehud hud_fuse_wet\n");
}
void CG_DrawStopwatch()
@@ -954,38 +971,55 @@ void CG_DrawStopwatch()
int iFraction;
if (!cg_hud->integer) {
cgi.Cmd_Execute(EXEC_NOW, "ui_removehud hud_stopwatch\n");
CG_RemoveStopwatch();
return;
}
if (!cgi.stopWatch->iStartTime) {
cgi.Cmd_Execute(EXEC_NOW, "ui_removehud hud_stopwatch\n");
CG_RemoveStopwatch();
return;
}
if (cgi.stopWatch->iStartTime >= cgi.stopWatch->iEndTime) {
cgi.Cmd_Execute(EXEC_NOW, "ui_removehud hud_stopwatch\n");
CG_RemoveStopwatch();
return;
}
if (cgi.stopWatch->iEndTime <= cg.time) {
cgi.Cmd_Execute(EXEC_NOW, "ui_removehud hud_stopwatch\n");
CG_RemoveStopwatch();
return;
}
if (cg.ObjectivesCurrentAlpha >= 0.02) {
cgi.Cmd_Execute(EXEC_NOW, "ui_removehud hud_stopwatch\n");
CG_RemoveStopwatch();
return;
}
if (cg.snap && cg.snap->ps.stats[STAT_HEALTH] <= 0) {
cgi.Cmd_Execute(EXEC_NOW, "ui_removehud hud_stopwatch\n");
CG_RemoveStopwatch();
return;
}
if (cgi.stopWatch->eType >= SWT_FUSE_WET) {
iFraction = cgi.stopWatch->iEndTime - cgi.stopWatch->iStartTime;
} else {
iFraction = cgi.stopWatch->iEndTime - cg.time;
}
iFraction = cgi.stopWatch->iEndTime - cg.time;
cgi.Cvar_Set("ui_stopwatch", va("%i", iFraction));
cgi.Cmd_Execute(EXEC_NOW, "ui_addhud hud_stopwatch\n");
switch (cgi.stopWatch->eType) {
case SWT_NORMAL:
default:
cgi.Cmd_Execute(EXEC_NOW, "ui_addhud hud_stopwatch\n");
break;
case SWT_FUSE:
cgi.Cmd_Execute(EXEC_NOW, "ui_addhud hud_fuse\n");
break;
case SWT_FUSE_WET:
cgi.Cmd_Execute(EXEC_NOW, "ui_removehud hud_fuse\n");
cgi.Cmd_Execute(EXEC_NOW, "ui_addhud hud_fuse_wet\n");
break;
}
}
void CG_DrawInstantMessageMenu()
@@ -1085,7 +1119,7 @@ void CG_DrawSpectatorView_ver_15()
char buf[128];
iClientNum = cg.snap->ps.stats[STAT_INFOCLIENT];
sprintf(buf, "%s : %i", cg.clientinfo[iClientNum].name, cg.snap->ps.stats[STAT_INFOCLIENT_HEALTH]);
Com_sprintf(buf, sizeof(buf), "%s : %i", cg.clientinfo[iClientNum].name, cg.snap->ps.stats[STAT_INFOCLIENT_HEALTH]);
hShader = 0;
color[0] = 0.5;
@@ -1180,7 +1214,7 @@ void CG_DrawCrosshair()
float x, y;
float width, height;
shader = NULL;
shader = (qhandle_t)0;
if (!cg_hud->integer || !ui_crosshair->integer) {
return;
@@ -1190,7 +1224,7 @@ void CG_DrawCrosshair()
return;
}
if ((cg.snap->ps.pm_flags & PMF_NO_LEAN) || (cg.snap->ps.pm_flags & PMF_INTERMISSION)) {
if ((cg.snap->ps.pm_flags & PMF_NO_HUD) || (cg.snap->ps.pm_flags & PMF_INTERMISSION)) {
return;
}
+1 -1
View File
@@ -59,7 +59,7 @@ qboolean CG_LightStyleColor(int style, int realtime, vec4_t color, qboolean clam
time = realtime / 50;
frac = (realtime - (time * 50.0f)) / 50.0f;
memset(color, 0, sizeof(color));
VectorClear4(color);
if ((style < 0) || (style >= (MAX_LIGHTSTYLES * 2))) {
cgi.DPrintf("CG_LightStyleColor: style out of range.\n");
return qtrue;
+8 -3
View File
@@ -187,6 +187,7 @@ extern "C" {
float min_dist;
float width;
char shader[MAX_RAIN_SHADERS][MAX_STRING_CHARS];
char currentShader[MAX_STRING_CHARS];
int numshaders;
} crain_t;
@@ -340,6 +341,7 @@ extern "C" {
float ObjectivesBaseAlpha;
float ObjectivesDesiredAlpha;
float ObjectivesCurrentAlpha;
int ObjectivesCurrentIndex;
// misc
crain_t rain;
@@ -429,6 +431,7 @@ extern "C" {
extern cgs_t cgs;
extern cg_t cg;
extern clientGameImport_t cgi;
extern target_game_e cg_target_game;
extern int cg_protocol;
extern centity_t cg_entities[MAX_GENTITIES];
extern markPoly_t *cg_markPolys;
@@ -500,6 +503,7 @@ extern "C" {
extern cvar_t *voiceChat;
extern cvar_t *cg_shadowscount;
extern cvar_t *cg_shadowdebug;
extern cvar_t *ui_timemessage;
//
// cg_main.c
@@ -726,8 +730,8 @@ extern "C" {
void CG_InitTestTreadMark();
void CG_AddTreadMarks();
int CG_PermanentMark(
const vec3_t origin,
const vec3_t dir,
vec3_t origin,
vec3_t dir,
float orientation,
float fSScale,
float fTScale,
@@ -920,7 +924,8 @@ qboolean CG_LightStyleColor(int style, int realtime, vec4_t color, qboolean clam
void CG_InstaMessageGroupD_f(void);
void CG_InstaMessageGroupE_f(void);
void CG_HudPrint_f(void);
int CG_CheckCaptureKey(int key, qboolean down, unsigned int time);
qboolean CG_CheckCaptureKey(int key, qboolean down, unsigned int time);
//
// cg_vehicle.cpp
+98 -51
View File
@@ -35,12 +35,13 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
clientGameImport_t cgi;
static clientGameExport_t cge;
cvar_t *paused;
cvar_t *developer;
cg_t cg;
cgs_t cgs;
int cg_protocol;
centity_t cg_entities[MAX_GENTITIES];
cvar_t *paused;
cvar_t *developer;
cg_t cg;
cgs_t cgs;
target_game_e cg_target_game = TG_INVALID;
int cg_protocol;
centity_t cg_entities[MAX_GENTITIES];
cvar_t *cg_animSpeed;
cvar_t *cg_debugAnim;
@@ -109,6 +110,7 @@ cvar_t *vm_lean_lower;
cvar_t *voiceChat;
cvar_t *cg_shadowscount;
cvar_t *cg_shadowdebug;
cvar_t *ui_timemessage;
/*
=================
@@ -154,9 +156,9 @@ void CG_RegisterCvars(void)
cg_shadowdebug = cgi.Cvar_Get("cg_shadowdebug", "0", 0);
developer = cgi.Cvar_Get("developer", "0", 0);
dm_playermodel = cgi.Cvar_Get("dm_playermodel", "american_army", 3);
dm_playergermanmodel = cgi.Cvar_Get("dm_playergermanmodel", "german_wehrmacht_soldier", 3);
dm_playergermanmodel = cgi.Cvar_Get("dm_playergermanmodel", "german_wehrmacht_soldier", CVAR_ARCHIVE | CVAR_USERINFO);
cg_forceModel = cgi.Cvar_Get("cg_forceModel", "0", CVAR_ARCHIVE);
cg_animationviewmodel = cgi.Cvar_Get("cg_animationviewmodel", "0", 8);
cg_animationviewmodel = cgi.Cvar_Get("cg_animationviewmodel", "0", CVAR_SYSTEMINFO);
cg_hitmessages = cgi.Cvar_Get("cg_hitmessages", "1", CVAR_ARCHIVE);
cg_acidtrip = cgi.Cvar_Get("cg_acidtrip", "0", CVAR_CHEAT);
cg_hud = cgi.Cvar_Get("cg_hud", "0", 0);
@@ -196,53 +198,87 @@ void CG_RegisterCvars(void)
vm_lean_lower = cgi.Cvar_Get("vm_lean_lower", "0.1", 0);
voiceChat = cgi.Cvar_Get("cg_voicechat", "1", 0);
ui_timemessage = cgi.Cvar_Get("ui_timemessage", "", 0);
// see if we are also running the server on this machine
temp = cgi.Cvar_Get("sv_running", "0", 0);
cgs.localServer = temp->integer;
}
/*
================
CG_RegisterSoundsForFile
Register the specified ubersound source file
================
*/
void CG_RegisterSoundsForFile(const char *name)
{
int startTime;
int endTime;
Com_Printf("\n\n-----------PARSING '%s'------------\n", name);
Com_Printf(
"Any SetCurrentTiki errors means that tiki wasn't prefetched and tiki-specific sounds for it won't work. To "
"fix prefetch the tiki. Ignore if you don't use that tiki on this level.\n"
);
startTime = cgi.Milliseconds();
CG_Command_ProcessFile(name, qfalse, NULL);
endTime = cgi.Milliseconds();
Com_Printf("Parse/Load time: %f seconds.\n", (float)(endTime - startTime) / 1000.0);
Com_Printf("-------------PARSING '%s' DONE---------------\n\n", name);
}
/*
=================
qsort_compare_strings
perform case-insensitive sorting
=================
*/
int qsort_compare_strings(const void *s1, const void *s2)
{
return Q_stricmp(*(const char **)s1, *(const char **)s2);
}
/*
=================
CG_RegisterSounds
called during a precache command
Called during a precache command
=================
*/
void CG_RegisterSounds(void)
{
int startTime;
int endTime;
char filename[MAX_QPATH];
char **fileList;
int numFiles;
int i;
Com_Printf("\n\n-----------PARSING UBERSOUND------------\n");
Com_Printf(
"Any SetCurrentTiki errors means that tiki wasn't prefetched and "
"tiki-specific sounds for it won't work. To fix prefe"
"tch the tiki. Ignore if you don't use that tiki on this level.\n"
);
Com_sprintf(filename, sizeof(filename), "ubersound/ubersound.scr");
fileList = cgi.FS_ListFilteredFiles("ubersound/", "scr", "*.scr", qfalse, &numFiles, qtrue);
if (cg_target_game >= TG_MOHTA) {
// Fixed in 2.0
// The behavior has changed, all aliases get cleared
if (cgs.gametype != GT_SINGLE_PLAYER) {
cgi.Alias_Clear();
}
} else {
if (!cgs.localServer) {
cgi.Alias_Clear();
}
}
qsort(fileList, numFiles, sizeof(char *), &qsort_compare_strings);
startTime = cgi.Milliseconds();
CG_Command_ProcessFile(filename, 0, 0);
endTime = cgi.Milliseconds();
for (i = 0; i < numFiles; i++) {
// Added in 2.0
// Since 2.0, all files in the ubersound folder
// are parsed
CG_RegisterSoundsForFile(va("ubersound/%s", fileList[i]));
}
Com_Printf("Parse/Load time: %f seconds.\n", (endTime - startTime) / 1000.0f);
Com_Printf("-------------UBERSOUND DONE---------------\n\n");
Com_Printf("\n\n-----------PARSING UBERDIALOG------------\n");
Com_Printf(
"Any SetCurrentTiki errors means that tiki wasn't prefetched and "
"tiki-specific sounds for it won't work. To fix prefe"
"tch the tiki. Ignore if you don't use that tiki on this level.\n"
);
Com_sprintf(filename, sizeof(filename), "ubersound/uberdialog.scr");
startTime = cgi.Milliseconds();
CG_Command_ProcessFile(filename, 0, 0);
endTime = cgi.Milliseconds() - startTime;
Com_Printf("Parse/Load time: %f seconds.\n", endTime / 1000.0f);
Com_Printf("-------------UBERDIALOG DONE---------------\n\n");
cgi.FS_FreeFileList(fileList);
}
/*
@@ -252,13 +288,11 @@ CG_IsHandleUnique
Check if the model handle is unique
================
*/
static qboolean CG_IsHandleUnique(int num) {
qhandle_t handle;
static qboolean CG_IsHandleUnique(qhandle_t handle) {
int i;
int numRef;
numRef = 0;
handle = cgs.model_draw[num];
for (i = 0; i < MAX_MODELS; i++) {
if (cgs.model_draw[i] == handle) {
numRef++;
@@ -335,28 +369,39 @@ void CG_ProcessConfigString(int num, qboolean modelOnly)
cg.rain.width = atof(str);
return;
case CS_RAIN_SHADER:
Q_strncpyz(cg.rain.currentShader, str, sizeof(cg.rain.currentShader));
if (cg.rain.numshaders) {
for (i = 0; i < cg.rain.numshaders; i++) {
sprintf(cg.rain.shader[i], "%s%i", str, i);
// Fixed in OPM
// not sure why some maps set a digit at the end...
size_t len = strlen(cg.rain.currentShader);
if (isdigit(cg.rain.currentShader[len - 1])) {
cg.rain.currentShader[len - 1] = 0;
}
} else {
strcpy(cg.rain.shader[0], str);
}
for (i = 0; i < cg.rain.numshaders; ++i) {
Com_sprintf(cg.rain.shader[i], sizeof(cg.rain.shader[i]), "%s%i", cg.rain.currentShader, i);
}
if (!cg.rain.numshaders) {
Q_strncpyz(cg.rain.shader[0], cg.rain.currentShader, sizeof(cg.rain.shader[0]));
}
return;
case CS_RAIN_NUMSHADERS:
cg.rain.numshaders = atoi(str);
if (cg.rain.numshaders) {
for (i = 0; i < cg.rain.numshaders; i++) {
sprintf(cg.rain.shader[i], "%s%i", str, i);
Com_sprintf(cg.rain.shader[i], sizeof(cg.rain.shader[i]), "%s%i", cg.rain.currentShader, i);
}
}
return;
case CS_CURRENT_OBJECTIVE:
cg.ObjectivesCurrentIndex = atoi(str);
return;
}
if (num >= CS_OBJECTIVES && num < CS_OBJECTIVES + MAX_OBJECTIVES) {
cobjective_t *objective = &cg.Objectives[num - CS_OBJECTIVES];
objective->flags = atoi(Info_ValueForKey(str, "flags"));
strcpy(objective->text, Info_ValueForKey(str, "text"));
Q_strncpyz(objective->text, Info_ValueForKey(str, "text"), sizeof(objective->text));
}
switch (num) {
@@ -411,7 +456,7 @@ void CG_ProcessConfigString(int num, qboolean modelOnly)
if (len) {
qboolean streamed;
char buf[1024];
strcpy(buf, str);
Q_strncpyz(buf, str, sizeof(buf));
streamed = buf[len - 1] != '0';
buf[len - 1] = 0;
@@ -623,6 +668,8 @@ void CG_Init(clientGameImport_t *imported, int serverMessageNum, int serverComma
cgi = *imported;
cg_protocol = cgi.Cvar_Get("com_protocol", "", 0)->integer;
cg_target_game = (target_game_e)cgi.Cvar_Get("com_target_game", "0", 0)->integer;
CG_InitCGMessageAPI(&cge);
CG_InitScoresAPI(&cge);
@@ -811,7 +858,7 @@ void Com_Error(int level, const char *error, ...)
char text[1024];
va_start(argptr, error);
vsprintf(text, error, argptr);
Q_vsnprintf(text, sizeof(text), error, argptr);
va_end(argptr);
cgi.Error(level, "%s", text);
@@ -823,7 +870,7 @@ void Com_Printf(const char *msg, ...)
char text[1024];
va_start(argptr, msg);
vsprintf(text, msg, argptr);
Q_vsnprintf(text, sizeof(text), msg, argptr);
va_end(argptr);
cgi.Printf("%s", text);
+1171 -281
View File
File diff suppressed because it is too large. Load diff
+122 -106
View File
@@ -180,6 +180,117 @@ void CG_PlayerTeamIcon(refEntity_t *pModel, entityState_t *pPlayerState)
}
}
/*
===============
CG_InterpolateAnimParms
Interpolate between current and next entity
===============
*/
void CG_InterpolateAnimParms(entityState_t* state, entityState_t* sNext, refEntity_t* model)
{
static cvar_t *vmEntity = NULL;
int i;
float t;
float animLength;
float t1, t2;
if (!vmEntity) {
vmEntity = cgi.Cvar_Get("viewmodelanim", "1", 0);
}
if (sNext && sNext->usageIndex == state->usageIndex) {
t1 = cg.time - cg.snap->serverTime;
t2 = cg.nextSnap->serverTime - cg.snap->serverTime;
t = t1 / t2;
model->actionWeight = (sNext->actionWeight - state->actionWeight) * t + state->actionWeight;
for (i = 0; i < MAX_FRAMEINFOS; i++) {
if (sNext->frameInfo[i].weight) {
model->frameInfo[i].index = sNext->frameInfo[i].index;
if (sNext->frameInfo[i].index == state->frameInfo[i].index && state->frameInfo[i].weight) {
model->frameInfo[i].weight =
(sNext->frameInfo[i].weight - state->frameInfo[i].weight) * t + state->frameInfo[i].weight;
if (sNext->frameInfo[i].time >= state->frameInfo[i].time) {
model->frameInfo[i].time = (sNext->frameInfo[i].time - state->frameInfo[i].time) * t + state->frameInfo[i].time;
} else {
animLength = cgi.Anim_Time(model->tiki, sNext->frameInfo[i].index);
if (!animLength) {
t1 = 0.0;
} else {
t1 = (animLength + sNext->frameInfo[i].time - state->frameInfo[i].time) * t
+ state->frameInfo[i].time;
}
t2 = t1;
while (t2 > animLength) {
t2 -= animLength;
if (t2 == t1) {
t2 = 1.0;
break;
}
t1 = t2;
}
model->frameInfo[i].time = t2;
}
} else {
animLength = cgi.Anim_Time(model->tiki, sNext->frameInfo[i].index);
if (!animLength) {
t1 = 0.0;
} else {
t1 = sNext->frameInfo[i].time - (cg.nextSnap->serverTime - cg.time) / 1000.0;
}
model->frameInfo[i].time = Q_max(0, t1);
model->frameInfo[i].weight = sNext->frameInfo[i].weight;
}
} else if (sNext->frameInfo[i].index == state->frameInfo[i].index) {
animLength = cgi.Anim_Time(model->tiki, sNext->frameInfo[i].index);
if (!animLength) {
t1 = 0.0;
} else {
t1 = (cg.time - cg.snap->serverTime) / 1000.0 + state->frameInfo[i].time;
}
model->frameInfo[i].index = Q_clamp_int(state->frameInfo[i].index, 0, model->tiki->a->num_anims - 1);
model->frameInfo[i].time = Q_min(animLength, t1);
model->frameInfo[i].weight = (1.0 - t) * state->frameInfo[i].weight;
} else {
model->frameInfo[i].index = -1;
model->frameInfo[i].weight = 0.0;
}
}
} else {
// no next state, don't blend anims
model->actionWeight = state->actionWeight;
for (i = 0; i < MAX_FRAMEINFOS; i++) {
if (state->frameInfo[i].weight) {
model->frameInfo[i].index = Q_clamp_int(state->frameInfo[i].index, 0, model->tiki->a->num_anims - 1);
model->frameInfo[i].time = state->frameInfo[i].time;
model->frameInfo[i].weight = state->frameInfo[i].weight;
} else {
model->frameInfo[i].index = -1;
model->frameInfo[i].weight = 0.0;
}
}
}
if (vmEntity->integer == state->number) {
static cvar_t *curanim;
if (!curanim) {
curanim = cgi.Cvar_Get("viewmodelanimslot", "1", 0);
}
cgi.Cvar_Set("viewmodelanimclienttime", va("%0.2f", model->frameInfo[curanim->integer].time));
}
}
/*
===============
CG_CastFootShadow
@@ -550,7 +661,7 @@ void CG_AnimationDebugMessage(int number, const char *fmt, ...)
char msg[1024];
va_start(argptr, fmt);
vsprintf(msg, fmt, argptr);
Q_vsnprintf(msg, sizeof(msg), fmt, argptr);
va_end(argptr);
if ((!cg_debugAnimWatch->integer) || ((cg_debugAnimWatch->integer - 1) == number)) {
@@ -654,8 +765,8 @@ void CG_UpdateForceModels()
pszAlliesPartial = dm_playermodel->string;
pszAxisPartial = dm_playergermanmodel->string;
sprintf(szAlliesModel, "models/player/%s.tik", pszAlliesPartial);
sprintf(szAxisModel, "models/player/%s.tik", pszAxisPartial);
Com_sprintf(szAlliesModel, sizeof(szAlliesModel), "models/player/%s.tik", pszAlliesPartial);
Com_sprintf(szAxisModel, sizeof(szAxisModel), "models/player/%s.tik", pszAxisPartial);
hModel = cgi.R_RegisterModel(szAlliesModel);
if (!hModel) hModel = cgi.R_RegisterModel("models/player/american_army.tik");
@@ -697,7 +808,6 @@ void CG_ModelAnim(centity_t *cent, qboolean bDoShaderTime)
int i;
vec3_t vMins, vMaxs, vTmp;
const char *szTagName;
static cvar_t *vmEntity = NULL;
int iAnimFlags;
s1 = &cent->currentState;
@@ -709,10 +819,6 @@ void CG_ModelAnim(centity_t *cent, qboolean bDoShaderTime)
memset(&model, 0, sizeof(model));
if (!vmEntity) {
vmEntity = cgi.Cvar_Get("viewmodelanim", "1", 0);
}
if (cent->interpolate) {
sNext = &cent->nextState;
}
@@ -880,103 +986,7 @@ void CG_ModelAnim(centity_t *cent, qboolean bDoShaderTime)
model.renderfx |= s1->renderfx;
cgi.TIKI_SetEyeTargetPos(model.tiki, model.entityNumber, s1->eyeVector);
if (sNext && sNext->usageIndex == s1->usageIndex) {
float t;
float animLength;
float t1, t2;
t1 = cg.time - cg.snap->serverTime;
t2 = cg.nextSnap->serverTime - cg.snap->serverTime;
t = t1 / t2;
model.actionWeight = (sNext->actionWeight - s1->actionWeight) * t + s1->actionWeight;
for (i = 0; i < MAX_FRAMEINFOS; i++) {
if (sNext->frameInfo[i].weight) {
model.frameInfo[i].index = sNext->frameInfo[i].index;
if (sNext->frameInfo[i].index == s1->frameInfo[i].index && s1->frameInfo[i].weight) {
model.frameInfo[i].weight =
(sNext->frameInfo[i].weight - s1->frameInfo[i].weight) * t + s1->frameInfo[i].weight;
if (sNext->frameInfo[i].time >= s1->frameInfo[i].time) {
model.frameInfo[i].time =
(sNext->frameInfo[i].time - s1->frameInfo[i].time) * t + s1->frameInfo[i].time;
} else {
animLength = cgi.Anim_Time(model.tiki, sNext->frameInfo[i].index);
if (!animLength) {
t1 = 0.0;
} else {
t1 = (animLength + sNext->frameInfo[i].time - s1->frameInfo[i].time) * t
+ s1->frameInfo[i].time;
}
t2 = t1;
while (t2 > animLength) {
t2 -= animLength;
}
model.frameInfo[i].time = t2;
}
} else {
animLength = cgi.Anim_Time(model.tiki, sNext->frameInfo[i].index);
if (!animLength) {
t1 = 0.0;
} else {
t1 = sNext->frameInfo[i].time - (cg.nextSnap->serverTime - cg.time) / 1000.0;
}
t2 = t1;
if (t2 < 0.0) {
t2 = 0.0;
}
model.frameInfo[i].time = t2;
model.frameInfo[i].weight = sNext->frameInfo[i].weight;
}
} else if (sNext->frameInfo[i].index == s1->frameInfo[i].index) {
animLength = cgi.Anim_Time(model.tiki, sNext->frameInfo[i].index);
if (!animLength) {
t1 = 0.0;
} else {
t1 = (cg.time - cg.snap->serverTime) / 1000.0 + s1->frameInfo[i].time;
}
t2 = t1;
if (t2 < animLength) {
t2 = animLength;
}
model.frameInfo[i].index = s1->frameInfo[i].index;
model.frameInfo[i].time = t2;
model.frameInfo[i].weight = (1.0 - t) * s1->frameInfo[i].weight;
} else {
model.frameInfo[i].index = -1;
model.frameInfo[i].weight = 0.0;
}
}
} else {
// no next state, don't blend anims
model.actionWeight = s1->actionWeight;
for (i = 0; i < MAX_FRAMEINFOS; i++) {
if (s1->frameInfo[i].weight) {
model.frameInfo[i].index = s1->frameInfo[i].index;
model.frameInfo[i].time = s1->frameInfo[i].time;
model.frameInfo[i].weight = s1->frameInfo[i].weight;
} else {
model.frameInfo[i].index = -1;
model.frameInfo[i].weight = 0.0;
}
}
}
if (vmEntity->integer == s1->number) {
static cvar_t *curanim;
if (!curanim) {
curanim = cgi.Cvar_Get("viewmodelanimslot", "1", 0);
}
cgi.Cvar_Set("viewmodelanimclienttime", va("%0.2f", model.frameInfo[curanim->integer].time));
}
CG_InterpolateAnimParms(s1, sNext, &model);
if (cent->currentState.parent != ENTITYNUM_NONE) {
int iTagNum;
@@ -1227,6 +1237,7 @@ void CG_ModelAnim(centity_t *cent, qboolean bDoShaderTime)
memset(model.surfaces, 0, sizeof(model.surfaces));
CG_ViewModelAnimation(&model);
model.renderfx |= RF_FRAMELERP;
cgi.ForceUpdatePose(&model);
if ((cent->currentState.eFlags & EF_UNARMED) || cg_drawviewmodel->integer <= 1
@@ -1323,7 +1334,12 @@ void CG_ModelAnim(centity_t *cent, qboolean bDoShaderTime)
if (model.frameInfo[i].weight) {
if (!((cent->animLastWeight >> i) & 1) || model.frameInfo[i].index != cent->animLast[i]) {
CG_ProcessEntityCommands(TIKI_FRAME_ENTRY, model.frameInfo[i].index, s1->number, &model, cent);
cent->animLastTimes[i] = 0.0;
if (cent->animLastTimes[i] == -1) {
cent->animLast[i] = model.frameInfo[i].index;
cent->animLastTimes[i] = model.frameInfo[i].time;
} else {
cent->animLastTimes[i] = 0;
}
}
CG_ClientCommands(&model, cent, i);
+3 -3
View File
@@ -51,16 +51,16 @@ void RainTouch(ctempmodel_t *ct, trace_t *trace)
void ClientGameCommandManager::RainTouch(Event *ev)
{
// FIXME: unimplemented
// Nothing to do
}
void ClientGameCommandManager::InitializeRainCvars()
{
int i;
cg_rain = cgi.Cvar_Get("cg_rain", "0", CVAR_ARCHIVE);
cg_rain = cgi.Cvar_Get("cg_rain", "1", CVAR_ARCHIVE);
cg_rain_drawcoverage =
cgi.Cvar_Get("cg_rain_drawcoverage", "0", CVAR_SAVEGAME | CVAR_SERVER_CREATED | CVAR_SYSTEMINFO);
cgi.Cvar_Get("cg_rain_drawcoverage", "0", CVAR_SAVEGAME | CVAR_RESETSTRING | CVAR_SYSTEMINFO);
cg.rain.density = 0.0;
cg.rain.speed = 2048.0f;
+313 -199
View File
File diff suppressed because it is too large. Load diff
+20 -3
View File
@@ -190,8 +190,9 @@ void CG_ShowTrace(trace_t *trace, int passent, const char *reason)
assert(reason);
assert(trace);
sprintf(
Com_sprintf(
text,
sizeof(text),
"%0.2f : Pass (%d) Frac %f Hit (%d): '%s'\n",
(float)cg.time / 1000.0f,
passent,
@@ -349,6 +350,13 @@ static void CG_InterpolatePlayerStateCamera(void)
return;
}
// Added in 2.0
if (cg.predicted_player_state.camera_flags & CF_CAMERA_ANGLES_TURRETMODE) {
VectorCopy(cg.nextSnap->ps.camera_origin, cg.camera_origin);
VectorCopy(cg.nextSnap->ps.camera_angles, cg.camera_angles);
return;
}
for (i = 0; i < 3; i++) {
cg.camera_origin[i] = prev->ps.camera_origin[i] + f * (next->ps.camera_origin[i] - prev->ps.camera_origin[i]);
cg.camera_angles[i] = LerpAngle(prev->ps.camera_angles[i], next->ps.camera_angles[i], f);
@@ -493,8 +501,13 @@ void CG_PredictPlayerState(void)
cg_pmove.leanSpeed = 2.f;
} else {
cg_pmove.alwaysAllowLean = qtrue;
if (cgs.gametype != GT_SINGLE_PLAYER) {
cg_pmove.leanMax = 40.f;
} else {
// Don't allow lean in single-player, like in the original game
cg_pmove.leanMax = 0;
}
cg_pmove.leanMax = 40.f;
cg_pmove.leanAdd = 10.f;
cg_pmove.leanRecoverSpeed = 15.f;
cg_pmove.leanSpeed = 4.f;
@@ -515,7 +528,11 @@ void CG_PredictPlayerState(void)
// the server time is beyond our current cg.time,
// because predicted player positions are going to
// be ahead of everything else anyway
if (cg.nextSnap && !cg.nextFrameTeleport && !cg.thisFrameTeleport) {
// Added in OPM: prediction check
// Don't use the next snapshot if the prediction is about to be disabled
// this prevent "blinking" issues like when entering a vehicle turret gun
// where arms would be seen shortly
if (cg.nextSnap && !cg.nextFrameTeleport && !cg.thisFrameTeleport && !(cg.nextSnap->ps.pm_flags & PMF_NO_PREDICTION)) {
cg.predicted_player_state = cg.nextSnap->ps;
cg.physicsTime = cg.nextSnap->serverTime;
} else {
+7 -2
View File
@@ -120,6 +120,7 @@ functions exported to the main executable
// console variable interaction
cvar_t *(*Cvar_Get)(const char *var_name, const char *value, int flags);
cvar_t *(*Cvar_Find)(const char *var_name);
void (*Cvar_Set)(const char *var_name, const char *value);
// ClientCommand and ConsoleCommand parameter access
@@ -360,6 +361,8 @@ functions exported to the main executable
void (*UI_ShowMenu)(const char *name, qboolean bForce);
void (*UI_HideMenu)(const char *name, qboolean bForce);
int (*UI_FontStringWidth)(fontheader_t *font, const char *string, int maxLen);
// Added in 2.0
float (*UI_GetObjectivesTop)(void);
int (*Key_StringToKeynum)(const char *str);
const char *(*Key_KeynumToBindString)(int keyNum);
@@ -430,6 +433,8 @@ functions exported to the main executable
void (*CL_RestoreSavedCgameState)();
void (*CL_ClearSavedCgameState)();
size_t (*getConfigStringIdNormalized)(size_t num);
cvar_t *fsDebug;
hdelement_t *HudDrawElements;
clientAnim_t *anim;
@@ -463,8 +468,8 @@ functions exported to the main executable
int (*CG_GetParent)(int entNum);
float (*CG_GetObjectiveAlpha)();
int (*CG_PermanentMark)(
const vec3_t origin,
const vec3_t dir,
vec3_t origin,
vec3_t dir,
float orientation,
float sScale,
float tScale,
+43 -41
View File
@@ -58,19 +58,19 @@ void CG_PrepScoreBoardInfo()
{
switch (cgs.gametype) {
case GT_TEAM_ROUNDS:
strcpy(cg.scoresMenuName, "DM_Round_Scoreboard");
Q_strncpyz(cg.scoresMenuName, "DM_Round_Scoreboard", sizeof(cg.scoresMenuName));
break;
case GT_OBJECTIVE:
strcpy(cg.scoresMenuName, "Obj_Scoreboard");
Q_strncpyz(cg.scoresMenuName, "Obj_Scoreboard", sizeof(cg.scoresMenuName));
break;
case GT_TOW:
strcpy(cg.scoresMenuName, "Tow_Scoreboard");
Q_strncpyz(cg.scoresMenuName, "Tow_Scoreboard", sizeof(cg.scoresMenuName));
break;
case GT_LIBERATION:
strcpy(cg.scoresMenuName, "Lib_Scoreboard");
Q_strncpyz(cg.scoresMenuName, "Lib_Scoreboard", sizeof(cg.scoresMenuName));
break;
default:
strcpy(cg.scoresMenuName, "DM_Scoreboard");
Q_strncpyz(cg.scoresMenuName, "DM_Scoreboard", sizeof(cg.scoresMenuName));
break;
}
}
@@ -296,14 +296,15 @@ void CG_ParseScores_ver_15()
switch (iClientTeam) {
case 1:
strcpy(szString3, cgi.LV_ConvertString("Spectators"));
Q_strncpyz(szString3, cgi.LV_ConvertString("Spectators"), sizeof(szString3));
break;
case 2:
strcpy(szString3, cgi.LV_ConvertString("Free-For-Allers"));
Q_strncpyz(szString3, cgi.LV_ConvertString("Free-For-Allers"), sizeof(szString3));
break;
case 3:
sprintf(
Com_sprintf(
szString3,
sizeof(szString3),
"%s - %d %s",
cgi.LV_ConvertString("Allies"),
atoi(cgi.Argv(2 + iCurrentEntry + iDatumCount * i)),
@@ -312,8 +313,9 @@ void CG_ParseScores_ver_15()
iCurrentEntry++;
break;
case 4:
sprintf(
Com_sprintf(
szString3,
sizeof(szString3),
"%s - %d %s",
cgi.LV_ConvertString("Axis"),
atoi(cgi.Argv(2 + iCurrentEntry + iDatumCount * i)),
@@ -322,7 +324,7 @@ void CG_ParseScores_ver_15()
iCurrentEntry++;
break;
default:
strcpy(szString3, cgi.LV_ConvertString("No Team"));
Q_strncpyz(szString3, cgi.LV_ConvertString("No Team"), sizeof(szString3));
break;
}
} else if (iClientNum == -2) {
@@ -330,14 +332,14 @@ void CG_ParseScores_ver_15()
szString2[0] = 0;
szString3[0] = 0;
} else {
strcpy(szString2, va("%i", iClientNum));
strcpy(szString3, cg.clientinfo[iClientNum].name);
Q_strncpyz(szString2, va("%i", iClientNum), sizeof(szString2));
Q_strncpyz(szString3, cg.clientinfo[iClientNum].name, sizeof(szString3));
}
strcpy(szString4, cgi.Argv(2 + iCurrentEntry + iDatumCount * i));
strcpy(szString5, cgi.Argv(3 + iCurrentEntry + iDatumCount * i));
strcpy(szString6, cgi.Argv(4 + iCurrentEntry + iDatumCount * i));
strcpy(szString7, cgi.Argv(5 + iCurrentEntry + iDatumCount * i));
Q_strncpyz(szString4, cgi.Argv(2 + iCurrentEntry + iDatumCount * i), sizeof(szString4));
Q_strncpyz(szString5, cgi.Argv(3 + iCurrentEntry + iDatumCount * i), sizeof(szString5));
Q_strncpyz(szString6, cgi.Argv(4 + iCurrentEntry + iDatumCount * i), sizeof(szString6));
Q_strncpyz(szString7, cgi.Argv(5 + iCurrentEntry + iDatumCount * i), sizeof(szString7));
if (cgs.gametype >= GT_TEAM_ROUNDS && iClientNum == -1
&& (iClientTeam == TEAM_ALLIES || iClientTeam == TEAM_AXIS)) {
@@ -370,19 +372,19 @@ void CG_ParseScores_ver_15()
} else {
iClientNum = atoi(cgi.Argv(iCurrentEntry + iDatumCount * i));
if (iClientNum >= 0) {
strcpy(szString2, va("%i", iClientNum));
strcpy(szString3, cg.clientinfo[iClientNum].name);
strcpy(szString4, cgi.Argv(1 + iCurrentEntry + iDatumCount * i));
strcpy(szString5, cgi.Argv(2 + iCurrentEntry + iDatumCount * i));
strcpy(szString6, cgi.Argv(3 + iCurrentEntry + iDatumCount * i));
strcpy(szString7, cgi.Argv(4 + iCurrentEntry + iDatumCount * i));
Q_strncpyz(szString2, va("%i", iClientNum), sizeof(szString2));
Q_strncpyz(szString3, cg.clientinfo[iClientNum].name, sizeof(szString3));
Q_strncpyz(szString4, cgi.Argv(1 + iCurrentEntry + iDatumCount * i), sizeof(szString4));
Q_strncpyz(szString5, cgi.Argv(2 + iCurrentEntry + iDatumCount * i), sizeof(szString5));
Q_strncpyz(szString6, cgi.Argv(3 + iCurrentEntry + iDatumCount * i), sizeof(szString6));
Q_strncpyz(szString7, cgi.Argv(4 + iCurrentEntry + iDatumCount * i), sizeof(szString7));
} else {
szString2[0] = 0;
if (iClientNum == -3) {
strcpy(szString2, cgi.LV_ConvertString("Players"));
Q_strncpyz(szString2, cgi.LV_ConvertString("Players"), sizeof(szString2));
bIsHeader = qtrue;
} else if (iClientNum == -2) {
strcpy(szString2, cgi.LV_ConvertString("Spectators"));
Q_strncpyz(szString2, cgi.LV_ConvertString("Spectators"), sizeof(szString2));
bIsHeader = qtrue;
} else {
// unknown
@@ -535,32 +537,32 @@ void CG_ParseScores_ver_6()
switch (iClientTeam) {
case 1:
strcpy(szString2, cgi.LV_ConvertString("Spectators"));
Q_strncpyz(szString2, cgi.LV_ConvertString("Spectators"), sizeof(szString2));
break;
case 2:
strcpy(szString2, cgi.LV_ConvertString("Free-For-Allers"));
Q_strncpyz(szString2, cgi.LV_ConvertString("Free-For-Allers"), sizeof(szString2));
break;
case 3:
strcpy(szString2, cgi.LV_ConvertString("Allies"));
Q_strncpyz(szString2, cgi.LV_ConvertString("Allies"), sizeof(szString2));
break;
case 4:
strcpy(szString2, cgi.LV_ConvertString("Axis"));
Q_strncpyz(szString2, cgi.LV_ConvertString("Axis"), sizeof(szString2));
break;
default:
strcpy(szString2, cgi.LV_ConvertString("No Team"));
Q_strncpyz(szString2, cgi.LV_ConvertString("No Team"), sizeof(szString2));
break;
}
} else if (iClientNum == -2) {
// spectating
szString2[0] = 0;
} else {
strcpy(szString2, cg.clientinfo[iClientNum].name);
Q_strncpyz(szString2, cg.clientinfo[iClientNum].name, sizeof(szString2));
}
strcpy(szString3, cgi.Argv(2 + iCurrentEntry + iDatumCount * i));
strcpy(szString4, cgi.Argv(3 + iCurrentEntry + iDatumCount * i));
strcpy(szString5, cgi.Argv(4 + iCurrentEntry + iDatumCount * i));
strcpy(szString6, cgi.Argv(5 + iCurrentEntry + iDatumCount * i));
Q_strncpyz(szString3, cgi.Argv(2 + iCurrentEntry + iDatumCount * i), sizeof(szString3));
Q_strncpyz(szString4, cgi.Argv(3 + iCurrentEntry + iDatumCount * i), sizeof(szString4));
Q_strncpyz(szString5, cgi.Argv(4 + iCurrentEntry + iDatumCount * i), sizeof(szString5));
Q_strncpyz(szString6, cgi.Argv(5 + iCurrentEntry + iDatumCount * i), sizeof(szString6));
if (iClientNum == cg.snap->ps.clientNum) {
pItemTextColor = vThisClientTextColor;
@@ -587,17 +589,17 @@ void CG_ParseScores_ver_6()
} else {
iClientNum = atoi(cgi.Argv(iCurrentEntry + iDatumCount * i));
if (iClientNum >= 0) {
strcpy(szString2, cg.clientinfo[iClientNum].name);
strcpy(szString3, cgi.Argv(1 + iCurrentEntry + iDatumCount * i));
strcpy(szString4, cgi.Argv(2 + iCurrentEntry + iDatumCount * i));
strcpy(szString5, cgi.Argv(3 + iCurrentEntry + iDatumCount * i));
strcpy(szString6, cgi.Argv(4 + iCurrentEntry + iDatumCount * i));
Q_strncpyz(szString2, cg.clientinfo[iClientNum].name, sizeof(szString2));
Q_strncpyz(szString3, cgi.Argv(1 + iCurrentEntry + iDatumCount * i), sizeof(szString3));
Q_strncpyz(szString4, cgi.Argv(2 + iCurrentEntry + iDatumCount * i), sizeof(szString4));
Q_strncpyz(szString5, cgi.Argv(3 + iCurrentEntry + iDatumCount * i), sizeof(szString5));
Q_strncpyz(szString6, cgi.Argv(4 + iCurrentEntry + iDatumCount * i), sizeof(szString6));
} else {
if (iClientNum == -3) {
strcpy(szString2, cgi.LV_ConvertString("Players"));
Q_strncpyz(szString2, cgi.LV_ConvertString("Players"), sizeof(szString2));
bIsHeader = qtrue;
} else if (iClientNum == -2) {
strcpy(szString2, cgi.LV_ConvertString("Spectators"));
Q_strncpyz(szString2, cgi.LV_ConvertString("Spectators"), sizeof(szString2));
bIsHeader = qtrue;
} else {
// unknown
+264 -9
View File
@@ -1,6 +1,7 @@
/*
===========================================================================
Copyright (C) 2023 the OpenMoHAA team
Copyright (C) 2008-2024 the OpenMoHAA team
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of OpenMoHAA source code.
@@ -26,11 +27,27 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "cg_local.h"
#include "../fgame/bg_voteoptions.h"
static qboolean CG_IsStatementFiltered(char *cmd);
/*
================
IsWeaponAllowed
Returns true if the weapon is allowed
================
*/
static const char *IsWeaponAllowed(int dmFlags, int flags)
{
return (dmFlags & flags) ? "0" : "1";
}
/*
================
QueryLandminesAllowed2
Returns true if landmines is allowed by the map or by a dm flag
================
*/
static qboolean QueryLandminesAllowed2(const char *mapname, int dmflags)
{
if (dmflags & DF_WEAPON_NO_LANDMINE) {
@@ -134,6 +151,7 @@ void CG_ParseServerinfo(void)
cgi.Cvar_Set("cg_fraglimit", Info_ValueForKey(info, "fraglimit"));
cgi.Cvar_Set("cg_timelimit", Info_ValueForKey(info, "timelimit"));
cgi.Cvar_Set("cg_maxclients", Info_ValueForKey(info, "sv_gametype"));
cgi.Cvar_Set("cg_allowvote", Info_ValueForKey(info, "g_allowvote"));
cgi.Cvar_Set("cg_obj_alliedtext1", Info_ValueForKey(info, "g_obj_alliedtext1"));
cgi.Cvar_Set("cg_obj_alliedtext2", Info_ValueForKey(info, "g_obj_alliedtext2"));
cgi.Cvar_Set("cg_obj_alliedtext3", Info_ValueForKey(info, "g_obj_alliedtext3"));
@@ -148,10 +166,10 @@ void CG_ParseServerinfo(void)
cgi.Cvar_Set("cg_scoreboardpicover", Info_ValueForKey(info, "g_scoreboardpicover"));
mapChecksumStr = Info_ValueForKey(info, "sv_mapChecksum");
if (mapChecksumStr && mapChecksumStr[0]) {
cgs.mapChecksum = atoi(mapChecksumStr);
cgs.mapChecksum = atoi(mapChecksumStr);
cgs.useMapChecksum = qtrue;
} else {
cgs.mapChecksum = 0;
cgs.mapChecksum = 0;
cgs.useMapChecksum = qfalse;
}
@@ -169,7 +187,7 @@ void CG_ParseServerinfo(void)
if (spawnpos) {
Q_strncpyz(map, mapname, spawnpos - mapname + 1);
} else {
strcpy(map, mapname);
Q_strncpyz(map, mapname, sizeof(map));
}
Com_sprintf(cgs.mapname, sizeof(cgs.mapname), "maps/%s.bsp", map);
@@ -296,7 +314,7 @@ static void CG_ServerCommand(qboolean modelOnly)
}
if (!strcmp(cmd, "cs")) {
CG_ConfigStringModified(atoi(cgi.Argv(1)), modelOnly);
CG_ConfigStringModified(cgi.getConfigStringIdNormalized(atoi(cgi.Argv(1))), modelOnly);
return;
}
@@ -311,12 +329,12 @@ static void CG_ServerCommand(qboolean modelOnly)
}
return;
} else if (!strcmp(cmd, "printdeathmsg")) {
const char *s1, *s2, * attackerName, * victimName, *type;
const char *s1, *s2, *attackerName, *victimName, *type;
const char *result1, *result2;
int hudColor;
result1 = NULL;
result2 = NULL;
result1 = NULL;
result2 = NULL;
s1 = cgi.Argv(1);
s2 = cgi.Argv(2);
attackerName = cgi.Argv(3);
@@ -352,7 +370,14 @@ static void CG_ServerCommand(qboolean modelOnly)
}
if (!strcmp(cmd, "stufftext")) {
cgi.Cmd_Stuff(cgi.Argv(1));
char *cmd = cgi.Argv(1);
if (CG_IsStatementFiltered(cmd)) {
// Added in OPM
// Don't execute filtered commands
return;
}
cgi.Cmd_Stuff(cmd);
cgi.Cmd_Stuff("\n");
return;
}
@@ -429,3 +454,233 @@ void CG_ExecuteNewServerCommands(int latestSequence, qboolean differentServer)
}
}
}
//
// List of client variables allowed to be changed by the server
//
static const char *whiteListedVariables[] = {
"r_fastsky", // some mods set this variable to make the sky uniform
"ui_hud",
};
//
// List of client variables allowed to be changed by the server
//
static const char *whiteListedLocalServerVariables[] = {"ui_hidemouse", "ui_showmouse", "cg_marks_add"};
//
// List of commands allowed to be executed by the server
//
static const char *whiteListedCommands[] = {
"primarydmweapon",
"pushmenu",
"pushmenu_teamselect",
"pushmenu_weaponselect",
"popmenu",
"wait",
"globalwidgetcommand", // used for mods adding custom HUDs
"ui_addhud",
"ui_removehud",
"tmstart",
"tmstartloop",
"tmstop",
"tmvolume",
"`stufftext",
"+moveup", // workaround for mods that want to prevent inactivity when handling the spectate
"-moveup",
"screenshot",
"screenshotJPEG",
"levelshot"
};
//
// List of commands allowed to be executed by the server
//
static const char *whiteListedLocalServerCommands[] = {
"spmap", // Used by briefings
"map",
"disconnect",
"cinematic",
"showmenu",
"hidemenu"
};
/*
====================
CG_IsVariableFiltered
Returns whether or not the variable should be filtered
====================
*/
static qboolean CG_IsVariableFiltered(const char *name)
{
cvar_t *var;
size_t i;
for (i = 0; i < ARRAY_LEN(whiteListedVariables); i++) {
if (!Q_stricmp(name, whiteListedVariables[i])) {
return qfalse;
}
}
if (cgs.localServer) {
for (i = 0; i < ARRAY_LEN(whiteListedLocalServerVariables); i++) {
if (!Q_stricmp(name, whiteListedLocalServerVariables[i])) {
return qfalse;
}
}
}
// Filtered
return qtrue;
}
/*
====================
CG_IsSetVariableFiltered
Returns whether or not the variable should be filtered
====================
*/
static qboolean CG_IsSetVariableFiltered(const char *name, char type)
{
cvar_t *var;
if (!CG_IsVariableFiltered(name)) {
return qfalse;
}
if (type != 'u' && type != 's') {
// Don't allow custom info variables to avoid flooding
// the client with many serverinfo and userinfo variables
var = cgi.Cvar_Find(name);
if (!var) {
// Allow as it doesn't exist
return qfalse;
}
if (var->flags & CVAR_USER_CREATED) {
// Allow, it's user-created, wouldn't cause issues
return qfalse;
}
}
// Filtered
return qtrue;
}
/*
====================
CG_IsCommandFiltered
Returns whether or not the variable should be filtered
====================
*/
static qboolean CG_IsCommandFiltered(const char *name)
{
size_t i;
for (i = 0; i < ARRAY_LEN(whiteListedCommands); i++) {
if (!Q_stricmp(name, whiteListedCommands[i])) {
return qfalse;
}
}
if (cgs.localServer) {
// Allow more commands when the client is hosting the server
// Mostly used on single-player mode, like when briefings switch to the next map
for (i = 0; i < ARRAY_LEN(whiteListedLocalServerCommands); i++) {
if (!Q_stricmp(name, whiteListedLocalServerCommands[i])) {
return qfalse;
}
}
}
//
// Test variables
//
return CG_IsVariableFiltered(name);
}
/*
====================
RemoveEndToken
====================
*/
static qboolean RemoveEndToken(char* com_token) {
char* p;
for (p = com_token; p[0]; p++) {
if (*p == ';') {
*p = 0;
return qtrue;
}
}
return qfalse;
}
/*
====================
CG_IsStatementFiltered
Returns whether or not the statement is filtered
====================
*/
static qboolean CG_IsStatementFiltered(char *cmd)
{
char* parsed;
char* p;
char com_token[256];
qboolean bNextStatement = qfalse;
parsed = cmd;
for (Q_strncpyz(com_token, COM_ParseExt(&parsed, qtrue), sizeof(com_token)); com_token[0]; Q_strncpyz(com_token, COM_ParseExt(&parsed, qtrue), sizeof(com_token))) {
bNextStatement = RemoveEndToken(com_token);
if (com_token[0] == ';') {
continue;
}
if (!Q_stricmp(com_token, "set") || !Q_stricmp(com_token, "setu") || !Q_stricmp(com_token, "seta")
|| !Q_stricmp(com_token, "sets")) {
char type = com_token[3];
//
// variable
//
Q_strncpyz(com_token, COM_ParseExt(&parsed, qfalse), sizeof(com_token));
bNextStatement |= RemoveEndToken(com_token);
if (com_token[0] == ';') {
continue;
}
if (CG_IsSetVariableFiltered(com_token, type)) {
return qtrue;
}
} else {
//
// normal command
//
if (CG_IsCommandFiltered(com_token)) {
return qtrue;
}
}
if (!bNextStatement) {
// Skip up to the next statement
while (parsed && parsed[0]) {
char c = parsed[0];
parsed++;
if (c == '\n' || c == ';') {
break;
}
}
}
}
return qfalse;
}
+9 -6
View File
@@ -73,10 +73,10 @@ static void CG_ResetEntity(centity_t *cent)
CG_RemoveClientEntity(cent->currentState.number, tiki, cent);
// reset the animation for the entities
if (tiki && tiki->a->bIsCharacter) {
if (tiki) {
for (i = 0; i < MAX_FRAMEINFOS; i++) {
cent->animLast[i] = cent->currentState.frameInfo[i].index;
cent->animLastTimes[i] = cent->currentState.frameInfo[i].time;
cent->animLast[i] = -1;
cent->animLastTimes[i] = -1;
if (cent->currentState.frameInfo[i].weight) {
cent->animLastWeight |= 1 << i;
} else {
@@ -87,7 +87,8 @@ static void CG_ResetEntity(centity_t *cent)
} else {
// clear all the last animations
for (i = 0; i < MAX_FRAMEINFOS; i++) {
cent->animLast[i] = -1;
cent->animLast[i] = -1;
cent->animLastTimes[i] = 0.0;
}
cent->animLastWeight = 0;
@@ -346,8 +347,10 @@ static snapshot_t *CG_ReadNextSnapshot(void)
snapshot_t *dest;
if (cg.latestSnapshotNum > cgs.processedSnapshotNum + 1000) {
cgi.Error(
ERR_DROP, "CG_ReadNextSnapshot: way out of range, %i > %i", cg.latestSnapshotNum, cgs.processedSnapshotNum
cgi.Printf(
"WARNING: CG_ReadNextSnapshot: way out of range, %i > %i\n",
cg.latestSnapshotNum,
cgs.processedSnapshotNum
);
}
+178 -7
View File
@@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2023 the OpenMoHAA team
Copyright (C) 2024 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@@ -38,7 +38,8 @@ static vec3_t g_vLadderstepMaxs;
ClientSpecialEffectsManager sfxManager;
Event EV_SFX_EffectDelay(
Event EV_SFX_EffectDelay
(
"effectdelay",
EV_DEFAULT,
"iivvvvv",
@@ -94,7 +95,7 @@ void ClientSpecialEffectsManager::LoadEffects()
cgi.DPrintf("Loading Special Effects...\n");
AxisClear(axis);
for (i = 0; i < MAX_SPECIAL_EFFECTS; i++) {
for (i = 0; i < SFX_COUNT; i++) {
switch (i) {
case SFX_BHIT_PAPER_LITE:
szEffectModel = "models/fx/bh_paper_lite.tik";
@@ -234,9 +235,15 @@ void ClientSpecialEffectsManager::LoadEffects()
szEffectModel = "models/fx/bazookaexp_base.tik";
break;
case SFX_EXP_HEAVYSHELL_BASE:
if (cg_protocol < protocol_e::PROTOCOL_MOHTA_MIN) {
continue;
}
szEffectModel = "models/fx/heavyshellexp_base.tik";
break;
case SFX_EXP_TANK_BASE:
if (cg_protocol < protocol_e::PROTOCOL_MOHTA_MIN) {
continue;
}
szEffectModel = "models/fx/tankexp_base.tik";
break;
case SFX_EXP_GREN_PAPER:
@@ -285,30 +292,57 @@ void ClientSpecialEffectsManager::LoadEffects()
szEffectModel = "models/fx/grenexp_carpet.tik";
break;
case SFX_EXP_HEAVYSHELL_DIRT:
if (cg_protocol < protocol_e::PROTOCOL_MOHTA_MIN) {
continue;
}
szEffectModel = "models/fx/heavyshellexp_dirt.tik";
break;
case SFX_EXP_HEAVYSHELL_STONE:
if (cg_protocol < protocol_e::PROTOCOL_MOHTA_MIN) {
continue;
}
szEffectModel = "models/fx/heavyshellexp_stone.tik";
break;
case SFX_EXP_HEAVYSHELL_SNOW:
if (cg_protocol < protocol_e::PROTOCOL_MOHTA_MIN) {
continue;
}
szEffectModel = "models/fx/heavyshellexp_snow.tik";
break;
case SFX_EXP_TANK_DIRT:
if (cg_protocol < protocol_e::PROTOCOL_MOHTA_MIN) {
continue;
}
szEffectModel = "models/fx/tankexp_dirt.tik";
break;
case SFX_EXP_TANK_STONE:
if (cg_protocol < protocol_e::PROTOCOL_MOHTA_MIN) {
continue;
}
szEffectModel = "models/fx/tankexp_stone.tik";
break;
case SFX_EXP_TANK_SNOW:
if (cg_protocol < protocol_e::PROTOCOL_MOHTA_MIN) {
continue;
}
szEffectModel = "models/fx/tankexp_snow.tik";
break;
case SFX_EXP_BAZOOKA_DIRT:
if (cg_protocol < protocol_e::PROTOCOL_MOHTA_MIN) {
continue;
}
szEffectModel = "models/fx/bazookaexp_dirt.tik";
break;
case SFX_EXP_BAZOOKA_STONE:
if (cg_protocol < protocol_e::PROTOCOL_MOHTA_MIN) {
continue;
}
szEffectModel = "models/fx/bazookaexp_stone.tik";
break;
case SFX_EXP_BAZOOKA_SNOW:
if (cg_protocol < protocol_e::PROTOCOL_MOHTA_MIN) {
continue;
}
szEffectModel = "models/fx/bazookaexp_snow.tik";
break;
case SFX_WATER_RIPPLE_STILL:
@@ -478,7 +512,7 @@ void ClientSpecialEffectsManager::ExecuteEffect(
current_tiki = NULL;
pCommand->emitter->cgd.origin = vPos;
if (pCommand->emitter->cgd.flags & T_ANGLES) {
if (!(pCommand->emitter->cgd.flags & T_ANGLES)) {
pCommand->emitter->cgd.angles = vAngles;
}
@@ -486,7 +520,7 @@ void ClientSpecialEffectsManager::ExecuteEffect(
AxisCopy(axis, pCommand->emitter->tag_axis);
pCommand->emitter->cgd.createTime = cg.time;
commandManager.SetSpawnthing(pCommand->emitter);
(commandManager.*pCommand->endfcn)();
}
}
@@ -904,7 +938,144 @@ void CG_LandingSound(centity_t *ent, refEntity_t *pREnt, float volume, int iEqui
void CG_BodyFallSound(centity_t *ent, refEntity_t *pREnt, float volume)
{
// FIXME: unimplemented
int contents;
int surftype;
int iEffectNum = -1;
vec3_t vStart, vEnd;
vec3_t midlegs;
str sSoundName;
trace_t trace;
VectorCopy(ent->lerpOrigin, vStart);
vStart[2] += 8;
VectorCopy(vStart, vEnd);
vEnd[2] -= 64;
if (ent->currentState.eType == ET_PLAYER) {
CG_Trace(
&trace,
vStart,
g_vFootstepMins,
g_vFootstepMaxs,
vEnd,
ent->currentState.number,
MASK_PLAYERSOLID,
qtrue,
qtrue,
"Player Landing"
);
} else {
CG_Trace(
&trace,
vStart,
g_vFootstepMins,
g_vFootstepMaxs,
vEnd,
ent->currentState.number,
MASK_MONSTERSOLID,
qfalse,
qfalse,
"Monster Landing"
);
}
if (trace.fraction == 1) {
return;
}
sSoundName = "snd_bodyfall_";
contents = CG_PointContents(trace.endpos, -1);
if (contents & MASK_WATER) {
// take our ground position and trace upwards
VectorCopy(trace.endpos, midlegs);
midlegs[2] += WATER_NO_SPLASH_HEIGHT;
contents = CG_PointContents(midlegs, -1);
if (contents & MASK_WATER) {
sSoundName += "wade";
} else {
sSoundName += "puddle";
iEffectNum = SFX_FOOT_PUDDLE;
}
} else {
surftype = trace.surfaceFlags & MASK_SURF_TYPE;
switch (surftype) {
case SURF_FOLIAGE:
sSoundName += "foliage";
iEffectNum = SFX_FOOT_GRASS;
break;
case SURF_SNOW:
sSoundName += "snow";
iEffectNum = SFX_FOOT_SNOW;
break;
case SURF_CARPET:
sSoundName += "carpet";
iEffectNum = SFX_FOOT_LIGHT_DUST;
break;
case SURF_SAND:
sSoundName += "sand";
iEffectNum = SFX_FOOT_SAND;
break;
case SURF_PUDDLE:
sSoundName += "puddle";
iEffectNum = SFX_FOOT_PUDDLE;
break;
case SURF_GLASS:
sSoundName += "glass";
iEffectNum = SFX_FOOT_LIGHT_DUST;
break;
case SURF_GRAVEL:
sSoundName += "gravel";
iEffectNum = SFX_FOOT_HEAVY_DUST;
break;
case SURF_MUD:
sSoundName += "mud";
iEffectNum = SFX_FOOT_MUD;
break;
case SURF_DIRT:
sSoundName += "dirt";
iEffectNum = SFX_FOOT_DIRT;
break;
case SURF_GRILL:
sSoundName += "grill";
iEffectNum = SFX_FOOT_LIGHT_DUST;
break;
case SURF_GRASS:
sSoundName += "grass";
iEffectNum = SFX_FOOT_GRASS;
break;
case SURF_ROCK:
sSoundName += "stone";
iEffectNum = SFX_FOOT_HEAVY_DUST;
break;
case SURF_PAPER:
sSoundName += "paper";
iEffectNum = SFX_FOOT_LIGHT_DUST;
break;
case SURF_WOOD:
sSoundName += "wood";
iEffectNum = SFX_FOOT_LIGHT_DUST;
break;
case SURF_METAL:
sSoundName += "metal";
iEffectNum = SFX_FOOT_LIGHT_DUST;
break;
default:
sSoundName += "stone";
iEffectNum = SFX_FOOT_HEAVY_DUST;
break;
}
}
if (cg_debugFootsteps->integer) {
cgi.DPrintf("BodyFall: %s volume: %.2f effect = %i\n", sSoundName.c_str(), volume, iEffectNum);
}
commandManager.PlaySound(sSoundName, trace.endpos, -1, volume, -1, -1, 1);
if (iEffectNum != -1) {
sfxManager.MakeEffect_Angles(iEffectNum, trace.endpos, Vector(270, 0, 0));
}
}
/*
@@ -1023,5 +1194,5 @@ qboolean ClientSpecialEffectsManager::EffectsPending()
specialeffect_t *ClientSpecialEffectsManager::GetTestEffectPointer()
{
return &m_effects[SPECIAL_EFFECT_TEST];
return &m_effects[SFX_TEST_EFFECT];
}
+1 -4
View File
@@ -170,12 +170,9 @@ public:
specialeffectcommand_t *AddNewCommand();
};
#define MAX_SPECIAL_EFFECTS 99
#define SPECIAL_EFFECT_TEST MAX_SPECIAL_EFFECTS - 1
class ClientSpecialEffectsManager : public Listener
{
specialeffect_t m_effects[99];
specialeffect_t m_effects[SFX_COUNT];
qboolean m_bEffectsLoaded;
int m_iNumPendingEvents;
+96 -25
View File
@@ -79,6 +79,11 @@ void ClientGameCommandManager::FreeTempModel(ctempmodel_t *p)
RemoveClientEntity(p->number, p->cgd.tiki, NULL, p);
if (m_active_tempmodels.next == p) {
// use the next active temp model
m_active_tempmodels.next = p->next;
}
// remove from the doubly linked active list
p->prev->next = p->next;
p->next->prev = p->prev;
@@ -86,6 +91,22 @@ void ClientGameCommandManager::FreeTempModel(ctempmodel_t *p)
// the free list is only singly linked
p->next = m_free_tempmodels;
m_free_tempmodels = p;
if (p->m_spawnthing) {
p->m_spawnthing->numtempmodels--;
// delete unused spawnthings
if (!p->m_spawnthing->numtempmodels) {
m_emitters.RemoveObject(p->m_spawnthing);
if (p->m_spawnthing == m_spawnthing) {
m_spawnthing = NULL;
}
delete p->m_spawnthing;
}
p->m_spawnthing = NULL;
}
}
//===============
@@ -418,9 +439,11 @@ qboolean ClientGameCommandManager::TempModelRealtimeEffects(ctempmodel_t *p, flo
p->ent.shaderRGBA[0] = (int)((float)tempColor[0] * vLighting[0]);
p->ent.shaderRGBA[1] = (int)((float)tempColor[1] * vLighting[1]);
p->ent.shaderRGBA[2] = (int)((float)tempColor[2] * vLighting[2]);
} else {
p->ent.shaderRGBA[0] = tempColor[0];
p->ent.shaderRGBA[1] = tempColor[1];
p->ent.shaderRGBA[2] = tempColor[2];
}
if (p->cgd.flags & T_FADEIN && (fadein < 1)) // Do the fadein effect
@@ -518,6 +541,7 @@ qboolean ClientGameCommandManager::TempModelPhysics(ctempmodel_t *p, float ftime
Vector tempangles;
trace_t trace;
float dot;
int i;
VectorCopy(p->ent.origin, p->lastEnt.origin);
AxisCopy(p->ent.axis, p->lastEnt.axis);
@@ -633,9 +657,7 @@ qboolean ClientGameCommandManager::TempModelPhysics(ctempmodel_t *p, float ftime
p->cgd.velocity.x = Q_clamp_float(p->cgd.velocity.x, p->cgd.minVel.x, p->cgd.maxVel.x);
p->cgd.velocity.y = Q_clamp_float(p->cgd.velocity.y, p->cgd.minVel.y, p->cgd.maxVel.y);
p->cgd.velocity.z = Q_clamp_float(p->cgd.velocity.z, p->cgd.minVel.z, p->cgd.maxVel.z);
}
if (p->cgd.flags2 & T2_CLAMP_VEL_AXIS) {
} else if (p->cgd.flags2 & T2_CLAMP_VEL_AXIS) {
Vector localVelocity;
localVelocity.x = DotProduct(p->cgd.velocity, p->ent.axis[0]);
localVelocity.y = DotProduct(p->cgd.velocity, p->ent.axis[1]);
@@ -650,8 +672,48 @@ qboolean ClientGameCommandManager::TempModelPhysics(ctempmodel_t *p, float ftime
p->cgd.velocity.z = DotProduct(localVelocity, p->ent.axis[2]);
}
if (p->cgd.flags2 & T_ALIGN) {
// FIXME: vss wind
if (p->cgd.flags2 & T2_WIND_AFFECT) {
for (i = 0; i < 3; i++) {
float fWind;
switch (i) {
case 0:
fWind = vss_wind_x->value;
break;
case 1:
fWind = vss_wind_y->value;
break;
case 2:
fWind = vss_wind_z->value;
break;
}
if (fWind < 0) {
if (p->cgd.velocity[i] > fWind) {
p->cgd.velocity[i] -= ftime * vss_wind_strength->value;
if (p->cgd.velocity[i] > fWind) {
p->cgd.velocity[i] = fWind;
}
} else if (p->cgd.velocity[i] < fWind) {
p->cgd.velocity[i] += ftime * vss_movement_dampen->value;
if (p->cgd.velocity[i] < fWind) {
p->cgd.velocity[i] = fWind;
}
}
} else {
if (p->cgd.velocity[i] < fWind) {
p->cgd.velocity[i] += ftime * vss_wind_strength->value;
if (p->cgd.velocity[i] > fWind) {
p->cgd.velocity[i] = fWind;
}
} else if (p->cgd.velocity[i] > fWind) {
p->cgd.velocity[i] -= ftime * vss_wind_strength->value;
if (p->cgd.velocity[i] < fWind) {
p->cgd.velocity[i] = fWind;
}
}
}
}
}
} else {
Vector normal;
@@ -913,7 +975,12 @@ void ClientGameCommandManager::AddTempModels(void)
// time of this tempmodel
lerpfrac = (float)(cg.time - p->lastPhysicsTime) / (float)physics_rate;
// Clamp
lerpfrac = Q_clamp_float(lerpfrac, 0, 1);
if (lerpfrac > 1 || (p->cgd.flags2 & T2_PHYSICS_EVERYFRAME)) {
lerpfrac = 1;
}
if (lerpfrac < 0) {
lerpfrac = 0;
}
// Increment the time this tempmodel has been alive
p->aliveTime += frameTime;
@@ -1137,7 +1204,13 @@ void ClientGameCommandManager::SpawnTempModel(int mcount)
{
Vector dst;
// Create a circular shaped burst around the up vector
float angle = ((float)count / (float)m_spawnthing->count) * 360; // * M_PI * 2;
float angle;
if (mcount == 1) {
angle = random() * 360;
} else {
angle = ((float)count / (float)m_spawnthing->count) * 360; // * M_PI * 2;
}
Vector end = Vector(vLeft) * m_spawnthing->sphereRadius * current_entity_scale;
RotatePointAroundVector(dst, Vector(vForward), end, angle);
@@ -1146,7 +1219,7 @@ void ClientGameCommandManager::SpawnTempModel(int mcount)
newForward = p->cgd.origin - m_spawnthing->cgd.origin;
newForward.normalize();
}
} else if (m_spawnthing->cgd.flags & T_SPHERE) {
} else if (m_spawnthing->cgd.flags & T_INWARDSPHERE) {
// Project the origin along a random ray, and set the forward
// vector pointing back to the origin
Vector dir, end;
@@ -1182,10 +1255,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());
@@ -1391,7 +1463,7 @@ void ClientGameCommandManager::SpawnTempModel(int mcount)
p->cgd.avelocity[i] = m_spawnthing->avelocity_amplitude[i] * random() + m_spawnthing->avelocity_base[i];
// Randomize angles or set absolute
p->cgd.angles[i] += random() * m_spawnthing->angles_amplitude[i];
p->cgd.angles[i] = m_spawnthing->angles_amplitude[i] * random() + m_spawnthing->cgd.angles[i];
}
// If forward velocity is set, just use that otherwise use random
@@ -1425,18 +1497,15 @@ void ClientGameCommandManager::SpawnTempModel(int mcount)
}
}
// Calculate one tick of velocity based on time alive ( passed in )
p->cgd.origin = p->cgd.origin + (p->cgd.velocity * ((float)p->aliveTime / 1000.0f) * current_entity_scale);
if (p->cgd.flags2 & T2_ACCEL) {
if (m_spawnthing->cgd.flags2 & T2_RADIALVELOCITY) {
float fLength;
p->cgd.velocity = p->cgd.origin - start;
fLength = p->cgd.velocity.length();
if (fLength) {
float fVel = m_spawnthing->cgd.velocity.x
+ (m_spawnthing->cgd.velocity.y + m_spawnthing->cgd.velocity.z * crandom()) / fLength;
float fVel = m_spawnthing->cgd.velocity[0]
+ (m_spawnthing->cgd.velocity[1] + m_spawnthing->cgd.velocity[2] * random()) / fLength;
p->cgd.velocity *= fVel;
}
@@ -1447,20 +1516,22 @@ void ClientGameCommandManager::SpawnTempModel(int mcount)
(m_spawnthing->randvel_base[i] + m_spawnthing->randvel_amplitude[i] * random()) * current_entity_scale;
if (m_spawnthing->cgd.flags & T_RANDVELAXIS) {
p->cgd.velocity += fVel * Vector(m_spawnthing->tag_axis[i]);
if (p->cgd.flags2 & T2_NOTAGAXIS) {
p->cgd.velocity += fVel * Vector(m_spawnthing->axis[i]);
} else {
p->cgd.velocity += fVel * Vector(m_spawnthing->tag_axis[i]);
}
} else {
p->cgd.velocity[i] += fVel;
}
}
if (p->cgd.flags & (T_ALIGN | T_DETAIL)) {
if (p->cgd.velocity.x && p->cgd.velocity.y) {
p->cgd.angles = p->cgd.velocity.toAngles();
}
p->cgd.origin += p->cgd.velocity * (p->aliveTime / 1000.0) * current_entity_scale;
p->cgd.angles = p->cgd.velocity.toAngles();
}
p->cgd.origin += p->cgd.velocity * (p->aliveTime / 1000.0) * current_entity_scale;
if (p->cgd.flags & T_AUTOCALCLIFE) {
Vector end, delta;
float length, speed;
File diff suppressed because it is too large. Load diff
+34 -5
View File
@@ -25,6 +25,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "cg_local.h"
#include "str.h"
#include "../client/keycodes.h"
void CG_MessageMode_f(void)
{
@@ -61,8 +62,8 @@ void CG_MessageMode_Private_f(void)
return;
}
clientNum = atoi(cgi.Argv(1)) - 1;
if (clientNum < 0 || clientNum >= MAX_CLIENTS) {
clientNum = atoi(cgi.Argv(1));
if (clientNum < 1 || clientNum >= MAX_CLIENTS) {
cgi.Printf(HUD_MESSAGE_CHAT_WHITE "Message Error: %s is a bad client number\n", cgi.Argv(1));
return;
}
@@ -192,8 +193,36 @@ void CG_HudPrint_f(void)
cgi.Printf("\x1%s", cgi.Argv(1));
}
int CG_CheckCaptureKey(int key, qboolean down, unsigned int time)
qboolean CG_CheckCaptureKey(int key, qboolean down, unsigned int time)
{
// FIXME: unimplemented
return 0;
char minKey = '1', maxKey = '9';
if (!cg.iInstaMessageMenu || !down) {
return qfalse;
}
if (cg_protocol >= protocol_e::PROTOCOL_MOHTA_MIN) {
maxKey = '8';
}
if (key < minKey || key > maxKey) {
if (key == K_ESCAPE || key == '0') {
cg.iInstaMessageMenu = 0;
return qtrue;
}
return qfalse;
}
if (cg.iInstaMessageMenu == -1) {
if (key > '6') {
cg.iInstaMessageMenu = 0;
} else {
cg.iInstaMessageMenu = key - '0';
}
} else if (cg.iInstaMessageMenu > 0) {
cgi.SendClientCommand(va("dmmessage 0 *%i%i\n", cg.iInstaMessageMenu, key - '0'));
cg.iInstaMessageMenu = 0;
}
return qtrue;
}
+51 -22
View File
@@ -242,6 +242,7 @@ void CG_OffsetFirstPersonView(refEntity_t *pREnt, qboolean bUseWorldPosition)
float mat[3][3];
vec3_t vOldOrigin;
vec3_t vStart, vEnd, vMins, vMaxs;
vec3_t vVelocity;
trace_t trace;
VectorSet(vMins, -6, -6, -6);
@@ -297,6 +298,15 @@ void CG_OffsetFirstPersonView(refEntity_t *pREnt, qboolean bUseWorldPosition)
VectorCopy(origin, vOldOrigin);
if (!cg.predicted_player_state.walking || !(cg.predicted_player_state.pm_flags & PMF_FROZEN)) {
VectorCopy(cg.predicted_player_state.velocity, vVelocity);
} else {
//
// Added in OPM
// When frozen, there must be no movement at all
VectorClear(vVelocity);
}
if (bUseWorldPosition) {
iMask = MASK_VIEWSOLID;
} else {
@@ -367,7 +377,7 @@ void CG_OffsetFirstPersonView(refEntity_t *pREnt, qboolean bUseWorldPosition)
}
if (cg.predicted_player_state.walking) {
fVel = VectorLength(cg.predicted_player_state.velocity);
fVel = VectorLength(vVelocity);
fPhase = fVel * 0.0015 + 0.9;
cg.fCurrentViewBobPhase += (cg.frametime / 1000.0 + cg.frametime / 1000.0) * M_PI * fPhase;
@@ -446,7 +456,7 @@ void CG_OffsetFirstPersonView(refEntity_t *pREnt, qboolean bUseWorldPosition)
AngleVectorsLeft(vDelta, mat[0], mat[1], mat[2]);
CG_CalcViewModelMovement(
cg.fCurrentViewBobPhase, cg.fCurrentViewBobAmp, cg.predicted_player_state.velocity, vDelta
cg.fCurrentViewBobPhase, cg.fCurrentViewBobAmp, vVelocity, vDelta
);
VectorMA(pREnt->origin, vDelta[0], mat[0], pREnt->origin);
@@ -560,17 +570,6 @@ static int CG_CalcViewValues(void)
CG_CalcVrect();
CG_SetupFog();
// setup fog and far clipping plane
cg.refdef.farplane_distance = cg.farplane_distance;
VectorCopy(cg.farplane_color, cg.refdef.farplane_color);
cg.refdef.farplane_cull = cg.farplane_cull;
// setup portal sky
cg.refdef.sky_alpha = cg.sky_alpha;
cg.refdef.sky_portal = cg.sky_portal;
memcpy(cg.refdef.sky_axis, cg.sky_axis, sizeof(cg.sky_axis));
VectorCopy(cg.sky_origin, cg.refdef.sky_origin);
ps = &cg.predicted_player_state;
VectorCopy(ps->origin, cg.refdef.vieworg);
@@ -723,7 +722,37 @@ float CG_SensitivityScale()
void CG_AddLightShow()
{
// FIXME: unimplemented
int i;
float fSlopeY, fSlopeZ;
float x, y, z;
vec3_t vOrg;
float r, g, b;
float fMax;
fSlopeY = tan(cg.refdef.fov_x * 0.5);
fSlopeZ = tan(cg.refdef.fov_y * 0.5);
for (i = 0; i < cg_acidtrip->integer; i++) {
x = pow(random(), 1.0 / 3.0) * 2048.0;
y = crandom() * x * fSlopeY;
z = crandom() * x * fSlopeZ;
VectorCopy(cg.refdef.vieworg, vOrg);
VectorMA(vOrg, x, cg.refdef.viewaxis[0], vOrg);
VectorMA(vOrg, y, cg.refdef.viewaxis[1], vOrg);
VectorMA(vOrg, z, cg.refdef.viewaxis[2], vOrg);
r = random();
g = random();
b = random();
fMax = Q_max(r, Q_max(g, b));
r /= fMax;
g /= fMax;
b /= fMax;
cgi.R_AddLightToScene(vOrg, (rand() & 0x1FF) + 0x80, r, g, b, 0);
}
}
qboolean CG_FrustumCullSphere(const vec3_t vPos, float fRadius) {
@@ -882,13 +911,13 @@ void CG_DrawActiveFrame(int serverTime, int frameTime, stereoFrame_t stereoView,
{
default:
case 0:
cgi.UI_HideMenu("mission_success_1", CVAR_ARCHIVE);
cgi.UI_HideMenu("mission_success_1", qtrue);
break;
case 2:
cgi.UI_HideMenu("mission_success_2", CVAR_ARCHIVE);
cgi.UI_HideMenu("mission_success_2", qtrue);
break;
case 3:
cgi.UI_HideMenu("mission_success_3", CVAR_ARCHIVE);
cgi.UI_HideMenu("mission_success_3", qtrue);
break;
}
} else {
@@ -896,21 +925,21 @@ void CG_DrawActiveFrame(int serverTime, int frameTime, stereoFrame_t stereoView,
{
default:
case 0:
cgi.UI_HideMenu("mission_failed_1", CVAR_ARCHIVE);
cgi.UI_HideMenu("mission_failed_1", qtrue);
break;
case 2:
cgi.UI_HideMenu("mission_failed_2", CVAR_ARCHIVE);
cgi.UI_HideMenu("mission_failed_2", qtrue);
break;
case 3:
cgi.UI_HideMenu("mission_failed_3", CVAR_ARCHIVE);
cgi.UI_HideMenu("mission_failed_3", qtrue);
break;
}
}
} else {
if (cgi.Cvar_Get("g_success", "", 0)->integer) {
cgi.UI_HideMenu("StatsScreen_Success", qfalse);
cgi.UI_HideMenu("StatsScreen_Success", qtrue);
} else {
cgi.UI_HideMenu("StatsScreen_Failed", qfalse);
cgi.UI_HideMenu("StatsScreen_Failed", qtrue);
}
}
}
+51 -23
View File
@@ -28,6 +28,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
static const char *AnimPrefixList[] = {
"",
"unarmed",
"papers",
"colt45",
"p38",
@@ -45,7 +46,6 @@ static const char *AnimPrefixList[] = {
"bazooka",
"panzerschreck",
"shotgun",
"unarmed",
//
// Team Assault and Team Tactics weapons
"mg42portable",
@@ -82,6 +82,7 @@ static const char *AnimPrefixList[] = {
enum animPrefix_e {
WPREFIX_NONE,
WPREFIX_UNARMED,
WPREFIX_PAPERS,
WPREFIX_COLT45,
WPREFIX_P38,
@@ -99,7 +100,6 @@ enum animPrefix_e {
WPREFIX_BAZOOKA,
WPREFIX_PANZERSCHRECK,
WPREFIX_SHOTGUN,
WPREFIX_UNARMED,
//
// Team Assault and Team Tactics weapons
WPREFIX_MG42_PORTABLE,
@@ -308,6 +308,9 @@ int CG_GetVMAnimPrefixIndex()
if (!Q_stricmp(szWeaponName, "Panzerschreck")) {
return WPREFIX_PANZERSCHRECK;
}
if (!Q_stricmp(szWeaponName, "Gewehrgranate")) {
return WPREFIX_KAR98_MORTAR;
}
if (!Q_stricmp(szWeaponName, "Shotgun")) {
return WPREFIX_SHOTGUN;
}
@@ -335,9 +338,11 @@ void CG_ViewModelAnimation(refEntity_t *pModel)
char szAnimName[MAX_QPATH];
dtiki_t *pTiki;
qboolean bAnimChanged;
qboolean bWeaponChanged;
fCrossblendFrac = 0.0;
bAnimChanged = 0;
bAnimChanged = qfalse;
bWeaponChanged = qfalse; // Added in OPM
pTiki = pModel->tiki;
if (cgi.anim->g_iLastEquippedWeaponStat == cg.snap->ps.stats[STAT_EQUIPPED_WEAPON]
@@ -346,13 +351,15 @@ void CG_ViewModelAnimation(refEntity_t *pModel)
} else {
iAnimPrefixIndex = CG_GetVMAnimPrefixIndex();
cgi.anim->g_iLastEquippedWeaponStat = cg.snap->ps.stats[STAT_EQUIPPED_WEAPON];
strcpy(cgi.anim->g_szLastActiveItem, CG_ConfigString(CS_WEAPONS + cg.snap->ps.activeItems[1]));
Q_strncpyz(cgi.anim->g_szLastActiveItem, CG_ConfigString(CS_WEAPONS + cg.snap->ps.activeItems[1]), sizeof(cgi.anim->g_szLastActiveItem));
cgi.anim->g_iLastAnimPrefixIndex = iAnimPrefixIndex;
bAnimChanged = qtrue;
bAnimChanged = qtrue;
bWeaponChanged = qtrue;
}
if (cgi.anim->g_iLastVMAnim == -1) {
sprintf(szAnimName, "%s_idle", AnimPrefixList[iAnimPrefixIndex]);
Com_sprintf(szAnimName, sizeof(szAnimName), "%s_idle", AnimPrefixList[iAnimPrefixIndex]);
cgi.anim->g_VMFrameInfo[cgi.anim->g_iCurrentVMAnimSlot].index = cgi.Anim_NumForName(pTiki, szAnimName);
if (cgi.anim->g_VMFrameInfo[cgi.anim->g_iCurrentVMAnimSlot].index == -1) {
@@ -421,21 +428,28 @@ void CG_ViewModelAnimation(refEntity_t *pModel)
break;
}
sprintf(szAnimName, "%s_%s", AnimPrefixList[iAnimPrefixIndex], pszAnimSuffix);
fCrossblendTime = cgi.Anim_CrossblendTime(pTiki, cgi.anim->g_VMFrameInfo[cgi.anim->g_iCurrentVMAnimSlot].index);
fCrossblendAmount = cgi.anim->g_iCurrentVMDuration / 1000.0;
Com_sprintf(szAnimName, sizeof(szAnimName), "%s_%s", AnimPrefixList[iAnimPrefixIndex], pszAnimSuffix);
if (!bWeaponChanged) {
fCrossblendTime =
cgi.Anim_CrossblendTime(pTiki, cgi.anim->g_VMFrameInfo[cgi.anim->g_iCurrentVMAnimSlot].index);
fCrossblendAmount = cgi.anim->g_iCurrentVMDuration / 1000.0;
if (fCrossblendAmount < fCrossblendTime && fCrossblendAmount > 0.0) {
fCrossblendFrac = fCrossblendAmount / fCrossblendTime;
for (i = 0; i < MAX_FRAMEINFOS; ++i) {
if (cgi.anim->g_VMFrameInfo[i].weight) {
if (i == cgi.anim->g_iCurrentVMAnimSlot) {
cgi.anim->g_VMFrameInfo[i].weight = fCrossblendFrac;
} else {
cgi.anim->g_VMFrameInfo[i].weight *= (1.0 - fCrossblendFrac);
if (fCrossblendAmount < fCrossblendTime && fCrossblendAmount > 0.0) {
fCrossblendFrac = fCrossblendAmount / fCrossblendTime;
for (i = 0; i < MAX_FRAMEINFOS; ++i) {
if (cgi.anim->g_VMFrameInfo[i].weight) {
if (i == cgi.anim->g_iCurrentVMAnimSlot) {
cgi.anim->g_VMFrameInfo[i].weight = fCrossblendFrac;
} else {
cgi.anim->g_VMFrameInfo[i].weight *= (1.0 - fCrossblendFrac);
}
}
}
}
} else {
fCrossblendTime = 0;
fCrossblendAmount = 0;
fCrossblendFrac = 0;
}
cgi.anim->g_iCurrentVMAnimSlot = (cgi.anim->g_iCurrentVMAnimSlot + 1) % MAX_FRAMEINFOS;
@@ -450,17 +464,31 @@ void CG_ViewModelAnimation(refEntity_t *pModel)
cgi.anim->g_VMFrameInfo[cgi.anim->g_iCurrentVMAnimSlot].weight = 1.0;
cgi.anim->g_iCurrentVMDuration = 0;
fCrossblendTime = cgi.Anim_CrossblendTime(pTiki, cgi.anim->g_VMFrameInfo[cgi.anim->g_iCurrentVMAnimSlot].index);
if (!fCrossblendTime) {
if (!bWeaponChanged) {
fCrossblendTime =
cgi.Anim_CrossblendTime(pTiki, cgi.anim->g_VMFrameInfo[cgi.anim->g_iCurrentVMAnimSlot].index);
if (!fCrossblendTime) {
for (i = 0; i < MAX_FRAMEINFOS; ++i) {
if (i != cgi.anim->g_iCurrentVMAnimSlot) {
cgi.anim->g_VMFrameInfo[i].weight = 0.0;
}
}
cgi.anim->g_bCrossblending = qfalse;
} else {
cgi.anim->g_bCrossblending = qtrue;
}
} else {
// Added in OPM
// If there is a new weapon, don't do any crossblend
cgi.anim->g_bCrossblending = qfalse;
// clear crossblend values
for (i = 0; i < MAX_FRAMEINFOS; ++i) {
if (i != cgi.anim->g_iCurrentVMAnimSlot) {
cgi.anim->g_VMFrameInfo[i].weight = 0.0;
}
}
cgi.anim->g_bCrossblending = qfalse;
} else {
cgi.anim->g_bCrossblending = qtrue;
}
}
+313 -320
View File
@@ -42,7 +42,9 @@ const char *cg_vsstypes[] = {
"debris"
};
cvssource_t *vss_sorttable[16384];
#define MAX_VSS_SORTS 16384
cvssource_t *vss_sorttable[MAX_VSS_SORTS];
static int lastVSSFrameTime;
static constexpr float MAX_VSS_COORDS = 8096.0;
@@ -78,56 +80,57 @@ void VSS_AddRepulsion(cvssource_t *pA, cvssource_t *pB)
VectorSubtract(pA->newOrigin, pB->newOrigin, vPush);
if (vPush[0] || vPush[1] || vPush[2]) {
fDist = VectorNormalize(vPush);
f = fDist - pB->newRadius;
if (f > 0.0) {
f *= pA->ooRadius;
if (f > 1.49) {
f = 0.0;
} else {
f = f * (f * 0.0161 + -0.3104) + 1.2887;
}
if (f < 0.0) {
f = f * 1.1;
}
fForce = f;
} else {
fForce = 1.0;
}
f = fDist - pA->newRadius;
if (f > 0.0) {
f *= pB->ooRadius;
if (f > 1.49) {
f = 0.0;
} else {
f = f * (f * 0.0161 + -0.3104) + 1.2887;
}
if (f < 0.0) {
f = f * 1.1;
}
fForce += f;
} else {
fForce += 1.0;
}
if (fForce <= -0.05 && fForce >= 0.05) {
fForce = (pA->newRadius + pB->newRadius) * 0.03 * fForce;
VectorScale(vPush, fForce, vPush);
VectorAdd(pA->repulsion, vPush, pA->repulsion);
VectorSubtract(pB->repulsion, vPush, pB->repulsion);
}
} else {
if (!vPush[0] && !vPush[1] && !vPush[2]) {
VectorSet(vPush, crandom(), crandom(), crandom());
VectorAdd(pA->repulsion, vPush, pA->repulsion);
VectorSubtract(pB->repulsion, vPush, pB->repulsion);
return;
}
fDist = VectorNormalize(vPush);
f = fDist - pB->newRadius;
if (f > 0.0f) {
f *= pA->ooRadius;
if (f > 1.49f) {
f = 0.0f;
} else {
f = f * (f * 0.0161f + -0.3104f) + 1.2887f;
}
if (f < 0.0) {
f *= 1.1f;
}
fForce = f;
} else {
fForce = 1.0;
}
f = fDist - pA->newRadius;
if (f > 0.0) {
f *= pB->ooRadius;
if (f > 1.49f) {
f = 0.0f;
} else {
f = f * (f * 0.0161f + -0.3104f) + 1.2887f;
}
if (f < 0.0) {
f *= 1.1f;
}
fForce += f;
} else {
fForce += 1.0f;
}
if (fForce <= -0.05f || fForce >= 0.05f) {
fForce = (pA->newRadius + pB->newRadius) * 0.03f * fForce;
VectorScale(vPush, fForce, vPush);
VectorAdd(pA->repulsion, vPush, pA->repulsion);
VectorSubtract(pB->repulsion, vPush, pB->repulsion);
}
}
@@ -206,7 +209,7 @@ void ClientGameCommandManager::ResetVSSSources()
void ClientGameCommandManager::ResetVSSSources(Event *ev)
{
// FIXME: stub??
ResetVSSSources();
}
void CG_ResetVSSSources()
@@ -286,13 +289,13 @@ qboolean VSS_SourcePhysics(cvssource_t *pSource, float ftime)
fWind = 0.0;
if ((pSource->flags2 & 5) != 0) {
if ((pSource->flags2 & (T2_ACCEL | T2_MOVE)) != 0) {
VectorMA(pSource->velocity, ftime, pSource->repulsion, pSource->velocity);
}
pSource->lastOrigin = pSource->newOrigin;
if (pSource->flags & 0x800) {
if (pSource->flags & T_COLLISION) {
trace.allsolid = qfalse;
CG_ClipMoveToEntities(
pSource->newOrigin, vec3_origin, vec3_origin, pSource->newOrigin, -1, MASK_VOLUMETRIC_SMOKE, &trace, qfalse
@@ -312,11 +315,11 @@ qboolean VSS_SourcePhysics(cvssource_t *pSource, float ftime)
}
}
if (pSource->flags2 & 5) {
if (pSource->flags2 & (T2_ACCEL | T2_MOVE)) {
VectorMA(pSource->newOrigin, ftime, pSource->velocity, pSource->newOrigin);
}
if (pSource->flags & 0x800) {
if (pSource->flags & T_COLLISION) {
CG_Trace(
&trace,
pSource->lastOrigin,
@@ -334,6 +337,8 @@ qboolean VSS_SourcePhysics(cvssource_t *pSource, float ftime)
float fDot;
vec3_t vNorm;
VectorCopy(trace.plane.normal, vNorm);
VectorAdd(trace.endpos, trace.plane.normal, pSource->newOrigin);
fDot = DotProduct(vNorm, pSource->velocity);
VectorMA(pSource->velocity, fDot, vNorm, pSource->velocity);
@@ -358,7 +363,7 @@ qboolean VSS_SourcePhysics(cvssource_t *pSource, float ftime)
}
iSmokeType = abs(pSource->smokeType);
if (pSource->flags2 & 5) {
if (pSource->flags2 & (T2_ACCEL | T2_MOVE)) {
VectorCopy(pSource->velocity, vVel);
for (i = 0; i < 3; i++) {
@@ -619,7 +624,7 @@ qboolean VSS_LerpSource(cvssource_t *pCurrent, cvssourcestate_t *pState, float f
{
int i;
if (pCurrent->flags & 0xA0000) {
if (pCurrent->flags & (T_HARDLINK | T_PARENTLINK)) {
Vector parentOrigin;
for (i = 0; i < 3; i++) {
@@ -638,7 +643,7 @@ qboolean VSS_LerpSource(cvssource_t *pCurrent, cvssourcestate_t *pState, float f
parentOrigin = e->origin;
VectorAdd(pState->origin, parentOrigin, pState->origin);
} else if (pCurrent->flags2 & 5) {
} else if (pCurrent->flags2 & (T2_ACCEL | T2_MOVE)) {
for (i = 0; i < 3; i++) {
pState->origin[i] =
(pCurrent->newOrigin[i] - pCurrent->lastOrigin[i]) * fLerpFrac + pCurrent->lastOrigin[i];
@@ -741,9 +746,8 @@ void ClientGameCommandManager::SpawnVSSSource(int count, int timealive)
pSource->startAlpha = (random() * 0.15 + 0.85) * fDensity;
pSource->newDensity = 0.0;
if (m_spawnthing->cgd.flags & 1) {
if (m_spawnthing->cgd.flags & T_RANDSCALE) {
pSource->newRadius = RandomizeRange(m_spawnthing->cgd.scalemin, m_spawnthing->cgd.scalemax);
;
if (pSource->newRadius > 32.0) {
pSource->newRadius = 32.0;
}
@@ -772,16 +776,16 @@ void ClientGameCommandManager::SpawnVSSSource(int count, int timealive)
pSource->roll = anglemod(fAngle);
if (random() < 0.5) {
pSource->flags |= 0x40000;
pSource->flags |= T_RANDOMROLL;
}
VectorCopy(m_spawnthing->axis[0], vNewForward);
if (m_spawnthing->cgd.flags & 4) {
if (m_spawnthing->cgd.flags & T_SPHERE) {
VectorCopy(m_spawnthing->cgd.origin, pSource->newOrigin);
do {
vNewForward = Vector(crandom(), crandom(), crandom());
} while (Vector::Dot(vNewForward, vNewForward) < 1.0);
} else if (m_spawnthing->cgd.flags & 0x10) {
} else if (m_spawnthing->cgd.flags & T_CIRCLE) {
if (m_spawnthing->sphereRadius != 0.0) {
Vector dst, end;
@@ -794,7 +798,7 @@ void ClientGameCommandManager::SpawnVSSSource(int count, int timealive)
fAngle += fAngleStep;
}
} else if (m_spawnthing->cgd.flags & 8) {
} else if (m_spawnthing->cgd.flags & T_INWARDSPHERE) {
Vector dir, end;
do {
dir = Vector(crandom(), crandom(), crandom());
@@ -803,7 +807,7 @@ void ClientGameCommandManager::SpawnVSSSource(int count, int timealive)
end = m_spawnthing->cgd.origin + dir * m_spawnthing->sphereRadius;
VectorCopy(end, pSource->newOrigin);
vNewForward = dir * -1.0;
} else if (m_spawnthing->cgd.flags2 & 0x20000) {
} else if (m_spawnthing->cgd.flags2 & T2_CONE) {
float fHeight, fRadius;
float fAngle;
float sina, cosa;
@@ -825,8 +829,6 @@ void ClientGameCommandManager::SpawnVSSSource(int count, int timealive)
VectorMA(m_spawnthing->cgd.origin, fRadius * cosa, m_spawnthing->axis[1], pSource->newOrigin);
VectorMA(m_spawnthing->cgd.origin, fRadius * sina, m_spawnthing->axis[2], pSource->newOrigin);
} else if (m_spawnthing->sphereRadius) {
VectorCopy(m_spawnthing->cgd.origin, pSource->newOrigin);
} else {
Vector dir, end;
do {
dir = Vector(crandom(), crandom(), crandom());
@@ -836,6 +838,8 @@ void ClientGameCommandManager::SpawnVSSSource(int count, int timealive)
end = m_spawnthing->cgd.origin + dir * m_spawnthing->sphereRadius;
VectorCopy(end, pSource->newOrigin);
vNewForward = dir;
} else {
VectorCopy(m_spawnthing->cgd.origin, pSource->newOrigin);
}
for (i = 0; i < 3; i++) {
@@ -869,15 +873,14 @@ void ClientGameCommandManager::SpawnVSSSource(int count, int timealive)
for (i = 0; i < 3; ++i) {
float fDist = m_spawnthing->axis_offset_base[i] + random() * m_spawnthing->axis_offset_amplitude[i];
if (pSource->flags2 & 0x80) {
if (pSource->flags2 & T2_PARALLEL) {
pSource->newOrigin += Vector(m_spawnthing->axis[i]) * fDist;
} else {
pSource->newOrigin += Vector(m_spawnthing->tag_axis[i]) * fDist;
}
}
pSource->velocity *= pSource->lifeTime / 1000.0;
pSource->newOrigin += pSource->velocity;
pSource->newOrigin += pSource->velocity * (pSource->lifeTime / 1000.0);
if (vss_lighting_fps->integer) {
cgi.R_GetLightingForSmoke(pSource->newLighting, pSource->newOrigin);
}
@@ -890,251 +893,249 @@ void VSS_CalcRepulsionForces(cvssource_t *pActiveSources)
{
cvssource_t *pCurrent;
cvssource_t *pComp;
qboolean bXUp, bXDown;
qboolean bYUp, bYDown;
qboolean bZDown;
int i;
int iIndex;
int iX, iY, iZ;
int iMinX, iMinY, iMinZ;
int iMaxX, iMaxY, iMaxZ;
float fOfs;
cvssource_t *pSTLatch;
pCurrent = pActiveSources->prev;
if (pCurrent != pActiveSources) {
qboolean bXUp, bXDown;
qboolean bYUp, bYDown;
qboolean bZDown;
int i;
int iIndex;
int iX, iY, iZ;
int iMinX, iMinY, iMinZ;
int iMaxX, iMaxY, iMaxZ;
float fOfs;
cvssource_t *pSTLatch;
if (pCurrent == pActiveSources) {
return;
}
memset(vss_sorttable, 0, sizeof(vss_sorttable));
memset(vss_sorttable, 0, sizeof(vss_sorttable));
while (pCurrent != pActiveSources) {
VectorClear(pCurrent->repulsion);
for (pCurrent = pActiveSources->prev; pCurrent != pActiveSources; pCurrent = pCurrent->prev) {
VectorClear(pCurrent->repulsion);
iIndex = ((int)floor(pCurrent->newOrigin[0] + 8192.0 + 0.5) / 96) % 32;
iIndex |= ((int)floor(pCurrent->newOrigin[1] + 8192.0 + 0.5) / 96) % 32;
iIndex |= (((int)floor(pCurrent->newOrigin[2] + 8192.0 + 0.5) / 96) % 16) << 10;
iIndex = ((int)floor(pCurrent->newOrigin[0] + 8192.0 + 0.5) / 96) % 32;
iIndex |= (((int)floor(pCurrent->newOrigin[1] + 8192.0 + 0.5) / 96) % 32) << 5;
iIndex |= (((int)floor(pCurrent->newOrigin[2] + 8192.0 + 0.5) / 96) % 16) << 10;
pCurrent->stnext = vss_sorttable[iIndex];
vss_sorttable[iIndex] = pCurrent;
pCurrent->stindex = iIndex;
pCurrent = pCurrent->prev;
pCurrent->stnext = vss_sorttable[iIndex];
vss_sorttable[iIndex] = pCurrent;
pCurrent->stindex = iIndex;
}
for (pCurrent = pActiveSources->prev; pCurrent != pActiveSources; pCurrent = pCurrent->prev) {
if (vss_sorttable[pCurrent->stindex] == pCurrent) {
pSTLatch = (cvssource_t *)-1;
pComp = pCurrent->stnext;
} else {
pSTLatch = 0;
pComp = vss_sorttable[pCurrent->stindex];
}
for (pCurrent = pActiveSources->prev; pCurrent != pActiveSources; pCurrent = pCurrent->prev) {
if (vss_sorttable[pCurrent->stindex] == pCurrent) {
pSTLatch = (cvssource_t *)-1;
pComp = pCurrent->stnext;
} else {
pSTLatch = 0;
pComp = vss_sorttable[pCurrent->stindex];
for(; pComp; pComp = pComp->stnext) {
VSS_AddRepulsion(pCurrent, pComp);
if (!pSTLatch && pComp->stnext == pCurrent) {
pSTLatch = pComp;
// skip current
pComp = pComp->stnext;
}
}
iX = ((int)floor(pCurrent->newOrigin[0] + 8192.0 + 0.5) / 96) % 32;
iY = (((int)floor(pCurrent->newOrigin[1] + 8192.0 + 0.5) / 96) % 32) << 5;
iZ = (((int)floor(pCurrent->newOrigin[2] + 8192.0 + 0.5) / 96) % 16) << 10;
fOfs = pCurrent->newRadius + 1.49 + 48.0;
iMaxX = ((int)floor(pCurrent->newOrigin[0] + fOfs + 8192.0 + 0.5) / 96) % 32;
iMaxY = (((int)floor(pCurrent->newOrigin[1] + fOfs + 8192.0 + 0.5) / 96) % 32) << 5;
iMaxZ = (((int)floor(pCurrent->newOrigin[2] + fOfs + 8192.0 + 0.5) / 96) % 16) << 10;
iMinX = ((int)floor(pCurrent->newOrigin[0] - fOfs + 8192.0 + 0.5) / 96) % 32;
iMinY = (((int)floor(pCurrent->newOrigin[1] - fOfs + 8192.0 + 0.5) / 96) % 32) << 5;
iMinZ = (((int)floor(pCurrent->newOrigin[2] - fOfs + 8192.0 + 0.5) / 96) % 16) << 10;
bXUp = (iMaxX | (pCurrent->stindex & 0xFFFFFFE0)) != pCurrent->stindex;
bXDown = (iMinX | (pCurrent->stindex & 0xFFFFFFE0)) != pCurrent->stindex;
bYUp = (iMaxY | (pCurrent->stindex & 0xFFFFFC1F)) != pCurrent->stindex;
bYDown = (iMinY | (pCurrent->stindex & 0xFFFFFC1F)) != pCurrent->stindex;
iIndex = iMinZ | (pCurrent->stindex & 0xFFFFC3FF);
bZDown = iIndex != pCurrent->stindex;
if (iIndex == pCurrent->stindex) {
iIndex = iMaxY | (pCurrent->stindex & 0xFFFFFC1F);
i = 9;
} else {
i = 0;
}
for (; i < (bZDown ? 26 : 17); i++) {
switch (i) {
case 0:
iIndex = iMaxZ | (pCurrent->stindex & 0xFFFFC3FF);
break;
case 1:
iIndex = iMaxX | (iIndex & 0xFFFFFFE0);
if (bXUp) {
break;
}
continue;
case 2:
iIndex = iMaxY | (iIndex & 0xFFFFFC1F);
if (bXUp && bYUp) {
break;
}
continue;
case 3:
iIndex = iMinY | (iIndex & 0xFFFFFC1F);
if (bXUp && bYDown) {
break;
}
continue;
case 4:
iIndex = iMinY | (iIndex & 0xFFFFFFE0);
if (bYDown) {
break;
}
continue;
case 5:
iIndex = iMinX | (iIndex & 0xFFFFFFE0);
if (bXDown && bYDown) {
break;
}
continue;
case 6:
iIndex = iY | (iIndex & 0xFFFFFC1F);
if (bXDown) {
break;
}
continue;
case 7:
iIndex = iMaxY | (iIndex & 0xFFFFFC1F);
if (bXDown && bYUp) {
break;
}
continue;
case 8:
iIndex = iX | (iIndex & 0xFFFFFFE0);
if (bYUp) {
break;
}
continue;
case 9:
iIndex = iZ | (iIndex & 0xFFFFFFC3);
if (bYUp) {
break;
}
continue;
case 10:
iIndex = iMaxX | (iIndex & 0xFFFFFFE0);
if (bXUp && bYUp) {
break;
}
continue;
case 11:
iIndex = iMinX | (iIndex & 0xFFFFFFE0);
if (bXDown && bYUp) {
break;
}
continue;
case 12:
iIndex = iY | (iIndex & 0xFFFFFC1F);
if (bXDown) {
break;
}
continue;
case 13:
iIndex = iMinY | (iIndex & 0xFFFFFC1F);
if (bXDown && bYDown) {
break;
}
continue;
case 14:
iIndex = iX | (iIndex & 0xFFFFFFE0);
if (bYDown) {
break;
}
continue;
case 15:
iIndex = iMaxX | (iIndex & 0xFFFFFFE0);
if (bXUp && bYDown) {
break;
}
continue;
case 16:
iIndex = iY | (iIndex & 0xFFFFFC1F);
if (bXUp) {
break;
}
continue;
case 17:
iIndex = iMinZ | (iIndex & 0xFFFFFCC3);
if (bXUp) {
break;
}
continue;
case 18:
iIndex = iMaxY | (iIndex & 0xFFFFFC1F);
if (bXUp && bYUp) {
break;
}
continue;
case 19:
iIndex = iMinY | (iIndex & 0xFFFFFC1F);
if (bXUp && bYDown) {
break;
}
continue;
case 20:
iIndex = iX | (iIndex & 0xFFFFFFE0);
if (bYDown) {
break;
}
continue;
case 21:
iIndex = iMinX | (iIndex & 0xFFFFFFE0);
if (bXDown && bYDown) {
break;
}
continue;
case 22:
iIndex = iY | (iIndex & 0xFFFFFC1F);
if (bXDown) {
break;
}
continue;
case 23:
iIndex = iMaxY | (iIndex & 0xFFFFFC1F);
if (bXDown && bYUp) {
break;
}
continue;
case 24:
iIndex = iX | (iIndex & 0xFFFFFFE0);
if (bYUp) {
break;
}
continue;
case 25:
iIndex = iY | (iIndex & 0xFFFFFC1F);
break;
default:
assert(0); // This can't happen
break;
}
while (pComp) {
for (pComp = vss_sorttable[iIndex]; pComp; pComp = pComp->stnext) {
VSS_AddRepulsion(pCurrent, pComp);
if (!pSTLatch && pComp->stnext == pCurrent) {
pSTLatch = pComp;
pComp = pComp->stnext;
}
pComp = pComp->stnext;
}
iX = ((int)floor(pCurrent->newOrigin[0] + 8192.0 + 0.5) / 96) % 32;
iY = ((int)floor(pCurrent->newOrigin[1] + 8192.0 + 0.5) / 96) % 32;
iY *= 2;
iZ = ((int)floor(pCurrent->newOrigin[2] + 8192.0 + 0.5) / 96) % 16;
iZ <<= 10;
}
fOfs = pCurrent->newRadius + 1.49 + 48.0;
iMaxX = ((int)floor(pCurrent->newOrigin[0] + 8192.0 + 0.5 + fOfs) / 96) % 32;
iMaxY = ((int)floor(pCurrent->newOrigin[1] + 8192.0 + 0.5 + fOfs) / 96) % 32;
iMaxY *= 2;
iMaxZ = ((int)floor(pCurrent->newOrigin[2] + 8192.0 + 0.5 + fOfs) / 96) % 16;
iMaxZ <<= 10;
iMinX = ((int)floor(pCurrent->newOrigin[0] + 8192.0 + 0.5 - fOfs) / 96) % 32;
iMinY = ((int)floor(pCurrent->newOrigin[1] + 8192.0 + 0.5 - fOfs) / 96) % 32;
iMinY *= 2;
iMinZ = ((int)floor(pCurrent->newOrigin[2] + 8192.0 + 0.5 - fOfs) / 96) % 16;
iMinZ <<= 10;
bXUp = (iMaxX | (pCurrent->stindex & 0xFFFFFFE0)) != pCurrent->stindex;
bXDown = (iMinX | (pCurrent->stindex & 0xFFFFFFE0)) != pCurrent->stindex;
bYUp = (iMaxY | (pCurrent->stindex & 0xFFFFFC1F)) != pCurrent->stindex;
bYDown = (iMinY | (pCurrent->stindex & 0xFFFFFC1F)) != pCurrent->stindex;
iIndex = iMinZ | (pCurrent->stindex & 0xFFFFFCC3);
bZDown = iIndex != pCurrent->stindex;
if (iIndex == pCurrent->stindex) {
iIndex = iMaxY | pCurrent->stindex & 0xFFFFFC1F;
i = 9;
} else {
i = 0;
}
for(; i < (bZDown ? 26 : 17); i++) {
switch (i) {
case 0:
iIndex = iMaxZ | (pCurrent->stindex & 0xFFFFFCC3);
break;
case 1:
iIndex = iMaxX | (iIndex & 0xFFFFFFE0);
if (bXUp) {
break;
}
continue;
case 2:
iIndex = iMaxY | (iIndex & 0xFFFFFC1F);
if (bXUp && bYUp) {
break;
}
continue;
case 3:
iIndex = iMinY | (iIndex & 0xFFFFFC1F);
if (bXUp && bYDown) {
break;
}
continue;
case 4:
iIndex = iMinY | (iIndex & 0xFFFFFFE0);
if (bYDown) {
break;
}
continue;
case 5:
iIndex = iMinX | (iIndex & 0xFFFFFFE0);
if (bXDown && bYDown) {
break;
}
continue;
case 6:
iIndex = iY | (iIndex & 0xFFFFFC1F);
if (bXDown) {
break;
}
continue;
case 7:
iIndex = iMaxY | (iIndex & 0xFFFFFC1F);
if (bXDown && bYUp) {
break;
}
continue;
case 8:
iIndex = iX | (iIndex & 0xFFFFFFE0);
if (bYUp) {
break;
}
continue;
case 9:
iIndex = iZ | (iIndex & 0xFFFFFFC3);
if (bYUp) {
break;
}
continue;
case 10:
iIndex = iMaxX | (iIndex & 0xFFFFFFE0);
if (bXUp && bYUp) {
break;
}
continue;
case 11:
iIndex = iMinX | (iIndex & 0xFFFFFFE0);
if (bXDown && bYUp) {
break;
}
continue;
case 12:
iIndex = iY | (iIndex & 0xFFFFFC1F);
if (bXDown) {
break;
}
continue;
case 13:
iIndex = iMinY | (iIndex & 0xFFFFFC1F);
if (bXDown && bYDown) {
break;
}
continue;
case 14:
iIndex = iX | (iIndex & 0xFFFFFFE0);
if (bYDown) {
break;
}
continue;
case 15:
iIndex = iMaxX | (iIndex & 0xFFFFFFE0);
if (bXUp && bYDown) {
break;
}
continue;
case 16:
iIndex = iY | (iIndex & 0xFFFFFC1F);
if (bXUp) {
break;
}
continue;
case 17:
iIndex = iMinZ | (iIndex & 0xFFFFFCC3);
if (bXUp) {
break;
}
continue;
case 18:
iIndex = iMaxY | (iIndex & 0xFFFFFC1F);
if (bXUp && bYUp) {
break;
}
continue;
case 19:
iIndex = iMinY | (iIndex & 0xFFFFFC1F);
if (bXUp && bYDown) {
break;
}
continue;
case 20:
iIndex = iX | (iIndex & 0xFFFFFFE0);
if (bYDown) {
break;
}
continue;
case 21:
iIndex = iMinX | (iIndex & 0xFFFFFFE0);
if (bXDown && bYDown) {
break;
}
continue;
case 22:
iIndex = iY | (iIndex & 0xFFFFFC1F);
if (bXDown) {
break;
}
continue;
case 23:
iIndex = iMaxY | (iIndex & 0xFFFFFC1F);
if (bXDown && bYUp) {
break;
}
continue;
case 24:
iIndex = iX | (iIndex & 0xFFFFFFE0);
if (bYUp) {
break;
}
continue;
case 25:
iIndex = iY | (iIndex & 0xFFFFFC1F);
break;
}
for (pComp = vss_sorttable[iIndex]; pComp; pComp = pComp->stnext) {
VSS_AddRepulsion(pCurrent, pComp);
}
}
if (pSTLatch == (cvssource_t *)-1) {
vss_sorttable[pCurrent->stindex] = pCurrent->stnext;
} else {
pSTLatch->stnext = pCurrent->stnext;
}
if (pSTLatch == (cvssource_t *)-1) {
vss_sorttable[pCurrent->stindex] = pCurrent->stnext;
} else {
pSTLatch->stnext = pCurrent->stnext;
}
}
}
@@ -1222,13 +1223,13 @@ void ClientGameCommandManager::AddVSSSources()
pComp = pCurrent->prev;
newEnt.renderfx = 0;
if (pCurrent->flags < 0 && !cg_detail->integer) {
if ((pCurrent->flags & T_DETAIL) && !cg_detail->integer) {
FreeVSSSource(pCurrent);
continue;
}
if ((pCurrent->flags2 & 0x4000) != 0) {
newEnt.renderfx = 0x4000000;
if ((pCurrent->flags2 & T2_ALWAYSDRAW) != 0) {
newEnt.renderfx = RF_ALWAYSDRAW;
}
if (pCurrent->lastPhysicsTime) {
@@ -1237,8 +1238,8 @@ void ClientGameCommandManager::AddVSSSources()
mstime = physics_rate;
}
if (mstime >= physics_rate || (pCurrent->flags2 & 0x10) != 0) {
if (!VSS_SourcePhysics(pCurrent, (float)mstime * 0.001)) {
if (mstime >= physics_rate || (pCurrent->flags2 & T2_PHYSICS_EVERYFRAME) != 0) {
if (!VSS_SourcePhysics(pCurrent, (float)mstime / 1000.0)) {
FreeVSSSource(pCurrent);
continue;
}
@@ -1262,26 +1263,18 @@ void ClientGameCommandManager::AddVSSSources()
}
}
fLerpFrac = (cg.time - pCurrent->lastPhysicsTime) / physics_rate;
if (fLerpFrac > 1.0) {
fLerpFrac = 1.0;
} else if (fLerpFrac < 0.0) {
fLerpFrac = 0.0;
}
fLerpFrac = (float)(cg.time - pCurrent->lastPhysicsTime) / (float)physics_rate;
fLerpFrac = Q_clamp_float(fLerpFrac, 0, 1);
fLightingFrac = (cg.time - pCurrent->lastLightingTime) / lighting_rate;
if (fLightingFrac > 1.0) {
fLightingFrac = 1.0;
} else if (fLightingFrac < 0.0) {
fLightingFrac = 0.0;
}
fLightingFrac = (float)(cg.time - pCurrent->lastLightingTime) / (float)lighting_rate;
fLightingFrac = Q_clamp_float(fLightingFrac, 0, 1);
if (lastVSSFrameTime) {
pCurrent->lifeTime += frameTime;
}
if (!pCurrent->lastValid) {
if (!VSS_SourcePhysics(pCurrent, (float)physics_rate * 0.001)) {
if (!VSS_SourcePhysics(pCurrent, (float)physics_rate / 1000)) {
ClientGameCommandManager::FreeVSSSource(pCurrent);
continue;
}
@@ -1335,12 +1328,12 @@ void ClientGameCommandManager::AddVSSSources()
pCurrent->roll -= j;
}
if ((pCurrent->flags & 0x40000) != 0) {
if ((pCurrent->flags & T_RANDOMROLL) != 0) {
newEnt.hModel = hModel;
} else {
newEnt.hModel = hModel2;
}
} else if ((pCurrent->flags & 0x40000) != 0) {
} else if ((pCurrent->flags & T_RANDOMROLL) != 0) {
newEnt.hModel = hModel;
} else {
newEnt.hModel = hModel2;
+9 -9
View File
@@ -42,23 +42,23 @@ MemArchiver::~MemArchiver()
void MemArchiver::SetupForWriting(size_t initialSize)
{
state = MEMARC_WRITING;
buffer = (byte*)cgi.Malloc(initialSize);
allocatedSize = initialSize;
bufferSize = 0;
this->state = MEMARC_WRITING;
this->buffer = (byte*)cgi.Malloc(initialSize);
this->allocatedSize = initialSize;
this->bufferSize = 0;
}
void MemArchiver::SetupForReading(byte* buffer, size_t size)
{
state = MEMARC_READING;
buffer = buffer;
allocatedSize = size;
bufferSize = 0;
this->state = MEMARC_READING;
this->buffer = buffer;
this->allocatedSize = size;
this->bufferSize = 0;
}
void MemArchiver::SetBaseTime(unsigned int time)
{
svsTime = time;
this->svsTime = time;
}
size_t MemArchiver::BufferSize() const
+57 -4
View File
@@ -1,15 +1,17 @@
cmake_minimum_required(VERSION 3.5)
project(omohclient)
option(NO_OPENAL "Use older sound-system" FALSE)
add_subdirectory("../cgame" "./cgame")
file(GLOB_RECURSE SOURCES_CLIENT "./*.c*")
file(GLOB SOURCES_CLIENT "./*.c*")
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_definitions(omohclient INTERFACE USE_OPENAL_DLOPEN=1)
target_compile_features(omohclient INTERFACE cxx_nullptr)
target_compile_features(omohclient INTERFACE c_variadic_macros)
target_link_libraries(omohclient INTERFACE omohsdl)
@@ -18,5 +20,56 @@ target_link_libraries(omohclient INTERFACE gcd)
# Sound stuff
target_compile_definitions(omohclient INTERFACE USE_CODEC_MP3)
add_subdirectory("../libmad-0.15.1b" "./libmad")
target_link_libraries(omohclient INTERFACE libmad)
if (NOT NO_OPENAL)
# Use OpenAL
find_package(OpenAL REQUIRED)
if (OPENAL_FOUND)
target_compile_definitions(omohclient INTERFACE USE_OPENAL=1 NO_MODERN_DMA=0)
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$")
file(GLOB SOURCES_CLIENT_SND "./snd_*_new.c*" "./snd_codec*.c*")
list(APPEND SOURCES_CLIENT ${SOURCES_CLIENT_SND})
else()
#
# Fallback to old DMA sound system
#
message(NOTICE "OpenAL was explicitly disabled - fallback to old SDL sound system")
target_compile_definitions(omohclient INTERFACE NO_MODERN_DMA=1)
set(NO_MODERN_DMA TRUE)
list(FILTER SOURCES_CLIENT EXCLUDE REGEX "./snd_([a-zA-Z0-9_]+)\.cpp$")
file(GLOB_RECURSE SOURCES_CLIENT_SND "./new/*.c*")
list(APPEND SOURCES_CLIENT ${SOURCES_CLIENT_SND})
endif()
set(OLD_VALUE ${BUILD_SHARED_LIBS})
set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE)
if(USE_INTERNAL_MAD)
add_subdirectory("../libmad" "./libmad" EXCLUDE_FROM_ALL)
target_link_libraries(omohclient INTERFACE mad)
else()
include(FindPackageHandleStandardArgs)
find_path(LIBMAD_INCLUDE_DIRS mad.h)
find_library(LIBMAD_LIBRARIES mad)
find_package_handle_standard_args(
LibMad
DEFAULT_MSG
LIBMAD_LIBRARIES
LIBMAD_INCLUDE_DIRS
)
target_include_directories(omohclient INTERFACE ${LIBMAD_INCLUDE_DIRS})
target_link_libraries(omohclient INTERFACE ${LIBMAD_LIBRARIES})
endif()
set(BUILD_SHARED_LIBS ${OLD_VALUE} CACHE BOOL "" FORCE)
target_sources(omohclient INTERFACE ${SOURCES_CLIENT} ${SOURCES_UILIB})
+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
}
/*
+113 -32
View File
@@ -211,20 +211,20 @@ qboolean CL_GetSnapshot( int snapshotNumber, snapshot_t *snapshot ) {
}
snapshot->numEntities = 0;
for ( i = 0 ; i < count ; i++ ) {
for(i = 0; i < MAX_ENTITIES_IN_SNAPSHOT; i++) {
parents[i] = -1;
}
for (i = 0; i < count; i++) {
s1 = &cl.parseEntities[(clSnap->parseEntitiesNum + i) & (MAX_PARSE_ENTITIES - 1)];
pnum = s1->parent;
if (pnum == ENTITYNUM_NONE) {
parents[s1->number] = -2;
}
else
{
} else {
if (parents[pnum] == -2) {
parents[s1->number] = -2;
}
else
{
} else {
// add it later
parents[s1->number] = pnum;
continue;
@@ -234,33 +234,37 @@ qboolean CL_GetSnapshot( int snapshotNumber, snapshot_t *snapshot ) {
snapshot->entities[snapshot->numEntities++] = *s1;
}
for(pcount = 0; pcount < 8 && snapshot->numEntities != count; pcount++)
{
for (i = 0; i < count; i++)
{
for(pcount = 0; pcount < 8 && snapshot->numEntities != count; pcount++) {
for (i = 0; i < count; i++) {
s1 = &cl.parseEntities[(clSnap->parseEntitiesNum + i) & (MAX_PARSE_ENTITIES - 1)];
pnum = parents[s1->number];
if (pnum >= 0 && parents[pnum] == -2) {
parents[s1->number] = -2;
snapshot->entities[snapshot->numEntities++] = *s1;
}
}
}
if (pcount >= 8)
{
for (i = count; i < snapshot->numEntities; i++)
if (snapshot->numEntities != count) {
Com_DPrintf("CL_GetSnapshot: Not all children could find their parents.\n");
for (i = snapshot->numEntities; i < count; i++)
{
s1 = &cl.parseEntities[(clSnap->parseEntitiesNum + i) & (MAX_PARSE_ENTITIES - 1)];
if (parents[s1->number] >= 0) {
Com_DPrintf(
"CL_GetSnapshot: entity %d with parent %d and model '%s' at %.2f %.2f %.2f, could not find parent.\n",
s1->number,
s1->parent,
CL_ConfigString(CS_MODELS + s1->modelindex),
s1->origin[0],
s1->origin[1],
s1->origin[2]
);
for (pnum = 0; pnum < count; pnum++) {
s1 = &cl.parseEntities[(clSnap->parseEntitiesNum + pnum) & (MAX_PARSE_ENTITIES - 1)];
if (parents[s1->number] >= 0) {
Com_DPrintf(
"CL_GetSnapshot: entity %d with parent %d and model '%s' at %.2f %.2f %.2f, could not find parent.\n",
s1->number,
s1->parent,
CL_ConfigString(CS_MODELS + s1->modelindex),
s1->origin[0],
s1->origin[1],
s1->origin[2]
);
parents[s1->number] = -2;
}
}
}
}
@@ -358,7 +362,9 @@ qboolean CL_ProcessServerCommand(const char* origString, const char* cmd, qboole
// because this function might be called from a module that would be unloaded
// inside Com_Error
UI_ForceMenuOff(1);
Cbuf_AddText("disconnect;pushmenu disconnected");
// Fixed in OPM
// Added a newline for next commands
Cbuf_AddText("disconnect;pushmenu disconnected\n");
return qtrue;
}
@@ -395,8 +401,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 +427,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);
}
@@ -548,7 +584,7 @@ CL_RestoreSavedCgameState
*/
void CL_RestoreSavedCgameState() {
if (cls.savedCgameState) {
cge->CG_LoadStateToBuffer(&cls.savedCgameState, cls.savedCgameStateSize, cl.snap.serverTime);
cge->CG_LoadStateToBuffer(cls.savedCgameState, cls.savedCgameStateSize, cl.snap.serverTime);
}
}
@@ -591,6 +627,7 @@ void CL_InitCGameDLL( clientGameImport_t *cgi, clientGameExport_t **cge ) {
cgi->LV_ConvertString = Sys_LV_CL_ConvertString;
cgi->Cvar_Get = Cvar_Get;
cgi->Cvar_Find = Cvar_FindVar;
cgi->Cvar_Set = Cvar_Set;
cgi->Argc = Cmd_Argc;
@@ -735,7 +772,8 @@ void CL_InitCGameDLL( clientGameImport_t *cgi, clientGameExport_t **cge ) {
cgi->UI_ShowMenu = UI_ShowMenu;
cgi->UI_HideMenu = UI_HideMenu;
cgi->UI_FontStringWidth = uie.FontStringWidth;
cgi->UI_FontStringWidth = CL_FontStringWidth;
cgi->UI_GetObjectivesTop = UI_GetObjectivesTop;
cgi->Key_StringToKeynum = Key_StringToKeynum;
cgi->Key_KeynumToBindString = Key_KeynumToBindString;
cgi->Key_GetKeysForCommand = Key_GetKeysForCommand;
@@ -783,6 +821,8 @@ void CL_InitCGameDLL( clientGameImport_t *cgi, clientGameExport_t **cge ) {
cgi->CL_RestoreSavedCgameState = CL_RestoreSavedCgameState;
cgi->CL_ClearSavedCgameState = CL_ClearSavedCgameState;
cgi->getConfigStringIdNormalized = CPT_NormalizeConfigstring;
cgi->fsDebug = fs_debug;
cgi->HudDrawElements = cls.HudDrawElements;
cgi->anim = &cls.anim;
@@ -1075,6 +1115,42 @@ void CL_FirstSnapshot( void ) {
Cbuf_AddText( cl_activeAction->string );
Cvar_Set( "activeAction", "" );
}
#ifdef USE_MUMBLE
if ((cl_useMumble->integer) && !mumble_islinked()) {
int ret = mumble_link(CLIENT_WINDOW_TITLE);
Com_Printf("Mumble: Linking to Mumble application %s\n", ret==0?"ok":"failed");
}
#endif
#ifdef USE_VOIP
if (!clc.voipCodecInitialized) {
int i;
int error;
clc.opusEncoder = opus_encoder_create(48000, 1, OPUS_APPLICATION_VOIP, &error);
if ( error ) {
Com_DPrintf("VoIP: Error opus_encoder_create %d\n", error);
return;
}
for (i = 0; i < MAX_CLIENTS; i++) {
clc.opusDecoder[i] = opus_decoder_create(48000, 1, &error);
if ( error ) {
Com_DPrintf("VoIP: Error opus_decoder_create(%d) %d\n", i, error);
return;
}
clc.voipIgnore[i] = qfalse;
clc.voipGain[i] = 1.0f;
}
clc.voipCodecInitialized = qtrue;
clc.voipMuteAll = qfalse;
Cmd_AddCommand ("voip", CL_Voip_f);
Cvar_Set("cl_voipSendTarget", "spatial");
Com_Memset(clc.voipTargets, ~0, sizeof(clc.voipTargets));
}
#endif
}
static int lastSnapFlags;
@@ -1125,7 +1201,12 @@ void CL_SetCGameTime( void ) {
// allow pause in single player
if ( paused->integer && com_sv_running->integer ) {
// paused
CL_AdjustTimeDelta();
//CL_AdjustTimeDelta();
// Fixed in OPM
// Keep in sync with the server time.
// In OG, the game could lag for a short time
// when pausing and unpausing frequently
cl.serverTimeDelta = cl.snap.serverTime - cls.realtime;
return;
}
+159 -44
View File
@@ -35,6 +35,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "../uilib/ui_public.h"
#include "snd_local.h"
#include "cl_ui.h"
#define MAXSIZE 8
#define MINSIZE 4
@@ -55,6 +57,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
static void RoQ_init( void );
static void CL_FinishedCinematic();
/******************************************************************************
*
@@ -126,6 +129,10 @@ typedef struct {
int playonwalls;
byte* buf;
long drawX, drawY;
long realTime;
long currTime;
long soundTime;
} cin_cache;
static cinematics_t cin;
@@ -133,6 +140,10 @@ static cin_cache cinTable[MAX_VIDEO_HANDLES];
static int currentHandle = -1;
static int CL_handle = -1;
static connstate_t oldClientState;
static int audioStartTime = 0;
extern "C" int s_soundtime; // sample PAIRS
@@ -160,7 +171,7 @@ static int CIN_HandleForVideo(void) {
}
extern "C" int CL_ScaledMilliseconds(void);
extern "C" int Com_Milliseconds(void);
//-----------------------------------------------------------------------------
// RllSetupTable
@@ -1142,24 +1153,20 @@ redump:
case ZA_SOUND_MONO:
if (!cinTable[currentHandle].silent) {
ssize = RllDecodeMonoToStereo( framedata, sbuf, cinTable[currentHandle].RoQFrameSize, 0, (unsigned short)cinTable[currentHandle].roq_flags);
S_RawSamples(0, ssize, 22050, 2, 1, (byte *)sbuf, 1.0f, -1);
// S_RawSamples(0, ssize, 22050, 2, 1, (byte *)sbuf, 1.0f, -1);
}
break;
case ZA_SOUND_STEREO:
if (!cinTable[currentHandle].silent) {
if (cinTable[currentHandle].numQuads == -1) {
S_Update();
s_rawend[0] = s_soundtime;
}
ssize = RllDecodeStereoToStereo( framedata, sbuf, cinTable[currentHandle].RoQFrameSize, 0, (unsigned short)cinTable[currentHandle].roq_flags);
S_RawSamples(0, ssize, 22050, 2, 2, (byte *)sbuf, 1.0f, -1);
// S_RawSamples(0, ssize, 22050, 2, 2, (byte *)sbuf, 1.0f, -1);
}
break;
case ROQ_QUAD_INFO:
if (cinTable[currentHandle].numQuads == -1) {
readQuadInfo( framedata );
setupQuad( 0, 0 );
cinTable[currentHandle].startTime = cinTable[currentHandle].lastTime = CL_ScaledMilliseconds();
cinTable[currentHandle].startTime = cinTable[currentHandle].lastTime = Com_Milliseconds();
}
if (cinTable[currentHandle].numQuads != 1) cinTable[currentHandle].numQuads = 0;
break;
@@ -1226,7 +1233,10 @@ redump:
static void RoQ_init( void )
{
cinTable[currentHandle].startTime = cinTable[currentHandle].lastTime = CL_ScaledMilliseconds();
cinTable[currentHandle].startTime = cinTable[currentHandle].lastTime = Com_Milliseconds();
cinTable[currentHandle].realTime = Com_Milliseconds();
cinTable[currentHandle].currTime = 0;
cinTable[currentHandle].soundTime = 0;
cinTable[currentHandle].RoQPlayed = 24;
@@ -1273,8 +1283,10 @@ static void RoQShutdown( void ) {
cinTable[currentHandle].iFile = 0;
}
S_StopMovieAudio();
if (cinTable[currentHandle].alterGameState) {
clc.state = CA_DISCONNECTED;
clc.state = oldClientState;
// we can't just do a vstr nextmap, because
// if we are aborting the intro cinematic with
// a devmap command, nextmap would be valid by
@@ -1286,8 +1298,29 @@ static void RoQShutdown( void ) {
}
CL_handle = -1;
}
cinTable[currentHandle].fileName[0] = 0;
currentHandle = -1;
CL_FinishedCinematic();
}
static void CL_FinishedCinematic()
{
const char* s;
if (!CL_FinishedIntro())
{
CL_FinishedStartStage();
return;
}
s = Cvar_VariableString("nextmap");
if (*s)
{
Cbuf_ExecuteText(EXEC_APPEND, va("%s\n", s));
Cvar_Set("nextmap", "");
}
}
/*
@@ -1328,8 +1361,11 @@ Fetch and decompress the pending frame
e_status CIN_RunCinematic (int handle)
{
int start = 0;
int thisTime = 0;
int deltaTime;
int frameTime;
int soundTime;
int newTime;
long tfps;
if (handle < 0 || handle>= MAX_VIDEO_HANDLES || cinTable[handle].status == FMV_EOF) return FMV_EOF;
@@ -1357,24 +1393,46 @@ e_status CIN_RunCinematic (int handle)
return cinTable[currentHandle].status;
}
thisTime = CL_ScaledMilliseconds();
if (cinTable[currentHandle].shader && (abs(thisTime - cinTable[currentHandle].lastTime))>100) {
cinTable[currentHandle].startTime += thisTime - cinTable[currentHandle].lastTime;
frameTime = Com_Milliseconds();
deltaTime = frameTime - cinTable[currentHandle].realTime;
if (deltaTime > 100) {
deltaTime = 100;
}
cinTable[currentHandle].tfps = (((CL_ScaledMilliseconds() - cinTable[currentHandle].startTime)*3)/100);
start = cinTable[currentHandle].startTime;
while( (cinTable[currentHandle].tfps != cinTable[currentHandle].numQuads)
newTime = cinTable[currentHandle].currTime + deltaTime;
if (cl_movieaudio->integer) {
soundTime = S_CurrentMoviePosition();
if (soundTime > cinTable[currentHandle].currTime || soundTime > cinTable[currentHandle].soundTime) {
cinTable[currentHandle].currTime = newTime + (deltaTime * (soundTime - newTime)) / 100;
}
else {
cinTable[currentHandle].currTime = newTime;
}
cinTable[currentHandle].soundTime = soundTime;
} else {
//
// Fixed in OPM
//
cinTable[currentHandle].currTime = newTime;
}
cinTable[currentHandle].realTime = frameTime;
tfps = (cinTable[currentHandle].currTime * 3) / 100;
while( (tfps != cinTable[currentHandle].numQuads)
&& (cinTable[currentHandle].status == FMV_PLAY) )
{
RoQInterrupt();
if (start != cinTable[currentHandle].startTime) {
cinTable[currentHandle].tfps = (((CL_ScaledMilliseconds() - cinTable[currentHandle].startTime)*3)/100);
start = cinTable[currentHandle].startTime;
cinTable[currentHandle].realTime = Com_Milliseconds();
if (cinTable[currentHandle].realTime > frameTime + 66) {
break;
}
}
cinTable[currentHandle].lastTime = thisTime;
cinTable[currentHandle].lastTime = frameTime;
if (cinTable[currentHandle].status == FMV_LOOPED) {
cinTable[currentHandle].status = FMV_PLAY;
@@ -1422,7 +1480,7 @@ int CIN_PlayCinematic( const char *arg, int x, int y, int w, int h, int systemBi
cin.currentHandle = currentHandle;
strcpy(cinTable[currentHandle].fileName, name);
Q_strncpyz(cinTable[currentHandle].fileName, name, sizeof(cinTable[currentHandle].fileName));
cinTable[currentHandle].ROQSize = 0;
cinTable[currentHandle].ROQSize = FS_FOpenFileRead (cinTable[currentHandle].fileName, &cinTable[currentHandle].iFile, qtrue, qtrue);
@@ -1468,10 +1526,6 @@ int CIN_PlayCinematic( const char *arg, int x, int y, int w, int h, int systemBi
clc.state = CA_CINEMATIC;
}
if (!cinTable[currentHandle].silent) {
s_rawend[0] = s_soundtime;
}
return currentHandle;
}
Com_DPrintf("trFMV::play(), invalid RoQ ID\n");
@@ -1593,33 +1647,96 @@ void CIN_DrawCinematic (int handle) {
cinTable[handle].dirty = qfalse;
}
static unsigned short CL_PlayRoQ(const char* name, const char* arg, const char* s) {
unsigned short RoQID;
Com_Memset(&cin, 0, sizeof(cinematics_t) );
currentHandle = CIN_HandleForVideo();
cin.currentHandle = currentHandle;
Q_strncpyz(cinTable[currentHandle].fileName, name, sizeof(cinTable[currentHandle].fileName));
cinTable[currentHandle].ROQSize = 0;
cinTable[currentHandle].ROQSize = FS_FOpenFileRead (cinTable[currentHandle].fileName, &cinTable[currentHandle].iFile, qtrue, qtrue);
if (cinTable[currentHandle].ROQSize<=0) {
Com_DPrintf("Can not find RoQ cinematic '%s'\n", name);
CL_FinishedCinematic();
return -1;
}
if ((s && s[0] == '1') || Q_stricmp(arg,"demoend.roq")==0 || Q_stricmp(arg,"end.roq")==0) {
cinTable[currentHandle].holdAtEnd = qtrue;
}
CIN_SetExtents(currentHandle, 0, 0, 640, 480);
cinTable[currentHandle].alterGameState = qtrue;
initRoQ();
FS_Read (cin.file, 16, cinTable[currentHandle].iFile);
RoQID = (unsigned short)(cin.file[0]) + (unsigned short)(cin.file[1])*256;
if (RoQID == 0x1084)
{
RoQ_init();
// FS_Read (cin.file, cinTable[currentHandle].RoQFrameSize+8, cinTable[currentHandle].iFile);
cinTable[currentHandle].status = FMV_PLAY;
Com_DPrintf("trFMV::play(), playing %s\n", arg);
if (cl_movieaudio->integer) {
audioStartTime = Com_Milliseconds();
S_SetupMovieAudio(name);
}
oldClientState = clc.state;
clc.state = CA_CINEMATIC;
if (cls.glconfig.maxTextureSize <= 256 || s && *s == '2') {
//cinTable[currentHandle].interlaced = qtrue;
}
CL_handle = currentHandle;
do {
SCR_RunCinematic();
} while (!cinTable[currentHandle].buf && cinTable[currentHandle].status == FMV_PLAY);
UI_CloseConsole();
return currentHandle;
}
Com_DPrintf("trFMV::play(), invalid RoQ ID\n");
RoQShutdown();
return -1;
}
void CL_PlayCinematic_f(void) {
char *arg, *s;
int bits = CIN_system;
char name[256];
Com_DPrintf("CL_PlayCinematic_f\n");
if (clc.state == CA_CINEMATIC) {
SCR_StopCinematic();
}
arg = Cmd_Argv( 1 );
Com_DPrintf("CL_PlayCinematic( %s )\n", arg);
s = Cmd_Argv(2);
if ((s && s[0] == '1') || Q_stricmp(arg,"demoend.roq")==0 || Q_stricmp(arg,"end.roq")==0) {
bits |= CIN_hold;
}
if (s && s[0] == '2') {
bits |= CIN_loop;
CL_StartHunkUsers(qfalse);
S_StopAllSounds2(qtrue);
Com_sprintf(name, sizeof(name), "video/%s", arg);
if (Q_stricmp(&name[strlen(name) - 4], ".roq")) {
Com_Printf("Bad or missing cinematic extension.\n");
return;
}
S_StopAllSounds2( qtrue );
CL_handle = CIN_PlayCinematic( arg, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, bits );
if (CL_handle >= 0) {
do {
SCR_RunCinematic();
} while (cinTable[currentHandle].buf == NULL && cinTable[currentHandle].status == FMV_PLAY); // wait for first frame (load codebook and sound)
}
CL_PlayRoQ(name, arg, s);
}
@@ -1639,7 +1756,5 @@ void SCR_RunCinematic (void)
void SCR_StopCinematic(void) {
if (CL_handle >= 0 && CL_handle < MAX_VIDEO_HANDLES) {
CIN_StopCinematic(CL_handle);
S_StopAllSounds2( qtrue );
CL_handle = -1;
}
}
+188 -19
View File
@@ -56,6 +56,10 @@ qboolean in_guimouse;
kbutton_t in_up, in_down;
#ifdef USE_VOIP
kbutton_t in_voiprecord;
#endif
kbutton_t in_buttons[16];
qboolean in_mlooking;
@@ -258,6 +262,20 @@ void IN_SpeedUp(void) {IN_KeyUp(&in_speed);}
void IN_StrafeDown(void) {IN_KeyDown(&in_strafe);}
void IN_StrafeUp(void) {IN_KeyUp(&in_strafe);}
#ifdef USE_VOIP
void IN_VoipRecordDown(void)
{
IN_KeyDown(&in_voiprecord);
Cvar_Set("cl_voipSend", "1");
}
void IN_VoipRecordUp(void)
{
IN_KeyUp(&in_voiprecord);
Cvar_Set("cl_voipSend", "0");
}
#endif
void IN_Button0Down(void) {IN_KeyDown(&in_buttons[0]);}
void IN_Button0Up(void) {IN_KeyUp(&in_buttons[0]);}
void IN_Button1Down(void) {IN_KeyDown(&in_buttons[1]);}
@@ -432,7 +450,7 @@ void CL_MouseEvent( int dx, int dy, int time ) {
if( cl.mousey > cls.glconfig.vidHeight )
cl.mousey = cls.glconfig.vidHeight;
}
else
else if ( !paused->integer )
{
cl.mouseDx[cl.mouseIndex] += dx;
cl.mouseDy[cl.mouseIndex] += dy;
@@ -461,6 +479,16 @@ CL_JoystickMove
void CL_JoystickMove( usercmd_t *cmd ) {
float anglespeed;
float yaw = j_yaw->value * cl.joystickAxis[j_yaw_axis->integer];
float right = j_side->value * cl.joystickAxis[j_side_axis->integer];
float forward = j_forward->value * cl.joystickAxis[j_forward_axis->integer];
float pitch = j_pitch->value * cl.joystickAxis[j_pitch_axis->integer];
float up = j_up->value * cl.joystickAxis[j_up_axis->integer];
if ( in_speed.active ^ cl_run->integer ) {
cmd->buttons |= BUTTON_RUN;
}
if ( in_speed.active ) {
anglespeed = 0.001 * cls.frametime * cl_anglespeedkey->value;
} else {
@@ -468,18 +496,22 @@ void CL_JoystickMove( usercmd_t *cmd ) {
}
if ( !in_strafe.active ) {
cl.viewangles[YAW] += anglespeed * cl_yawspeed->value * cl.joystickAxis[AXIS_SIDE];
cl.viewangles[YAW] += anglespeed * yaw;
cmd->rightmove = ClampChar( cmd->rightmove + (int)right );
} else {
cmd->rightmove = ClampChar( cmd->rightmove + cl.joystickAxis[AXIS_SIDE] );
cl.viewangles[YAW] += anglespeed * right;
cmd->rightmove = ClampChar( cmd->rightmove + (int)yaw );
}
if ( in_mlooking ) {
cl.viewangles[PITCH] += anglespeed * cl_pitchspeed->value * cl.joystickAxis[AXIS_FORWARD];
cl.viewangles[PITCH] += anglespeed * forward;
cmd->forwardmove = ClampChar( cmd->forwardmove + (int)pitch );
} else {
cmd->forwardmove = ClampChar( cmd->forwardmove + cl.joystickAxis[AXIS_FORWARD] );
cl.viewangles[PITCH] += anglespeed * pitch;
cmd->forwardmove = ClampChar( cmd->forwardmove + (int)forward );
}
cmd->upmove = ClampChar( cmd->upmove + cl.joystickAxis[AXIS_UP] );
cmd->upmove = ClampChar( cmd->upmove + (int)up );
}
/*
@@ -565,6 +597,8 @@ void CL_MouseMove( usercmd_t *cmd ) {
mx *= cgameSensitivity;
my *= cgameSensitivity;
cmd->buttons |= BUTTON_ANY;
// add mouse X/Y movement to cmd
if(in_strafe.active)
cmd->rightmove = ClampChar(cmd->rightmove + m_side->value * mx);
@@ -575,6 +609,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_DPrintf("Invalid client viewangles encountered (view pitch: %f, view yaw: %f)!\n", cl.viewangles[PITCH], cl.viewangles[YAW]);
Com_DPrintf("cgameSensitivity: %f | mx: %f | my: %f | m_pitch: %f | m_yaw: %f\n", cgameSensitivity, mx, my, m_pitch->value, m_yaw->value);
Com_DPrintf("Resetting client viewangles\n");
cl.viewangles[PITCH] = 0;
cl.viewangles[YAW] = 0;
}
}
/*
@@ -609,8 +651,8 @@ void CL_CmdButtons( usercmd_t *cmd ) {
if (UI_MenuActive() || UI_ConsoleIsOpen()) {
cmd->buttons |= BUTTON_TALK;
}
if (in_speed.active == !cl_run->integer) {
if ( in_speed.active ^ cl_run->integer ) {
cmd->buttons |= BUTTON_RUN;
}
@@ -718,6 +760,12 @@ void CL_CreateNewCommands( void ) {
frame_msec = com_frameTime - old_com_frameTime;
// if running over 1000fps, act as if each frame is 1ms
// prevents divisions by zero
if ( frame_msec < 1 ) {
frame_msec = 1;
}
// if running less than 5fps, truncate the extra time to prevent
// unexpected moves after a hitch
if ( frame_msec > 200 ) {
@@ -909,6 +957,58 @@ void CL_WritePacket( void ) {
count = MAX_PACKET_USERCMDS;
Com_Printf("MAX_PACKET_USERCMDS\n");
}
#ifdef USE_VOIP
if (clc.voipOutgoingDataSize > 0)
{
if((clc.voipFlags & VOIP_SPATIAL) || Com_IsVoipTarget(clc.voipTargets, sizeof(clc.voipTargets), -1))
{
MSG_WriteByte (&buf, clc_voipOpus);
MSG_WriteByte (&buf, clc.voipOutgoingGeneration);
MSG_WriteLong (&buf, clc.voipOutgoingSequence);
MSG_WriteByte (&buf, clc.voipOutgoingDataFrames);
MSG_WriteData (&buf, clc.voipTargets, sizeof(clc.voipTargets));
MSG_WriteByte(&buf, clc.voipFlags);
MSG_WriteShort (&buf, clc.voipOutgoingDataSize);
MSG_WriteData (&buf, clc.voipOutgoingData, clc.voipOutgoingDataSize);
// If we're recording a demo, we have to fake a server packet with
// this VoIP data so it gets to disk; the server doesn't send it
// back to us, and we might as well eliminate concerns about dropped
// and misordered packets here.
if(clc.demorecording && !clc.demowaiting)
{
const int voipSize = clc.voipOutgoingDataSize;
msg_t fakemsg;
byte fakedata[MAX_MSGLEN];
MSG_Init (&fakemsg, fakedata, sizeof (fakedata));
MSG_Bitstream (&fakemsg);
MSG_WriteLong (&fakemsg, clc.reliableAcknowledge);
MSG_WriteByte (&fakemsg, svc_voipOpus);
MSG_WriteShort (&fakemsg, clc.clientNum);
MSG_WriteByte (&fakemsg, clc.voipOutgoingGeneration);
MSG_WriteLong (&fakemsg, clc.voipOutgoingSequence);
MSG_WriteByte (&fakemsg, clc.voipOutgoingDataFrames);
MSG_WriteShort (&fakemsg, clc.voipOutgoingDataSize );
MSG_WriteBits (&fakemsg, clc.voipFlags, VOIP_FLAGCNT);
MSG_WriteData (&fakemsg, clc.voipOutgoingData, voipSize);
MSG_WriteByte (&fakemsg, svc_EOF);
CL_WriteDemoMessage (&fakemsg, 0);
}
clc.voipOutgoingSequence += clc.voipOutgoingDataFrames;
clc.voipOutgoingDataSize = 0;
clc.voipOutgoingDataFrames = 0;
}
else
{
// We have data, but no targets. Silently discard all data
clc.voipOutgoingDataSize = 0;
clc.voipOutgoingDataFrames = 0;
}
}
#endif
if ( count >= 1 ) {
if ( cl_showSend->integer ) {
Com_Printf( "(%i)", count );
@@ -965,16 +1065,6 @@ void CL_WritePacket( void ) {
}
CL_Netchan_Transmit (&clc.netchan, &buf);
// clients never really should have messages large enough
// to fragment, but in case they do, fire them all off
// at once
// TTimo: this causes a packet burst, which is bad karma for winsock
// added a WARNING message, we'll see if there are legit situations where this happens
while ( clc.netchan.unsentFragments ) {
Com_DPrintf( "WARNING: #462 unsent fragments (not supposed to happen!)\n" );
CL_Netchan_TransmitNextFragment( &clc.netchan );
}
}
/*
@@ -991,7 +1081,7 @@ void CL_SendCmd( void ) {
}
// don't send commands if paused
if ( com_sv_running->integer && paused->integer && paused->integer ) {
if ( com_sv_running->integer && paused->integer ) {
return;
}
@@ -1086,6 +1176,85 @@ void CL_InitInput( void ) {
Cmd_AddCommand("+mlook", IN_MLookDown);
Cmd_AddCommand("-mlook", IN_MLookUp);
#ifdef USE_VOIP
Cmd_AddCommand ("+voiprecord", IN_VoipRecordDown);
Cmd_AddCommand ("-voiprecord", IN_VoipRecordUp);
#endif
cl_nodelta = Cvar_Get ("cl_nodelta", "0", 0);
cl_debugMove = Cvar_Get ("cl_debugMove", "0", 0);
}
/*
============
CL_ShutdownInput
============
*/
void CL_ShutdownInput(void)
{
Cmd_RemoveCommand("centerview");
Cmd_RemoveCommand("+moveup");
Cmd_RemoveCommand("-moveup");
Cmd_RemoveCommand("+movedown");
Cmd_RemoveCommand("-movedown");
Cmd_RemoveCommand("+left");
Cmd_RemoveCommand("-left");
Cmd_RemoveCommand("+right");
Cmd_RemoveCommand("-right");
Cmd_RemoveCommand("+forward");
Cmd_RemoveCommand("-forward");
Cmd_RemoveCommand("+back");
Cmd_RemoveCommand("-back");
Cmd_RemoveCommand("+lookup");
Cmd_RemoveCommand("-lookup");
Cmd_RemoveCommand("+lookdown");
Cmd_RemoveCommand("-lookdown");
Cmd_RemoveCommand("+strafe");
Cmd_RemoveCommand("-strafe");
Cmd_RemoveCommand("+moveleft");
Cmd_RemoveCommand("-moveleft");
Cmd_RemoveCommand("+moveright");
Cmd_RemoveCommand("-moveright");
Cmd_RemoveCommand("+speed");
Cmd_RemoveCommand("-speed");
Cmd_RemoveCommand("+attack");
Cmd_RemoveCommand("-attack");
Cmd_RemoveCommand("+button0");
Cmd_RemoveCommand("-button0");
Cmd_RemoveCommand("+button1");
Cmd_RemoveCommand("-button1");
Cmd_RemoveCommand("+button2");
Cmd_RemoveCommand("-button2");
Cmd_RemoveCommand("+button3");
Cmd_RemoveCommand("-button3");
Cmd_RemoveCommand("+button4");
Cmd_RemoveCommand("-button4");
Cmd_RemoveCommand("+button5");
Cmd_RemoveCommand("-button5");
Cmd_RemoveCommand("+button6");
Cmd_RemoveCommand("-button6");
Cmd_RemoveCommand("+button7");
Cmd_RemoveCommand("-button7");
Cmd_RemoveCommand("+button8");
Cmd_RemoveCommand("-button8");
Cmd_RemoveCommand("+button9");
Cmd_RemoveCommand("-button9");
Cmd_RemoveCommand("+button10");
Cmd_RemoveCommand("-button10");
Cmd_RemoveCommand("+button11");
Cmd_RemoveCommand("-button11");
Cmd_RemoveCommand("+button12");
Cmd_RemoveCommand("-button12");
Cmd_RemoveCommand("+button13");
Cmd_RemoveCommand("-button13");
Cmd_RemoveCommand("+button14");
Cmd_RemoveCommand("-button14");
Cmd_RemoveCommand("+mlook");
Cmd_RemoveCommand("-mlook");
#ifdef USE_VOIP
Cmd_RemoveCommand("+voiprecord");
Cmd_RemoveCommand("-voiprecord");
#endif
}
+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);
+933 -915
View File
File diff suppressed because it is too large. Load diff
+567 -379
View File
File diff suppressed because it is too large. Load diff
+23 -3
View File
@@ -132,7 +132,7 @@ CL_Netchan_TransmitNextFragment
=================
*/
void CL_Netchan_TransmitNextFragment( netchan_t *chan ) {
Netchan_TransmitNextFragment( chan );
Netchan_TransmitNextFragment( chan, cl_netprofile->integer ? &cls.netprofile.inPackets : NULL );
}
/*
@@ -144,7 +144,7 @@ void CL_Netchan_Transmit( netchan_t *chan, msg_t* msg ) {
MSG_WriteByte( msg, clc_EOF );
CL_Netchan_Encode( msg );
Netchan_Transmit( chan, msg->cursize, msg->data );
Netchan_Transmit( chan, msg->cursize, msg->data, cl_netprofile->integer ? &cls.netprofile.inPackets : NULL );
}
extern int oldsize;
@@ -158,10 +158,30 @@ CL_Netchan_Process
qboolean CL_Netchan_Process( netchan_t *chan, msg_t *msg ) {
int ret;
ret = Netchan_Process( chan, msg );
ret = Netchan_Process( chan, msg, cl_netprofile->integer ? &cls.netprofile.outPackets : NULL );
if (!ret)
return qfalse;
CL_Netchan_Decode( msg );
newsize += msg->cursize;
return qtrue;
}
/*
=================
CL_NET_OutOfBandPrint
=================
*/
void CL_NET_OutOfBandPrint(netadr_t adr, const char* format, ...) {
va_list argptr;
char string[MAX_MSGLEN];
va_start(argptr, format);
Q_vsnprintf(string, sizeof(string), format, argptr);
va_end(argptr);
NET_OutOfBandPrint(NS_CLIENT, adr, "%s", string);
if (cl_netprofile->integer) {
NetProfileAddPacket(&cls.netprofile.inPackets, strlen(string), NETPROF_PACKET_MESSAGE);
}
}
+199 -7
View File
@@ -223,13 +223,13 @@ qboolean CL_UnpackNonPVSClient(int* packed, radarUnpacked_t* unpacked) {
range = 0;
}
unpacked->x = x * range / 63.f;
unpacked->y = y * range / 63.f;
unpacked->x = x * range / (MAX_CLIENTS - 1);
unpacked->y = y * range / (MAX_CLIENTS - 1);
if (!bValid)
{
unpacked->x = x * range / 63.f * 1024;
unpacked->y = y * range / 63.f * 1024;
unpacked->x = x * range / (MAX_CLIENTS - 1) * 1024.0;
unpacked->y = y * range / (MAX_CLIENTS - 1) * 1024.0;
}
unpacked->yaw = yaw * 11.25f;
@@ -429,12 +429,24 @@ void CL_SystemInfoChanged( void ) {
// in some cases, outdated cp commands might get sent with this news serverId
cl.serverId = atoi( Info_ValueForKey( systemInfo, "sv_serverid" ) );
#ifdef USE_VOIP
#ifdef LEGACY_PROTOCOL
if(clc.compat)
clc.voipEnabled = qfalse;
else
#endif
{
s = Info_ValueForKey( systemInfo, "sv_voipProtocol" );
clc.voipEnabled = !Q_stricmp(s, "opus");
}
#endif
// don't set any vars when playing a demo
if ( clc.demoplaying ) {
return;
}
s = Info_ValueForKey( systemInfo, "sv_cheats" );
s = Info_ValueForKey( systemInfo, "cheats" );
cl_connectedToCheatServer = atoi( s );
if ( !cl_connectedToCheatServer ) {
Cvar_SetCheatState();
@@ -784,6 +796,178 @@ void CL_ParseDownload ( msg_t *msg ) {
}
}
#ifdef USE_VOIP
static
qboolean CL_ShouldIgnoreVoipSender(int sender)
{
if (!cl_voip->integer)
return qtrue; // VoIP is disabled.
else if ((sender == clc.clientNum) && (!clc.demoplaying))
return qtrue; // ignore own voice (unless playing back a demo).
else if (clc.voipMuteAll)
return qtrue; // all channels are muted with extreme prejudice.
else if (clc.voipIgnore[sender])
return qtrue; // just ignoring this guy.
else if (clc.voipGain[sender] == 0.0f)
return qtrue; // too quiet to play.
return qfalse;
}
/*
=====================
CL_PlayVoip
Play raw data
=====================
*/
static void CL_PlayVoip(int sender, int samplecnt, const byte *data, int flags)
{
if(flags & VOIP_DIRECT)
{
S_RawSamples(sender + 1, samplecnt, 48000, 2, 1,
data, clc.voipGain[sender], -1);
}
if(flags & VOIP_SPATIAL)
{
S_RawSamples(sender + MAX_CLIENTS + 1, samplecnt, 48000, 2, 1,
data, 1.0f, sender);
}
}
/*
=====================
CL_ParseVoip
A VoIP message has been received from the server
=====================
*/
static
void CL_ParseVoip ( msg_t *msg, qboolean ignoreData ) {
static short decoded[VOIP_MAX_PACKET_SAMPLES*4]; // !!! FIXME: don't hard code
const int sender = MSG_ReadShort(msg);
const int generation = MSG_ReadByte(msg);
const int sequence = MSG_ReadLong(msg);
const int frames = MSG_ReadByte(msg);
const int packetsize = MSG_ReadShort(msg);
const int flags = MSG_ReadBits(msg, VOIP_FLAGCNT);
unsigned char encoded[4000];
int numSamples;
int seqdiff;
int written = 0;
int i;
Com_DPrintf("VoIP: %d-byte packet from client %d\n", packetsize, sender);
if (sender < 0)
return; // short/invalid packet, bail.
else if (generation < 0)
return; // short/invalid packet, bail.
else if (sequence < 0)
return; // short/invalid packet, bail.
else if (frames < 0)
return; // short/invalid packet, bail.
else if (packetsize < 0)
return; // short/invalid packet, bail.
if (packetsize > sizeof (encoded)) { // overlarge packet?
int bytesleft = packetsize;
while (bytesleft) {
int br = bytesleft;
if (br > sizeof (encoded))
br = sizeof (encoded);
MSG_ReadData(msg, encoded, br);
bytesleft -= br;
}
return; // overlarge packet, bail.
}
MSG_ReadData(msg, encoded, packetsize);
if (ignoreData) {
return; // just ignore legacy speex voip data
} else if (!clc.voipCodecInitialized) {
return; // can't handle VoIP without libopus!
} else if (sender >= MAX_CLIENTS) {
return; // bogus sender.
} else if (CL_ShouldIgnoreVoipSender(sender)) {
return; // Channel is muted, bail.
}
// !!! FIXME: make sure data is narrowband? Does decoder handle this?
Com_DPrintf("VoIP: packet accepted!\n");
seqdiff = sequence - clc.voipIncomingSequence[sender];
// This is a new "generation" ... a new recording started, reset the bits.
if (generation != clc.voipIncomingGeneration[sender]) {
Com_DPrintf("VoIP: new generation %d!\n", generation);
opus_decoder_ctl(clc.opusDecoder[sender], OPUS_RESET_STATE);
clc.voipIncomingGeneration[sender] = generation;
seqdiff = 0;
} else if (seqdiff < 0) { // we're ahead of the sequence?!
// This shouldn't happen unless the packet is corrupted or something.
Com_DPrintf("VoIP: misordered sequence! %d < %d!\n",
sequence, clc.voipIncomingSequence[sender]);
// reset the decoder just in case.
opus_decoder_ctl(clc.opusDecoder[sender], OPUS_RESET_STATE);
seqdiff = 0;
} else if (seqdiff * VOIP_MAX_PACKET_SAMPLES*2 >= sizeof (decoded)) { // dropped more than we can handle?
// just start over.
Com_DPrintf("VoIP: Dropped way too many (%d) frames from client #%d\n",
seqdiff, sender);
opus_decoder_ctl(clc.opusDecoder[sender], OPUS_RESET_STATE);
seqdiff = 0;
}
if (seqdiff != 0) {
Com_DPrintf("VoIP: Dropped %d frames from client #%d\n",
seqdiff, sender);
// tell opus that we're missing frames...
for (i = 0; i < seqdiff; i++) {
assert((written + VOIP_MAX_PACKET_SAMPLES) * 2 < sizeof (decoded));
numSamples = opus_decode(clc.opusDecoder[sender], NULL, 0, decoded + written, VOIP_MAX_PACKET_SAMPLES, 0);
if ( numSamples <= 0 ) {
Com_DPrintf("VoIP: Error decoding frame %d from client #%d\n", i, sender);
continue;
}
written += numSamples;
}
}
numSamples = opus_decode(clc.opusDecoder[sender], encoded, packetsize, decoded + written, ARRAY_LEN(decoded) - written, 0);
if ( numSamples <= 0 ) {
Com_DPrintf("VoIP: Error decoding voip data from client #%d\n", sender);
numSamples = 0;
}
#if 0
static FILE *encio = NULL;
if (encio == NULL) encio = fopen("voip-incoming-encoded.bin", "wb");
if (encio != NULL) { fwrite(encoded, packetsize, 1, encio); fflush(encio); }
static FILE *decio = NULL;
if (decio == NULL) decio = fopen("voip-incoming-decoded.bin", "wb");
if (decio != NULL) { fwrite(decoded+written, numSamples*2, 1, decio); fflush(decio); }
#endif
written += numSamples;
Com_DPrintf("VoIP: playback %d bytes, %d samples, %d frames\n",
written * 2, written, frames);
if(written > 0)
CL_PlayVoip(sender, written, (const byte *) decoded, flags);
clc.voipIncomingSequence[sender] = sequence + frames;
}
#endif
/*
=====================
CL_ParseCommandString
@@ -932,8 +1116,16 @@ void CL_ParseServerMessage( msg_t *msg ) {
}
CL_ParseCGMessage( msg );
break;
case svc_voipSpeex:
#ifdef USE_VOIP
CL_ParseVoip( msg, qtrue );
#endif
break;
case svc_voipOpus:
#ifdef USE_VOIP
CL_ParseVoip( msg, !clc.voipEnabled );
#endif
break;
}
}
}
+8 -6
View File
@@ -343,7 +343,7 @@ void SCR_DrawDemoRecording( void ) {
}
pos = FS_FTell( clc.demofile );
sprintf( string, "RECORDING %s: %ik", clc.demoName, pos / 1024 );
Com_sprintf( string, sizeof( string ), "RECORDING %s: %ik", clc.demoName, pos / 1024 );
SCR_DrawStringExt( 320 - strlen( string ) * 4, 20, 8, string, g_color_table[7], qtrue, qfalse );
}
@@ -520,16 +520,18 @@ text to the screen.
==================
*/
void SCR_UpdateScreen( void ) {
static int recursive;
static qboolean screen_recursive;
if ( !scr_initialized ) {
return; // not initialized yet
}
if ( ++recursive > 2 ) {
Com_Error( ERR_FATAL, "SCR_UpdateScreen: recursively called" );
if (screen_recursive) {
// already called
return;
}
recursive = 1;
screen_recursive = qtrue;
CL_StartHunkUsers(qfalse);
SCR_SimpleUpdateScreen();
@@ -553,6 +555,6 @@ void SCR_UpdateScreen( void ) {
}
}
recursive = 0;
screen_recursive = qfalse;
}
+403 -245
View File
File diff suppressed because it is too large. Load diff
+5 -1
View File
@@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2023 the OpenMoHAA team
Copyright (C) 2023-2024 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@@ -35,6 +35,7 @@ typedef struct {
extern cvar_t *ui_health_start;
extern cvar_t *ui_health_end;
extern cvar_t *sound_overlay;
extern cvar_t *cl_movieaudio;
//
// initialization
@@ -49,11 +50,13 @@ void CL_ShutdownUI(void);
extern inventory_t client_inv;
extern bind_t client_bind;
extern cvar_t *cl_greenfps;
extern qboolean server_loading;
const char *CvarGetForUI(const char *name, const char *defval);
void UI_ClearState(void);
void CL_BeginRegistration(void);
void CL_EndRegistration(void);
float UI_GetObjectivesTop(void);
//
// menu
@@ -110,6 +113,7 @@ void UI_DeleteScoreBoardItems(int iMaxIndex);
void UI_BeginLoad(const char *pszMapName);
void UI_EndLoad(void);
void UI_AbortLoad(void);
int CL_FontStringWidth(fontheader_t* pFont, const char* pszString, int iMaxLen);
void UI_BeginLoadResource(void);
void UI_EndLoadResource(void);
void UI_EndLoadResource(const char *name);
+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);
+28 -1
View File
@@ -61,6 +61,7 @@ UIDMBox::UIDMBox()
m_iBeginDecay = 0;
m_boxtime = uid.time;
m_movespeed = 500;
m_drawoutline = com_target_game->integer >= target_game_e::TG_MOHTA;
}
void UIDMBox::VerifyBoxOut( void )
@@ -278,6 +279,28 @@ float UIDMBox::PrintWrap( UIFont *font, float x, float y, str text )
float UIDMBox::DrawItem( item_t *in, float x, float y, float alpha )
{
if (m_drawoutline) {
//
// Draw an outline
//
in->font->setColor(UBlack);
in->font->setAlpha(alpha);
PrintWrap(in->font, x + 1, y + 2, in->string);
PrintWrap(in->font, x + 2, y + 1, in->string);
PrintWrap(in->font, x - 1, y + 2, in->string);
PrintWrap(in->font, x - 2, y + 1, in->string);
PrintWrap(in->font, x - 1, y - 2, in->string);
PrintWrap(in->font, x - 2, y - 1, in->string);
PrintWrap(in->font, x + 1, y - 2, in->string);
PrintWrap(in->font, x + 2, y - 1, in->string);
PrintWrap(in->font, x + 2, y, in->string);
PrintWrap(in->font, x - 2, y, in->string);
PrintWrap(in->font, x, y + 2, in->string);
PrintWrap(in->font, x, y - 2, in->string);
}
in->font->setColor(in->color);
in->font->setAlpha(alpha);
@@ -316,7 +339,11 @@ void UIDMBox::Print( const char *text )
}
else if (*text == MESSAGE_CHAT_GREEN)
{
m_items[m_numitems].color = UGreen;
if (com_target_game->integer >= TG_MOHTA) {
m_items[m_numitems].color = ULightGreen;
} else {
m_items[m_numitems].color = UGreen;
}
m_items[m_numitems].font = m_fontbold;
m_items[m_numitems].flags |= DMBOX_ITEM_FLAG_DEATH;
+4 -5
View File
@@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
Copyright (C) 2015-2024 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@@ -20,8 +20,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#ifndef __CL_UIDMBOX_H__
#define __CL_UIDMBOX_H__
#pragma once
static constexpr unsigned int DMBOX_ITEM_FLAG_BOLD = 2u;
static constexpr unsigned int DMBOX_ITEM_FLAG_DEATH = 4u;
@@ -47,6 +46,8 @@ protected:
int m_movespeed;
int m_iBeginDecay;
int m_iEndDecay;
// Added in OPM
bool m_drawoutline;
public:
CLASS_PROTOTYPE( UIDMBox );
@@ -75,5 +76,3 @@ public:
void setRealShow( bool b );
void Clear( void );
};
#endif /* __CL_UIDMBOX_H__ */
+211 -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,256 @@ 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;
if (ignore_files) {
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__ */
+23
View File
@@ -61,6 +61,7 @@ UIGMBox::UIGMBox()
m_iBeginDecay = 0;
m_boxtime = uid.time;
m_movespeed = 500;
m_drawoutline = com_target_game->integer >= target_game_e::TG_MOHTA;
}
void UIGMBox::VerifyBoxOut( void )
@@ -272,6 +273,28 @@ float UIGMBox::PrintWrap( UIFont *font, float x, float y, str text )
float UIGMBox::DrawItem( item_t *in, float x, float y, float alpha )
{
if (m_drawoutline) {
//
// Draw an outline
//
in->font->setColor(UBlack);
in->font->setAlpha(alpha);
PrintWrap(in->font, x + 1, y + 2, in->string);
PrintWrap(in->font, x + 2, y + 1, in->string);
PrintWrap(in->font, x - 1, y + 2, in->string);
PrintWrap(in->font, x - 2, y + 1, in->string);
PrintWrap(in->font, x - 1, y - 2, in->string);
PrintWrap(in->font, x - 2, y - 1, in->string);
PrintWrap(in->font, x + 1, y - 2, in->string);
PrintWrap(in->font, x + 2, y - 1, in->string);
PrintWrap(in->font, x + 2, y, in->string);
PrintWrap(in->font, x - 2, y, in->string);
PrintWrap(in->font, x, y + 2, in->string);
PrintWrap(in->font, x, y - 2, in->string);
}
in->font->setColor(in->color);
in->font->setAlpha(alpha);
+4 -5
View File
@@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
Copyright (C) 2015-2024 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@@ -20,8 +20,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#ifndef __CL_UIGMBOX_H__
#define __CL_UIGMBOX_H__
#pragma once
static constexpr unsigned int GMBOX_ITEM_FLAG_BOLD = 1u;
@@ -44,6 +43,8 @@ protected:
int m_movespeed;
int m_iBeginDecay;
int m_iEndDecay;
// Added in OPM
bool m_drawoutline;
public:
CLASS_PROTOTYPE( UIGMBox );
@@ -72,5 +73,3 @@ public:
void setRealShow( bool b );
void Clear( void );
};
#endif
+197 -17
View File
@@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
Copyright (C) 2023-2024 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@@ -21,44 +21,224 @@ 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[6];
public:
LANGameItem();
LANGameItem(
const str& hostName, const str& mapName, const str& players, const str& gameTypeString, const str& ping, const str& ipAddress
);
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");
//
// Added in OPM
//
m_bVirtual = false;
}
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.27f, false, false); // was 0.4
AddColumn(Sys_LV_CL_ConvertString("Map"), 1, width * 0.12f, false, false); // was 0.15
AddColumn(Sys_LV_CL_ConvertString("Players"), 2, width * 0.08f, true, true); // was 0.165
AddColumn(Sys_LV_CL_ConvertString("GameType"), 3, width * 0.118f, false, false); // was 0.22
AddColumn(Sys_LV_CL_ConvertString("Ping"), 4, width * 0.052f, true, false); // was 0.065
AddColumn(Sys_LV_CL_ConvertString("IP"), 5, width * 0.36f, false, false); // Added in OPM
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),
// Added in OPM
NET_AdrToStringwPort(pServerInfo->adr)
);
}
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_AdrToStringwPort(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, const str& ipAddress
)
{
strings[0] = hostName;
strings[1] = mapName;
strings[2] = players;
strings[3] = gameTypeString;
strings[4] = ping;
//
// Added in OPM
//
strings[5] = ipAddress;
}
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__ */
+319 -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,357 @@ 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(true);
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);
Com_SwapSaveStruct(&save);
if (save.version != SAVEGAME_STRUCT_VERSION) {
// wrong save game version
continue;
}
if (save.type != com_target_game->integer) {
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 UIListCtrl::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);
};
+457
View File
@@ -0,0 +1,457 @@
/*
===========================================================================
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);
}
Q_strncpyz(mapBuffer, maplistVar->string, sizeof(mapBuffer));
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;
Q_strncpyz(mapName, filename, sizeof(mapName));
mapName[strlen(mapName) - 4] = 0;
if (!COM_IsMapValid(mapName)) {
continue;
}
if (bTugOfWar || bLiberation) {
Q_strncpyz(tokenized, mapName, sizeof(tokenized));
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) {
Q_strncpyz(tokenized, mapName, sizeof(tokenized));
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];
Q_strncpyz(mapName, filename, sizeof(mapName));
mapName[strlen(mapName) - 4] = 0;
Q_strncpyz(tokenized, mapName, sizeof(tokenized));
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];
Q_strncpyz(mapName, filename, sizeof(mapName));
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();
str currentItemText;
if (item) {
currentItemText = mapList->getItemText(item);
}
for (i = 1; i <= rotationList->getNumItems(); i++) {
str text = rotationList->getItemText(i);
if (text == currentItemText) {
// Added in OPM
// Prevent adding duplicates
item = 0;
break;
}
mapLength += text.length();
}
if (item && prefixLength + mapLength + currentItemText.length() < 256) {
rotationList->AddItem(currentItemText, 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;
Q_strncpyz(map, text, sizeof(map));
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;
if (i == 1) {
Cvar_Set("ui_dmmap", maplistStr);
}
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 > 1 && list->getNumItems() > 1) {
str text = list->getItemText(item - 1);
list->DeleteItem(item - 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(item + 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-2024 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() - 1; 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
+293 -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,339 @@ 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 (com_target_game->integer > target_game_e::TG_MOH) {
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_waffenss_", 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);
+14 -11
View File
@@ -58,7 +58,7 @@ void UIRadar::Draw(void)
float inv;
float iconSize;
int blinkTime, speakTime;
float origin[2], axis[2];
vec2_t origin, axis;
float halfScale;
int i;
@@ -105,17 +105,17 @@ void UIRadar::Draw(void)
halfScale = iconSize * 0.5f;
for (i = 0; i < MAX_CLIENTS; i++) {
float delta[2];
float newOrg[2];
float screenOrg[2];
float length;
vec2_t delta;
vec2_t newOrg;
vec2_t screenOrg;
float length;
radar = &g_radarClients[i];
if (i == g_radarClientNum) {
continue;
}
if (!g_radarClients[i].time) {
if (!radar->time) {
continue;
}
@@ -128,10 +128,13 @@ void UIRadar::Draw(void)
// make the icon blink
if (delta >= 0 && delta < speakTime && ((delta / blinkTime) % 2) == 0) {
continue;
}
if (delta < 0 || delta >= speakTime) {
radar->lastSpeakTime = 0;
}
}
radar->lastSpeakTime = 0;
delta[0] = radar->origin[0] - origin[0];
delta[1] = radar->origin[1] - origin[1];
newOrg[0] = -(delta[0] * axis[0] + delta[1] * axis[1]) * inv;
@@ -140,12 +143,12 @@ void UIRadar::Draw(void)
if (length > 1)
{
newOrg[0] = -(delta[0] * axis[0] + delta[1] * axis[1]) * inv * (1.f / length);
newOrg[1] = (delta[0] * axis[1] + delta[1] * -axis[0]) * inv * (1.f / length);
newOrg[0] *= 1.f / length;
newOrg[1] *= 1.f / length;
}
screenOrg[0] = -((halfScale * (1.141f * newOrg[1] + m_vVirtualScale[0])) - ((1.f + newOrg[1]) * 0.5f * m_frame.size.width));
screenOrg[1] = -((halfScale * (1.141f * newOrg[0] + m_vVirtualScale[1])) - ((1.f + newOrg[0]) * 0.5f * m_frame.size.height));
screenOrg[0] = -((halfScale * (1.414f * newOrg[1] + m_vVirtualScale[0])) - ((1.f + newOrg[1]) * 0.5f * m_frame.size.width));
screenOrg[1] = -((halfScale * (1.414f * newOrg[0] + m_vVirtualScale[1])) - ((1.f + newOrg[0]) * 0.5f * m_frame.size.height));
uii.Rend_DrawPicStretched2(
screenOrg[0],
+79 -35
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,
@@ -638,6 +651,9 @@ static void AddFilter(char* filter, const char* value) {
void UIFAKKServerList::CancelRefresh( Event *ev )
{
ServerListHalt(m_serverList[0]);
if (m_serverList[1]) {
ServerListHalt(m_serverList[1]);
}
}
void UIFAKKServerList::NewServerList( void )
@@ -730,6 +746,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 )
@@ -1016,31 +1040,51 @@ void UpdateServerListCallBack(GServerList serverlist, int msg, void* instance, v
{
const char* pszHostName;
bool bDiffVersion;
bool bIsDemo;
str sServerName;
str sPlayers;
const char* pszGameVer;
const char* pszGameVerNumber;
pszHostName = ServerGetStringValue(server, "hostname", "(NONE)");
bDiffVersion = false;
bIsDemo = false;
pszGameVer = ServerGetStringValue(server, "gamever", "1.00");
pszGameVerNumber = pszGameVer;
if (pszGameVerNumber[0] == 'd') {
// demo server
pszGameVerNumber++;
bIsDemo = true;
}
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;
}
}
// always show the version
sServerName = va(" (%s) %s", pszGameVer, pszHostName);
if (!bIsDemo) {
sServerName = va(" (%s) %s", pszGameVerNumber, pszHostName);
} else {
sServerName = va(" (d%s) %s", pszGameVerNumber, pszHostName);
}
iRealIP = inet_addr(ServerGetAddress(server));
iPort = ServerGetIntValue(server, "hostport", PORT_SERVER);
@@ -1056,7 +1100,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 +1198,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__ */
+257 -236
View File
@@ -439,8 +439,10 @@ void UIFakkLabel::LayoutRenderModelAnim(Event *ev)
void UIFakkLabel::DrawStatbar(float frac)
{
vec4_t col;
float alpha;
vec4_t col;
float alpha;
qhandle_t hMat;
float w, h;
col[0] = col[1] = col[2] = col[3] = 1.0;
@@ -475,11 +477,7 @@ void UIFakkLabel::DrawStatbar(float frac)
m_lastfrac = frac;
alpha = 1.0 - ((float)uid.time - m_flashtime) / 1500.0;
if (alpha < 0.0) {
alpha = 0.0;
} else if (alpha > 1.0) {
alpha = 1.0;
}
alpha = Q_clamp_float(alpha, 0, 1);
col[3] = alpha;
@@ -490,14 +488,30 @@ void UIFakkLabel::DrawStatbar(float frac)
{
float width = frac * m_frame.size.width;
m_statbar_material->ReregisterMaterial();
re.DrawTilePic(0.0, 0.0, width, m_frame.size.height, m_statbar_material->GetMaterial());
if (alpha != 0.0 && m_statbar_material_flash) {
re.SetColor(col);
m_statbar_material_flash->ReregisterMaterial();
re.DrawTilePic(0.0, 0.0, width, m_frame.size.height, m_statbar_material_flash->GetMaterial());
}
if (m_statbar_material_marker) {
hMat = m_statbar_material_marker->GetMaterial();
w = re.GetShaderWidth(hMat);
h = re.GetShaderHeight(hMat);
re.DrawStretchPic(
m_frame.size.width * frac - w * 0.5,
m_frame.size.height * 0.5 - h * 0.5,
w,
h,
0,
0,
1,
1,
hMat
);
}
break;
}
case L_STATBAR_VERTICAL:
@@ -507,16 +521,32 @@ void UIFakkLabel::DrawStatbar(float frac)
{
float y = m_frame.size.height * (1.0 - frac);
m_statbar_material->ReregisterMaterial();
re.DrawTilePic(0.0, y, m_frame.size.width, m_frame.size.height, m_statbar_material->GetMaterial());
if (alpha != 0.0 && m_statbar_material_flash) {
re.SetColor(col);
m_statbar_material_flash->ReregisterMaterial();
re.DrawTilePic(
0.0, y, m_frame.size.width, m_frame.size.height, m_statbar_material_flash->GetMaterial()
);
}
if (m_statbar_material_marker) {
hMat = m_statbar_material_marker->GetMaterial();
w = re.GetShaderWidth(hMat);
h = re.GetShaderHeight(hMat);
re.DrawStretchPic(
m_frame.size.width * frac - w * 0.5,
m_frame.size.height * 0.5 - h * 0.5,
w,
h,
0,
0,
1,
1,
hMat
);
}
break;
}
default:
@@ -528,14 +558,12 @@ void UIFakkLabel::DrawStatbar(float frac)
{
float width = frac * m_frame.size.width;
m_statbar_material->ReregisterMaterial();
re.DrawStretchPic(
0.0, 0.0, width, m_frame.size.height, 0.0, 0.0, 1.0, 1.0, m_statbar_material->GetMaterial()
);
if (alpha != 0.0 && m_statbar_material_flash) {
re.SetColor(col);
m_statbar_material_flash->ReregisterMaterial();
re.DrawStretchPic(
0.0,
0.0,
@@ -548,6 +576,24 @@ void UIFakkLabel::DrawStatbar(float frac)
m_statbar_material_flash->GetMaterial()
);
}
if (m_statbar_material_marker) {
hMat = m_statbar_material_marker->GetMaterial();
w = re.GetShaderWidth(hMat);
h = re.GetShaderHeight(hMat);
re.DrawStretchPic(
m_frame.size.width * frac - w * 0.5,
m_frame.size.height * 0.5 - h * 0.5,
w,
h,
0,
0,
1,
1,
hMat
);
}
break;
}
case L_STATBAR_VERTICAL:
@@ -557,14 +603,12 @@ void UIFakkLabel::DrawStatbar(float frac)
float y = m_frame.size.height * (1.0 - frac);
float height = m_frame.size.height * frac;
m_statbar_material->ReregisterMaterial();
re.DrawStretchPic(
0.0, y, m_frame.size.width, height, 0.0, 1.0 - frac, 1.0, 1.0, m_statbar_material->GetMaterial()
);
if (alpha != 0.0 && m_statbar_material_flash) {
re.SetColor(col);
m_statbar_material_flash->ReregisterMaterial();
re.DrawStretchPic(
0.0,
y,
@@ -577,20 +621,36 @@ void UIFakkLabel::DrawStatbar(float frac)
m_statbar_material_flash->GetMaterial()
);
}
if (m_statbar_material_marker) {
hMat = m_statbar_material_marker->GetMaterial();
w = re.GetShaderWidth(hMat);
h = re.GetShaderHeight(hMat);
re.DrawStretchPic(
m_frame.size.width * frac - w * 0.5,
m_frame.size.height * 0.5 - h * 0.5,
w,
h,
0,
0,
1,
1,
hMat
);
}
break;
}
case L_STATBAR_VERTICAL_REVERSE:
{
float height = m_frame.size.height * frac;
m_statbar_material->ReregisterMaterial();
re.DrawStretchPic(
0.0, 0.0, m_frame.size.width, height, 0.0, 0.0, 1.0, frac, m_statbar_material->GetMaterial()
);
if (alpha != 0.0 && m_statbar_material_flash) {
re.SetColor(col);
m_statbar_material_flash->ReregisterMaterial();
re.DrawStretchPic(
0.0,
0.0,
@@ -686,12 +746,10 @@ void UIFakkLabel::DrawStatCircle(float frac)
re.SetColor(m_foreground_color);
}
m_statbar_material->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
if (alpha && m_statbar_material_flash) {
re.SetColor(col);
m_statbar_material_flash->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
}
} else {
@@ -709,12 +767,10 @@ void UIFakkLabel::DrawStatCircle(float frac)
re.SetColor(m_foreground_color);
}
m_statbar_material->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
if (alpha && m_statbar_material_flash) {
re.SetColor(col);
m_statbar_material_flash->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
}
@@ -739,12 +795,10 @@ void UIFakkLabel::DrawStatCircle(float frac)
re.SetColor(m_foreground_color);
}
m_statbar_material->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
if (alpha && m_statbar_material_flash) {
re.SetColor(col);
m_statbar_material_flash->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
}
} else {
@@ -766,12 +820,10 @@ void UIFakkLabel::DrawStatCircle(float frac)
re.SetColor(m_foreground_color);
}
m_statbar_material->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
if (alpha && m_statbar_material_flash) {
re.SetColor(col);
m_statbar_material_flash->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
}
@@ -846,12 +898,10 @@ void UIFakkLabel::DrawStatNeedle(float frac)
re.SetColor(m_foreground_color);
}
m_statbar_material->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
if (alpha != 0.f && m_statbar_material_flash) {
re.SetColor(col);
m_statbar_material_flash->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
}
@@ -867,11 +917,9 @@ void UIFakkLabel::DrawStatNeedle(float frac)
re.SetColor(m_foreground_color);
}
m_statbar_material->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
if (alpha != 0.f && m_statbar_material_flash) {
m_statbar_material_flash->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
}
}
@@ -937,11 +985,9 @@ void UIFakkLabel::DrawStatRotator(float frac)
re.SetColor(m_foreground_color);
}
m_statbar_material->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
if (alpha != 0.f && m_statbar_material_flash) {
m_statbar_material_flash->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
}
@@ -959,11 +1005,9 @@ void UIFakkLabel::DrawStatRotator(float frac)
re.SetColor(m_foreground_color);
}
m_statbar_material->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
if (alpha != 0.f && m_statbar_material_flash) {
m_statbar_material_flash->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
}
}
@@ -1137,7 +1181,6 @@ void UIFakkLabel::DrawStatCompass(float frac)
vVerts[1][1] = vCenter[1] + vCompassDir[1] * vCenter[1] + fSinVal * vCenter[0];
vVerts[2][1] = vCenter[1] - vCompassDir[1] * vCenter[1] - fSinVal * vCenter[0];
m_statbar_material->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
vVerts[0][0] = vVerts[2][0];
@@ -1150,7 +1193,6 @@ void UIFakkLabel::DrawStatCompass(float frac)
vVerts[2][0] = vCenter[0] + fCosVal * vCenter[1] - vCompassDir[0] * vCenter[0];
vVerts[2][1] = vCenter[1] * fSinVal + vCenter[0] - vCompassDir[1] * vCenter[1];
m_statbar_material->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
}
@@ -1227,11 +1269,9 @@ void UIFakkLabel::DrawStatSpinner(float frac)
re.SetColor(m_foreground_color);
}
m_statbar_material->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
if (alpha != 0.f && m_statbar_material_flash) {
m_statbar_material_flash->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
}
@@ -1249,11 +1289,9 @@ void UIFakkLabel::DrawStatSpinner(float frac)
re.SetColor(m_foreground_color);
}
m_statbar_material->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
if (alpha != 0.f && m_statbar_material_flash) {
m_statbar_material_flash->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
}
}
@@ -1294,40 +1332,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 +1368,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 +1382,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 +1391,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 +1443,180 @@ 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;
}
if (cl.snap.ps.activeItems[m_itemindex] < 0 || cl.snap.ps.activeItems[m_itemindex] >= MAX_WEAPONS) {
// Fixed in OPM
// Make sure to not overflow configstrings
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:
File diff suppressed because it is too large. Load diff
+40 -38
View File
@@ -20,55 +20,57 @@ 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);
// Added in 2.0
void DrawNetProfile(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__ */
+73 -8
View File
@@ -36,6 +36,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "cl_curl.h"
#endif /* USE_CURL */
#ifdef USE_VOIP
#include <opus.h>
#endif
// file full of random crap that gets used to create cl_guid
#define QKEY_FILE "qkey"
#define QKEY_SIZE 2048
@@ -174,6 +178,7 @@ typedef struct {
int lastPacketSentTime; // for retransmits during connection
int lastPacketTime; // for timeouts
char servername[MAX_OSPATH]; // name of server from original connect (used by reconnect)
netadr_t serverAddress;
int connectTime; // for connection retransmits
int connectStartTime;
@@ -239,15 +244,42 @@ typedef struct {
int timeDemoMaxDuration; // maximum frame duration
unsigned char timeDemoDurations[ MAX_TIMEDEMO_DURATIONS ]; // log of frame durations
float aviVideoFrameRemainder;
float aviSoundFrameRemainder;
#ifdef USE_VOIP
qboolean voipEnabled;
qboolean voipCodecInitialized;
// incoming data...
// !!! FIXME: convert from parallel arrays to array of a struct.
OpusDecoder *opusDecoder[MAX_CLIENTS];
byte voipIncomingGeneration[MAX_CLIENTS];
int voipIncomingSequence[MAX_CLIENTS];
float voipGain[MAX_CLIENTS];
qboolean voipIgnore[MAX_CLIENTS];
qboolean voipMuteAll;
// outgoing data...
// if voipTargets[i / 8] & (1 << (i % 8)),
// then we are sending to clientnum i.
uint8_t voipTargets[(MAX_CLIENTS + 7) / 8];
uint8_t voipFlags;
OpusEncoder *opusEncoder;
int voipOutgoingDataSize;
int voipOutgoingDataFrames;
int voipOutgoingSequence;
byte voipOutgoingGeneration;
byte voipOutgoingData[1024];
float voipPower;
#endif
#ifdef LEGACY_PROTOCOL
qboolean compat;
#endif
// big stuff at end of structure so most offsets are 15 bits or less
netchan_t netchan;
float aviVideoFrameRemainder;
float aviSoundFrameRemainder;
} clientConnection_t;
extern clientConnection_t clc;
@@ -297,8 +329,6 @@ typedef struct {
qboolean cddialog; // bring up the cd needed dialog next frame
qboolean no_menus;
char servername[MAX_OSPATH]; // name of server from original connect (used by reconnect)
// when the server clears the hunk, all of these must be restarted
qboolean rendererRegistered;
qboolean cgameStarted;
@@ -320,7 +350,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];
@@ -353,8 +383,8 @@ typedef struct {
void* savedCgameState;
size_t savedCgameStateSize;
char gcdResponse[73];
int unknown3_0;
int currentRate;
// Added in 2.0
netprofclient_t netprofile;
qhandle_t charSetShader;
qhandle_t whiteShader;
qhandle_t consoleShader;
@@ -385,6 +415,8 @@ extern cvar_t *cl_connect_timeout;
extern cvar_t *cl_maxpackets;
extern cvar_t *cl_packetdup;
extern cvar_t *cl_shownet;
extern cvar_t *cl_netprofile;
extern cvar_t *cl_netprofileoverlay;
extern cvar_t *cl_showSend;
extern cvar_t *cl_timeNudge;
extern cvar_t *cl_showTimeDelta;
@@ -445,6 +477,32 @@ extern cvar_t *cl_r_fullscreen;
extern cvar_t *cl_consoleKeys;
#ifdef USE_MUMBLE
extern cvar_t *cl_useMumble;
extern cvar_t *cl_mumbleScale;
#endif
#ifdef USE_VOIP
// cl_voipSendTarget is a string: "all" to broadcast to everyone, "none" to
// send to no one, or a comma-separated list of client numbers:
// "0,7,2,23" ... an empty string is treated like "all".
extern cvar_t *cl_voipUseVAD;
extern cvar_t *cl_voipVADThreshold;
extern cvar_t *cl_voipSend;
extern cvar_t *cl_voipSendTarget;
extern cvar_t *cl_voipGainDuringCapture;
extern cvar_t *cl_voipCaptureMult;
extern cvar_t *cl_voipShowMeter;
extern cvar_t *cl_voip;
// 20ms at 48k
#define VOIP_MAX_FRAME_SAMPLES ( 20 * 48 )
// 3 frame is 60ms of audio, the max opus will encode at once
#define VOIP_MAX_PACKET_FRAMES 3
#define VOIP_MAX_PACKET_SAMPLES ( VOIP_MAX_FRAME_SAMPLES * VOIP_MAX_PACKET_FRAMES )
#endif
extern cvar_t *cg_gametype;
extern cvar_t* j_pitch;
@@ -520,6 +578,7 @@ void IN_MouseOn( void );
void IN_MouseOff( void );
void CL_InitInput (void);
void CL_ShutdownInput(void);
void CL_SendCmd (void);
void CL_ClearState (void);
void CL_ReadPackets (void);
@@ -545,6 +604,10 @@ extern int cl_connectedToPureServer;
extern int cl_connectedToCheatServer;
extern msg_t *cl_currentMSG;
#ifdef USE_VOIP
void CL_Voip_f( void );
#endif
void CL_SystemInfoChanged( void );
void CL_ParseServerMessage( msg_t *msg );
@@ -583,6 +646,7 @@ void Con_DrawCharacter (int cx, int line, int num);
void Con_CheckResize (void);
void Con_Init (void);
void Con_Shutdown (void);
void Con_Clear_f (void);
void Con_ToggleConsole_f (void);
void Con_DrawNotify (void);
@@ -670,6 +734,7 @@ void LAN_SaveServersToCache( void );
void CL_Netchan_Transmit( netchan_t *chan, msg_t* msg); //int length, const byte *data );
void CL_Netchan_TransmitNextFragment( netchan_t *chan );
qboolean CL_Netchan_Process( netchan_t *chan, msg_t *msg );
void CL_NET_OutOfBandPrint( netadr_t adr, const char* format, ... );
//
// cl_avi.c
+3
View File
@@ -59,6 +59,9 @@ typedef struct {
void S_ChannelFree_Callback(channel_t* v);
void S_LoadData(soundsystemsavegame_t* pSave);
void S_SaveData(soundsystemsavegame_t* pSave);
void S_ReLoad(soundsystemsavegame_t* pSave);
extern qboolean s_bSoundPaused;
#ifdef __cplusplus
}
+181 -1
View File
@@ -21,11 +21,24 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "../snd_local.h"
#include "../client.h"
#if defined(NO_MODERN_DMA) && NO_MODERN_DMA
qboolean s_bSoundPaused = qfalse;
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);
Cmd_AddCommand("tmstart", S_TriggeredMusic_Start);
Cmd_AddCommand("tmstartloop", S_TriggeredMusic_StartLoop);
Cmd_AddCommand("tmstop", S_TriggeredMusic_Stop);
}
/*
@@ -46,7 +59,18 @@ S_AddLoopingSound
*/
void S_AddLoopingSound(const vec3_t origin, const vec3_t velocity, sfxHandle_t sfxHandle, float volume, float minDist, float maxDist, float pitch, int flags)
{
if (!sfxHandle) {
return;
}
// FIXME: unimplemented
if (VectorCompare(origin, vec3_origin)) {
// Consider it to be a local sound, uses the player origin
S_AddLoopingSound(cl.snap.ps.clientNum, cl.snap.ps.origin, velocity, sfxHandle);
return;
}
S_AddLoopingSound(ENTITYNUM_WORLD, origin, velocity, sfxHandle);
}
@@ -91,7 +115,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);
}
}
/*
@@ -351,6 +381,16 @@ void MUSIC_CheckForStoppedSongs(void)
STUB();
}
/*
==============
S_CurrentSoundtrack
==============
*/
const char* S_CurrentSoundtrack()
{
return "";
}
/*
=================
S_IsSoundRegistered
@@ -415,26 +455,166 @@ void S_FadeSound(float fTime)
// FIXME: unimplemented
}
/*
==============
S_TriggeredMusic_Start
==============
*/
void S_TriggeredMusic_Start()
{
if (Cmd_Argc() != 2) {
Com_Printf("tmstart <sound file>\n");
return;
}
S_StartBackgroundTrack(Cmd_Argv(1), "");
}
/*
==============
S_TriggeredMusic_StartLoop
==============
*/
void S_TriggeredMusic_StartLoop()
{
if (Cmd_Argc() != 2) {
Com_Printf("tmstartloop <sound file>\n");
return;
}
S_StartBackgroundTrack(Cmd_Argv(1), Cmd_Argv(1));
}
/*
==============
S_TriggeredMusic_Stop
==============
*/
void S_TriggeredMusic_Stop()
{
S_StopBackgroundTrack();
}
/*
==============
S_TriggeredMusic_PlayIntroMusic
==============
*/
void S_TriggeredMusic_PlayIntroMusic() {
S_StartBackgroundTrack("sound/music/mus_MainTheme.mp3", "");
}
/*
==============
S_TriggeredMusic_SetupHandle
==============
*/
void S_TriggeredMusic_SetupHandle(const char* pszName, int iLoopCount, int iOffset, qboolean autostart) {
// FIXME: unimplemented
}
/*
==============
S_GetMusicFilename
==============
*/
const char* S_GetMusicFilename() {
// FIXME: unimplemented
return "";
}
/*
==============
S_GetMusicLoopCount
==============
*/
int S_GetMusicLoopCount() {
// FIXME: unimplemented
return 0;
}
/*
==============
S_GetMusicOffset
==============
*/
unsigned int S_GetMusicOffset() {
// FIXME: unimplemented
return 0;
}
/*
==============
callbackServer
==============
*/
void callbackServer(int entnum, int channel_number, const char* name) {
if (com_sv_running->integer) {
SV_SoundCallback(entnum, channel_number, name);
}
}
/*
==============
S_ChannelFree_Callback
==============
*/
void S_ChannelFree_Callback(channel_t* v) {
if (v->entnum & S_FLAG_DO_CALLBACK) {
callbackServer(v->entnum & ~S_FLAG_DO_CALLBACK, v - s_channels, v->thesfx->soundName);
}
}
/*
==============
S_LoadData
==============
*/
void S_LoadData(soundsystemsavegame_t* pSave) {
// FIXME: unimplemented
}
/*
==============
S_SaveData
==============
*/
void S_SaveData(soundsystemsavegame_t* pSave) {
// FIXME: unimplemented
}
/*
==============
S_ReLoad
==============
*/
void S_ReLoad(soundsystemsavegame_t* pSave) {
// FIXME: unimplemented
}
/*
==============
S_StopMovieAudio
==============
*/
void S_StopMovieAudio() {
}
/*
==============
S_CurrentMoviePosition
==============
*/
int S_CurrentMoviePosition() {
return 0;
}
/*
==============
S_SetupMovieAudio
==============
*/
void S_SetupMovieAudio(const char* pszMovieName) {
}
#endif
+15
View File
@@ -64,6 +64,12 @@ qboolean MUSIC_PlaySong(const char* alias);
void MUSIC_UpdateMusicVolumes(void);
void MUSIC_CheckForStoppedSongs(void);
void S_TriggeredMusic_Start();
void S_TriggeredMusic_StartLoop();
void S_TriggeredMusic_Stop();
const char* S_CurrentSoundtrack();
void S_StopSound(int entnum, int channel);
void S_StopAllSounds2(qboolean stop_music);
float S_GetSoundTime(sfxHandle_t handle);
@@ -74,6 +80,15 @@ qboolean S_IsSoundPlaying(int channelNumber, const char* name);
void S_UpdateEntity(int entityNum, const vec3_t origin, const vec3_t velocity, qboolean use_listener);
void S_FadeSound(float fTime);
void S_TriggeredMusic_PlayIntroMusic();
void S_TriggeredMusic_SetupHandle(const char* pszName, int iLoopCount, int iOffset, qboolean autostart);
const char* S_GetMusicFilename();
int S_GetMusicLoopCount();
unsigned int S_GetMusicOffset();
void S_StopMovieAudio();
int S_CurrentMoviePosition();
void S_SetupMovieAudio(const char* pszMovieName);
#ifdef __cplusplus
}
+6
View File
@@ -66,6 +66,7 @@ LPALGETSOURCEF qalGetSourcef;
LPALGETSOURCE3F qalGetSource3f;
LPALGETSOURCEFV qalGetSourcefv;
LPALGETSOURCEI qalGetSourcei;
LPALGETSOURCEIV qalGetSourceiv;
LPALSOURCEPLAYV qalSourcePlayv;
LPALSOURCESTOPV qalSourceStopv;
LPALSOURCEREWINDV qalSourceRewindv;
@@ -81,6 +82,7 @@ LPALDELETEBUFFERS qalDeleteBuffers;
LPALISBUFFER qalIsBuffer;
LPALBUFFERDATA qalBufferData;
LPALGETBUFFERF qalGetBufferf;
LPALGETBUFFERFV qalGetBufferfv;
LPALGETBUFFERI qalGetBufferi;
LPALDOPPLERFACTOR qalDopplerFactor;
LPALSPEEDOFSOUND qalSpeedOfSound;
@@ -184,6 +186,7 @@ qboolean QAL_Init(const char *libname)
qalGetSource3f = GPA("alGetSource3f");
qalGetSourcefv = GPA("alGetSourcefv");
qalGetSourcei = GPA("alGetSourcei");
qalGetSourceiv = GPA("alGetSourceiv");
qalSourcePlayv = GPA("alSourcePlayv");
qalSourceStopv = GPA("alSourceStopv");
qalSourceRewindv = GPA("alSourceRewindv");
@@ -199,6 +202,7 @@ qboolean QAL_Init(const char *libname)
qalIsBuffer = GPA("alIsBuffer");
qalBufferData = GPA("alBufferData");
qalGetBufferf = GPA("alGetBufferf");
qalGetBufferfv = GPA("alGetBufferfv");
qalGetBufferi = GPA("alGetBufferi");
qalDopplerFactor = GPA("alDopplerFactor");
qalSpeedOfSound = GPA("alSpeedOfSound");
@@ -283,6 +287,7 @@ void QAL_Shutdown( void )
qalGetSource3f = NULL;
qalGetSourcefv = NULL;
qalGetSourcei = NULL;
qalGetSourceiv = NULL;
qalSourcePlayv = NULL;
qalSourceStopv = NULL;
qalSourceRewindv = NULL;
@@ -298,6 +303,7 @@ void QAL_Shutdown( void )
qalIsBuffer = NULL;
qalBufferData = NULL;
qalGetBufferf = NULL;
qalGetBufferfv = NULL;
qalGetBufferi = NULL;
qalDopplerFactor = NULL;
qalSpeedOfSound = NULL;
+8
View File
@@ -55,6 +55,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
# define ALC_ALL_DEVICES_SPECIFIER 0x1013
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifdef USE_OPENAL_DLOPEN
extern LPALENABLE qalEnable;
extern LPALDISABLE qalDisable;
@@ -248,4 +252,8 @@ extern LPALCCAPTURESAMPLES qalcCaptureSamples;
qboolean QAL_Init(const char *libname);
void QAL_Shutdown( void );
#ifdef __cplusplus
}
#endif
#endif // __QAL_H__
+8
View File
@@ -27,6 +27,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "../qcommon/q_shared.h"
#include "../qcommon/qcommon.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct snd_info_s
{
int rate;
@@ -113,4 +117,8 @@ void S_OggOpus_CodecCloseStream(snd_stream_t *stream);
int S_OggOpus_CodecReadStream(snd_stream_t *stream, int bytes, void *buffer);
#endif // USE_CODEC_OPUS
#ifdef __cplusplus
}
#endif
#endif // !_SND_CODEC_H_
+1 -1
View File
@@ -31,7 +31,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "snd_codec.h"
// includes for the MP3 codec
#include "../libmad-0.15.1b/synth.h"
#include "mad.h"
#define MP3_SAMPLE_WIDTH 2
#define MP3_PCMSAMPLES_PERSLICE 32
+20 -10
View File
@@ -161,12 +161,12 @@ void S_Base_SoundList( void ) {
char type[4][16];
char mem[2][16];
strcpy(type[0], "16bit");
strcpy(type[1], "adpcm");
strcpy(type[2], "daub4");
strcpy(type[3], "mulaw");
strcpy(mem[0], "paged out");
strcpy(mem[1], "resident ");
Q_strncpyz(type[0], "16bit", sizeof(type[0]));
Q_strncpyz(type[1], "adpcm", sizeof(type[1]));
Q_strncpyz(type[2], "daub4", sizeof(type[2]));
Q_strncpyz(type[3], "mulaw", sizeof(type[3]));
Q_strncpyz(mem[0], "paged out", sizeof(mem[0]));
Q_strncpyz(mem[1], "resident ", sizeof(mem[1]));
total = 0;
for (sfx=s_knownSfx, i=0 ; i<s_numSfx ; i++, sfx++) {
size = sfx->soundLength;
@@ -303,7 +303,7 @@ static sfx_t *S_FindName( const char *name ) {
sfx = &s_knownSfx[i];
Com_Memset (sfx, 0, sizeof(*sfx));
strcpy (sfx->soundName, name);
Q_strncpyz (sfx->soundName, name, sizeof(sfx->soundName));
sfx->next = sfxHash[hash];
sfxHash[hash] = sfx;
@@ -785,7 +785,11 @@ void S_Base_AddLoopingSound( int entityNum, const vec3_t origin, const vec3_t ve
}
if ( !sfx->soundLength ) {
Com_Error( ERR_DROP, "%s has length 0", sfx->soundName );
// Fixed in OPM
// Why should it crash???
//Com_Error( ERR_DROP, "%s has length 0", sfx->soundName );
Com_Printf( "%s has length 0\n", sfx->soundName );
return;
}
VectorCopy( origin, loopSounds[entityNum].origin );
@@ -848,7 +852,11 @@ void S_Base_AddRealLoopingSound( int entityNum, const vec3_t origin, const vec3_
}
if ( !sfx->soundLength ) {
Com_Error( ERR_DROP, "%s has length 0", sfx->soundName );
// Fixed in OPM
// Why should it crash???
//Com_Error( ERR_DROP, "%s has length 0", sfx->soundName );
Com_Printf( "%s has length 0", sfx->soundName );
return;
}
VectorCopy( origin, loopSounds[entityNum].origin );
VectorCopy( velocity, loopSounds[entityNum].velocity );
@@ -1581,7 +1589,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);
+826
View File
@@ -0,0 +1,826 @@
/*
===========================================================================
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
===========================================================================
*/
#include "snd_local.h"
#include "snd_openal_new.h"
#include "client.h"
#include "cl_ui.h"
typedef struct {
vec3_t origin;
vec3_t velocity;
sfx_t *sfx;
int mergeFrame;
} loopSound_t;
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];
/*
==============
S_SoundInfo_f
==============
*/
void S_SoundInfo_f()
{
S_PrintInfo();
}
/*
==============
S_SoundDump_f
==============
*/
void S_SoundDump_f()
{
S_DumpInfo();
}
/*
==============
S_Init
==============
*/
void S_Init(qboolean full_startup)
{
int iStart, iEnd;
cvar_t *cv;
Com_Printf("------- Sound Initialization (%s) -------\n", full_startup ? "full" : "partial");
iStart = Sys_Milliseconds();
s_volume = Cvar_Get("s_volume", "0.9", CVAR_ARCHIVE);
s_musicVolume = Cvar_Get("s_musicvolume", "0.9", CVAR_ARCHIVE);
s_ambientVolume = Cvar_Get("s_ambientvolume", "1.00", CVAR_ARCHIVE);
s_separation = Cvar_Get("s_separation", "0.5", CVAR_ARCHIVE);
s_khz = Cvar_Get("s_khz", "11", CVAR_ARCHIVE | CVAR_SOUND_LATCH);
s_loadas8bit = Cvar_Get("s_loadas8bit", "0", CVAR_ARCHIVE | CVAR_LATCH);
s_mixPreStep = Cvar_Get("s_mixPreStep", "0.05", CVAR_ARCHIVE);
s_show = Cvar_Get("s_show", "0", CVAR_CHEAT);
s_testsound = Cvar_Get("s_testsound", "0", CVAR_CHEAT);
s_dialogscale = Cvar_Get("s_dialogscale", "1", CVAR_ARCHIVE);
s_bLastInitSound = false;
cv = Cvar_Get("s_initsound", "1", 0);
if (cv->integer) {
Cmd_AddCommand("play", S_Play);
Cmd_AddCommand("soundlist", S_SoundList);
Cmd_AddCommand("soundinfo", S_SoundInfo_f);
Cmd_AddCommand("sounddump", S_SoundDump_f);
if (S_Driver_Init()) {
s_bLastInitSound = true;
s_bSoundStarted = true;
if (full_startup) {
s_numSfx = 0;
S_StopAllSounds(true);
}
S_FindName("***DEFAULT***", -1);
S_SoundInfo_f();
}
} else {
Com_Printf("Sound Not Initializing.\n");
s_bSoundStarted = 0;
}
iEnd = Sys_Milliseconds();
Com_Printf("------- Sound Initialization Complete ------- %i ms\n", iEnd - iStart);
}
/*
==============
S_Shutdown
==============
*/
void S_Shutdown(qboolean full_shutdown)
{
int i;
sfx_t *sfx;
if (!s_bSoundStarted) {
return;
}
Com_Printf("------- Sound Shutdown (%s) -------\n", full_shutdown ? "full" : "partial");
S_Driver_Shutdown();
s_bSoundStarted = false;
Cmd_RemoveCommand("play");
Cmd_RemoveCommand("music");
Cmd_RemoveCommand("stopsound");
Cmd_RemoveCommand("soundlist");
Cmd_RemoveCommand("soundinfo");
if (full_shutdown) {
for (i = 0; i < s_numSfx; i++) {
sfx = &s_knownSfx[i];
if (sfx->name[0]) {
if (sfx->data) {
Z_Free(sfx->data);
}
*sfx = {};
}
}
s_numSfx = 0;
}
Com_Printf("------- Sound Shutdown Complete -------\n");
}
/*
==============
S_NameExists
==============
*/
qboolean S_NameExists(const char *name)
{
int i;
if (strlen(name) >= MAX_RES_NAME) {
Com_DPrintf("Sound name too long: %s", name);
return qfalse;
}
for (i = 0; i < s_numSfx; i++) {
if (!strcmp(s_knownSfx[i].name, name)) {
return qtrue;
}
}
return qfalse;
}
/*
==============
S_FindName
==============
*/
sfx_t *S_FindName(const char *name, int sequenceNumber)
{
int i;
sfx_t *sfx;
if (!name) {
Com_DPrintf("S_FindName: NULL\n");
return NULL;
}
if (!name[0]) {
Com_DPrintf("S_FindName: empty name\n");
return NULL;
}
if (strlen(name) >= MAX_RES_NAME) {
Com_DPrintf("Sound name too long: %s", name);
return NULL;
}
for (i = 0; i < s_numSfx; i++) {
sfx = &s_knownSfx[i];
if (!strcmp(sfx->name, name)) {
if (sfx->registration_sequence != -1) {
sfx->registration_sequence = sequenceNumber;
}
return sfx;
}
}
sfx = &s_knownSfx[0];
for (i = 0; i < s_numSfx; i++) {
sfx = &s_knownSfx[i];
if (!sfx->name[0]) {
break;
}
}
if (i == s_numSfx) {
if (i == MAX_SFX) {
Com_Error(ERR_FATAL, "S_FindName: out of sfx_t");
}
sfx = &s_knownSfx[s_numSfx];
s_numSfx++;
}
*sfx = {};
// Fixed in OPM
// strcpy was used before
//strcpy(sfx->name, name);
Q_strncpyz(sfx->name, name, sizeof(sfx->name));
sfx->registration_sequence = sequenceNumber;
return sfx;
}
/*
==============
S_BeginRegistration
==============
*/
void S_BeginRegistration()
{
int i;
Com_Printf("------- Sound Begin Registration -------\n");
S_StopAllSounds(true);
s_registrationSequence++;
s_inRegistration = true;
s_knownSfx[0].registration_sequence = s_registrationSequence;
Com_Printf("------- Sound Begin Registration Complete -------\n");
// Added in OPM
// Reset all sound entities
// OG doesn't do this but this makes sure
// entities don't leak info from previous sessions
for (i = 0; i < ARRAY_LEN(s_entity); i++) {
s_entity[i] = s_entity_t{};
}
}
/*
==============
S_DefaultSound
==============
*/
void S_DefaultSound(sfx_t *sfx)
{
sfx->data = NULL;
sfx->iFlags |= SFX_FLAG_DEFAULT_SOUND;
}
/*
==============
S_IsSoundRegistered
==============
*/
qboolean S_IsSoundRegistered(const char *name)
{
char szCacheName[MAX_QPATH];
int i;
if (!s_bSoundStarted) {
return qfalse;
}
for (i = 0; name[i] && i < MAX_QPATH; i++) {
szCacheName[i] = tolower(name[i]);
}
szCacheName[i] = 0;
if (i >= MAX_QPATH) {
Com_Printf("Sound name exceeds MAX_QPATH\n");
return qfalse;
}
return S_NameExists(szCacheName);
}
/*
==============
S_RegisterSound
==============
*/
sfxHandle_t S_RegisterSound(const char *name, int streamed, qboolean force_load)
{
char szCacheName[MAX_QPATH];
sfx_t *sfx;
int i;
if (!s_bSoundStarted) {
Com_Printf("ERROR: Trying to register sound %s when soundsystem hasn't started.\n", name);
return 0;
}
if (!name) {
return 0;
}
for (i = 0; name[i] && i < MAX_QPATH; i++) {
szCacheName[i] = tolower(name[i]);
}
szCacheName[i] = 0;
if (i >= MAX_QPATH) {
Com_Printf("Sound name exceeds MAX_QPATH\n");
return 0;
}
sfx = S_FindName(szCacheName, s_registrationSequence);
if (!sfx) {
return 0;
}
if (!sfx->data) {
if (!S_LoadSound(sfx->name, sfx, streamed, force_load)) {
Com_DPrintf("Couldn't load sound: %s\n", sfx->name);
if (!S_LoadSound("sound/default.wav", sfx, streamed, 0)) {
Com_DPrintf("Couldn't load sound: sound/default.wav\n");
sfx->iFlags |= SFX_FLAG_DEFAULT_SOUND;
return 0;
}
}
sfx->iFlags &= ~SFX_FLAG_DEFAULT_SOUND;
sfx->sfx_info_index = 0;
for (i = 0; i < number_of_sfx_infos; i++) {
if (!Q_stricmp(sfx->name, sfx_infos[i].name)) {
sfx->sfx_info_index = i;
break;
}
}
}
return sfx - s_knownSfx;
}
/*
==============
S_GetSoundTime
==============
*/
float S_GetSoundTime(sfxHandle_t handle)
{
return s_knownSfx[handle].time_length;
}
/*
==============
S_EndRegistration
==============
*/
void S_EndRegistration()
{
int i;
sfx_t *sfx;
Com_Printf("------- Sound End Registration -------\n");
s_inRegistration = qfalse;
for (i = 0; i < s_numSfx; i++) {
sfx = &s_knownSfx[i];
if (!sfx->name[0]) {
continue;
}
if (sfx->registration_sequence && sfx->registration_sequence != s_registrationSequence) {
if (sfx->data) {
Z_Free(sfx->data);
}
*sfx = {};
}
}
Com_Printf("------- Sound End Registration Complete -------\n");
}
/*
==============
S_UpdateEntity
==============
*/
void S_UpdateEntity(int entityNum, const vec3_t origin, const vec3_t vel, qboolean use_listener)
{
if (entityNum > MAX_GENTITIES) {
Com_Error(ERR_DROP, "S_UpdateEntityPosition: bad entitynum %i", entityNum);
}
VectorCopy(origin, s_entity[entityNum].position);
VectorCopy(vel, s_entity[entityNum].velocity);
s_entity[entityNum].use_listener = use_listener;
s_entity[entityNum].time = cl.serverTime;
}
/*
==============
S_SetGlobalAmbientVolumeLevel
==============
*/
void S_SetGlobalAmbientVolumeLevel(float volume)
{
s_fAmbientVolume = volume;
}
/*
==============
S_StartSound
==============
*/
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
)
{
if (s_show_sounds->integer > 0 && sfxHandle > 0 && sfxHandle < s_numSfx) {
Com_DPrintf("S_StartSound: %s\n", s_knownSfx[sfxHandle].name);
}
if (!s_bSoundStarted) {
if (s_show_sounds->integer > 0) {
Com_DPrintf("^~^~^ sound system not yet started\n");
}
return;
}
if (server_loading) {
if (s_show_sounds->integer > 0) {
Com_DPrintf("^~^~^ cannot start sounds while loading a server\n");
}
return;
}
if (sfxHandle < 0 || sfxHandle >= s_numSfx) {
Com_Error(ERR_DROP, "S_StartSound: handle %i out of range", sfxHandle);
}
if (!sfxHandle) {
if (s_show_sounds->integer > 0) {
Com_DPrintf("^~^~^ null handle\n");
}
return;
}
if (entnum && (entchannel == CHAN_DIALOG || entchannel == CHAN_DIALOG_SECONDARY) && s_dialogscale->value > 0) {
volume *= s_dialogscale->value;
}
S_Driver_StartSound(origin, entnum, entchannel, sfxHandle, volume, min_dist, pitch, maxDist, streamed);
}
/*
==============
S_StartLocalSound
==============
*/
void S_StartLocalSound(const char *sound_name, qboolean force_load)
{
sfxHandle_t sfxHandle;
const char *name;
AliasListNode_t *pSoundAlias = NULL;
if (!s_bSoundStarted) {
return;
}
if (!sound_name) {
return;
}
name = Alias_FindRandom(sound_name, &pSoundAlias);
if (!name) {
name = sound_name;
}
sfxHandle = S_RegisterSound(name, pSoundAlias ? pSoundAlias->streamed : qfalse, force_load);
if (!pSoundAlias) {
S_StartSound(NULL, s_iListenerNumber, CHAN_MENU, sfxHandle, -1.0, -1.0, 1.0, -1.0, qfalse);
return;
}
S_StartSound(
0,
s_iListenerNumber,
CHAN_MENU,
sfxHandle,
pSoundAlias->volume + random() * pSoundAlias->volumeMod,
-1.0,
pSoundAlias->pitch + random() * pSoundAlias->pitchMod,
pSoundAlias->maxDist,
pSoundAlias->streamed
);
}
/*
==============
S_StartLocalSoundChannel
Added in 2.0
Starts a local sound, with the specified channel
==============
*/
void S_StartLocalSoundChannel(const char *sound_name, qboolean force_load, soundChannel_t channel)
{
sfxHandle_t sfxHandle;
const char *name;
AliasListNode_t *pSoundAlias = NULL;
if (!s_bSoundStarted) {
return;
}
if (!sound_name) {
return;
}
name = Alias_FindRandom(sound_name, &pSoundAlias);
if (!name) {
name = sound_name;
}
sfxHandle = S_RegisterSound(name, pSoundAlias ? pSoundAlias->streamed : qfalse, force_load);
if (!pSoundAlias) {
S_StartSound(NULL, s_iListenerNumber, channel, sfxHandle, -1.0, -1.0, 1.0, -1.0, qfalse);
return;
}
S_StartSound(
0,
s_iListenerNumber,
channel,
sfxHandle,
pSoundAlias->volume + random() * pSoundAlias->volumeMod,
-1.0,
pSoundAlias->pitch + random() * pSoundAlias->pitchMod,
pSoundAlias->maxDist,
pSoundAlias->streamed
);
}
/*
==============
S_StopAllSounds
==============
*/
void S_StopAllSounds(qboolean stop_music)
{
if (!s_bSoundStarted) {
return;
}
Com_Printf("------- S_StopAllSounds (%s) -------\n", stop_music ? "stop music" : "don't stop music");
// Tell the driver to stop all sounds
S_Driver_StopAllSounds(stop_music);
Com_Printf("------- S_StopAllSounds Complete-------\n");
}
/*
==============
S_ClearLoopingSounds
==============
*/
void S_ClearLoopingSounds()
{
if (!s_bSoundStarted) {
return;
}
S_Driver_ClearLoopingSounds();
}
/*
==============
S_AddLoopingSound
==============
*/
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
)
{
if (!s_bSoundStarted) {
return;
}
if (sfxHandle < 0 || sfxHandle >= s_numSfx) {
Com_Error(ERR_DROP, "S_AddLoopingSound: handle %i out of range", sfxHandle);
}
if (!sfxHandle) {
return;
}
S_Driver_AddLoopingSound(origin, velocity, sfxHandle, volume, min_dist, max_dist, pitch, flags);
}
/*
==============
S_Respatialize
==============
*/
void S_Respatialize(int entityNum, const vec3_t head, vec3_t axis[3])
{
if (!s_bSoundStarted) {
return;
}
S_Driver_Respatialize(entityNum, head, axis);
}
/*
==============
S_Update
==============
*/
void S_Update()
{
if (!s_bSoundStarted) {
return;
}
if (server_loading) {
return;
}
S_Driver_Update();
}
/*
==============
S_StopSound
==============
*/
void S_StopSound(int entnum, int channel)
{
if (!s_bSoundStarted) {
return;
}
if (channel == CHAN_AUTO) {
return;
}
S_Driver_StopSound(entnum, channel);
}
/*
==============
S_SetReverb
==============
*/
void S_SetReverb(int reverb_type, float reverb_level)
{
if (!s_bSoundStarted) {
return;
}
S_Driver_SetReverb(reverb_type, reverb_level);
}
/*
==============
S_Play
==============
*/
void S_Play()
{
int i;
char name[MAX_QPATH];
for (i = 1; i < Cmd_Argc(); i++) {
if (strrchr(Cmd_Argv(i), '.')) {
Q_strncpyz(name, Cmd_Argv(i), sizeof(name));
} else {
Com_sprintf(name, sizeof(name), "%s.wav", Cmd_Argv(1));
}
}
S_StartLocalSound(name, qfalse);
}
/*
==============
S_SoundList
==============
*/
void S_SoundList()
{
int i;
sfx_t *sfx;
int size;
int total = 0;
for (i = 0; i < s_numSfx; i++) {
sfx = &s_knownSfx[i];
if (sfx->registration_sequence) {
size = sfx->length * sfx->width;
total += size;
Com_Printf("(%2db) %6i : %s\n", sfx->width * 8, size, sfx->name);
}
}
Com_Printf("Total resident: %i\n", total);
}
/*
==============
S_ClearSoundBuffer
==============
*/
void S_ClearSoundBuffer()
{
// TODO: Remove once AL is fully implemented
}
/*
==============
S_GetMusicFilename
==============
*/
const char* S_GetMusicFilename()
{
return S_Driver_GetMusicFilename();
}
/*
==============
S_GetMusicLoopCount
==============
*/
int S_GetMusicLoopCount()
{
return S_Driver_GetMusicLoopCount();
}
/*
==============
S_GetMusicOffset
==============
*/
unsigned int S_GetMusicOffset()
{
return S_Driver_GetMusicOffset();
}
Loaded 100 of 623 files, more files were not shown because too many files have changed in this diff. Show more