Compare commits

...
745 Commits
Author SHA1 Message Date
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
348 changed files with 46259 additions and 15049 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.
+75 -13
View File
@@ -3,7 +3,7 @@ name: Build
on:
push:
branches:
- '*'
- '**'
pull_request:
workflow_call:
@@ -20,10 +20,13 @@ jobs:
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: '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}}"
@@ -38,7 +41,8 @@ jobs:
- name: Install required packages
run: |
sudo apt update && sudo apt install -y flex bison
sudo apt update && sudo apt install -y flex bison \
libpulse-dev portaudio19-dev libasound2-dev libjack-dev libpipewire-0.3-dev qtbase5-dev libdbus-1-dev
- name: Install required cross-platform packages (${{ matrix.architecture.triple }})
if: matrix.architecture.name != 'amd64'
@@ -56,7 +60,27 @@ jobs:
-DCMAKE_C_FLAGS=--target=${{ matrix.architecture.triple }}
-DCMAKE_CXX_FLAGS=--target=${{ matrix.architecture.triple }}"
- uses: actions/checkout@v3
# 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.23.1'
- name: Configure and install soft-oal
working-directory: ${{github.workspace}}/thirdparties/soft-oal
run: |
cmake -B ./build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} \
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/thirdparties/soft-oal/install' \
-DCMAKE_C_COMPILER=${{ matrix.architecture.triple }}-gcc-12 \
-DCMAKE_CXX_COMPILER=${{ matrix.architecture.triple }}-g++-12
cmake --build ./build --config ${{env.BUILD_TYPE}}
cmake --install ./build --config ${{env.BUILD_TYPE}}
- uses: actions/checkout@v4
with:
path: 'source'
@@ -69,6 +93,8 @@ jobs:
-DCMAKE_CXX_COMPILER=clang++ \
-DCMAKE_C_FLAGS=--target=${{ matrix.architecture.triple }} \
-DCMAKE_CXX_FLAGS=--target=${{ matrix.architecture.triple }} \
-DOPENAL_LIBRARY='${{github.workspace}}/thirdparties/soft-oal' \
-DOPENAL_INCLUDE_DIR='${{github.workspace}}/thirdparties/soft-oal/include' \
-DGIT_REVISION_BUILD_NUMBER=${{ github.run_number }}" >> $GITHUB_ENV
- name: Configure CMake
@@ -94,9 +120,11 @@ jobs:
# 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'
# Create hard-link and copy symbolic links
cp -l ${{steps.sdl.outputs.prefix}}/lib/libSDL2-2.0.so.0 '${{github.workspace}}/install/'
cp -l ${{github.workspace}}/thirdparties/soft-oal/install/lib/libopenal.so.1 '${{github.workspace}}/install/'
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: out-linux-${{matrix.architecture.name}}
if-no-files-found: error
@@ -121,7 +149,7 @@ jobs:
run: |
echo "CMAKE_BUILD_PARALLEL_LEVEL=$((Get-CimInstance Win32_ComputerSystem).NumberOfLogicalProcessors * 16)" >> $GITHUB_ENV
# Setup SDL
# Setup SDL
- name: Set up SDL
id: sdl
uses: libsdl-org/setup-sdl@main
@@ -139,7 +167,38 @@ jobs:
cmake --build winflexbison-build --config Release --parallel
cmake --install winflexbison-build
- uses: actions/checkout@v3
# soft-oal setup
- name: Checkout soft-oal
uses: actions/checkout@v4
with:
repository: 'kcat/openal-soft'
path: 'thirdparties/soft-oal'
ref: '1.23.1'
# 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 -A ${{ matrix.architecture.config }} `
-DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} `
-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 ${{env.BUILD_TYPE}}
cmake --install ./build --config ${{env.BUILD_TYPE}}
# 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' }
- uses: actions/checkout@v4
with:
path: 'source'
@@ -151,6 +210,8 @@ jobs:
-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'".Replace("`r", "").Replace("`n", "") >> $env:GITHUB_ENV
- name: Configure CMake
@@ -177,8 +238,9 @@ jobs:
run: |
cmake --install ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
Copy-Item '${{steps.sdl.outputs.prefix}}/bin/*.dll' -Destination '${{github.workspace}}/install'
Copy-Item '${{github.workspace}}/thirdparties/soft-oal/install/bin/*.dll' -Destination '${{github.workspace}}/install'
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: out-windows-${{matrix.architecture.name}}
if-no-files-found: error
@@ -186,7 +248,7 @@ jobs:
${{github.workspace}}/install
!${{github.workspace}}/install/**/*.pdb
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: out-windows-${{matrix.architecture.name}}-pdb
if-no-files-found: error
+4 -4
View File
@@ -41,7 +41,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4
# Setup SDL
- name: Set up SDL
@@ -52,7 +52,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 +66,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 +79,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}}"
+6 -3
View File
@@ -25,8 +25,11 @@ 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',
@@ -43,7 +46,7 @@ jobs:
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,7 +56,7 @@ 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}}'
prerelease: ${{env.RELEASE_IS_PRERELEASE}}
+2
View File
@@ -5,6 +5,8 @@ Makefile.local
*.swp
*tags
*~
/.vscode/
/baseq3
# OS X
####################
+2 -2
View File
@@ -105,10 +105,10 @@ 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")
+5 -5
View File
@@ -26,6 +26,10 @@ The main goal of OpenMoHAA is to ensure the future and continuity of **Medal of
## Current state
### Single-player
The entire single-player campaign can be played from start to end. There may be occasional bugs though; if you encounter any, please create a new [GitHub issue](https://github.com/openmoh/openmohaa/issues) describing them.
### Multiplayer
The Multiplayer part is almost fully stable.
@@ -34,13 +38,9 @@ Server admins can use OpenMoHAA to [host](docs/getting_started_installation.md#s
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.
### Single-player
The `training` map can be played from start to end. The single-player campaign is not fully functional, but at least AI can breathe, talk, run, and shoot.
## Features
- [What's working and what's not](docs/features_implementation.md)
- [What's working](docs/features_implementation.md)
- [New features](docs/features.md)
- [Scripting commands](https://htmlpreview.github.io/?https://github.com/openmoh/openmohaa/blob/main/docs/features_g_allclasses.html)
+13 -5
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__
+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 -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);
+25 -3
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",
@@ -1221,6 +1231,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 },
@@ -2157,7 +2168,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);
}
}
//=============
@@ -2666,6 +2679,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) {
+2
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;
@@ -788,6 +789,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);
+1 -1
View File
@@ -1180,7 +1180,7 @@ void CG_DrawCrosshair()
float x, y;
float width, height;
shader = NULL;
shader = (qhandle_t)0;
if (!cg_hud->integer || !ui_crosshair->integer) {
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;
+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;
+28 -16
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;
@@ -154,9 +155,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);
@@ -252,13 +253,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,22 +334,33 @@ 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...
int 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) {
@@ -623,6 +633,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);
+7 -6
View File
@@ -191,7 +191,7 @@ int CG_GetMarkFragments(
}
iNewPoints = 0;
for (j = 0, pFragment = pCurrFragment; j < iNewPoints; j++, pFragment++) {
for (j = 0, pFragment = pCurrFragment; j < iNewFragments; j++, pFragment++) {
pFragment->firstPoint += iCurrPoints;
pFragment->iIndex = -pEnt->number;
iNewPoints += pFragment->numPoints;
@@ -219,10 +219,11 @@ static qboolean CG_GetMarkInlineModelOrientation(int iIndex) {
}
pCEnt = &cg_entities[-iIndex];
if (pCEnt->currentValid && pCEnt->currentState.modelindex < cgs.inlineDrawModel[ENTITYNUM_NONE])
if (pCEnt->currentValid && pCEnt->currentState.modelindex < cgs.numInlineModels)
{
VectorCopy(pCEnt->lerpAngles, cg_vEntAngles);
VectorCopy(pCEnt->lerpOrigin, cg_vEntOrigin);
cg_bLastEntValid = qtrue;
if (cg_vEntAngles[0] || cg_vEntAngles[1] || cg_vEntAngles[2]) {
AngleVectorsLeft(cg_vEntAngles, cg_fEntAxis[0], cg_fEntAxis[1], cg_fEntAxis[2]);
@@ -937,15 +938,15 @@ void CG_AddMarks(void)
}
if (pMark->markPolys->iIndex < 0) {
if (CG_FrustumCullSphere(pMark->pos, pMark->radius)) {
continue;
}
} else {
vec3_t vWorldPos;
CG_FragmentPosToWorldPos(pMark->pos, vWorldPos);
if (CG_FrustumCullSphere(vWorldPos, pMark->radius)) {
continue;
}
} else {
if (CG_FrustumCullSphere(pMark->pos, pMark->radius)) {
continue;
}
}
pMark->lastVisTime = cg.time;
+6 -1
View File
@@ -1323,7 +1323,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);
+1 -1
View File
@@ -58,7 +58,7 @@ 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);
+222 -167
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.
@@ -160,49 +160,49 @@ static void CG_MakeBulletHoleType(
float fVolume;
switch (iEffectNum) {
case 0:
case SFX_BHIT_PAPER_LITE:
sBulletHole += "paper";
break;
case 2:
case SFX_BHIT_WOOD_LITE:
sBulletHole += "wood";
break;
case 4:
case SFX_BHIT_METAL_LITE:
sBulletHole += "metal";
break;
case 6:
case SFX_BHIT_STONE_LITE:
sBulletHole += "stone";
break;
case 8:
case SFX_BHIT_DIRT_LITE:
sBulletHole += "dirt";
break;
case 10:
case SFX_BHIT_GRILL_LITE:
sBulletHole += "grill";
break;
case 12:
case SFX_BHIT_GRASS_LITE:
sBulletHole += "grass";
break;
case 14:
case SFX_BHIT_MUD_LITE:
sBulletHole += "mud";
break;
case 16:
case SFX_BHIT_PUDDLE_LITE:
sBulletHole += "puddle";
break;
case 18:
case SFX_BHIT_GLASS_LITE:
sBulletHole += "glass";
break;
case 20:
case SFX_BHIT_GRAVEL_LITE:
sBulletHole += "gravel";
break;
case 22:
case SFX_BHIT_SAND_LITE:
sBulletHole += "sand";
break;
case 24:
case SFX_BHIT_FOLIAGE_LITE:
sBulletHole += "foliage";
break;
case 26:
case SFX_BHIT_SNOW_LITE:
sBulletHole += "snow";
break;
case 28:
case SFX_BHIT_CARPET_LITE:
sBulletHole += "carpet";
break;
default:
@@ -267,7 +267,7 @@ CG_MakeBulletHole(const vec3_t i_vPos, const vec3_t i_vNorm, int iLarge, trace_t
break;
case SURF_SNOW:
sBulletHole += "snow";
iEffect = SFX_BHIT_FOLIAGE_LITE;
iEffect = SFX_BHIT_SNOW_LITE;
break;
case SURF_CARPET:
sBulletHole += "carpet";
@@ -283,7 +283,7 @@ CG_MakeBulletHole(const vec3_t i_vPos, const vec3_t i_vNorm, int iLarge, trace_t
break;
case SURF_GLASS:
sBulletHole += "glass";
iEffect = SFX_BHIT_GRASS_LITE;
iEffect = SFX_BHIT_GLASS_LITE;
break;
case SURF_GRAVEL:
fRadius = 0.f;
@@ -366,7 +366,7 @@ static void CG_MakeBubbleTrail(const vec3_t i_vStart, const vec3_t i_vEnd, int i
fDist -= fMove;
while (fDist > 0.f) {
VectorMA(vPos, fMove, vDir, vPos);
sfxManager.MakeEffect_Angles(32, vPos, vec_zero);
sfxManager.MakeEffect_Angles(SFX_WATER_TRAIL_BUBBLE, vPos, vec_zero);
fMove = 16.f + crandom() * 8.f * alpha;
fDist -= fMove;
@@ -535,7 +535,7 @@ static void CG_MakeBulletTracerInternal(
while (trace.fraction < 1) {
if (bIgnoreEntities) {
cgi.CM_BoxTrace(&trace, vTraceStart, vTraceEnd, vec_zero, vec_zero, 0, MASK_SHOT, qfalse);
cgi.CM_BoxTrace(&trace, vTraceStart, vTraceEnd, vec_zero, vec_zero, 0, MASK_SHOT_FLUID, qfalse);
if (trace.fraction == 1.0f) {
trace.entityNum = ENTITYNUM_NONE;
@@ -554,7 +554,7 @@ static void CG_MakeBulletTracerInternal(
vec_zero,
vTraceStart,
ENTITYNUM_NONE,
MASK_SHOT,
MASK_SHOT_FLUID,
qfalse,
qfalse,
"CG_MakeBulletTracerInternal"
@@ -564,11 +564,11 @@ static void CG_MakeBulletTracerInternal(
if (trace.contents & CONTENTS_FLUID) {
fDist = DotProduct(vDir, trace.plane.normal) * -2.0f;
VectorMA(vDir, fDist, trace.plane.normal, vTmp);
VectorAdd(vTmp, vTmp, trace.plane.normal);
VectorMA(trace.plane.normal, 2.0, vTmp, trace.plane.normal);
VectorNormalizeFast(trace.plane.normal);
}
if (!bInWater && trace.fraction < 1.0f && iNumImpacts <= 127) {
if (!bInWater && trace.fraction < 1.0f && iNumImpacts < ARRAY_LEN(tImpacts)) {
memcpy(&tImpacts[iNumImpacts], &trace, sizeof(trace_t));
iNumImpacts++;
}
@@ -859,14 +859,14 @@ void CG_AddBulletImpacts()
}
if (fImpSndDistRA < fImpSndDistLA) {
if (wall_impact_type[iImpSndIndexRA]) {
if (wall_impact_type[iImpSndIndexRA] != SFX_BHIT_PAPER_LITE) {
if (wall_impact_large[iImpSndIndexRA]) {
fVolume = 1.f;
} else {
fVolume = 0.75f;
}
if (wall_impact_type[iImpSndIndexRA] == 2 || wall_impact_type[iImpSndIndexRA] == 3) {
if (wall_impact_type[iImpSndIndexRA] == SFX_BHIT_WOOD_LITE || wall_impact_type[iImpSndIndexRA] == SFX_BHIT_WOOD_HARD) {
sSoundName = "snd_bh_metal";
} else {
sSoundName = "snd_bh_wood";
@@ -897,7 +897,7 @@ void CG_AddBulletImpacts()
fVolume = 0.75f;
}
if (wall_impact_type[iImpSndIndexRB] == 2 || wall_impact_type[iImpSndIndexRB] == 3) {
if (wall_impact_type[iImpSndIndexRB] == SFX_BHIT_WOOD_LITE || wall_impact_type[iImpSndIndexRB] == SFX_BHIT_WOOD_HARD) {
sSoundName = "snd_bh_metal";
} else {
sSoundName = "snd_bh_wood";
@@ -923,14 +923,14 @@ void CG_AddBulletImpacts()
}
if (fImpSndDistLA > 9999.0f) {
if (wall_impact_type[0]) {
if (wall_impact_type[0] != SFX_BHIT_PAPER_LITE) {
if (wall_impact_large[0]) {
fVolume = 1.f;
} else {
fVolume = 0.75f;
}
if (wall_impact_type[0] == 2 || wall_impact_type[0] == 3) {
if (wall_impact_type[0] == SFX_BHIT_WOOD_LITE || wall_impact_type[0] == SFX_BHIT_WOOD_HARD) {
sSoundName = "snd_bh_metal";
} else {
sSoundName = "snd_bh_wood";
@@ -945,14 +945,14 @@ void CG_AddBulletImpacts()
}
if (fImpSndDistLB < fImpSndDistLA) {
if (wall_impact_type[iImpSndIndexLB]) {
if (wall_impact_type[iImpSndIndexLB] != SFX_BHIT_PAPER_LITE) {
if (wall_impact_large[iImpSndIndexLB]) {
fVolume = 1.f;
} else {
fVolume = 0.75f;
}
if (wall_impact_type[iImpSndIndexLB] == 2 || wall_impact_type[iImpSndIndexLB] == 3) {
if (wall_impact_type[iImpSndIndexLB] == SFX_BHIT_WOOD_LITE || wall_impact_type[iImpSndIndexLB] == SFX_BHIT_WOOD_HARD) {
sSoundName = "snd_bh_metal";
} else {
sSoundName = "snd_bh_wood";
@@ -987,14 +987,16 @@ void CG_AddBulletImpacts()
if (flesh_impact_count) {
if (flesh_impact_count > 1) {
fImpSndDistRA = 9999.0;
fImpSndDistRB = 9999.0;
iImpSndIndexRA = 0;
iImpSndIndexRB = 0;
for (i = 0; i < flesh_impact_count; i++) {
VectorSubtract(wall_impact_pos[i], cg.SoundOrg, vTmp);
VectorSubtract(flesh_impact_pos[i], cg.SoundOrg, vTmp);
iHeadDist = VectorLength(vTmp);
if (DotProduct(vTmp, cg.SoundAxis[1]) > 0.f) {
if (iHeadDist < fImpSndDistRA) {
if (iHeadDist < fImpSndDistRB) {
fImpSndDistRA = iHeadDist;
iImpSndIndexRA = i;
}
@@ -1003,6 +1005,30 @@ void CG_AddBulletImpacts()
iImpSndIndexRA = i;
}
}
if (fImpSndDistRA < 9999) {
sfxManager.MakeEffect_Normal(
flesh_impact_large[iImpSndIndexRA] ? SFX_BHIT_HUMAN_UNIFORM_HARD : SFX_BHIT_HUMAN_UNIFORM_LITE,
flesh_impact_pos[iImpSndIndexRA],
flesh_impact_norm[iImpSndIndexRA]
);
}
if (fImpSndDistRB < 9999) {
sfxManager.MakeEffect_Normal(
flesh_impact_large[iImpSndIndexRB] ? SFX_BHIT_HUMAN_UNIFORM_HARD : SFX_BHIT_HUMAN_UNIFORM_LITE,
flesh_impact_pos[iImpSndIndexRB],
flesh_impact_norm[iImpSndIndexRB]
);
}
} else {
for (i = 0; i < flesh_impact_count; i++) {
sfxManager.MakeEffect_Normal(
flesh_impact_large[i] ? SFX_BHIT_HUMAN_UNIFORM_HARD : SFX_BHIT_HUMAN_UNIFORM_LITE,
flesh_impact_pos[i],
flesh_impact_norm[i]
);
}
}
flesh_impact_count = 0;
@@ -1031,22 +1057,33 @@ void CG_MakeExplosionEffect(const vec3_t vPos, int iType)
return;
}
switch (iType) {
case 13:
iBaseEffect = SFX_EXP_GREN_BASE;
break;
case 14:
iBaseEffect = SFX_EXP_BAZOOKA_BASE;
break;
case 15:
iBaseEffect = SFX_EXP_HEAVYSHELL_BASE;
break;
case 16:
iBaseEffect = SFX_EXP_TANK_BASE;
break;
default:
iBaseEffect = SFX_EXP_GREN_BASE;
break;
if (cg_protocol >= protocol_e::PROTOCOL_MOHTA_MIN) {
switch (iType) {
case CGM_EXPLOSION_EFFECT_1:
iBaseEffect = SFX_EXP_GREN_BASE;
break;
case CGM_EXPLOSION_EFFECT_2:
iBaseEffect = SFX_EXP_BAZOOKA_BASE;
break;
case CGM_EXPLOSION_EFFECT_3:
iBaseEffect = SFX_EXP_HEAVYSHELL_BASE;
break;
case CGM_EXPLOSION_EFFECT_4:
iBaseEffect = SFX_EXP_TANK_BASE;
break;
default:
iBaseEffect = SFX_EXP_GREN_BASE;
break;
}
} else {
switch (iType) {
case CGM6_EXPLOSION_EFFECT_2:
iBaseEffect = SFX_EXP_BAZOOKA_BASE;
break;
default:
iBaseEffect = SFX_EXP_GREN_BASE;
break;
}
}
CG_Trace(
@@ -1074,14 +1111,18 @@ void CG_MakeExplosionEffect(const vec3_t vPos, int iType)
break;
case SFX_EXP_BAZOOKA_BASE:
iSurfEffect = SFX_EXP_BAZOOKA_SNOW;
iBaseEffect = -1;
if (cg_protocol >= protocol_e::PROTOCOL_MOHTA_MIN) {
iBaseEffect = -1;
}
break;
case SFX_EXP_HEAVYSHELL_BASE:
iSurfEffect = SFX_EXP_HEAVYSHELL_SNOW;
break;
default:
iSurfEffect = SFX_EXP_GREN_SNOW;
iBaseEffect = -1;
if (cg_protocol >= protocol_e::PROTOCOL_MOHTA_MIN) {
iBaseEffect = -1;
}
break;
}
fRadius = 0;
@@ -1115,14 +1156,18 @@ void CG_MakeExplosionEffect(const vec3_t vPos, int iType)
break;
case SFX_EXP_BAZOOKA_BASE:
iSurfEffect = SFX_EXP_BAZOOKA_DIRT;
iBaseEffect = -1;
if (cg_protocol >= protocol_e::PROTOCOL_MOHTA_MIN) {
iBaseEffect = -1;
}
break;
case SFX_EXP_HEAVYSHELL_BASE:
iSurfEffect = SFX_EXP_HEAVYSHELL_DIRT;
break;
default:
iSurfEffect = SFX_EXP_GREN_DIRT;
iBaseEffect = -1;
if (cg_protocol >= protocol_e::PROTOCOL_MOHTA_MIN) {
iBaseEffect = -1;
}
break;
}
fRadius = 0;
@@ -1144,7 +1189,9 @@ void CG_MakeExplosionEffect(const vec3_t vPos, int iType)
break;
default:
iSurfEffect = SFX_EXP_GREN_GRASS;
iBaseEffect = -1;
if (cg_protocol >= protocol_e::PROTOCOL_MOHTA_MIN) {
iBaseEffect = -1;
}
break;
}
fRadius = 0;
@@ -1156,14 +1203,18 @@ void CG_MakeExplosionEffect(const vec3_t vPos, int iType)
break;
case SFX_EXP_BAZOOKA_BASE:
iSurfEffect = SFX_EXP_BAZOOKA_STONE;
iBaseEffect = -1;
if (cg_protocol >= protocol_e::PROTOCOL_MOHTA_MIN) {
iBaseEffect = -1;
}
break;
case SFX_EXP_HEAVYSHELL_BASE:
iSurfEffect = SFX_EXP_HEAVYSHELL_STONE;
break;
default:
iSurfEffect = SFX_EXP_GREN_STONE;
iBaseEffect = -1;
if (cg_protocol >= protocol_e::PROTOCOL_MOHTA_MIN) {
iBaseEffect = -1;
}
break;
}
break;
@@ -1211,7 +1262,9 @@ void CG_MakeExplosionEffect(const vec3_t vPos, int iType)
);
}
sfxManager.MakeEffect_Normal(iBaseEffect, vEnd, trace.plane.normal);
if (iBaseEffect != -1) {
sfxManager.MakeEffect_Normal(iBaseEffect, vEnd, trace.plane.normal);
}
}
void CG_MakeVehicleEffect(vec3_t i_vStart, vec3_t i_vEnd, vec3_t i_vDir)
@@ -1247,10 +1300,10 @@ void CG_ParseCGMessage_ver_15()
iType = cgi.MSG_ReadBits(6);
switch (iType) {
case 1:
case 2:
case 5:
if (iType == 1) {
case CGM_BULLET_1:
case CGM_BULLET_2:
case CGM_BULLET_5:
if (iType == CGM_BULLET_1) {
vTmp[0] = cgi.MSG_ReadCoord();
vTmp[1] = cgi.MSG_ReadCoord();
vTmp[2] = cgi.MSG_ReadCoord();
@@ -1259,7 +1312,7 @@ void CG_ParseCGMessage_ver_15()
vStart[1] = cgi.MSG_ReadCoord();
vStart[2] = cgi.MSG_ReadCoord();
if (iType != 1) {
if (iType != CGM_BULLET_1) {
vTmp[0] = vStart[0];
vTmp[1] = vStart[1];
vTmp[2] = vStart[2];
@@ -1279,18 +1332,18 @@ void CG_ParseCGMessage_ver_15()
alpha = 1.0f;
}
if (iType == 1) {
CG_MakeBulletTracer(vTmp, vStart, vEndArray, 1, iLarge, qfalse, qtrue, alpha);
} else if (iType == 2) {
if (iType == CGM_BULLET_1) {
CG_MakeBulletTracer(vTmp, vStart, vEndArray, 1, iLarge, qtrue, qtrue, alpha);
} else if (iType == CGM_BULLET_2) {
CG_MakeBulletTracer(vTmp, vStart, vEndArray, 1, iLarge, qfalse, qtrue, alpha);
} else {
CG_MakeBubbleTrail(vStart, vEndArray[0], iLarge, alpha);
}
break;
case 3:
case 4:
if (iType == 3) {
case CGM_BULLET_3:
case CGM_BULLET_4:
if (iType == CGM_BULLET_3) {
vTmp[0] = cgi.MSG_ReadCoord();
vTmp[1] = cgi.MSG_ReadCoord();
vTmp[2] = cgi.MSG_ReadCoord();
@@ -1324,12 +1377,12 @@ void CG_ParseCGMessage_ver_15()
CG_MakeBulletTracer(vTmp, vStart, vEndArray, iCount, iLarge, iInfo, qtrue, alpha);
}
break;
case 6:
case 7:
case 8:
case 9:
case 10:
case 11:
case CGM_BULLET_6:
case CGM_BULLET_7:
case CGM_BULLET_8:
case CGM_BULLET_9:
case CGM_BULLET_10:
case CGM_BULLET_11:
vStart[0] = cgi.MSG_ReadCoord();
vStart[1] = cgi.MSG_ReadCoord();
vStart[2] = cgi.MSG_ReadCoord();
@@ -1337,7 +1390,7 @@ void CG_ParseCGMessage_ver_15()
iLarge = cgi.MSG_ReadBits(2);
switch (iType) {
case 6:
case CGM_BULLET_6:
if (wall_impact_count < MAX_IMPACTS) {
VectorCopy(vStart, wall_impact_pos[wall_impact_count]);
VectorCopy(vEnd, wall_impact_norm[wall_impact_count]);
@@ -1346,16 +1399,16 @@ void CG_ParseCGMessage_ver_15()
wall_impact_count++;
}
break;
case 7:
case CGM_BULLET_7:
if (wall_impact_count < MAX_IMPACTS) {
VectorCopy(vStart, wall_impact_pos[wall_impact_count]);
VectorCopy(vEnd, wall_impact_norm[wall_impact_count]);
wall_impact_large[wall_impact_count] = iLarge;
wall_impact_type[wall_impact_count] = 6;
wall_impact_type[wall_impact_count] = SFX_BHIT_STONE_LITE;
wall_impact_count++;
}
break;
case 8:
case CGM_BULLET_8:
if (flesh_impact_count < MAX_IMPACTS) {
// negative
VectorNegate(vEnd, vEnd);
@@ -1365,7 +1418,7 @@ void CG_ParseCGMessage_ver_15()
flesh_impact_count++;
}
break;
case 9:
case CGM_BULLET_9:
if (flesh_impact_count < MAX_IMPACTS) {
// negative
VectorNegate(vEnd, vEnd);
@@ -1375,21 +1428,21 @@ void CG_ParseCGMessage_ver_15()
flesh_impact_count++;
}
break;
case 10:
case CGM_BULLET_10:
if (wall_impact_count < MAX_IMPACTS) {
VectorCopy(vStart, wall_impact_pos[wall_impact_count]);
VectorCopy(vEnd, wall_impact_norm[wall_impact_count]);
wall_impact_large[wall_impact_count] = iLarge;
wall_impact_type[wall_impact_count] = 2;
wall_impact_type[wall_impact_count] = SFX_BHIT_WOOD_LITE;
wall_impact_count++;
}
break;
case 11:
case CGM_BULLET_11:
if (wall_impact_count < MAX_IMPACTS) {
VectorCopy(vStart, wall_impact_pos[wall_impact_count]);
VectorCopy(vEnd, wall_impact_norm[wall_impact_count]);
wall_impact_large[wall_impact_count] = iLarge;
wall_impact_type[wall_impact_count] = 4;
wall_impact_type[wall_impact_count] = SFX_BHIT_METAL_LITE;
wall_impact_count++;
}
break;
@@ -1398,7 +1451,7 @@ void CG_ParseCGMessage_ver_15()
}
break;
case 12:
case CGM_MELEE_IMPACT:
vStart[0] = cgi.MSG_ReadCoord();
vStart[1] = cgi.MSG_ReadCoord();
vStart[2] = cgi.MSG_ReadCoord();
@@ -1407,33 +1460,33 @@ void CG_ParseCGMessage_ver_15()
vEnd[2] = cgi.MSG_ReadCoord();
CG_MeleeImpact(vStart, vEnd);
break;
case 13:
case 14:
case 15:
case 16:
case CGM_EXPLOSION_EFFECT_1:
case CGM_EXPLOSION_EFFECT_2:
case CGM_EXPLOSION_EFFECT_3:
case CGM_EXPLOSION_EFFECT_4:
vStart[0] = cgi.MSG_ReadCoord();
vStart[1] = cgi.MSG_ReadCoord();
vStart[2] = cgi.MSG_ReadCoord();
CG_MakeExplosionEffect(vStart, iType);
break;
case 18:
case 19:
case 20:
case 21:
case 22:
case 23:
case 24:
case 25:
case CGM_MAKE_EFFECT_1:
case CGM_MAKE_EFFECT_2:
case CGM_MAKE_EFFECT_3:
case CGM_MAKE_EFFECT_4:
case CGM_MAKE_EFFECT_5:
case CGM_MAKE_EFFECT_6:
case CGM_MAKE_EFFECT_7:
case CGM_MAKE_EFFECT_8:
vStart[0] = cgi.MSG_ReadCoord();
vStart[1] = cgi.MSG_ReadCoord();
vStart[2] = cgi.MSG_ReadCoord();
cgi.MSG_ReadDir(vEnd);
sfxManager.MakeEffect_Normal(iType + SFX_EXP_GREN_PUDDLE, vStart, vEnd);
sfxManager.MakeEffect_Normal(SFX_EXP_GREN_PUDDLE + iType, vStart, vEnd);
break;
case 26:
case 27:
case CGM_MAKE_CRATE_DEBRIS:
case CGM_MAKE_WINDOW_DEBRIS:
{
str sEffect;
char cTmp[8];
@@ -1446,7 +1499,7 @@ void CG_ParseCGMessage_ver_15()
// get the integer as string
snprintf(cTmp, sizeof(cTmp), "%d", iLarge);
if (iType == 26) {
if (iType == CGM_MAKE_CRATE_DEBRIS) {
sEffect = "models/fx/crates/debris_";
} else {
sEffect = "models/fx/windows/debris_";
@@ -1463,7 +1516,7 @@ void CG_ParseCGMessage_ver_15()
}
break;
case 28:
case CGM_BULLET_NO_BARREL_1:
vTmp[0] = cgi.MSG_ReadCoord();
vTmp[1] = cgi.MSG_ReadCoord();
vTmp[2] = cgi.MSG_ReadCoord();
@@ -1474,6 +1527,7 @@ void CG_ParseCGMessage_ver_15()
vEndArray[0][1] = cgi.MSG_ReadCoord();
vEndArray[0][2] = cgi.MSG_ReadCoord();
iLarge = cgi.MSG_ReadBits(2);
if (cgi.MSG_ReadBits(1)) {
int iAlpha = cgi.MSG_ReadBits(10);
alpha = (float)iAlpha / 512.0;
@@ -1487,7 +1541,7 @@ void CG_ParseCGMessage_ver_15()
CG_MakeBulletTracer(vTmp, vStart, vEndArray, 1, iLarge, qtrue, qtrue, alpha);
break;
case 29:
case CGM_BULLET_NO_BARREL_2:
memset(vTmp, 0, sizeof(vTmp));
vStart[0] = cgi.MSG_ReadCoord();
vStart[1] = cgi.MSG_ReadCoord();
@@ -1496,6 +1550,7 @@ void CG_ParseCGMessage_ver_15()
vEndArray[0][1] = cgi.MSG_ReadCoord();
vEndArray[0][2] = cgi.MSG_ReadCoord();
iLarge = cgi.MSG_ReadBits(1);
if (cgi.MSG_ReadBits(1)) {
int iAlpha = cgi.MSG_ReadBits(10);
alpha = (float)iAlpha / 512.0;
@@ -1509,7 +1564,7 @@ void CG_ParseCGMessage_ver_15()
CG_MakeBulletTracer(vTmp, vStart, vEndArray, 1, iLarge, qfalse, qtrue, alpha);
break;
case 30:
case CGM_HUDDRAW_SHADER:
iInfo = cgi.MSG_ReadByte();
strcpy(cgi.HudDrawElements[iInfo].shaderName, cgi.MSG_ReadString());
cgi.HudDrawElements[iInfo].string[0] = 0;
@@ -1519,13 +1574,13 @@ void CG_ParseCGMessage_ver_15()
CG_HudDrawShader(iInfo);
break;
case 31:
case CGM_HUDDRAW_ALIGN:
iInfo = cgi.MSG_ReadByte();
cgi.HudDrawElements[iInfo].iHorizontalAlign = cgi.MSG_ReadBits(2);
cgi.HudDrawElements[iInfo].iVerticalAlign = cgi.MSG_ReadBits(2);
break;
case 32:
case CGM_HUDDRAW_RECT:
iInfo = cgi.MSG_ReadByte();
cgi.HudDrawElements[iInfo].iX = cgi.MSG_ReadShort();
cgi.HudDrawElements[iInfo].iY = cgi.MSG_ReadShort();
@@ -1533,30 +1588,30 @@ void CG_ParseCGMessage_ver_15()
cgi.HudDrawElements[iInfo].iHeight = cgi.MSG_ReadShort();
break;
case 33:
case CGM_HUDDRAW_VIRTUALSIZE:
iInfo = cgi.MSG_ReadByte();
cgi.HudDrawElements[iInfo].bVirtualScreen = cgi.MSG_ReadBits(1);
break;
case 34:
case CGM_HUDDRAW_COLOR:
iInfo = cgi.MSG_ReadByte();
cgi.HudDrawElements[iInfo].vColor[0] = cgi.MSG_ReadByte() / 255.0;
cgi.HudDrawElements[iInfo].vColor[1] = cgi.MSG_ReadByte() / 255.0;
cgi.HudDrawElements[iInfo].vColor[2] = cgi.MSG_ReadByte() / 255.0;
break;
case 35:
case CGM_HUDDRAW_ALPHA:
iInfo = cgi.MSG_ReadByte();
cgi.HudDrawElements[iInfo].vColor[3] = cgi.MSG_ReadByte() / 255.0;
break;
case 36:
case CGM_HUDDRAW_STRING:
iInfo = cgi.MSG_ReadByte();
cgi.HudDrawElements[iInfo].hShader = 0;
strcpy(cgi.HudDrawElements[iInfo].string, cgi.MSG_ReadString());
break;
case 37:
case CGM_HUDDRAW_FONT:
iInfo = cgi.MSG_ReadByte();
strcpy(cgi.HudDrawElements[iInfo].fontName, cgi.MSG_ReadString());
cgi.HudDrawElements[iInfo].hShader = 0;
@@ -1565,14 +1620,14 @@ void CG_ParseCGMessage_ver_15()
CG_HudDrawFont(iInfo);
break;
case 38:
case 39:
case CGM_NOTIFY_KILL:
case CGM_NOTIFY_HIT:
{
int iOldEnt;
iOldEnt = current_entity_number;
current_entity_number = cg.snap->ps.clientNum;
if (iType == 36) {
if (iType == CGM_NOTIFY_HIT) {
commandManager.PlaySound("dm_kill_notify", NULL, CHAN_LOCAL, 2.0, -1, -1, 1);
} else {
commandManager.PlaySound("dm_hit_notify", NULL, CHAN_LOCAL, 2.0, -1, -1, 1);
@@ -1582,7 +1637,7 @@ void CG_ParseCGMessage_ver_15()
}
break;
case 40:
case CGM_VOICE_CHAT:
{
int iOldEnt;
@@ -1608,7 +1663,7 @@ void CG_ParseCGMessage_ver_15()
current_entity_number = iOldEnt;
}
break;
case 41:
case CGM_FENCEPOST:
vStart[0] = cgi.MSG_ReadCoord();
vStart[1] = cgi.MSG_ReadCoord();
vStart[2] = cgi.MSG_ReadCoord();
@@ -1647,10 +1702,10 @@ void CG_ParseCGMessage_ver_6()
iType = cgi.MSG_ReadBits(6);
switch (iType) {
case 1:
case 2:
case 5:
if (iType == 1) {
case CGM6_BULLET_1:
case CGM6_BULLET_2:
case CGM6_BULLET_5:
if (iType == CGM6_BULLET_1) {
vTmp[0] = cgi.MSG_ReadCoord();
vTmp[1] = cgi.MSG_ReadCoord();
vTmp[2] = cgi.MSG_ReadCoord();
@@ -1659,7 +1714,7 @@ void CG_ParseCGMessage_ver_6()
vStart[1] = cgi.MSG_ReadCoord();
vStart[2] = cgi.MSG_ReadCoord();
if (iType != 1) {
if (iType != CGM6_BULLET_1) {
vTmp[0] = vStart[0];
vTmp[1] = vStart[1];
vTmp[2] = vStart[2];
@@ -1670,18 +1725,18 @@ void CG_ParseCGMessage_ver_6()
vEndArray[0][2] = cgi.MSG_ReadCoord();
iLarge = cgi.MSG_ReadBits(1);
if (iType == 1) {
CG_MakeBulletTracer(vTmp, vStart, vEndArray, 1, iLarge, qfalse, qtrue);
} else if (iType == 2) {
if (iType == CGM6_BULLET_1) {
CG_MakeBulletTracer(vTmp, vStart, vEndArray, 1, iLarge, qtrue, qtrue);
} else if (iType == CGM6_BULLET_2) {
CG_MakeBulletTracer(vTmp, vStart, vEndArray, 1, iLarge, qfalse, qtrue);
} else {
CG_MakeBubbleTrail(vStart, vEndArray[0], iLarge);
}
break;
case 3:
case 4:
if (iType == 3) {
case CGM6_BULLET_3:
case CGM6_BULLET_4:
if (iType == CGM6_BULLET_3) {
vTmp[0] = cgi.MSG_ReadCoord();
vTmp[1] = cgi.MSG_ReadCoord();
vTmp[2] = cgi.MSG_ReadCoord();
@@ -1705,11 +1760,11 @@ void CG_ParseCGMessage_ver_6()
CG_MakeBulletTracer(vTmp, vStart, vEndArray, iCount, iLarge, iInfo, qtrue);
}
break;
case 6:
case 7:
case 8:
case 9:
case 10:
case CGM6_BULLET_6:
case CGM6_BULLET_7:
case CGM6_BULLET_8:
case CGM6_BULLET_9:
case CGM6_BULLET_10:
vStart[0] = cgi.MSG_ReadCoord();
vStart[1] = cgi.MSG_ReadCoord();
vStart[2] = cgi.MSG_ReadCoord();
@@ -1717,16 +1772,16 @@ void CG_ParseCGMessage_ver_6()
iLarge = cgi.MSG_ReadBits(1);
switch (iType) {
case 6:
case CGM6_BULLET_6:
if (wall_impact_count < MAX_IMPACTS) {
VectorCopy(vStart, wall_impact_pos[wall_impact_count]);
VectorCopy(vEnd, wall_impact_norm[wall_impact_count]);
wall_impact_large[wall_impact_count] = iLarge;
wall_impact_type[wall_impact_count] = 0;
wall_impact_type[wall_impact_count] = SFX_BHIT_PAPER_LITE;
wall_impact_count++;
}
break;
case 7:
case CGM6_BULLET_7:
if (flesh_impact_count < MAX_IMPACTS) {
// negative
VectorNegate(vEnd, vEnd);
@@ -1736,7 +1791,7 @@ void CG_ParseCGMessage_ver_6()
flesh_impact_count++;
}
break;
case 8:
case CGM6_BULLET_8:
if (flesh_impact_count < MAX_IMPACTS) {
// negative
VectorNegate(vEnd, vEnd);
@@ -1746,21 +1801,21 @@ void CG_ParseCGMessage_ver_6()
flesh_impact_count++;
}
break;
case 9:
case CGM6_BULLET_9:
if (wall_impact_count < MAX_IMPACTS) {
VectorCopy(vStart, wall_impact_pos[wall_impact_count]);
VectorCopy(vEnd, wall_impact_norm[wall_impact_count]);
wall_impact_large[wall_impact_count] = iLarge;
wall_impact_type[wall_impact_count] = (iLarge != 0) + 2;
wall_impact_type[wall_impact_count] = iLarge ? SFX_BHIT_WOOD_HARD : SFX_BHIT_WOOD_LITE;
wall_impact_count++;
}
break;
case 10:
case CGM6_BULLET_10:
if (wall_impact_count < MAX_IMPACTS) {
VectorCopy(vStart, wall_impact_pos[wall_impact_count]);
VectorCopy(vEnd, wall_impact_norm[wall_impact_count]);
wall_impact_large[wall_impact_count] = iLarge;
wall_impact_type[wall_impact_count] = (iLarge != 0) + 4;
wall_impact_type[wall_impact_count] = iLarge ? SFX_BHIT_METAL_HARD : SFX_BHIT_METAL_LITE;
wall_impact_count++;
}
break;
@@ -1769,7 +1824,7 @@ void CG_ParseCGMessage_ver_6()
}
break;
case 11:
case CGM6_MELEE_IMPACT:
vStart[0] = cgi.MSG_ReadCoord();
vStart[1] = cgi.MSG_ReadCoord();
vStart[2] = cgi.MSG_ReadCoord();
@@ -1778,31 +1833,31 @@ void CG_ParseCGMessage_ver_6()
vEnd[2] = cgi.MSG_ReadCoord();
CG_MeleeImpact(vStart, vEnd);
break;
case 12:
case 13:
case CGM6_EXPLOSION_EFFECT_1:
case CGM6_EXPLOSION_EFFECT_2:
vStart[0] = cgi.MSG_ReadCoord();
vStart[1] = cgi.MSG_ReadCoord();
vStart[2] = cgi.MSG_ReadCoord();
CG_MakeExplosionEffect(vStart, iType);
break;
case 15:
case 16:
case 17:
case 18:
case 19:
case 20:
case 21:
case 22:
case CGM6_MAKE_EFFECT_1:
case CGM6_MAKE_EFFECT_2:
case CGM6_MAKE_EFFECT_3:
case CGM6_MAKE_EFFECT_4:
case CGM6_MAKE_EFFECT_5:
case CGM6_MAKE_EFFECT_6:
case CGM6_MAKE_EFFECT_7:
case CGM6_MAKE_EFFECT_8:
vStart[0] = cgi.MSG_ReadCoord();
vStart[1] = cgi.MSG_ReadCoord();
vStart[2] = cgi.MSG_ReadCoord();
cgi.MSG_ReadDir(vEnd);
sfxManager.MakeEffect_Normal(iType + SFX_EXP_GREN_PUDDLE, vStart, vEnd);
sfxManager.MakeEffect_Normal(SFX_EXP_GREN_PUDDLE + iType, vStart, vEnd);
break;
case 23:
case 24:
case CGM6_MAKE_CRATE_DEBRIS:
case CGM6_MAKE_WINDOW_DEBRIS:
{
str sEffect;
char cTmp[8];
@@ -1815,7 +1870,7 @@ void CG_ParseCGMessage_ver_6()
// get the integer as string
snprintf(cTmp, sizeof(cTmp), "%d", iLarge);
if (iType == 23) {
if (iType == CGM6_MAKE_CRATE_DEBRIS) {
sEffect = "models/fx/crates/debris_";
} else {
sEffect = "models/fx/windows/debris_";
@@ -1832,7 +1887,7 @@ void CG_ParseCGMessage_ver_6()
}
break;
case 25:
case CGM6_BULLET_NO_BARREL_1:
vTmp[0] = cgi.MSG_ReadCoord();
vTmp[1] = cgi.MSG_ReadCoord();
vTmp[2] = cgi.MSG_ReadCoord();
@@ -1847,7 +1902,7 @@ void CG_ParseCGMessage_ver_6()
CG_MakeBulletTracer(vTmp, vStart, vEndArray, 1, iLarge, qtrue, qtrue);
break;
case 26:
case CGM6_BULLET_NO_BARREL_2:
memset(vTmp, 0, sizeof(vTmp));
vStart[0] = cgi.MSG_ReadCoord();
vStart[1] = cgi.MSG_ReadCoord();
@@ -1860,7 +1915,7 @@ void CG_ParseCGMessage_ver_6()
CG_MakeBulletTracer(vTmp, vStart, vEndArray, 1, iLarge, qfalse, qtrue);
break;
case 27:
case CGM6_HUDDRAW_SHADER:
iInfo = cgi.MSG_ReadByte();
strcpy(cgi.HudDrawElements[iInfo].shaderName, cgi.MSG_ReadString());
cgi.HudDrawElements[iInfo].string[0] = 0;
@@ -1870,13 +1925,13 @@ void CG_ParseCGMessage_ver_6()
CG_HudDrawShader(iInfo);
break;
case 28:
case CGM6_HUDDRAW_ALIGN:
iInfo = cgi.MSG_ReadByte();
cgi.HudDrawElements[iInfo].iHorizontalAlign = cgi.MSG_ReadBits(2);
cgi.HudDrawElements[iInfo].iVerticalAlign = cgi.MSG_ReadBits(2);
break;
case 29:
case CGM6_HUDDRAW_RECT:
iInfo = cgi.MSG_ReadByte();
cgi.HudDrawElements[iInfo].iX = cgi.MSG_ReadShort();
cgi.HudDrawElements[iInfo].iY = cgi.MSG_ReadShort();
@@ -1884,30 +1939,30 @@ void CG_ParseCGMessage_ver_6()
cgi.HudDrawElements[iInfo].iHeight = cgi.MSG_ReadShort();
break;
case 30:
case CGM6_HUDDRAW_VIRTUALSIZE:
iInfo = cgi.MSG_ReadByte();
cgi.HudDrawElements[iInfo].bVirtualScreen = cgi.MSG_ReadBits(1);
break;
case 31:
case CGM6_HUDDRAW_COLOR:
iInfo = cgi.MSG_ReadByte();
cgi.HudDrawElements[iInfo].vColor[0] = cgi.MSG_ReadByte() / 255.0;
cgi.HudDrawElements[iInfo].vColor[1] = cgi.MSG_ReadByte() / 255.0;
cgi.HudDrawElements[iInfo].vColor[2] = cgi.MSG_ReadByte() / 255.0;
break;
case 32:
case CGM6_HUDDRAW_ALPHA:
iInfo = cgi.MSG_ReadByte();
cgi.HudDrawElements[iInfo].vColor[3] = cgi.MSG_ReadByte() / 255.0;
break;
case 33:
case CGM6_HUDDRAW_STRING:
iInfo = cgi.MSG_ReadByte();
cgi.HudDrawElements[iInfo].hShader = 0;
strcpy(cgi.HudDrawElements[iInfo].string, cgi.MSG_ReadString());
break;
case 34:
case CGM6_HUDDRAW_FONT:
iInfo = cgi.MSG_ReadByte();
strcpy(cgi.HudDrawElements[iInfo].fontName, cgi.MSG_ReadString());
cgi.HudDrawElements[iInfo].hShader = 0;
@@ -1916,14 +1971,14 @@ void CG_ParseCGMessage_ver_6()
CG_HudDrawFont(iInfo);
break;
case 35:
case 36:
case CGM6_NOTIFY_KILL:
case CGM6_NOTIFY_HIT:
{
int iOldEnt;
iOldEnt = current_entity_number;
current_entity_number = cg.snap->ps.clientNum;
if (iType == 36) {
if (iType == CGM6_NOTIFY_HIT) {
commandManager.PlaySound("dm_kill_notify", NULL, CHAN_LOCAL, 2.0, -1, -1, 1);
} else {
commandManager.PlaySound("dm_hit_notify", NULL, CHAN_LOCAL, 2.0, -1, -1, 1);
@@ -1933,7 +1988,7 @@ void CG_ParseCGMessage_ver_6()
}
break;
case 37:
case CGM6_VOICE_CHAT:
{
int iOldEnt;
+2
View File
@@ -430,6 +430,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;
+1 -1
View File
@@ -296,7 +296,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;
}
+175 -4
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",
@@ -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:
@@ -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));
}
}
/*
+1 -1
View File
@@ -1146,7 +1146,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;
-11
View File
@@ -560,17 +560,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);
+48 -20
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]
@@ -348,7 +353,9 @@ void CG_ViewModelAnimation(refEntity_t *pModel)
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]));
cgi.anim->g_iLastAnimPrefixIndex = iAnimPrefixIndex;
bAnimChanged = qtrue;
bAnimChanged = qtrue;
bWeaponChanged = qtrue;
}
if (cgi.anim->g_iLastVMAnim == -1) {
@@ -422,20 +429,27 @@ void CG_ViewModelAnimation(refEntity_t *pModel)
}
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;
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;
}
}
+283 -280
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);
}
}
@@ -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);
@@ -890,251 +895,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;
}
}
}
+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
+28 -8
View File
@@ -1,14 +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_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)
@@ -17,11 +20,12 @@ target_link_libraries(omohclient INTERFACE gcd)
# Sound stuff
target_compile_definitions(omohclient INTERFACE USE_CODEC_MP3)
if (USE_SOUND_NEW)
# Try to use OpenAL
find_package(OpenAL)
if (NOT NO_OPENAL)
# Use OpenAL
find_package(OpenAL REQUIRED)
if (OPENAL_FOUND)
target_compile_definitions(omohclient INTERFACE USE_SOUND_NEW=1)
target_compile_definitions(omohclient INTERFACE USE_OPENAL=1 NO_MODERN_DMA=0)
if (MSVC)
target_include_directories(omohclient INTERFACE ${OPENAL_INCLUDE_DIR}/AL)
else()
@@ -31,8 +35,27 @@ if (USE_SOUND_NEW)
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)
add_subdirectory("../libmad" "./libmad" EXCLUDE_FROM_ALL)
target_link_libraries(omohclient INTERFACE mad)
set(BUILD_SHARED_LIBS ${OLD_VALUE} CACHE BOOL "" FORCE)
if (USE_OPENAL)
# Try to use OpenAL
find_package(OpenAL)
@@ -44,6 +67,3 @@ if (USE_OPENAL)
endif()
target_sources(omohclient INTERFACE ${SOURCES_CLIENT} ${SOURCES_UILIB})
add_subdirectory("../libmad-0.15.1b" "./libmad")
target_link_libraries(omohclient INTERFACE libmad)
+21 -15
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,20 +234,20 @@ 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)
{
if (snapshot->numEntities != count) {
Com_DPrintf("CL_GetSnapshot: Not all children could find their parents.\n");
for (i = count; i < snapshot->numEntities; i++)
{
s1 = &cl.parseEntities[(clSnap->parseEntitiesNum + i) & (MAX_PARSE_ENTITIES - 1)];
@@ -261,6 +261,8 @@ qboolean CL_GetSnapshot( int snapshotNumber, snapshot_t *snapshot ) {
s1->origin[1],
s1->origin[2]
);
parents[s1->number] = -2;
}
}
}
@@ -358,7 +360,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;
}
@@ -578,7 +582,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);
}
}
@@ -813,6 +817,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;
+5 -5
View File
@@ -432,7 +432,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;
@@ -577,9 +577,9 @@ void CL_MouseMove( usercmd_t *cmd ) {
cmd->forwardmove = ClampChar(cmd->forwardmove - m_forward->value * my);
if (!isfinite(cl.viewangles[PITCH]) || !isfinite(cl.viewangles[YAW])) {
Com_Printf("Invalid client viewangles encountered!\n");
Com_Printf("cgameSensitivity: %f - mx: %f - my: %f - m_pitch: %f - m_yaw: %f", cgameSensitivity, mx, my, m_pitch->value, m_yaw->value);
Com_Printf("Resetting client viewangles");
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;
}
@@ -999,7 +999,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;
}
+2 -2
View File
@@ -23,8 +23,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "cl_ui.h"
typedef struct {
char *string;
int value;
const char *string;
int value;
} equipment_event_table_t;
static equipment_event_table_t s_equipTable[] = {
+114 -18
View File
@@ -769,7 +769,7 @@ void CL_ShutdownAll(qboolean shutdownRef) {
CL_cURL_Shutdown();
#endif
// clear sounds
#if !defined(USE_SOUND_NEW) || !USE_SOUND_NEW
#if defined(NO_MODERN_DMA) && NO_MODERN_DMA
S_DisableSounds();
#endif
// shutdown CGame
@@ -1486,7 +1486,7 @@ void CL_SendPureChecksums( void ) {
Q_strcat(cMsg, sizeof(cMsg), va("%d ", cl.serverId) );
Q_strcat(cMsg, sizeof(cMsg), pChecksums);
for (i = 0; i < 2; i++) {
cMsg[i] += 10;
cMsg[i] += '\n';
}
CL_AddReliableCommand( cMsg, qfalse );
}
@@ -1515,6 +1515,12 @@ because the renderer doesn't know what graphics to reload
=================
*/
void CL_Vid_Restart_f( void ) {
soundsystemsavegame_t save;
char tm_filename[MAX_RES_NAME];
int tm_loopcount;
int tm_offset;
char current_soundtrack[128];
if (!CL_Allowed_Vid_Restart()) {
return;
}
@@ -1522,11 +1528,18 @@ void CL_Vid_Restart_f( void ) {
Com_Printf("-------- CL_Vid_Restart_f --------\n");
cls.vid_restart = qtrue;
// don't let them loop during the restart
S_StopAllSounds2(qtrue);
//
// Save the current music
//
Q_strncpyz(tm_filename, S_GetMusicFilename(), sizeof(tm_filename));
tm_loopcount = S_GetMusicLoopCount();
tm_offset = S_GetMusicOffset();
SV_ClearSvsTimeFixups();
S_SaveData(&save);
Q_strncpyz(current_soundtrack, S_CurrentSoundtrack(), sizeof(current_soundtrack));
S_BeginRegistration();
// shutdown the renderer and clear the renderer interface
@@ -1547,13 +1560,22 @@ void CL_Vid_Restart_f( void ) {
CL_StartHunkUsers(qfalse);
#if !defined(NO_MODERN_DMA) || !NO_MODERN_DMA
s_bSoundPaused = true;
S_LoadData(&save);
#else
S_Init();
#endif
SV_FinishSvsTimeFixups();
#if !defined(USE_SOUND_NEW) || !USE_SOUND_NEW
S_Init();
#else
S_Init(qtrue);
#endif
S_ReLoad(&save);
if (tm_filename[0]) {
S_TriggeredMusic_SetupHandle(tm_filename, tm_loopcount, tm_offset, 0);
}
MUSIC_NewSoundtrack(current_soundtrack);
if (clc.state > CA_CONNECTED && clc.state != CA_CINEMATIC)
{
@@ -1575,15 +1597,52 @@ handles will be invalid
=================
*/
void CL_Snd_Restart_f( void ) {
#if !defined(USE_SOUND_NEW) || !USE_SOUND_NEW
#if defined(NO_MODERN_DMA) && NO_MODERN_DMA
S_Shutdown();
S_Init();
CL_Vid_Restart_f();
#else
qboolean full;
soundsystemsavegame_t save;
char tm_filename[MAX_RES_NAME];
int tm_loopcount;
int tm_offset;
char current_soundtrack[128];
full = S_NeedFullRestart();
//
// Save the current music
//
Q_strncpyz(tm_filename, S_GetMusicFilename(), sizeof(tm_filename));
tm_loopcount = S_GetMusicLoopCount();
tm_offset = S_GetMusicOffset();
SV_ClearSvsTimeFixups();
S_SaveData(&save);
Q_strncpyz(current_soundtrack, S_CurrentSoundtrack(), sizeof(current_soundtrack));
S_Shutdown(qfalse);
S_Init(qfalse);
#endif
CL_Vid_Restart_f();
s_bSoundPaused = true;
S_LoadData(&save);
SV_FinishSvsTimeFixups();
S_ReLoad(&save);
if (tm_filename[0]) {
S_TriggeredMusic_SetupHandle(tm_filename, tm_loopcount, tm_offset, 0);
}
MUSIC_NewSoundtrack(current_soundtrack);
if (full) {
CL_Vid_Restart_f();
}
#endif
}
@@ -2383,6 +2442,13 @@ CL_CheckTimeout
==================
*/
void CL_CheckTimeout( void ) {
if (com_sv_running->integer) {
// Added in OPM
// Timeout should not be possible if the client is hosting the game
// (like in single-player mode)
return;
}
//
// check timeout
//
@@ -2390,10 +2456,37 @@ void CL_CheckTimeout( void ) {
&& clc.state >= CA_CONNECTED && clc.state != CA_CINEMATIC
&& cls.realtime - clc.lastPacketTime > cl_timeout->value*1000) {
if (++cl.timeoutcount > 5) { // timeoutcount saves debugger
Com_Printf ("\nServer connection timed out.\n");
Cbuf_AddText( "pushmenu servertimeout\n" );
CL_Disconnect();
return;
const char* info;
const char* maxclients;
info = &cl.gameState.stringData[cl.gameState.stringOffsets[CS_SERVERINFO]];
maxclients = Info_ValueForKey(info, "maxclients");
//
// Disconnect if the player isn't alone (single-player mode)
//
if (!maxclients || atoi(maxclients) != 1) {
qboolean bConsoleState;
bConsoleState = UI_ConsoleIsOpen();
Com_Printf("\nServer connection timed out.\n");
SV_Shutdown("\nServer connection timed out\n");
if (com_cl_running && com_cl_running->integer) {
CL_AbnormalDisconnect();
CL_FlushMemory();
CL_StartHunkUsers(qfalse);
}
UI_ForceMenuOff(qtrue);
UI_PushMenu("servertimeout");
if (bConsoleState) {
UI_OpenConsole();
} else {
UI_CloseConsole();
}
}
}
} else {
cl.timeoutcount = 0;
@@ -2486,6 +2579,7 @@ void CL_Frame ( int msec ) {
&& !com_sv_running->integer ) {
// if disconnected, bring up the menu
S_StopAllSounds2( qtrue );
S_TriggeredMusic_PlayIntroMusic();
UI_MenuEscape( "main" );
}
@@ -3398,8 +3492,10 @@ void CL_Init( void ) {
Cvar_Set( "cl_running", "1" );
#if !defined(USE_SOUND_NEW) || !USE_SOUND_NEW
#if defined(NO_MODERN_DMA) && NO_MODERN_DMA
S_Init2();
#else
S_Init(qtrue);
#endif
// fixme: should we leave it?
@@ -3441,7 +3537,7 @@ void CL_Shutdown(const char* finalmsg, qboolean disconnect, qboolean quit) {
if(disconnect)
CL_Disconnect();
#if !defined(USE_SOUND_NEW) || !USE_SOUND_NEW
#if defined(NO_MODERN_DMA) && NO_MODERN_DMA
S_Shutdown();
#else
S_Shutdown(qtrue);
+15 -10
View File
@@ -1289,7 +1289,9 @@ void UI_PrintConsole(const char *msg)
break;
}
pszString++;
if (*pszString != 0) {
pszString++;
}
//
// print to the deathmatch console
@@ -1775,6 +1777,8 @@ void UI_Update(void)
hud_compass->GetContainerWidget()->Display(frame, 1.0);
}
}
return;
}
if (fakk_console) {
@@ -1887,7 +1891,7 @@ void UI_Update(void)
UI_CloseConsole();
}
} else if (ui_static_materials.loading) {
ui_static_materials.loading->ReregisterMaterial();
ui_static_materials.loading->GetMaterial();
}
}
}
@@ -3333,6 +3337,7 @@ void UI_GetPlayerModel_f(void)
Cvar_Set("ui_dm_playergermanmodel_set", pszUIPlayerModel);
if (!strncmp(pszUIPlayerModel, "german_waffen_", 14)) {
Q_strncpyz(donotshowssindeorfr, "german_waffenss_", sizeof(donotshowssindeorfr));
Q_strcat(donotshowssindeorfr, sizeof(donotshowssindeorfr), pszUIPlayerModel + 14);
Cvar_Set("ui_disp_playergermanmodel", va("models/player/%s.tik", donotshowssindeorfr));
} else {
@@ -3674,7 +3679,7 @@ void CL_FillUIImports(void)
uii.Cvar_GetString = CvarGetForUI;
uii.Cvar_Reset = Cvar_Reset;
uii.Cvar_Find = Cvar_FindVar;
uii.Cvar_Set = Cvar_Set;
uii.Cvar_Set = UI_Cvar_Set;
uii.File_PickFile = PickFile;
uii.File_FreeFile = FS_FreeFile;
uii.File_ListFiles = ListFilesForUI;
@@ -3971,13 +3976,13 @@ void S_ServerLoaded(void)
Com_DPrintf("Loading Previous Sound State.\n");
S_StopAllSounds2(qfalse);
//S_TriggeredMusic_Stop();
//s_bSoundPaused = qtrue;
//S_ReLoad( &svs.soundSystem );
//
//if( svs.tm_filename[ 0 ] ) {
// S_TriggeredMusic_SetupHandle( svs.tm_filename, svs.tm_loopcount, svs.tm_offset, 0 );
//}
S_TriggeredMusic_Stop();
s_bSoundPaused = qtrue;
S_ReLoad( &svs.soundSystem );
if( svs.tm_filename[ 0 ] ) {
S_TriggeredMusic_SetupHandle( svs.tm_filename, svs.tm_loopcount, svs.tm_offset, 0 );
}
}
/*
+1
View File
@@ -49,6 +49,7 @@ 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);
+5
View File
@@ -155,12 +155,17 @@ void UIFAKKLoadGameClass::SetupFiles(void)
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;
+2 -2
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.
@@ -94,7 +94,7 @@ void PickFile(const char *name, Listener *obj, Event& event)
currentpath = "";
}
picker->Setup("", currentpath, ".*");
picker->Setup("", currentpath, ".*", "");
}
CLASS_DECLARATION(FilePickerClass, ViewSpawnerClass, NULL) {
+14 -12
View File
@@ -180,12 +180,14 @@ void MpMapPickerClass::SetupFiles(void)
FS_FreeFileList(filenames);
}
if (currentDirectory.length()) {
if (currentDirectory == "maps/-/") {
SetupSecondaryFiles(currentDirectory, bTugOfWar, bObjective, bLiberation);
} else {
SetupSecondaryFiles("maps/obj/", bTugOfWar, bObjective, bLiberation);
SetupSecondaryFiles("maps/lib/", bTugOfWar, bObjective, bLiberation);
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);
}
}
}
@@ -278,9 +280,9 @@ void MpMapPickerClass::FileSelected(Event *ev)
uii.Snd_PlaySound("sound/menu/apply.wav");
UIListCtrlItem* item = listbox->GetItem(listbox->getCurrentItem());
str name = item->getListItemString(0);
str directory = item->getListItemString(1);
UIListCtrlItem *item = listbox->GetItem(listbox->getCurrentItem());
str name = item->getListItemString(0);
str directory = item->getListItemString(1);
FileSelected(directory, name, directory + name);
}
@@ -305,9 +307,9 @@ void MpMapPickerClass::FileChosen(Event *ev)
uii.Snd_PlaySound("sound/menu/apply.wav");
UIListCtrlItem* item = listbox->GetItem(listbox->getCurrentItem());
str name = item->getListItemString(0);
str directory = item->getListItemString(1);
UIListCtrlItem *item = listbox->GetItem(listbox->getCurrentItem());
str name = item->getListItemString(0);
str directory = item->getListItemString(1);
FileSelected(directory, name, directory + name);
}
+1 -1
View File
@@ -295,7 +295,7 @@ void PlayerModelPickerClass::FileSelected(Event *ev)
fullname = PM_DisplaynameToFilename(name);
if (!Q_stricmpn(fullname, "german_waffen_", 14)) {
Q_strncpyz(donotshowssindeorfr, "german_waffen_", sizeof(donotshowssindeorfr));
Q_strncpyz(donotshowssindeorfr, "german_waffenss_", sizeof(donotshowssindeorfr));
Q_strcat(donotshowssindeorfr, sizeof(donotshowssindeorfr), fullname.c_str() + 14);
} else {
Q_strncpyz(donotshowssindeorfr, fullname, sizeof(donotshowssindeorfr));
-32
View File
@@ -490,12 +490,10 @@ 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());
}
break;
@@ -507,12 +505,10 @@ 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()
);
@@ -528,14 +524,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,
@@ -557,14 +551,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,
@@ -583,14 +575,12 @@ void UIFakkLabel::DrawStatbar(float frac)
{
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 +676,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 +697,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 +725,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 +750,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 +828,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 +847,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 +915,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 +935,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 +1111,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 +1123,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 +1199,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 +1219,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());
}
}
+1 -3
View File
@@ -30,8 +30,6 @@ CLASS_DECLARATION(UIWidget, View3D, NULL) {
{NULL, NULL }
};
#define MAX_SUBTITLES 4
cvar_t *subs[MAX_SUBTITLES];
cvar_t *teams[MAX_SUBTITLES];
float fadeTime[MAX_SUBTITLES];
@@ -316,7 +314,7 @@ void View3D::DrawSubtitleOverlay(void)
if (total > maxY) {
total = 0;
if (end < start) {
Com_Printf("ERROR - word longer than possible line\n");
Com_DPrintf("ERROR - word longer than possible line\n");
break;
}
+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
}
+142 -1
View File
@@ -21,8 +21,11 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "../snd_local.h"
#include "../client.h"
#if !defined(USE_SOUND_NEW) || !USE_SOUND_NEW
#if defined(NO_MODERN_DMA) && NO_MODERN_DMA
qboolean s_bSoundPaused = qfalse;
void S_Init2()
{
@@ -32,6 +35,10 @@ void S_Init2()
// 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);
}
/*
@@ -52,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);
}
@@ -363,6 +381,16 @@ void MUSIC_CheckForStoppedSongs(void)
STUB();
}
/*
==============
S_CurrentSoundtrack
==============
*/
const char* S_CurrentSoundtrack()
{
return "";
}
/*
=================
S_IsSoundRegistered
@@ -427,28 +455,141 @@ 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
}
#endif
+11
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,11 @@ 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();
#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
+10 -2
View File
@@ -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 );
+621 -37
View File
@@ -20,10 +20,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#if USE_SOUND_NEW
#include "snd_local.h"
#include "snd_openal_new.h"
#include "client.h"
#include "cl_ui.h"
typedef struct {
vec3_t origin;
@@ -32,10 +32,6 @@ typedef struct {
int mergeFrame;
} loopSound_t;
# define MAX_SFX 1400
# define MAX_SFX_INFOS 1000
# define MAX_LOOP_SOUNDS 64
qboolean s_bLastInitSound = qfalse;
qboolean s_bSoundStarted = qfalse;
qboolean s_bSoundPaused = qfalse;
@@ -70,81 +66,402 @@ cvar_t *s_dialogscale;
int numLoopSounds;
loopSound_t loopSounds[MAX_LOOP_SOUNDS];
/*
==============
S_SoundInfo_f
==============
*/
void S_SoundInfo_f()
{
// FIXME: unimplemented
S_PrintInfo();
}
/*
==============
S_SoundDump_f
==============
*/
void S_SoundDump_f()
{
// FIXME: unimplemented
S_DumpInfo();
}
/*
==============
S_Init
==============
*/
void S_Init(qboolean full_startup)
{
// FIXME: unimplemented
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)
{
// FIXME: unimplemented
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)
{
// FIXME: unimplemented
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)
{
// FIXME: unimplemented
return NULL;
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()
{
// FIXME: unimplemented
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");
}
/*
==============
S_DefaultSound
==============
*/
void S_DefaultSound(sfx_t *sfx)
{
// FIXME: unimplemented
sfx->data = NULL;
sfx->iFlags |= SFX_FLAG_DEFAULT_SOUND;
}
/*
==============
S_IsSoundRegistered
==============
*/
qboolean S_IsSoundRegistered(const char *name)
{
// FIXME: unimplemented
return qfalse;
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)
{
// FIXME: unimplemented
return 0;
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)
{
// FIXME: unimplemented
return 0;
return s_knownSfx[handle].time_length;
}
/*
==============
S_EndRegistration
==============
*/
void S_EndRegistration()
{
// FIXME: unimplemented
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)
{
// FIXME: unimplemented
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)
{
// FIXME: unimplemented
s_fAmbientVolume = volume;
}
/*
==============
S_StartSound
==============
*/
void S_StartSound(
const vec3_t origin,
int entnum,
@@ -157,29 +474,171 @@ void S_StartSound(
int streamed
)
{
// FIXME: unimplemented
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)
{
// FIXME: unimplemented
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)
{
// FIXME: unimplemented
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)
{
// FIXME: unimplemented
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()
{
// FIXME: unimplemented
if (!s_bSoundStarted) {
return;
}
S_Driver_ClearLoopingSounds();
}
/*
==============
S_AddLoopingSound
==============
*/
void S_AddLoopingSound(
const vec3_t origin,
const vec3_t velocity,
@@ -191,42 +650,167 @@ void S_AddLoopingSound(
int flags
)
{
// FIXME: unimplemented
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])
{
// FIXME: unimplemented
if (!s_bSoundStarted) {
return;
}
S_Driver_Respatialize(entityNum, head, axis);
}
/*
==============
S_Update
==============
*/
void S_Update()
{
// FIXME: unimplemented
if (!s_bSoundStarted) {
return;
}
if (server_loading) {
return;
}
S_Driver_Update();
}
/*
==============
S_StopSound
==============
*/
void S_StopSound(int entnum, int channel)
{
// FIXME: unimplemented
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)
{
// FIXME: unimplemented
if (!s_bSoundStarted) {
return;
}
S_Driver_SetReverb(reverb_type, reverb_level);
}
/*
==============
S_Play
==============
*/
void S_Play()
{
// FIXME: unimplemented
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()
{
// FIXME: unimplemented
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
}
#endif
/*
==============
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();
}
+95
View File
@@ -0,0 +1,95 @@
/*
===========================================================================
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 "../qcommon/tiki.h"
void load_sfx_info()
{
TikiScript tiki;
const char *token;
int current_sound_file;
char file_name[MAX_QPATH];
sfx_infos[0].name[0] = 0;
sfx_infos[0].max_factor = -1.0;
sfx_infos[0].loop_start = -1;
sfx_infos[0].loop_end = -1;
sfx_infos[0].max_number_playing = 5;
number_of_sfx_infos = 1;
for (current_sound_file = 0; current_sound_file < 10; current_sound_file++) {
Com_sprintf(file_name, sizeof(file_name), "global/sound%d.txt", current_sound_file);
if (!tiki.LoadFile(file_name, qtrue)) {
continue;
}
Com_Printf("Loading %s\n", file_name);
while (tiki.TokenAvailable(qtrue)) {
token = tiki.GetToken(qtrue);
if (!Q_stricmp(token, "sound")) {
if (tiki.TokenAvailable(qtrue)) {
token = tiki.GetToken(qtrue);
if (number_of_sfx_infos == 1000) {
Com_DPrintf("Too many sound infos specified\n");
break;
}
Q_strncpyz(sfx_infos[number_of_sfx_infos].name, token, sizeof(sfx_infos[number_of_sfx_infos].name));
sfx_infos[number_of_sfx_infos].max_factor = -1.f;
sfx_infos[number_of_sfx_infos].loop_start = -1;
sfx_infos[number_of_sfx_infos].loop_end = -1;
sfx_infos[number_of_sfx_infos].max_number_playing = 5;
number_of_sfx_infos++;
}
} else if (!Q_stricmp(token, "loopstart")) {
if (!tiki.TokenAvailable(qtrue)) {
token = tiki.GetToken(qtrue);
sfx_infos[number_of_sfx_infos - 1].loop_start = atoi(token);
}
} else if (!Q_stricmp(token, "loopend")) {
if (!tiki.TokenAvailable(qtrue)) {
token = tiki.GetToken(qtrue);
sfx_infos[number_of_sfx_infos - 1].loop_end = atoi(token);
}
} else if (!Q_stricmp(token, "maxnumber")) {
if (!tiki.TokenAvailable(qtrue)) {
token = tiki.GetToken(qtrue);
sfx_infos[number_of_sfx_infos - 1].max_number_playing = atoi(token);
}
} else if (!Q_stricmp(token, "maxfactor")) {
if (!tiki.TokenAvailable(qtrue)) {
token = tiki.GetToken(qtrue);
sfx_infos[number_of_sfx_infos - 1].max_factor = atoi(token);
}
}
}
}
tiki.Close();
sfx_infos[0].name[0] = 0;
}
+1 -1
View File
@@ -27,7 +27,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "../qcommon/qcommon.h"
#include "snd_public.h"
#if !defined(USE_SOUND_NEW) || !USE_SOUND_NEW
#if defined(NO_MODERN_DMA) && NO_MODERN_DMA
#define PAINTBUFFER_SIZE 4096 // this is in samples
+70
View File
@@ -29,6 +29,13 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
extern "C" {
#endif
extern cvar_t *s_volume;
extern cvar_t *s_khz;
extern cvar_t *s_loadas8bit;
extern cvar_t *s_separation;
extern cvar_t *s_musicVolume;
extern cvar_t *s_ambientVolume;
typedef struct {
int format;
float rate;
@@ -130,10 +137,57 @@ typedef struct {
channelbasesavegame_t Channels[96];
} soundsystemsavegame_t;
enum channel_flags_t {
CHANNEL_FLAG_PLAY_DEFERRED = 1,
CHANNEL_FLAG_LOCAL_LISTENER = 16,
CHANNEL_FLAG_NO_ENTITY = 32,
CHANNEL_FLAG_PAUSED = 64,
CHANNEL_FLAG_LOOPING = 128,
// Added in OPM
CHANNEL_FLAG_MISSING_ENT = 256,
};
enum sfx_flags_t {
SFX_FLAG_DEFAULT_SOUND = 1,
SFX_FLAG_MP3 = 2,
SFX_FLAG_STREAMED = 4,
SFX_FLAG_NO_OFFSET = 8,
SFX_FLAG_NULL = 16,
};
enum loopsound_flags_t {
LOOPSOUND_FLAG_NO_PAN = 1
};
#define MAX_SFX 1400
#define MAX_SFX_INFOS 1000
#define MAX_LOOP_SOUNDS 64
extern qboolean s_bLastInitSound;
extern qboolean s_bSoundStarted;
extern qboolean s_bSoundPaused;
extern qboolean s_bTryUnpause;
extern int s_iListenerNumber;
extern float s_fAmbientVolume;
extern int number_of_sfx_infos;
extern sfx_info_t sfx_infos[];
extern sfx_t s_knownSfx[];
extern int s_numSfx;
extern s_entity_t s_entity[];
// The current sound driver.
// Currently OPENAL
#define SOUND_DRIVER OPENAL
//
// snd_info.cpp
//
void load_sfx_info();
//
// snd_dma_new.cpp
//
sfx_t *S_FindName(const char *name, int sequenceNumber);
void S_DefaultSound(sfx_t *sfx);
@@ -141,6 +195,11 @@ void S_LoadData(soundsystemsavegame_t *pSave);
void S_SaveData(soundsystemsavegame_t *pSave);
void S_ClearSoundBuffer();
//
// snd_mem.c
//
qboolean S_LoadSound(const char *fileName, sfx_t *sfx, int streamed, qboolean force_load);
#define S_StopAllSounds2 S_StopAllSounds
//
@@ -150,6 +209,7 @@ void S_ClearSoundBuffer();
#define S_Call_SndDriverX(driver, func) S_Call_SndDriver(driver, func)
#define S_Driver_Init S_Call_SndDriverX(SOUND_DRIVER, Init)
#define S_Driver_Shutdown S_Call_SndDriverX(SOUND_DRIVER, Shutdown)
#define S_Driver_StartSound S_Call_SndDriverX(SOUND_DRIVER, StartSound)
#define S_Driver_AddLoopingSound S_Call_SndDriverX(SOUND_DRIVER, AddLoopingSound)
#define S_Driver_ClearLoopingSounds S_Call_SndDriverX(SOUND_DRIVER, ClearLoopingSounds)
@@ -158,6 +218,16 @@ void S_ClearSoundBuffer();
#define S_Driver_Respatialize S_Call_SndDriverX(SOUND_DRIVER, Respatialize)
#define S_Driver_SetReverb S_Call_SndDriverX(SOUND_DRIVER, SetReverb)
#define S_Driver_Update S_Call_SndDriverX(SOUND_DRIVER, Update)
#define S_Driver_GetMusicFilename S_Call_SndDriverX(SOUND_DRIVER, GetMusicFilename)
#define S_Driver_GetMusicLoopCount S_Call_SndDriverX(SOUND_DRIVER, GetMusicLoopCount)
#define S_Driver_GetMusicOffset S_Call_SndDriverX(SOUND_DRIVER, GetMusicOffset)
void S_PrintInfo();
void S_DumpInfo();
qboolean S_NeedFullRestart();
void S_ReLoad(soundsystemsavegame_t* pSave);
extern cvar_t *s_show_sounds;
#ifdef __cplusplus
}
+567
View File
@@ -0,0 +1,567 @@
/*
===========================================================================
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 "cl_ui.h"
byte *data_p;
byte *iff_end;
byte *last_chunk;
byte *iff_data;
int iff_chunk_len;
qboolean S_LoadMP3(const char *fileName, sfx_t *sfx);
/*
==============
GetLittleShort
==============
*/
short int GetLittleShort()
{
union {
short value;
byte bytes[2];
} val;
# ifdef Q3_LITTLE_ENDIAN
val.bytes[0] = data_p[0];
val.bytes[1] = data_p[1];
# else
val.bytes[0] = data_p[1];
val.bytes[1] = data_p[0];
# endif
data_p += sizeof(short);
return val.value;
}
/*
==============
GetLittleLong
==============
*/
int GetLittleLong()
{
union {
int value;
byte bytes[4];
} val;
# ifdef Q3_LITTLE_ENDIAN
val.bytes[0] = data_p[0];
val.bytes[1] = data_p[1];
val.bytes[2] = data_p[2];
val.bytes[3] = data_p[3];
# else
val.bytes[0] = data_p[3];
val.bytes[1] = data_p[2];
val.bytes[2] = data_p[1];
val.bytes[3] = data_p[0];
# endif
data_p += sizeof(int);
return val.value;
}
/*
==============
SetLittleShort
==============
*/
void SetLittleShort(int i)
{
union {
short value;
byte bytes[2];
} val;
val.value = i;
# ifdef Q3_LITTLE_ENDIAN
data_p[0] = val.bytes[0];
data_p[1] = val.bytes[1];
# else
data_p[0] = val.bytes[1];
data_p[1] = val.bytes[0];
# endif
data_p += sizeof(short);
}
/*
==============
SetLittleLong
==============
*/
void SetLittleLong(int i)
{
union {
int value;
byte bytes[4];
} val;
val.value = i;
# ifdef Q3_LITTLE_ENDIAN
data_p[0] = val.bytes[0];
data_p[1] = val.bytes[1];
data_p[2] = val.bytes[2];
data_p[3] = val.bytes[3];
# else
data_p[0] = val.bytes[3];
data_p[1] = val.bytes[2];
data_p[2] = val.bytes[1];
data_p[3] = val.bytes[0];
# endif
data_p += sizeof(int);
}
/*
==============
FindNextChunk
==============
*/
void FindNextChunk(const char *name)
{
int value;
while (1) {
data_p = last_chunk;
if (last_chunk >= (byte *)iff_end) {
break;
}
data_p = last_chunk + 4;
value = GetLittleLong();
iff_chunk_len = value;
if (value < 0) {
break;
}
data_p -= 8;
value++;
value &= ~1;
last_chunk = data_p + value + 8;
if (!strncmp((const char *)data_p, name, 4u)) {
return;
}
}
data_p = NULL;
}
/*
==============
FindChunk
==============
*/
void FindChunk(const char *name)
{
last_chunk = iff_data;
FindNextChunk(name);
}
/*
==============
DumpChunks
==============
*/
void DumpChunks()
{
char str[5];
str[4] = 0;
data_p = iff_data;
do {
memcpy(str, data_p, 4);
data_p += 4;
iff_chunk_len = GetLittleLong();
Com_Printf("0x%x : %s (%d)\n", data_p - 4, str, iff_chunk_len);
data_p += (iff_chunk_len + 1) & ~1;
} while (data_p < (byte *)iff_end);
}
/*
==============
GetWavinfo
==============
*/
wavinfo_t GetWavinfo(const char *name, byte *wav, int wavlength)
{
wavinfo_t info;
int samples;
memset(&info, 0, sizeof(wavinfo_t));
if (!wav) {
return info;
}
iff_data = wav;
iff_end = &wav[wavlength];
FindChunk("RIFF");
if (!data_p || strncmp((const char *)data_p + 8, "WAVE", 4u)) {
Com_Printf("Missing RIFF/WAVE chunks\n");
return info;
}
iff_data = data_p + 12;
FindChunk("fmt ");
if (!data_p) {
Com_Printf("Missing fmt chunk\n");
return info;
}
data_p += 8;
info.format = GetLittleShort();
if (info.format == 17) {
info.channels = GetLittleShort();
info.rate = (float)GetLittleLong();
data_p += 6;
info.width = (float)GetLittleShort() / 8.f;
data_p += 2;
FindChunk("data");
if (!data_p) {
Com_Printf("Missing data chunk\n");
return info;
}
data_p += 4;
if (info.width >= 1.0) {
samples = (int)((float)GetLittleLong() / info.width);
} else {
samples = (int)((float)GetLittleLong() * info.width);
}
if (!info.samples) {
info.samples = samples;
} else if (samples < info.samples) {
Com_Error(ERR_DROP, "Sound %s has a bad loop length", name);
}
info.dataofs = 0;
} else if (info.format == 1) {
info.channels = GetLittleShort();
info.rate = (float)GetLittleLong();
data_p += 6;
info.width = (float)(GetLittleShort() / 8);
FindChunk("data");
if (!data_p) {
Com_Printf("Missing data chunk\n");
return info;
}
data_p += 4;
samples = (float)GetLittleLong() / info.width;
if (!info.samples) {
info.samples = samples;
} else if (samples < info.samples) {
Com_Error(ERR_DROP, "Sound %s has a bad loop length", name);
}
info.dataofs = data_p - wav;
} else {
Com_Printf("Microsoft PCM format only\n");
return info;
}
info.datasize = iff_chunk_len;
return info;
}
/*
==============
DownSampleWav
==============
*/
qboolean DownSampleWav(wavinfo_t *info, byte *wav, int wavlength, int newkhz, byte **newdata)
{
int newdatasize;
byte* datap;
int i;
int ii;
int error;
int width;
int oldsamples;
int oldrate;
newdatasize = 0;
datap = &wav[info->dataofs];
if (info->channels > 1)
{
Com_DPrintf("Could not downsample WAV file. Stereo WAVs not supported!\n");
return 0;
}
if (info->format != 1 || !info->dataofs)
{
Com_DPrintf("Could not downsample WAV file. Not PCM format!\n");
return 0;
}
if (info->rate <= newkhz) {
return 0;
}
error = 0;
width = info->width;
for (i = 0; i < info->samples; i++) {
error += newkhz;
while (error > info->rate) {
error -= info->rate;
newdatasize += width;
}
}
oldsamples = info->samples;
oldrate = info->rate;
info->samples = newdatasize / width;
info->rate = (float)newkhz;
newdatasize += info->dataofs;
*newdata = (byte*)Z_TagMalloc(newdatasize, TAG_SOUND);
memcpy(*newdata, wav, info->dataofs);
iff_data = *newdata;
iff_end = *newdata + newdatasize;
FindChunk("RIFF");
if (!data_p || strncmp((const char*)data_p + 8, "WAVE", 4u))
{
Com_DPrintf("Missing RIFF/WAVE chunks\n");
return 0;
}
iff_data = data_p + 12;
FindChunk("fmt ");
if (!data_p)
{
Com_DPrintf("Missing fmt chunk\n");
return 0;
}
data_p += 12;
SetLittleShort((int)info->rate);
data_p += 8;
FindChunk("data");
if (!data_p)
{
Com_DPrintf("Missing data chunk\n");
return 0;
}
data_p += 4;
SetLittleLong((int)(info->samples * info->width));
error = 0;
for (i = 0; i < oldsamples; i++) {
error += newkhz;
while (error > oldrate) {
error -= oldrate;
for (ii = 0; ii < width; ii++) {
data_p[ii] = datap[ii];
}
data_p += width;
}
datap += width;
}
return newdatasize;
}
/*
==============
DownSampleWav_MILES
==============
*/
int DownSampleWav_MILES(wavinfo_t *info, byte *wav, int wavlength, int newkhz, byte **newdata)
{
//STUB_DESC("sound stuff");
//return 0;
// FIXME: unimplemented
// Fallback to software downsampling
return DownSampleWav(info, wav, wavlength, newkhz, newdata);
}
/*
==============
S_LoadSound
==============
*/
qboolean S_LoadSound(const char *fileName, sfx_t *sfx, int streamed, qboolean force_load)
{
int size;
fileHandle_t file_handle;
char tempName[MAX_RES_NAME + 1];
int realKhz;
sfx->buffer = 0;
if (fileName[0] == '*') {
return qfalse;
}
if (streamed) {
//
// Added in 2.0
// Will be loaded next time
sfx->length = 5000;
sfx->width = 1;
sfx->iFlags |= SFX_FLAG_STREAMED;
sfx->time_length = 5000.0;
sfx->data = NULL;
return qtrue;
}
if (clc.state != CA_LOADING && !force_load) {
Com_Printf("**************S_LoadSound: %s\n", fileName);
}
if (strstr(fileName, ".mp3")) {
return S_LoadMP3(fileName, sfx);
}
size = FS_FOpenFileRead(fileName, &file_handle, qfalse, qtrue);
if (size <= 0)
{
if (file_handle) {
FS_FCloseFile(file_handle);
}
return qfalse;
}
sfx->data = (byte*)Z_TagMalloc(size, TAG_SOUND);
FS_Read(sfx->data, size, file_handle);
FS_FCloseFile(file_handle);
sfx->info = GetWavinfo(fileName, sfx->data, size);
if (sfx->info.channels != 1 && !streamed)
{
Com_Printf("%s is a stereo wav file\n", fileName);
Z_Free(sfx->data);
sfx->data = NULL;
return qfalse;
}
if (!sfx->info.dataofs) {
sfx->iFlags |= SFX_FLAG_NO_OFFSET;
}
switch (s_khz->integer) {
case 11:
realKhz = 11025;
break;
case 22:
default:
realKhz = 22050;
break;
case 44:
realKhz = 44100;
break;
}
if (!(sfx->iFlags & SFX_FLAG_STREAMED) && realKhz < sfx->info.rate) {
byte* newdata;
int newdatasize;
newdata = NULL;
if (sfx->iFlags & SFX_FLAG_NO_OFFSET) {
newdatasize = DownSampleWav_MILES(&sfx->info, sfx->data, size, realKhz, &newdata);
} else {
newdatasize = DownSampleWav(&sfx->info, sfx->data, size, realKhz, &newdata);
}
if (newdatasize) {
Z_Free(sfx->data);
sfx->data = newdata;
}
}
sfx->length = sfx->info.samples;
sfx->width = sfx->info.width;
sfx->time_length = sfx->info.samples / sfx->info.rate * 1000.f;
if (sfx->iFlags & SFX_FLAG_STREAMED) {
Z_Free(sfx->data);
sfx->data = NULL;
}
sprintf(tempName, "k%s", fileName);
UI_LoadResource(tempName);
if (strstr(fileName, "sound/null.wav")) {
sfx->iFlags |= SFX_FLAG_NULL;
return qtrue;
}
return qtrue;
}
/*
==============
S_LoadMP3
==============
*/
qboolean S_LoadMP3(const char *fileName, sfx_t *sfx)
{
int length;
fileHandle_t file_handle;
length = FS_FOpenFileRead(fileName, &file_handle, 0, 1);
if (length <= 0) {
if (file_handle) {
FS_FCloseFile(file_handle);
}
return qfalse;
}
memset(&sfx->info, 0, sizeof(sfx->info));
sfx->data = (byte*)Z_TagMalloc(length, TAG_SOUND);
sfx->length = length;
sfx->width = 1;
FS_Read(sfx->data, length, file_handle);
FS_FCloseFile(file_handle);
sfx->iFlags |= SFX_FLAG_MP3;
return qtrue;
}
File diff suppressed because it is too large. Load diff
+155 -77
View File
@@ -29,6 +29,25 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
typedef int S32;
typedef unsigned int U32;
#define MAX_OPENAL_CHANNELS_3D 32
#define MAX_OPENAL_CHANNELS_2D 32
#define MAX_OPENAL_CHANNELS_2D_STREAM 32
#define MAX_OPENAL_POSITION_CHANNELS (MAX_OPENAL_CHANNELS_3D + MAX_OPENAL_CHANNELS_2D + MAX_OPENAL_CHANNELS_2D_STREAM)
#define MAX_OPENAL_SONGS 2
#define MAX_OPENAL_MISC_CHANNELS 3
#define MAX_OPENAL_CHANNELS \
(MAX_OPENAL_CHANNELS_3D + MAX_OPENAL_CHANNELS_2D + MAX_OPENAL_CHANNELS_2D_STREAM + MAX_OPENAL_SONGS \
+ MAX_OPENAL_MISC_CHANNELS)
#define MAX_OPENAL_LOOP_SOUNDS 64
#define OPENAL_CHANNEL_MP3_ID \
(MAX_OPENAL_CHANNELS_3D + MAX_OPENAL_CHANNELS_2D + MAX_OPENAL_CHANNELS_2D_STREAM + MAX_OPENAL_SONGS)
#define OPENAL_CHANNEL_TRIGGER_MUSIC_ID (OPENAL_CHANNEL_MP3_ID + 1)
#define OPENAL_CHANNEL_MOVIE_ID (OPENAL_CHANNEL_TRIGGER_MUSIC_ID + 1)
#define MAX_STREAM_BUFFERS 16
#define MAX_BUFFER_SAMPLES 16384
typedef enum {
FADE_NONE,
FADE_IN,
@@ -36,53 +55,62 @@ typedef enum {
} fade_t;
typedef struct {
vec3_t vOrigin;
vec3_t vRelativeOrigin;
vec3_t vVelocity;
vec3_t vOrigin;
vec3_t vRelativeOrigin;
vec3_t vVelocity;
sfx_t *pSfx;
qboolean bPlaying;
int iChannel;
float fVolume;
float fPitch;
int iChannel;
float fVolume;
float fPitch;
int iStartTime;
qboolean bInUse;
qboolean bCombine;
float fBaseVolume;
float fMinDist;
float fMaxDist;
int iFlags;
float fBaseVolume;
float fMinDist;
float fMaxDist;
int iFlags;
} openal_loop_sound_t;
struct openal_channel {
sfx_t *pSfx;
int iEntNum;
int iEntChannel;
vec3_t vOrigin;
float fVolume;
int iBaseRate;
float fNewPitchMult;
float fMinDist;
float fMaxDist;
int iStartTime;
int iTime;
int iEndTime;
int iFlags;
int iPausedOffset;
int song_number;
fade_t fading;
int fade_time;
int fade_start_time;
sfx_t *pSfx;
int iEntNum;
int iEntChannel;
vec3_t vOrigin;
float fVolume;
int iBaseRate;
float fNewPitchMult;
float fMinDist;
float fMaxDist;
int iStartTime;
int iTime;
int iEndTime;
int iFlags;
int iPausedOffset;
int song_number;
fade_t fading;
int fade_time;
int fade_start_time;
ALuint source;
ALuint buffer;
ALubyte *bufferdata;
void play();
void stop();
void pause();
public:
void play();
virtual void stop();
void pause();
void set_no_3d();
void set_3d();
ALint get_state();
void set_gain(float gain);
void set_velocity(float v0, float v1, float v2);
@@ -92,8 +120,8 @@ struct openal_channel {
bool is_paused();
bool is_playing();
void force_free();
bool set_sfx(sfx_t *pSfx);
void force_free();
virtual bool set_sfx(sfx_t *pSfx);
void start_sample();
void stop_sample();
@@ -104,66 +132,116 @@ struct openal_channel {
void set_sample_playback_rate(S32 pan);
S32 sample_playback_rate();
S32 sample_volume();
U32 sample_offset();
U32 sample_ms_offset();
U32 sample_loop_count();
void set_sample_offset(U32 offset);
void set_sample_ms_offset(U32 offset);
void set_sample_loop_count(S32 count);
void set_sample_loop_block(S32 start_offset, S32 end_offset);
S32 sample_volume();
virtual U32 sample_offset();
U32 sample_ms_offset();
U32 sample_loop_count();
virtual void set_sample_offset(U32 offset);
void set_sample_ms_offset(U32 offset);
virtual void set_sample_loop_count(S32 count);
void set_sample_loop_block(S32 start_offset, S32 end_offset);
U32 sample_status();
public:
virtual void update();
virtual U32 buffer_frequency() const;
};
struct openal_channel_two_d_stream : public openal_channel {
private:
char fileName[64];
void *streamHandle;
unsigned int buffers[MAX_STREAM_BUFFERS];
unsigned int currentBuf;
unsigned int sampleLoopCount;
unsigned int sampleLooped;
unsigned int streamNextOffset;
bool streaming;
public:
openal_channel_two_d_stream();
~openal_channel_two_d_stream();
void stop() override;
bool set_sfx(sfx_t *pSfx) override;
void set_sample_loop_count(S32 count) override;
void update() override;
U32 sample_offset() override;
void set_sample_offset(U32 offset) override;
bool queue_stream(const char *fileName);
protected:
U32 buffer_frequency() const override;
private:
void clear_stream();
unsigned int getQueueLength() const;
unsigned int getCurrentStreamPosition() const;
unsigned int getBytesPerSample() const;
};
struct openal_internal_t {
openal_channel chan_3D[32];
openal_channel chan_2D[32];
openal_channel chan_2D_stream[32];
openal_channel chan_song[2];
openal_channel chan_mp3;
openal_channel chan_trig_music;
openal_channel chan_movie;
openal_channel *channel[101];
openal_loop_sound_t loop_sounds[64];
openal_channel movieChannel;
sfx_t movieSFX;
char tm_filename[64];
int tm_loopcount;
openal_channel chan_3D[MAX_OPENAL_CHANNELS_3D];
openal_channel chan_2D[MAX_OPENAL_CHANNELS_2D];
openal_channel_two_d_stream chan_2D_stream[MAX_OPENAL_CHANNELS_2D_STREAM];
openal_channel_two_d_stream chan_song[MAX_OPENAL_SONGS];
openal_channel_two_d_stream chan_mp3;
openal_channel_two_d_stream chan_trig_music;
openal_channel_two_d_stream chan_movie;
// Pointers to channels
openal_channel *channel[MAX_OPENAL_CHANNELS];
openal_loop_sound_t loop_sounds[MAX_OPENAL_LOOP_SOUNDS];
openal_channel movieChannel;
sfx_t movieSFX;
char tm_filename[MAX_RES_NAME];
int tm_loopcount;
};
#ifdef __cplusplus
extern "C" {
#endif
qboolean S_OPENAL_Init();
void S_OPENAL_StartSound(
qboolean S_OPENAL_Init();
void S_OPENAL_Shutdown();
void S_OPENAL_StartSound(
const vec3_t vOrigin,
int iEntNum,
int iEntChannel,
sfxHandle_t sfxHandle,
float fVolume,
float fMinDist,
float fPitch,
float fMaxDist,
qboolean bStreamed
);
void S_OPENAL_AddLoopingSound(
const vec3_t vOrigin,
int iEntNum,
int iEntChannel,
const vec3_t vVelocity,
sfxHandle_t sfxHandle,
float fVolume,
float fMinDist,
float fPitch,
float fMaxDist,
qboolean bStreamed
float fPitch,
int iFlags
);
void S_OPENAL_AddLoopingSound(
const vec3_t vOrigin,
const vec3_t vVelocity,
sfxHandle_t sfxHandle,
float fVolume,
float fMinDist,
float fMaxDist,
float fPitch,
int iFlags
);
void S_OPENAL_ClearLoopingSounds();
void S_OPENAL_StopSound(int iEntNum);
void S_OPENAL_StopAllSounds(qboolean bStopMusic);
void S_OPENAL_Respatialize(int iEntNum, const vec3_t vHeadPos, const vec3_t vAxis[3]);
void S_OPENAL_SetReverb(int iType, float fLevel);
void S_OPENAL_Update();
void S_OPENAL_ClearLoopingSounds();
void S_OPENAL_StopSound(int iEntNum, int iEntChannel);
void S_OPENAL_StopAllSounds(qboolean bStopMusic);
void S_OPENAL_Respatialize(int iEntNum, const vec3_t vHeadPos, const vec3_t vAxis[3]);
void S_OPENAL_SetReverb(int iType, float fLevel);
void S_OPENAL_Update();
const char *S_OPENAL_GetMusicFilename();
int S_OPENAL_GetMusicLoopCount();
unsigned int S_OPENAL_GetMusicOffset();
#ifdef __cplusplus
}
+5 -1
View File
@@ -20,7 +20,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#if !defined(USE_SOUND_NEW) || !USE_SOUND_NEW
#if defined(NO_MODERN_DMA) && NO_MODERN_DMA
#ifdef __cplusplus
extern "C" {
@@ -157,6 +157,10 @@ void S_StopMovieAudio();
void S_SetupMovieAudio(const char* pszMovieName);
int S_CurrentMoviePosition();
const char* S_GetMusicFilename();
int S_GetMusicLoopCount();
unsigned int S_GetMusicOffset();
#ifdef __cplusplus
}
#endif
+134 -9
View File
@@ -80,7 +80,8 @@ Event EV_PG_MaxDuration
"Sets the maximum duration of bursts(in seconds)\nDefault=3",
EV_NORMAL
);
Event EV_PG_MinNumShots(
Event EV_PG_MinNumShots
(
"MinNumShots",
EV_DEFAULT,
"i",
@@ -88,7 +89,8 @@ Event EV_PG_MinNumShots(
"Sets the minimum # of shots to fire in a cycle\nDefault=1",
EV_NORMAL
);
Event EV_PG_MaxNumShots(
Event EV_PG_MaxNumShots
(
"MaxNumShots",
EV_DEFAULT,
"i",
@@ -275,7 +277,8 @@ Event EV_PG_SetPreImpactSoundTime
"Set the time before impact to play the preimpact sound.",
EV_NORMAL
);
Event EV_PG_SetPreImpactSoundProbability(
Event EV_PG_SetPreImpactSoundProbability
(
"preimpactsoundprob",
EV_DEFAULT,
"f",
@@ -492,6 +495,7 @@ void ProjectileGenerator::TurnOn(Event *ev)
if (!m_bIsTurnedOn) {
CancelEventsOfType(EV_PG_BeginCycle);
CancelEventsOfType(EV_TickCycle);
SetupNextCycle();
m_bIsTurnedOn = true;
}
}
@@ -519,6 +523,7 @@ void ProjectileGenerator::SetupNextCycle()
// get a random delay
m_fShotsPerSec = numShots / m_fCycleTime;
delay = 0.01f;
if (m_bIsTurnedOn || !m_bFireOnStartUp) {
delay = G_Random(m_fMaxDelay - m_fMinDelay) + m_fMinDelay;
}
@@ -1986,6 +1991,26 @@ CLASS_DECLARATION(ThrobbingBox_Explosive, ThrobbingBox_Stickybomb, "ThrobbingBox
{NULL, NULL }
};
ThrobbingBox_Stickybomb::ThrobbingBox_Stickybomb()
{
if (LoadingSavegame) {
return;
}
setModel("items/pulse_stickybomb.tik");
m_sUsedModel = "items/stickybomb.tik";
m_sSound = "explode_flak88";
m_sActivateSound = "stickybomb_plant";
m_sTickSound = "stickybomb_fuse";
health = 10;
m_fStopwatchStartTime = 0;
setSolidType(SOLID_BBOX);
takedamage = DAMAGE_NO;
setContents(CONTENTS_WEAPONCLIP);
}
void ThrobbingBox_Stickybomb::OnStickyBombWet(Event *ev)
{
Player *player;
@@ -2193,10 +2218,110 @@ int Objective::GetObjectiveIndex() const
*/
CLASS_DECLARATION(Entity, FencePost, "func_fencepost") {
{&EV_Killed, NULL},
{NULL, NULL}
{&EV_Killed, &FencePost::Killed},
{NULL, NULL }
};
FencePost::FencePost()
{
max_health = 20;
health = 20;
damage_type = MOD_AAGUN;
if (!LoadingSavegame) {
PostEvent(EV_BecomeSolid, EV_POSTSPAWN);
}
takedamage = DAMAGE_YES;
}
void FencePost::Killed(Event *ev)
{
Vector vMins, vMaxs;
Vector vStart, vEnd;
Vector vCenter;
float fHalf;
vCenter = mins - maxs;
vCenter *= 0.5;
if (size.x > size.y) {
if (size.x > size.z) {
if (size.y > size.z) {
fHalf = size.y / 2.f;
} else {
fHalf = size.z / 2.f;
}
vMins[0] = mins[0];
vMaxs[0] = maxs[0];
vMins[1] = vCenter[1];
vMaxs[1] = vCenter[1];
vMins[2] = vCenter[2];
vMaxs[2] = vCenter[2];
} else {
fHalf = size.x / 2.f;
vMins[2] = mins[2];
vMaxs[2] = maxs[2];
vMins[1] = vCenter[1];
vMaxs[1] = vCenter[1];
vMins[0] = vCenter[0];
vMaxs[0] = vCenter[0];
}
} else {
if (size.y > size.z) {
if (size.x > size.z) {
fHalf = size.x / 2.f;
} else {
fHalf = size.z / 2.f;
}
vMins[1] = mins[1];
vMaxs[1] = maxs[1];
vMins[0] = vCenter[0];
vMaxs[0] = vCenter[0];
vMins[2] = vCenter[2];
vMaxs[2] = vCenter[2];
} else {
fHalf = size.y / 2.f;
vMins[2] = mins[2];
vMaxs[2] = maxs[2];
vMins[1] = vCenter[1];
vMaxs[1] = vCenter[1];
vMins[0] = vCenter[0];
vMaxs[0] = vCenter[0];
}
}
MatrixTransformVector(vMins, orientation, vStart);
MatrixTransformVector(vMaxs, orientation, vEnd);
vStart += origin;
vEnd += origin;
if (fHalf > 255) {
fHalf = 255;
}
gi.SetBroadcastVisible(vStart, vEnd);
gi.MSG_StartCGM(CGM_FENCEPOST);
gi.MSG_WriteCoord(vStart[0]);
gi.MSG_WriteCoord(vStart[1]);
gi.MSG_WriteCoord(vStart[2]);
gi.MSG_WriteCoord(vEnd[0]);
gi.MSG_WriteCoord(vEnd[1]);
gi.MSG_WriteCoord(vEnd[2]);
gi.MSG_WriteByte((int)fHalf);
gi.MSG_WriteByte(0);
gi.MSG_EndCGM();
deadflag = DEAD_DEAD;
PostEvent(EV_Remove, 0);
}
Event EV_SetEnemyName
(
"enemyname",
@@ -2213,7 +2338,7 @@ Event EV_SetEnemyName2
"s",
"enemyname",
"",
EV_GETTER
EV_SETTER
);
Event EV_GetEnemyName
(
@@ -2222,7 +2347,7 @@ Event EV_GetEnemyName
"s",
"enemyname",
"",
EV_SETTER
EV_GETTER
);
Event EV_Sentient_GetDontDropWeapons
(
@@ -2538,12 +2663,12 @@ void AISpawnPoint::SetFov(Event *ev)
void AISpawnPoint::SetSight(Event *ev)
{
ev->AddFloat(m_fSight);
m_fSight = ev->GetFloat(1);
}
void AISpawnPoint::GetSight(Event *ev)
{
m_fSight = ev->GetFloat(1);
ev->AddFloat(m_fSight);
}
void AISpawnPoint::GetHearing(Event *ev)
+36 -30
View File
@@ -26,19 +26,19 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "animate.h"
typedef enum {
CONTROLLER_ALLIES,
CONTROLLER_AXIS,
CONTROLLER_ALLIES,
CONTROLLER_AXIS,
CONTROLLER_DRAW
} eController;
#define PT_SPAWNFLAG_PLAY_FIRE_SOUND 1
#define PT_SPAWNFLAG_PLAY_MOTION_SOUND 2
#define PT_SPAWNFLAG_TARGET_RANDOM 4
#define PT_SPAWNFLAG_TURN_ON 8
#define PT_SPAWNFLAG_ROTATE_YAW 16
#define PT_SPAWNFLAG_ROTATE_ROLL 32
#define PT_SPAWNFLAG_TARGET_PLAYER 64
#define PT_SPAWNFLAG_HIDDEN 128
#define PT_SPAWNFLAG_PLAY_FIRE_SOUND 1
#define PT_SPAWNFLAG_PLAY_MOTION_SOUND 2
#define PT_SPAWNFLAG_TARGET_RANDOM 4
#define PT_SPAWNFLAG_TURN_ON 8
#define PT_SPAWNFLAG_ROTATE_YAW 16
#define PT_SPAWNFLAG_ROTATE_ROLL 32
#define PT_SPAWNFLAG_TARGET_PLAYER 64
#define PT_SPAWNFLAG_HIDDEN 128
void ClearProjectileTargets();
@@ -53,7 +53,7 @@ public:
ProjectileTarget();
void EventSetId(Event *ev);
int GetTarget() const;
int GetTarget() const;
};
#define MAX_PROJECTILE_GENERATOR_TARGETS 16
@@ -106,16 +106,16 @@ public:
bool ShouldRotateYaw() const;
bool ShouldRotateRoll() const;
void EventIsTurnedOn(Event *ev);
void EventGetTargetEntity(Event *ev);
void EventLaunchSound(Event *ev);
void SetTarget(Event *ev);
void SetTarget(Entity* ent);
void OnInitialize(Event *ev);
void TurnOff(Event *ev);
void TurnOn(Event *ev);
bool ShouldTargetRandom() const;
Entity* ChooseTarget();
void EventIsTurnedOn(Event *ev);
void EventGetTargetEntity(Event *ev);
void EventLaunchSound(Event *ev);
void SetTarget(Event *ev);
void SetTarget(Entity *ent);
void OnInitialize(Event *ev);
void TurnOff(Event *ev);
void TurnOn(Event *ev);
bool ShouldTargetRandom() const;
Entity *ChooseTarget();
void GetLocalTargets();
bool ShouldTargetPlayer() const;
@@ -123,7 +123,7 @@ public:
void GetMuzzlePos(Vector& pos);
void Fire();
void TryLaunchSound();
void SetWeaponAnim(const char* name, Event* ev);
void SetWeaponAnim(const char *name, Event *ev);
void EventAccuracy(Event *ev);
void EventMaxDelay(Event *ev);
void EventMinDelay(Event *ev);
@@ -134,11 +134,11 @@ public:
void EventMaxDuration(Event *ev);
void EventMinDuration(Event *ev);
void SetWeaponModel(Event *ev);
void EventSetId(Event* ev);
void EventmaxDonut(Event* ev);
void EventminDonut(Event* ev);
void EventarcDonut(Event* ev);
void EventisDonut(Event* ev);
void EventSetId(Event *ev);
void EventmaxDonut(Event *ev);
void EventminDonut(Event *ev);
void EventarcDonut(Event *ev);
void EventisDonut(Event *ev);
virtual bool Attack(int count);
void Archive(Archiver& arc) override;
@@ -164,8 +164,8 @@ public:
void SetProjectileModel(Event *ev);
float EstimateImpactTime(const Vector& targetOrigin, const Vector& fromOrigin, float speed) const;
bool Attack(int count) override;
void Archive(Archiver& arc) override;
bool Attack(int count) override;
void Archive(Archiver& arc) override;
};
class ProjectileGenerator_Gun : public ProjectileGenerator
@@ -306,6 +306,8 @@ private:
public:
CLASS_PROTOTYPE(ThrobbingBox_Stickybomb);
ThrobbingBox_Stickybomb();
void OnStickyBombWet(Event *ev);
void OnStickyBombUse(Event *ev);
@@ -325,7 +327,7 @@ public:
Objective();
void Archive(Archiver &arc) override;
void Archive(Archiver& arc) override;
void TurnOn(Event *ev);
void TurnOff(Event *ev);
void Complete(Event *ev);
@@ -340,6 +342,10 @@ class FencePost : public Entity
{
public:
CLASS_PROTOTYPE(FencePost);
FencePost();
void Killed(Event* ev) override;
};
class AISpawnPoint : public SimpleArchivedEntity
+53 -45
View File
@@ -24,69 +24,77 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "VehicleCollisionEntity.h"
#include "g_phys.h"
CLASS_DECLARATION( Entity, VehicleCollisionEntity, NULL )
{
{ &EV_Damage, &VehicleCollisionEntity::EventDamage },
{ NULL, NULL }
Event EV_Owner
(
"owner",
EV_DEFAULT,
NULL,
NULL,
"owner",
EV_GETTER
);
CLASS_DECLARATION(Entity, VehicleCollisionEntity, NULL) {
{&EV_Damage, &VehicleCollisionEntity::EventDamage},
{&EV_Owner, &VehicleCollisionEntity::GetOwner },
{NULL, NULL }
};
VehicleCollisionEntity::VehicleCollisionEntity
(
Entity *ent
)
VehicleCollisionEntity::VehicleCollisionEntity(Entity *ent)
{
if( LoadingSavegame )
{
return;
}
if (LoadingSavegame) {
return;
}
edict->s.eType = ET_GENERAL;
edict->s.eType = ET_GENERAL;
m_pOwner = ent;
takedamage = DAMAGE_YES;
m_pOwner = ent;
takedamage = DAMAGE_YES;
showModel();
setMoveType( MOVETYPE_PUSH );
setSolidType(SOLID_NOT);
showModel();
setMoveType(MOVETYPE_PUSH);
setSolidType(SOLID_NOT);
edict->clipmask |= MASK_VEHICLE;
edict->s.eFlags |= EF_LINKANGLES;
edict->clipmask |= MASK_VEHICLE;
edict->s.eFlags |= EF_LINKANGLES;
}
VehicleCollisionEntity::VehicleCollisionEntity
(
void
)
VehicleCollisionEntity::VehicleCollisionEntity(void)
{
if( LoadingSavegame )
{
return;
}
if (LoadingSavegame) {
return;
}
gi.Error( ERR_DROP, "VehicleCollisionEntity Created with no parameters!\n" );
gi.Error(ERR_DROP, "VehicleCollisionEntity Created with no parameters!\n");
}
void VehicleCollisionEntity::EventDamage
(
Event *ev
)
void VehicleCollisionEntity::GetOwner(Event *ev)
{
m_pOwner->ProcessEvent(*ev);
ev->AddListener(m_pOwner);
}
void VehicleCollisionEntity::Solid
(
void
)
void VehicleCollisionEntity::Solid(void)
{
setContents( CONTENTS_SOLID );
setSolidType( SOLID_BSP );
setContents(CONTENTS_SOLID);
setSolidType(SOLID_BSP);
}
void VehicleCollisionEntity::NotSolid
(
void
)
void VehicleCollisionEntity::NotSolid(void)
{
setSolidType( SOLID_NOT );
setSolidType(SOLID_NOT);
}
void VehicleCollisionEntity::EventDamage(Event *ev)
{
m_pOwner->ProcessEvent(*ev);
}
void VehicleCollisionEntity::Used(Event *ev)
{
m_pOwner->ProcessEvent(*ev);
}
Entity *VehicleCollisionEntity::GetOwner() const
{
return m_pOwner;
}
+15 -19
View File
@@ -21,40 +21,36 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// VehicleCollisionEntity.h : MOHAA vehicle collision
#ifndef __VEHICLECOLLISIONENTITY_H__
#define __VEHICLECOLLISIONENTITY_H__
#pragma once
#include "entity.h"
class VehicleCollisionEntity : public Entity
{
private:
EntityPtr m_pOwner;
EntityPtr m_pOwner;
private:
void EventDamage( Event *ev );
void EventDamage(Event *ev);
void GetOwner(Event *ev);
void Used(Event *ev);
public:
CLASS_PROTOTYPE( VehicleCollisionEntity );
CLASS_PROTOTYPE(VehicleCollisionEntity);
VehicleCollisionEntity( Entity *ent );
VehicleCollisionEntity();
VehicleCollisionEntity(Entity *ent);
VehicleCollisionEntity();
void Archive( Archiver& arc ) override;
void Archive(Archiver& arc) override;
void Solid( void );
void NotSolid( void );
void Solid(void);
void NotSolid(void);
Entity *GetOwner() const;
};
inline
void VehicleCollisionEntity::Archive
(
Archiver& arc
)
inline void VehicleCollisionEntity::Archive(Archiver& arc)
{
Entity::Archive( arc );
Entity::Archive(arc);
arc.ArchiveSafePointer( &m_pOwner );
arc.ArchiveSafePointer(&m_pOwner);
}
#endif // __VEHICLECOLLISIONENTITY_H__
+85 -116
View File
@@ -26,159 +26,128 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "vehicle.h"
Event EV_VehicleSoundEntity_PostSpawn
(
"vehiclesoundentity_post",
EV_DEFAULT,
NULL,
NULL,
"PostSpawn of a Vehicle Sound Entity"
);
(
"vehiclesoundentity_post",
EV_DEFAULT,
NULL,
NULL,
"PostSpawn of a Vehicle Sound Entity"
);
Event EV_VehicleSoundEntity_UpdateTraces
(
"vehiclesoudnentity_updatetraces",
EV_DEFAULT,
NULL,
NULL,
"Updates the traces of a Vehicle Sound Entity"
);
(
"vehiclesoudnentity_updatetraces",
EV_DEFAULT,
NULL,
NULL,
"Updates the traces of a Vehicle Sound Entity"
);
CLASS_DECLARATION( Entity, VehicleSoundEntity, NULL )
{
{ &EV_VehicleSoundEntity_PostSpawn, &VehicleSoundEntity::EventPostSpawn },
{ &EV_VehicleSoundEntity_UpdateTraces, &VehicleSoundEntity::EventUpdateTraces },
{ NULL, NULL }
CLASS_DECLARATION(Entity, VehicleSoundEntity, NULL) {
{&EV_VehicleSoundEntity_PostSpawn, &VehicleSoundEntity::EventPostSpawn },
{&EV_VehicleSoundEntity_UpdateTraces, &VehicleSoundEntity::EventUpdateTraces},
{NULL, NULL }
};
VehicleSoundEntity::VehicleSoundEntity()
{
if( LoadingSavegame )
{
return;
}
if (LoadingSavegame) {
return;
}
gi.Error( ERR_DROP, "VehicleSoundEntity Created with no parameters!\n" );
gi.Error(ERR_DROP, "VehicleSoundEntity Created with no parameters!\n");
}
VehicleSoundEntity::VehicleSoundEntity( Vehicle *owner )
VehicleSoundEntity::VehicleSoundEntity(Vehicle *owner)
{
m_pVehicle = owner;
m_bDoSoundStuff = false;
m_iTraceSurfaceFlags = 0;
m_pVehicle = owner;
m_bDoSoundStuff = false;
m_iTraceSurfaceFlags = 0;
PostEvent( EV_VehicleSoundEntity_PostSpawn, EV_POSTSPAWN );
PostEvent(EV_VehicleSoundEntity_PostSpawn, EV_POSTSPAWN);
}
void VehicleSoundEntity::Start
(
void
)
void VehicleSoundEntity::Start(void)
{
m_bDoSoundStuff = true;
m_bDoSoundStuff = true;
}
void VehicleSoundEntity::Stop
(
void
)
void VehicleSoundEntity::Stop(void)
{
m_bDoSoundStuff = false;
m_bDoSoundStuff = false;
}
void VehicleSoundEntity::Think
(
void
)
void VehicleSoundEntity::Think(void)
{
DoSoundStuff();
DoSoundStuff();
}
void VehicleSoundEntity::EventPostSpawn
(
Event *ev
)
void VehicleSoundEntity::EventPostSpawn(Event *ev)
{
setModel( "models/vehicles/vehiclesoundentity.tik" );
setModel("models/vehicles/vehiclesoundentity.tik");
PostEvent( EV_VehicleSoundEntity_UpdateTraces, 1.0f );
flags |= FL_THINK;
PostEvent(EV_VehicleSoundEntity_UpdateTraces, 1.0f);
flags |= FL_THINK;
}
void VehicleSoundEntity::EventUpdateTraces
(
Event *ev
)
void VehicleSoundEntity::EventUpdateTraces(Event *ev)
{
if( m_bDoSoundStuff )
{
m_pVehicle->SetSlotsNonSolid();
if (m_bDoSoundStuff) {
m_pVehicle->SetSlotsNonSolid();
trace_t trace = G_Trace(
origin,
vec3_origin,
vec3_origin,
Vector( origin[ 0 ], origin[ 1 ], origin[ 2 ] - 256.0f ),
m_pVehicle->edict,
MASK_SOUND,
qfalse,
"VehicleSoundEntity::DoSoundStuff"
);
trace_t trace = G_Trace(
origin,
vec3_origin,
vec3_origin,
Vector(origin[0], origin[1], origin[2] - 256.0f),
m_pVehicle->edict,
MASK_SOUND,
qfalse,
"VehicleSoundEntity::DoSoundStuff"
);
if( trace.fraction >= 1.0f )
m_iTraceSurfaceFlags = 0;
else
m_iTraceSurfaceFlags = trace.surfaceFlags;
if (trace.fraction >= 1.0f) {
m_iTraceSurfaceFlags = 0;
} else {
m_iTraceSurfaceFlags = trace.surfaceFlags;
}
m_pVehicle->SetSlotsSolid();
}
m_pVehicle->SetSlotsSolid();
}
PostEvent( EV_VehicleSoundEntity_UpdateTraces, 1.0f );
PostEvent(EV_VehicleSoundEntity_UpdateTraces, 1.0f);
}
void VehicleSoundEntity::DoSoundStuff
(
void
)
void VehicleSoundEntity::DoSoundStuff(void)
{
float pitch;
float pitch;
if( !m_bDoSoundStuff )
{
StopLoopSound();
return;
}
if (!m_bDoSoundStuff) {
StopLoopSound();
return;
}
pitch = ( velocity.length() - m_pVehicle->m_fSoundMinSpeed ) / ( m_pVehicle->m_fSoundMaxSpeed - m_pVehicle->m_fSoundMinSpeed );
if( pitch > 1.0f ) {
pitch = 1.0f;
} else if( pitch < 0.0f ) {
pitch = 0.0f;
}
pitch = (velocity.length() - m_pVehicle->m_fSoundMinSpeed)
/ (m_pVehicle->m_fSoundMaxSpeed - m_pVehicle->m_fSoundMinSpeed);
if (pitch > 1.0f) {
pitch = 1.0f;
} else if (pitch < 0.0f) {
pitch = 0.0f;
}
pitch *= m_pVehicle->m_fSoundMinPitch + ( m_pVehicle->m_fSoundMaxPitch - m_pVehicle->m_fSoundMinPitch );
pitch *= m_pVehicle->m_fSoundMinPitch + (m_pVehicle->m_fSoundMaxPitch - m_pVehicle->m_fSoundMinPitch);
if( m_iTraceSurfaceFlags & SURF_DIRT )
{
LoopSound( m_pVehicle->m_sSoundSet + "treat_snd_dirt", -1.0f, -1.0f, -1.0f, pitch );
}
else if( m_iTraceSurfaceFlags & SURF_GRASS )
{
LoopSound( m_pVehicle->m_sSoundSet + "treat_snd_grass", -1.0f, -1.0f, -1.0f, pitch );
}
else if( m_iTraceSurfaceFlags & SURF_WOOD )
{
LoopSound( m_pVehicle->m_sSoundSet + "treat_snd_wood", -1.0f, -1.0f, -1.0f, pitch );
}
else if( m_iTraceSurfaceFlags & SURF_MUD )
{
LoopSound( m_pVehicle->m_sSoundSet + "treat_snd_mud", -1.0f, -1.0f, -1.0f, pitch );
}
else if( m_iTraceSurfaceFlags & ( SURF_GRAVEL | SURF_ROCK ) )
{
LoopSound( m_pVehicle->m_sSoundSet + "treat_snd_stone", -1.0f, -1.0f, -1.0f, pitch );
}
else
{
StopLoopSound();
}
if (m_iTraceSurfaceFlags & SURF_DIRT) {
LoopSound(m_pVehicle->m_sSoundSet + "tread_snd_dirt", -1.0f, -1.0f, -1.0f, pitch);
} else if (m_iTraceSurfaceFlags & SURF_GRASS) {
LoopSound(m_pVehicle->m_sSoundSet + "tread_snd_grass", -1.0f, -1.0f, -1.0f, pitch);
} else if (m_iTraceSurfaceFlags & SURF_WOOD) {
LoopSound(m_pVehicle->m_sSoundSet + "tread_snd_wood", -1.0f, -1.0f, -1.0f, pitch);
} else if (m_iTraceSurfaceFlags & SURF_MUD) {
LoopSound(m_pVehicle->m_sSoundSet + "tread_snd_mud", -1.0f, -1.0f, -1.0f, pitch);
} else if (m_iTraceSurfaceFlags & (SURF_GRAVEL | SURF_ROCK) || m_iTraceSurfaceFlags == 0) {
LoopSound(m_pVehicle->m_sSoundSet + "tread_snd_stone", -1.0f, -1.0f, -1.0f, pitch);
} else {
StopLoopSound();
}
}
+21 -27
View File
@@ -21,47 +21,41 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// VehicleSoundEntity.h : Sound helper for vehicles
#ifndef __VEHICLESOUNDENTITY_H__
#define __VEHICLESOUNDENTITY_H__
#pragma once
#include "entity.h"
class Vehicle;
class VehicleSoundEntity : public Entity {
class VehicleSoundEntity : public Entity
{
private:
SafePtr<Vehicle> m_pVehicle;
bool m_bDoSoundStuff;
int m_iTraceSurfaceFlags;
SafePtr<Vehicle> m_pVehicle;
bool m_bDoSoundStuff;
int m_iTraceSurfaceFlags;
public:
CLASS_PROTOTYPE( VehicleSoundEntity );
CLASS_PROTOTYPE(VehicleSoundEntity);
VehicleSoundEntity();
VehicleSoundEntity( Vehicle *owner );
VehicleSoundEntity();
VehicleSoundEntity(Vehicle *owner);
void Start( void );
void Stop( void );
void Think( void ) override;
void Archive( Archiver& arc ) override;
void Start(void);
void Stop(void);
void Think(void) override;
void Archive(Archiver& arc) override;
private:
void EventPostSpawn( Event *ev );
void EventUpdateTraces( Event *ev );
void DoSoundStuff( void );
void EventPostSpawn(Event *ev);
void EventUpdateTraces(Event *ev);
void DoSoundStuff(void);
};
inline
void VehicleSoundEntity::Archive
(
Archiver& arc
)
inline void VehicleSoundEntity::Archive(Archiver& arc)
{
Entity::Archive( arc );
Entity::Archive(arc);
arc.ArchiveSafePointer( &m_pVehicle );
arc.ArchiveBool( &m_bDoSoundStuff );
arc.ArchiveInteger( &m_iTraceSurfaceFlags );
arc.ArchiveSafePointer(&m_pVehicle);
arc.ArchiveBool(&m_bDoSoundStuff);
arc.ArchiveInteger(&m_iTraceSurfaceFlags);
}
#endif // __VEHICLECOLLISIONENTITY_H__
+965 -52
View File
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -1714,7 +1714,7 @@ inline bool Actor::CanSeeFOV(Entity *ent)
bCanSee = false;
if (InFOV(ent->centroid) && gi.AreasConnected(edict->r.areanum, ent->edict->r.areanum)) {
if (InFOV(ent) && AreasConnected(ent)) {
bCanSee = CanSee(ent, 0, 0, false);
}
+2
View File
@@ -120,6 +120,8 @@ void Actor::Think_Alarm(void)
Com_Printf("Actor::Think_Alarm: invalid think state %i\n", m_State);
break;
}
PostThink(true);
}
void Actor::FinishedAnimation_Alarm(void)
+1 -1
View File
@@ -264,7 +264,7 @@ bool Actor::CalcFallPath(void)
loop = currentPos;
mm.desired_speed = 0;
mm.groundPlane = NULL;
mm.groundPlane = qfalse;
mm.walking = false;
VectorSet(mm.velocity, 0, 0, -171);
+3 -3
View File
@@ -79,7 +79,7 @@ bool Actor::Cover_SetPath(PathNode *node)
fPathDist = PathDist();
fMinDistSquared = Square(fPathDist);
if ((node->origin - origin).lengthSquared() <= fMinDistSquared * 4.0f && fPathDist > 128.0f) {
if ((node->origin - origin).lengthSquared() * 4 <= fMinDistSquared && fPathDist > 128.0f) {
return false;
}
@@ -343,7 +343,7 @@ void Actor::State_Cover_Hide(void)
bool bCanShoot, bCanSee;
if (m_Enemy) {
SetEnemyPos(origin);
SetEnemyPos(m_Enemy->origin);
}
if (!m_pCoverNode) {
@@ -380,7 +380,7 @@ void Actor::State_Cover_Hide(void)
return;
}
if (bCanShoot || bCanShoot) {
if (bCanSee || bCanShoot) {
m_pCoverNode->Relinquish();
m_pCoverNode->MarkTemporarilyBad();
m_pCoverNode = NULL;
+3 -3
View File
@@ -31,7 +31,7 @@ void Actor::InitCurious(GlobalFuncs_t *func)
func->EndState = &Actor::End_Curious;
func->ResumeState = &Actor::Resume_Curious;
func->SuspendState = &Actor::Suspend_Curious;
func->FinishedAnimation = &Actor::FinishedAnimation_Cover;
func->FinishedAnimation = &Actor::FinishedAnimation_Curious;
func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Curious;
func->IsState = &Actor::IsCuriousState;
}
@@ -246,8 +246,8 @@ void Actor::LookAtCuriosity(void)
iSeed = 0x19660D * (m_iCuriousTime - 0x2EB71B09 * ((level.inttime - m_iCuriousTime) & 0xFFFFFF00)) + 0x3C6EF35F;
vAngles[0] = m_DesiredLookAngles[0] + (float)iSeed / 0x4444444 * fLookScale;
vAngles[1] = m_DesiredLookAngles[1] + (float)iSeed / 0x2222222 * fLookScale;
vAngles[0] = m_DesiredLookAngles[0] + (float)iSeed / (float)0x4444444 * fLookScale;
vAngles[1] = m_DesiredLookAngles[1] + (float)iSeed / (float)0x2222222 * fLookScale;
vAngles[2] = m_DesiredLookAngles[2];
// clamp
vAngles[0] = Q_clamp_float(vAngles[0], -90, 90);
+8 -2
View File
@@ -31,6 +31,7 @@ void Actor::InitDisguiseSalute(GlobalFuncs_t *func)
func->EndState = &Actor::End_DisguiseSalute;
func->ResumeState = &Actor::Resume_DisguiseSalute;
func->SuspendState = &Actor::Suspend_DisguiseSalute;
func->FinishedAnimation = &Actor::FinishedAnimation_DisguiseSalute;
func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Disguise;
func->IsState = &Actor::IsDisguiseState;
}
@@ -51,7 +52,7 @@ void Actor::Begin_DisguiseSalute(void)
SetDesiredYawDest(m_Enemy->origin);
SetDesiredLookDir(m_Enemy->origin - origin);
DesiredAnimation(ANIM_MODE_NORMAL, STRING_ANIM_DISGUISE_PAPERS_SCR);
DesiredAnimation(ANIM_MODE_NORMAL, STRING_ANIM_DISGUISE_SALUTE_SCR);
} else {
SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_IDLE);
}
@@ -85,7 +86,12 @@ void Actor::Think_DisguiseSalute(void)
return;
}
if ((!EnemyIsDisguised() && !(m_Enemy->flags & FL_NOTARGET)) || level.m_bAlarm != qtrue) {
if (!EnemyIsDisguised() && !(m_Enemy->flags & FL_NOTARGET)) {
SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_IDLE);
return;
}
if (level.m_bAlarm == qtrue) {
SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_IDLE);
return;
}
+15 -4
View File
@@ -89,8 +89,11 @@ void Actor::End_MachineGunner(void)
}
Unholster();
if (m_pTurret && m_pTurret->GetOwner() == this) {
m_pTurret->TurretEndUsed();
if (m_pTurret) {
m_pTurret->m_bHadOwner = true;
if (m_pTurret->GetOwner() == this) {
m_pTurret->TurretEndUsed();
}
}
}
@@ -154,7 +157,7 @@ void Actor::ThinkHoldGun_TurretGun(void)
}
}
VectorScale2D(orientation[0], m_fCrouchWeight * -9.3f + 23.4f, offset);
VectorScale2D(orientation[0], -(m_fCrouchWeight * -9.3f + 23.4f), offset);
VectorAdd2D(newOrigin, offset, newOrigin);
VectorScale2D(orientation[1], m_fCrouchWeight * 2.6f + 10.3f, offset);
VectorAdd2D(newOrigin, offset, newOrigin);
@@ -164,7 +167,7 @@ void Actor::ThinkHoldGun_TurretGun(void)
m_fCrouchWeight = 1.0;
}
VectorScale2D(orientation[0], m_fCrouchWeight * -3.f + 23.4f, offset);
VectorScale2D(orientation[0], -(m_fCrouchWeight * -3.f + 23.4f), offset);
VectorAdd2D(newOrigin, offset, newOrigin);
VectorScale2D(orientation[1], m_fCrouchWeight * -1.6f + 10.3f, offset);
VectorAdd2D(newOrigin, offset, newOrigin);
@@ -179,6 +182,8 @@ void Actor::ThinkHoldGun_TurretGun(void)
UpdateAimMotion();
UpdateAnim();
newOrigin[2] += 18;
end[0] = newOrigin[0];
end[1] = newOrigin[1];
end[2] = newOrigin[2] - 94;
@@ -207,6 +212,12 @@ void Actor::Think_MachineGunner_TurretGun(void)
UpdateEnemyInternal();
if (m_Team == TEAM_AMERICAN) {
// Added in 2.30
ThinkHoldGun_TurretGun();
return;
}
if (m_pTurret->AI_CanTarget(G_GetEntity(0)->centroid)) {
ThinkHoldGun_TurretGun();
return;
+5
View File
@@ -81,6 +81,11 @@ void Actor::Think_Patrol(void)
} else if (bMoveInRadius) {
ClearPatrolCurrentNode();
SetThinkIdle(THINK_IDLE);
// Added in OPM
// Not sure why it was not cleared originally.
// Once you reach your goal, there is no point
// in leaving it set to true
m_bScriptGoalValid = false;
parm.movedone = true;
Unregister(STRING_MOVEDONE);
+19 -48
View File
@@ -21,6 +21,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// actor_runandshoot.cpp
//
// Added in 2.30
//
#include "actor.h"
@@ -37,9 +40,10 @@ void Actor::InitRunAndShoot(GlobalFuncs_t *func)
void Actor::Begin_RunAndShoot(void)
{
m_State = ACTOR_STATE_RUN_AND_SHOOT_RUN;
if (m_patrolCurrentNode) {
m_State = ACTOR_STATE_RUN_AND_SHOOT_RUNNING;
} else {
m_State = ACTOR_STATE_RUN_AND_SHOOT_RUN;
}
}
@@ -125,7 +129,7 @@ bool Actor::RunAndShoot_MoveToPatrolCurrentNode(void)
{
UpdatePatrolCurrentNode();
if (!m_patrolCurrentNode && m_bPatrolWaitTrigger) {
if (!m_patrolCurrentNode || m_bPatrolWaitTrigger) {
IdleLook();
Anim_Idle();
return false;
@@ -143,62 +147,29 @@ bool Actor::RunAndShoot_MoveToPatrolCurrentNode(void)
if (MoveOnPathWithSquad()) {
if (m_Enemy) {
m_eNextAnimMode = ANIM_MODE_PATH;
m_csNextAnimString = STRING_ANIM_RUNTO_INOPEN_SCR;
m_bNextForceStart = false;
Vector delta;
Vector lookDir;
delta = mTargetPos - EyePosition();
lookDir = delta;
lookDir[2] += 16;
SetDesiredLookDir(lookDir);
m_DesiredGunDir[0] = 360 - delta.toPitch();
m_DesiredGunDir[1] = delta.toYaw();
m_DesiredGunDir[2] = 0;
SetDesiredYaw(m_DesiredGunDir[1]);
DesiredAnimation(ANIM_MODE_PATH, STRING_ANIM_RUNTO_INOPEN_SCR);
AimAtTargetPos();
} else {
m_eNextAnimMode = ANIM_MODE_PATH;
m_csNextAnimString = STRING_ANIM_CROUCH_RUN_SCR;
m_bNextForceStart = false;
DesiredAnimation(ANIM_MODE_PATH, STRING_ANIM_CROUCH_RUN_SCR);
FaceMotion();
}
} else if (m_Enemy) {
Vector delta;
Vector lookDir;
delta = mTargetPos - EyePosition();
lookDir = delta;
lookDir[2] += 16;
SetDesiredLookDir(lookDir);
m_DesiredGunDir[0] = 360 - delta.toPitch();
m_DesiredGunDir[1] = delta.toYaw();
m_DesiredGunDir[2] = 0;
SetDesiredYaw(m_DesiredGunDir[1]);
AimAtTargetPos();
Anim_Attack();
} else {
Anim_Stand();
IdleLook();
}
if (!m_fMoveDoneRadiusSquared) {
return false;
if (m_fMoveDoneRadiusSquared) {
if (PathComplete()) {
return true;
}
if (m_Path.HasCompleteLookahead() && !m_patrolCurrentNode->Next()) {
return VectorLength2DSquared(PathDelta()) <= m_fMoveDoneRadiusSquared;
}
}
if (PathComplete()) {
return true;
}
if (!m_Path.HasCompleteLookahead() || m_patrolCurrentNode->Next()) {
return false;
}
if (VectorLength2DSquared(PathDelta()) > m_fMoveDoneRadiusSquared) {
return false;
}
return true;
return false;
}
+5
View File
@@ -76,6 +76,11 @@ void Actor::Think_Runner(void)
} else if (bMoveInRadius) {
ClearPatrolCurrentNode();
SetThinkIdle(THINK_IDLE);
// Added in OPM
// Not sure why it was not cleared originally.
// Once you reach your goal, there is no point
// in leaving it set to true
m_bScriptGoalValid = false;
parm.movedone = true;
Unregister(STRING_MOVEDONE);
+19 -8
View File
@@ -233,7 +233,13 @@ void Actor::Turret_BeginRetarget(void)
SetEnemyPos(m_Enemy->origin);
AimAtEnemyBehavior();
TransitionState(ACTOR_STATE_TURRET_RETARGET_SUPPRESS, 0);
// Replaced in 2.0
// Use the Retarget_Suppress state instead of the Retarget_Sniper_Node state
if (g_target_game >= target_game_e::TG_MOHTA) {
TransitionState(ACTOR_STATE_TURRET_RETARGET_SUPPRESS, 0);
} else {
TransitionState(ACTOR_STATE_TURRET_RETARGET_SNIPER_NODE, 0);
}
}
void Actor::Turret_NextRetarget(void)
@@ -287,28 +293,31 @@ void Actor::Turret_SideStep(int iStepSize, vec3_t vDir)
AimAtEnemyBehavior();
StrafeToAttack(iStepSize, vDir);
if (!PathExists() || PathComplete() || !PathAvoidsSquadMates()) {
StrafeToAttack(-iStepSize, vDir);
if (PathExists() && !PathComplete() && PathAvoidsSquadMates()) {
TransitionState(ACTOR_STATE_TURRET_REACQUIRE);
return;
}
StrafeToAttack(-iStepSize, vDir);
if (PathExists() && !PathComplete() && PathAvoidsSquadMates()) {
TransitionState(ACTOR_STATE_TURRET_REACQUIRE);
} else {
Turret_NextRetarget();
return;
}
Turret_NextRetarget();
}
void Actor::State_Turret_Shoot(void)
{
assert(g_target_game > target_game_e::TG_MOH);
if (CanSeeEnemy(200) || FriendlyInLineOfFire(m_Enemy)) {
TransitionState(ACTOR_STATE_TURRET_COMBAT);
State_Turret_Combat();
return;
}
AimAtTargetPos();
Anim_Suppress();
if (level.inttime >= m_iStateTime + 15000) {
Turret_SelectState();
if (m_State == ACTOR_STATE_TURRET_SHOOT) {
@@ -321,6 +330,8 @@ void Actor::State_Turret_Retarget_Suppress(void)
{
trace_t trace;
assert(g_target_game > target_game_e::TG_MOH);
if (rand() % 100 >= m_iSuppressChance) {
AimAtEnemyBehavior();
Turret_NextRetarget();
+8 -11
View File
@@ -353,7 +353,7 @@ void ActorEnemySet::CheckEnemies(Actor *pSelf)
pActorEnemy = &m_Enemies[i - 1];
if (!pActorEnemy->GetEnemy() || pActorEnemy->GetEnemy()->m_Team == pSelf->m_Team
|| pActorEnemy->GetEnemy()->IsDead() || level.inttime > pActorEnemy->m_iAddTime + 10000
|| pActorEnemy->GetEnemy()->m_iThreatBias == THREATBIAS_IGNOREME) {
|| pActorEnemy->GetEnemy()->m_iThreatBias == THREATBIAS_IGNOREME || pActorEnemy->GetEnemy()->IsDisabled()) {
m_Enemies.RemoveObjectAt(i);
} else {
i++;
@@ -420,15 +420,14 @@ void ActorEnemySet::CheckEnemies(Actor *pSelf)
m_iCurrentThreat = 0;
fRangeSquared = 1e37f;
if (m_fCurrentVisibility >= 1) {
iThreat = 0;
if (m_fCurrentVisibility >= 0.999f) {
for (i = 1; i <= m_Enemies.NumObjects(); i++) {
pActorEnemy = &m_Enemies.ObjectAt(i);
pActorEnemy->UpdateThreat(pSelf);
iThreat = pActorEnemy->GetThreat();
if (m_iCurrentThreat >= pActorEnemy->GetThreat()) {
if (m_iCheckCount != pActorEnemy->GetThreat()) {
if (m_iCurrentThreat >= iThreat) {
if (m_iCheckCount != iThreat) {
continue;
}
@@ -437,12 +436,10 @@ void ActorEnemySet::CheckEnemies(Actor *pSelf)
}
}
iThreat = pActorEnemy->GetThreat();
m_pCurrentEnemy = pActorEnemy->GetEnemy();
fRangeSquared = pActorEnemy->m_fCurrentRangeSquared;
m_iCurrentThreat = pActorEnemy->GetThreat();
m_pCurrentEnemy = pActorEnemy->GetEnemy();
fRangeSquared = pActorEnemy->m_fCurrentRangeSquared;
}
m_iCurrentThreat = iThreat;
}
if ((!m_pCurrentEnemy || !m_pCurrentEnemy->m_bIsDisguised) && m_iCurrentThreat <= 0) {
+2
View File
@@ -399,6 +399,7 @@ void ActorPath::UpdatePos(float *origin, float fNodeRadius)
m_pathpos->point[2] = m_pathpos->point[2] * s + current_path->point[2] * t;
current_path->dist *= s;
assert(current_path->dist > -1e+07 && current_path->dist < 1e+07);
m_Side = true;
} else {
@@ -457,6 +458,7 @@ void ActorPath::Shorten(float fDistRemove)
// This is a bug in mohaa as it can write past the end of the class instance
//m_path->point[2] += m_path->dir[2] * -fDistRemove;
m_path->dist -= fDistRemove;
assert(m_path->dist > -1e+07 && m_path->dist < 1e+07);
}
PathInfo *ActorPath::StartNode(void) const
+38 -13
View File
@@ -30,13 +30,23 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "ammo.h"
#include "player.h"
#include "g_phys.h"
Event EV_AmmoEntity_PostSpawn
(
"ammoentity_postspawn",
EV_DEFAULT,
NULL,
NULL,
"Ammo Entity Post Spawn"
);
CLASS_DECLARATION(Item, AmmoEntity, NULL) {
{NULL, NULL}
{&EV_AmmoEntity_PostSpawn, &AmmoEntity::EventPostSpawn},
{NULL, NULL }
};
AmmoEntity::AmmoEntity()
{
if (LoadingSavegame) {
// all data will be setup by the archive function
@@ -44,13 +54,14 @@ AmmoEntity::AmmoEntity()
}
setName("UnknownAmmo");
amount = 0;
PostEvent(EV_AmmoEntity_PostSpawn, EV_POSTSPAWN);
}
Item *AmmoEntity::ItemPickup(Entity *other, qboolean add_to_inventory)
{
Sentient *player;
Weapon* pWeap;
Weapon *pWeap;
if (!other->IsSubclassOfPlayer()) {
return NULL;
@@ -86,7 +97,11 @@ Item *AmmoEntity::ItemPickup(Entity *other, qboolean add_to_inventory)
Unregister(STRING_PICKUP);
// Tell the player about the ammo being picked
gi.SendServerCommand(other->edict - g_entities, "print \"" HUD_MESSAGE_YELLOW "%s\"", gi.LV_ConvertString(va("Got %d %s Rounds", amount, item_name.c_str())));
gi.SendServerCommand(
other->edict - g_entities,
"print \"" HUD_MESSAGE_YELLOW "%s\"",
gi.LV_ConvertString(va("Got %d %s Rounds", amount, item_name.c_str()))
);
// Give the ammo to the player
player->GiveAmmo(item_name, amount);
@@ -100,6 +115,21 @@ Item *AmmoEntity::ItemPickup(Entity *other, qboolean add_to_inventory)
return NULL; // This doesn't create any items
}
void AmmoEntity::EventPostSpawn(Event *ev)
{
vec3_t fullmins;
vec3_t fullmaxs;
setMoveType(MOVETYPE_TOSS);
if (edict->tiki) {
gi.TIKI_CalculateBounds(edict->tiki, edict->s.scale, fullmins, fullmaxs);
setSize(fullmins, fullmaxs);
link();
}
droptofloor(256);
}
// This is the Class that is used to keep track of ammo in the player's inventory.
// It is not an entit, just a name and an amount.
@@ -108,7 +138,9 @@ CLASS_DECLARATION(Class, Ammo, NULL) {
};
Ammo::Ammo()
: amount(0)
, maxamount(0)
, name_index(0)
{
if (LoadingSavegame) {
// all data will be setup by the archive function
@@ -120,7 +152,6 @@ Ammo::Ammo()
}
void Ammo::setAmount(int a)
{
amount = a;
@@ -130,38 +161,32 @@ void Ammo::setAmount(int a)
}
int Ammo::getAmount(void)
{
return amount;
}
void Ammo::setMaxAmount(int a)
{
maxamount = a;
}
int Ammo::getMaxAmount(void)
{
return maxamount;
}
void Ammo::setName(str n)
{
name = n;
name_index = gi.itemindex(name) + CS_WEAPONS;
}
str Ammo::getName(void)
{
return name;
}
int Ammo::getIndex(void)
{
return name_index;
}
+3 -5
View File
@@ -22,8 +22,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
// ammo.h: Base class for all ammunition for entities derived from the Weapon class.
#ifndef __AMMO_H__
#define __AMMO_H__
#pragma once
#include "g_local.h"
#include "item.h"
@@ -35,6 +34,7 @@ public:
AmmoEntity();
Item *ItemPickup(Entity *other, qboolean add_to_inventory) override;
void EventPostSpawn(Event *ev);
};
class Ammo : public Class
@@ -61,13 +61,13 @@ public:
};
inline void Ammo::Archive(Archiver& arc)
{
Class::Archive(arc);
arc.ArchiveInteger(&amount);
arc.ArchiveInteger(&maxamount);
arc.ArchiveString(&name);
arc.ArchiveInteger(&name_index);
//
// name_index not archived, because it is auto-generated by gi.itemindex
//
@@ -75,5 +75,3 @@ inline void Ammo::Archive(Archiver& arc)
setName(name);
}
}
#endif /* ammo.h */
+2 -3
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.
@@ -508,9 +508,8 @@ void Animate::StopAnimating(int slot)
edict->s.frameInfo[slot].index = 1;
}
edict->s.frameInfo[slot].weight = 0.0f;
animFlags[slot] = ANIM_LOOP | ANIM_NODELTA | ANIM_NOEXIT | ANIM_PAUSED;
SetWeight(slot, 0);
animtimes[slot] = 0.0f;
SlotChanged(slot);
+114 -39
View File
@@ -66,7 +66,7 @@ static const char *typenames[] = {
"object", "objectpointer", "safepointer", "eventpointer", "quaternion", "entity", "bool", "position",
"size"};
#define ArchiveHeader (*(int *)"MHAA")
#define ArchiveHeader (LittleLong(*(int *)"MHAA"))
#define ArchiveVersion 14 // This must be changed any time the format changes!
#define ArchiveInfo "OPENMOHAA Archive Version 14" // This must be changed any time the format changes!
@@ -208,6 +208,7 @@ qboolean ArchiveFile::OpenRead(const char *name)
new_len = 0;
Read(&new_len, sizeof(uint32_t));
new_len = LittleLong(new_len);
tempbuf = (byte *)gi.Malloc(new_len);
if (g_lz77.Decompress(pos, length - 8, tempbuf, &iCSVGLength) || iCSVGLength != new_len) {
@@ -487,11 +488,44 @@ File Archive functions
//#define ARCHIVE_USE_TYPES 1
#define ARCHIVE(func, type) \
void Archiver::Archive##func(type *v) \
\
{ \
ArchiveData(ARC_##func, v, sizeof(type)); \
template<typename v>
void ArchiveSwapValue(v* value) {
LittleSwap(value, sizeof(v));
}
template<typename v>
void ArchiveSwapValue(v* value, size_t size) {
for (size_t i = 0; i < size; i++) {
LittleSwap(&value[i], sizeof(value[i]));
}
}
template<>
void ArchiveSwapValue<Vector>(Vector* value) {
for (int i = 0; i < 3; i++) {
(*value)[i] = LittleFloat((*value)[i]);
}
}
template<>
void ArchiveSwapValue<Quat>(Quat* value) {
for (int i = 0; i < 4; i++) {
(*value)[i] = LittleFloat((*value)[i]);
}
}
#define ARCHIVE(func, type) \
void Archiver::Archive##func(type *v) \
{ \
int i; \
if (archivemode == ARCHIVE_WRITE) { \
type nv = *v; \
ArchiveSwapValue(&nv); \
ArchiveData(ARC_##func, &nv, sizeof(type)); \
} else { \
ArchiveData(ARC_##func, v, sizeof(type)); \
ArchiveSwapValue(v); \
} \
}
ARCHIVE(Vector, Vector);
@@ -525,17 +559,41 @@ void Archiver::ArchiveSvsTime(int *time)
void Archiver::ArchiveVec2(vec2_t vec)
{
ArchiveData(ARC_Vec2, vec, sizeof(vec2_t));
int i;
if (archivemode == ARCHIVE_WRITE) {
vec2_t nv = { vec[0], vec[1] };
ArchiveSwapValue(nv, 2);
ArchiveData(ARC_Vec2, nv, sizeof(vec2_t));
} else {
ArchiveData(ARC_Vec2, vec, sizeof(vec2_t));
ArchiveSwapValue(vec, 2);
}
}
void Archiver::ArchiveVec3(vec3_t vec)
{
ArchiveData(ARC_Vec3, vec, sizeof(vec3_t));
int i;
if (archivemode == ARCHIVE_WRITE) {
vec3_t nv = { vec[0], vec[1], vec[2]};
ArchiveSwapValue(nv, 3);
ArchiveData(ARC_Vec3, nv, sizeof(vec3_t));
} else {
ArchiveData(ARC_Vec3, vec, sizeof(vec3_t));
ArchiveSwapValue(vec, 3);
}
}
void Archiver::ArchiveVec4(vec4_t vec)
{
ArchiveData(ARC_Vec4, vec, sizeof(vec4_t));
int i;
if (archivemode == ARCHIVE_WRITE) {
vec4_t nv = { vec[0], vec[1], vec[2], vec[3] };
ArchiveSwapValue(nv, 4);
ArchiveData(ARC_Vec4, nv, sizeof(vec4_t));
} else {
ArchiveData(ARC_Vec4, vec, sizeof(vec4_t));
ArchiveSwapValue(vec, 4);
}
}
void Archiver::ArchiveObjectPointer(LightClass **ptr)
@@ -544,7 +602,9 @@ void Archiver::ArchiveObjectPointer(LightClass **ptr)
if (archivemode == ARCHIVE_READ) {
pointer_fixup_t *fixup;
ArchiveData(ARC_ObjectPointer, &index, sizeof(index));
index = LittleLong(index);
//
// see if the variable was NULL
@@ -567,6 +627,8 @@ void Archiver::ArchiveObjectPointer(LightClass **ptr)
} else {
index = ARCHIVE_NULL_POINTER;
}
index = LittleLong(index);
ArchiveData(ARC_ObjectPointer, &index, sizeof(index));
}
}
@@ -577,7 +639,9 @@ void Archiver::ArchiveObjectPointer(Class **ptr)
if (archivemode == ARCHIVE_READ) {
pointer_fixup_t *fixup;
ArchiveData(ARC_ObjectPointer, &index, sizeof(index));
index = LittleLong(index);
//
// see if the variable was NULL
@@ -600,6 +664,8 @@ void Archiver::ArchiveObjectPointer(Class **ptr)
} else {
index = ARCHIVE_NULL_POINTER;
}
index = LittleLong(index);
ArchiveData(ARC_ObjectPointer, &index, sizeof(index));
}
}
@@ -612,6 +678,7 @@ void Archiver::ArchiveSafePointer(SafePtrBase *ptr)
pointer_fixup_t *fixup;
ArchiveData(ARC_SafePointer, &index, sizeof(index));
index = LittleLong(index);
//
// see if the variable was NULL
@@ -638,6 +705,7 @@ void Archiver::ArchiveSafePointer(SafePtrBase *ptr)
} else {
index = ARCHIVE_NULL_POINTER;
}
index = LittleLong(index);
ArchiveData(ARC_SafePointer, &index, sizeof(index));
}
}
@@ -646,12 +714,13 @@ void Archiver::ArchiveEventPointer(Event **ev)
{
int index;
#ifdef ARCHIVE_USE_TYPES
CheckType(ARC_EventPointer);
#endif
if (archivemode == ARCHIVE_READ) {
#ifndef NDEBUG
CheckRead();
#endif
#ifdef ARCHIVE_USE_TYPES
CheckType(ARC_EventPointer);
#endif
ArchiveInteger(&index);
@@ -673,10 +742,6 @@ void Archiver::ArchiveEventPointer(Event **ev)
index = ARCHIVE_NULL_POINTER;
}
#ifdef ARCHIVE_USE_TYPES
WriteType(ARC_EventPointer);
#endif
ArchiveInteger(&index);
if (*ev) {
(*ev)->Archive(*this);
@@ -691,6 +756,10 @@ void Archiver::ArchiveRaw(void *data, size_t size)
void Archiver::ArchiveString(str *string)
{
#ifdef ARCHIVE_USE_TYPES
CheckType(ARC_String);
#endif
if (archivemode == ARCHIVE_READ) {
fileSize_t s;
char *data;
@@ -698,10 +767,6 @@ void Archiver::ArchiveString(str *string)
#ifndef NDEBUG
CheckRead();
#endif
#ifdef ARCHIVE_USE_TYPES
CheckType(ARC_String);
#endif
if (!fileerror) {
s = ReadSize();
if (!fileerror) {
@@ -719,13 +784,12 @@ void Archiver::ArchiveString(str *string)
}
}
} else {
fileSize_t s;
#ifndef NDEBUG
CheckWrite();
#endif
#ifdef ARCHIVE_USE_TYPES
WriteType(ARC_String);
#endif
WriteSize((fileSize_t)string->length());
WriteSize(string->length());
archivefile.Write(string->c_str(), string->length());
}
}
@@ -938,6 +1002,11 @@ void Archiver::ArchiveObject(Class *obj)
}
}
void Archiver::ArchiveObject(SafePtrBase* obj)
{
ArchiveSafePointer(obj);
}
void Archiver::ArchiveObjectPosition(LightClass *obj)
{
int index = 0;
@@ -1014,6 +1083,7 @@ fileSize_t Archiver::ReadSize(void)
s = 0;
if (!fileerror) {
archivefile.Read(&s, sizeof(s));
LittleSwap(&s, sizeof(s));
}
return s;
@@ -1034,6 +1104,7 @@ void Archiver::CheckSize(int type, fileSize_t size)
void Archiver::WriteSize(fileSize_t size)
{
LittleSwap(&size, sizeof(size));
archivefile.Write(&size, sizeof(fileSize_t));
}
@@ -1043,6 +1114,7 @@ int Archiver::ReadType(void)
if (!fileerror) {
archivefile.Read(&t, sizeof(t));
t = LittleLong(t);
return t;
}
@@ -1061,29 +1133,35 @@ void Archiver::CheckType(int type)
assert((type >= 0) && (type < ARC_NUMTYPES));
if (!fileerror) {
t = ReadType();
if (t != type) {
if (t < ARC_NUMTYPES) {
FileError("Expecting %s, Should be %s", typenames[type], typenames[t]);
assert(0);
} else {
FileError("Expecting %s, Should be %i (Unknown type)", typenames[type], t);
if (archivemode == ARCHIVE_READ) {
if (!fileerror) {
t = ReadType();
if (t != type) {
if (t < ARC_NUMTYPES) {
FileError("Expecting %s, Should be %s", typenames[type], typenames[t]);
assert(0);
}
else {
FileError("Expecting %s, Should be %i (Unknown type)", typenames[type], t);
}
}
}
} else {
int nt = LittleLong(type);
archivefile.Write(&nt, sizeof(nt));
}
}
void Archiver::ArchiveData(int type, void *data, size_t size)
{
#ifdef ARCHIVE_USE_TYPES
CheckType(type);
#endif
if (archivemode == ARCHIVE_READ) {
#ifndef NDEBUG
CheckRead();
#endif
#ifdef ARCHIVE_USE_TYPES
CheckType(type);
#endif
if (!fileerror && size) {
m_iNumBytesIO += size;
archivefile.Read(data, size);
@@ -1092,9 +1170,6 @@ void Archiver::ArchiveData(int type, void *data, size_t size)
#ifndef NDEBUG
CheckWrite();
#endif
#ifdef ARCHIVE_USE_TYPES
WriteType(type);
#endif
if (!fileerror && size) {
m_iNumBytesIO += size;
+1
View File
@@ -154,6 +154,7 @@ public:
void ArchiveRaw(void *data, size_t size);
void ArchiveObject(Class *obj);
void ArchiveObject(SafePtrBase* obj); // Added in OPM
qboolean ObjectPositionExists(void *obj);
+21 -16
View File
@@ -610,26 +610,28 @@ movement on the server game.
(CONTENTS_SOLID | CONTENTS_BODY | CONTENTS_UNKNOWN2 | CONTENTS_NOBOTCLIP | CONTENTS_BBOX | CONTENTS_FENCE)
#define MASK_SAFESOLID (CONTENTS_BODY | CONTENTS_UNKNOWN2 | CONTENTS_NOBOTCLIP | CONTENTS_BBOX)
#define MASK_USABLE (CONTENTS_SOLID | CONTENTS_BBOX | CONTENTS_NOBOTCLIP | CONTENTS_UNKNOWN2 | CONTENTS_BODY)
#define MASK_PLAYERSOLID \
(CONTENTS_SOLID | CONTENTS_PLAYERCLIP | CONTENTS_BODY | CONTENTS_TRIGGER | CONTENTS_FENCE | CONTENTS_UNKNOWN2 \
| CONTENTS_NOBOTCLIP | CONTENTS_BBOX)
#define MASK_PLAYERSOLID (CONTENTS_TRIGGER | CONTENTS_BODY | CONTENTS_PLAYERCLIP | CONTENTS_FENCE | CONTENTS_UNKNOWN2 | CONTENTS_NOBOTCLIP | CONTENTS_BBOX | CONTENTS_SOLID)
#define MASK_GUNTARGET \
(CONTENTS_SOLID | CONTENTS_LADDER | CONTENTS_LAVA | CONTENTS_SLIME | CONTENTS_CLAYPIDGEON | CONTENTS_BBOX \
| CONTENTS_NOBOTCLIP | CONTENTS_UNKNOWN2 | CONTENTS_UNKNOWN3 | CONTENTS_FENCE | CONTENTS_BODY | CONTENTS_CORPSE \
| CONTENTS_TRIGGER)
#define MASK_FOOTSHADOW (CONTENTS_FENCE | CONTENTS_SLIME | CONTENTS_LAVA | CONTENTS_SOLID)
#define MASK_PLAYERSTART (CONTENTS_SOLID | CONTENTS_BBOX | CONTENTS_NOBOTCLIP | CONTENTS_UNKNOWN2 | CONTENTS_BODY)
#define MASK_VIEWSOLID (CONTENTS_SOLID | CONTENTS_PLAYERCLIP | CONTENTS_FENCE | CONTENTS_TRIGGER)
#define MASK_DEADSOLID (CONTENTS_SOLID | CONTENTS_PLAYERCLIP | CONTENTS_CORPSE | CONTENTS_NOTTEAM2 | CONTENTS_FENCE)
#define MASK_MONSTERSOLID (CONTENTS_SOLID | CONTENTS_MONSTERCLIP | CONTENTS_BODY)
#define MASK_WATER (CONTENTS_WATER | CONTENTS_LAVA | CONTENTS_SLIME)
#define MASK_OPAQUE (CONTENTS_SOLID | CONTENTS_SLIME | CONTENTS_LAVA)
#define MASK_FOOTSHADOW (CONTENTS_FENCE | CONTENTS_SLIME | CONTENTS_LAVA | CONTENTS_SOLID)
#define MASK_PLAYERSTART (CONTENTS_SOLID | CONTENTS_BBOX | CONTENTS_NOBOTCLIP | CONTENTS_UNKNOWN2 | CONTENTS_BODY)
#define MASK_VIEWSOLID (CONTENTS_SOLID | CONTENTS_PLAYERCLIP | CONTENTS_FENCE | CONTENTS_TRIGGER)
#define MASK_DEADSOLID (CONTENTS_SOLID | CONTENTS_PLAYERCLIP | CONTENTS_CORPSE | CONTENTS_NOTTEAM2 | CONTENTS_FENCE)
#define MASK_MONSTERSOLID \
(CONTENTS_SOLID | CONTENTS_MONSTERCLIP | CONTENTS_BODY | CONTENTS_TRIGGER | CONTENTS_UNKNOWN2 | CONTENTS_BBOX)
#define MASK_WATER (CONTENTS_WATER | CONTENTS_LAVA | CONTENTS_SLIME)
#define MASK_OPAQUE (CONTENTS_SOLID | CONTENTS_SLIME | CONTENTS_LAVA)
#define MASK_SHOT \
(CONTENTS_SOLID | CONTENTS_BBOX | CONTENTS_NOBOTCLIP | CONTENTS_UNKNOWN2 | CONTENTS_FENCE | CONTENTS_WEAPONCLIP \
| CONTENTS_BODY | CONTENTS_TRIGGER)
#define MASK_SHOT_TRIG \
(CONTENTS_SOLID | CONTENTS_CLAYPIDGEON | CONTENTS_WATER | CONTENTS_BBOX | CONTENTS_NOBOTCLIP | CONTENTS_UNKNOWN2 \
| CONTENTS_FENCE | CONTENTS_WEAPONCLIP | CONTENTS_BODY | CONTENTS_TRIGGER)
#define MASK_SHOT_FLUID \
(CONTENTS_SOLID | CONTENTS_WATER | CONTENTS_BBOX | CONTENTS_NOBOTCLIP | CONTENTS_UNKNOWN2 | CONTENTS_FENCE \
| CONTENTS_WEAPONCLIP | CONTENTS_SHOOTONLY | CONTENTS_BODY | CONTENTS_TRIGGER)
#define MASK_PROJECTILE \
(CONTENTS_SOLID | CONTENTS_BODY | CONTENTS_TRIGGER | CONTENTS_FENCE | CONTENTS_WEAPONCLIP | CONTENTS_UNKNOWN2 \
| CONTENTS_NOBOTCLIP | CONTENTS_BBOX)
@@ -652,13 +654,15 @@ movement on the server game.
| CONTENTS_BODY | CONTENTS_TRIGGER)
#define MASK_VEHICLE_TIRES (CONTENTS_SOLID | CONTENTS_BBOX | CONTENTS_FENCE | CONTENTS_VEHICLECLIP | CONTENTS_TRIGGER)
#define MASK_CLICK \
(CONTENTS_SOLID | CONTENTS_BODY | CONTENTS_UNKNOWN3 | CONTENTS_UNKNOWN2 | CONTENTS_NOBOTCLIP | CONTENTS_BBOX)
#define MASK_CANSEE \
(CONTENTS_SOLID | CONTENTS_LAVA | CONTENTS_SLIME | CONTENTS_FENCE | CONTENTS_WEAPONCLIP | CONTENTS_BODY)
(CONTENTS_VEHICLECLIP | CONTENTS_WEAPONCLIP | CONTENTS_MONSTERCLIP | CONTENTS_PLAYERCLIP | CONTENTS_SOLID)
#define MASK_CANSEE \
(CONTENTS_SOLID | CONTENTS_LAVA | CONTENTS_SLIME | CONTENTS_BBOX | CONTENTS_NOBOTCLIP | CONTENTS_UNKNOWN2 \
| CONTENTS_FENCE | CONTENTS_WEAPONCLIP | CONTENTS_BODY)
#define MASK_CANSEE_NOENTS (CONTENTS_SOLID | CONTENTS_LAVA | CONTENTS_SLIME | CONTENTS_FENCE | CONTENTS_WEAPONCLIP)
#define MASK_USE (CONTENTS_SOLID | CONTENTS_BBOX | CONTENTS_NOBOTCLIP | CONTENTS_UNKNOWN2 | CONTENTS_FENCE | CONTENTS_WEAPONCLIP | CONTENTS_BODY | CONTENTS_TRIGGER)
#define MASK_CLICKITEM (MASK_SOLID | CONTENTS_UNKNOWN3)
#define MASK_ITEM (CONTENTS_SOLID | CONTENTS_TRIGGER | CONTENTS_PLAYERCLIP | CONTENTS_FENCE)
#define MASK_TRANSITION \
(CONTENTS_SOLID | CONTENTS_LAVA | CONTENTS_SLIME | CONTENTS_UNKNOWN2 | CONTENTS_NOTTEAM1 | CONTENTS_WEAPONCLIP)
#define MASK_TRANSITION (CONTENTS_SOLID | CONTENTS_LAVA | CONTENTS_SLIME | CONTENTS_FENCE | CONTENTS_WEAPONCLIP | CONTENTS_UNKNOWN2 | CONTENTS_BBOX)
#define MASK_TARGETPATH \
(CONTENTS_SOLID | CONTENTS_TRIGGER | CONTENTS_MONSTERCLIP | CONTENTS_FENCE | CONTENTS_UNKNOWN2 | CONTENTS_BBOX)
#define MASK_ACTORPATH (CONTENTS_SOLID | CONTENTS_FENCE | CONTENTS_MONSTERCLIP | CONTENTS_TRIGGER)
@@ -699,6 +703,7 @@ movement on the server game.
| CONTENTS_WEAPONCLIP)
#define MASK_CORNER_NODE \
(CONTENTS_SOLID | CONTENTS_LAVA | CONTENTS_SLIME | CONTENTS_UNKNOWN2 | CONTENTS_WEAPONCLIP | CONTENTS_BODY)
#define MASK_IGNORE_ENTS (CONTENTS_CORPSE | CONTENTS_BODY | CONTENTS_UNKNOWN3 | CONTENTS_UNKNOWN2 | CONTENTS_NOBOTCLIP | CONTENTS_BBOX | CONTENTS_CLAYPIDGEON | CONTENTS_LADDER)
void BG_EvaluateTrajectoryDelta(const trajectory_t *tr, int atTime, vec3_t result);
@@ -747,7 +752,7 @@ movement on the server game.
CGM_NOTIFY_KILL,
CGM_NOTIFY_HIT,
CGM_VOICE_CHAT,
CGM_UNKNOWN_1,
CGM_FENCEPOST,
};
enum cg_message_ver_6_e {
+2 -5
View File
@@ -49,7 +49,6 @@ qboolean PM_SlideMove( qboolean gravity )
float d;
int numplanes;
vec3_t planes[ MAX_CLIP_PLANES ];
vec3_t primal_velocity;
vec3_t clipVelocity;
int i, j, k;
trace_t trace;
@@ -61,13 +60,11 @@ qboolean PM_SlideMove( qboolean gravity )
numbumps = 4;
VectorCopy( pm->ps->velocity, primal_velocity );
VectorCopy( pm->ps->velocity, endVelocity );
if( gravity ) {
VectorCopy( pm->ps->velocity, endVelocity );
endVelocity[ 2 ] -= pm->ps->gravity * pml.frametime;
pm->ps->velocity[ 2 ] = ( pm->ps->velocity[ 2 ] + endVelocity[ 2 ] ) * 0.5;
primal_velocity[ 2 ] = endVelocity[ 2 ];
if( pml.groundPlane ) {
// slide along the ground plane
PM_ClipVelocity( pm->ps->velocity, pml.groundTrace.plane.normal,
@@ -113,7 +110,7 @@ qboolean PM_SlideMove( qboolean gravity )
break; // moved the entire distance
}
if( ( trace.plane.normal[ 2 ] < MIN_WALK_NORMAL ) && ( trace.plane.normal[ 2 ] > 0 ) )
if( ( trace.plane.normal[ 2 ] < MIN_WALK_NORMAL ) && ( trace.plane.normal[ 2 ] > 0 ) && DotProduct(trace.plane.normal, pm->ps->velocity) <= 0 )
{
// treat steep walls as vertical
trace.plane.normal[ 2 ] = 0;
+3 -3
View File
@@ -114,7 +114,7 @@ void VoteOptions::SetupVoteOptions(const char *configFileName, int length, const
if (length >= MAX_VOTEOPTIONS_BUFFER_LENGTH) {
Com_Error(
ERR_DROP,
"VoteOptions: Options file '%s' is too big. Max size is %i bytes\n",
"VoteOptions: Options file '%s' is too big. Max size is %lu bytes\n",
configFileName,
MAX_VOTEOPTIONS_BUFFER_LENGTH
);
@@ -564,11 +564,11 @@ void CG_PushCallVoteSubClient_f(void)
if (!strlen(cg.clientinfo[i].name)) {
continue;
}
VO_ExecuteCommand(
va("globalwidgetcommand voteclientlist additem \"%i: %s\" \"callvote %i %i;popmenu 0\"\n",
i,
cg.clientinfo[i],
cg.clientinfo[i].name,
index,
i)
);
+1
View File
@@ -725,6 +725,7 @@ Camera::Camera()
fadeTime = 2.0f;
fovFadeTime = 1.0f;
followFadeTime = 1.0f;
watchFadeTime = 1.0f;
m_bShowquakes = false;
setSolidType(SOLID_NOT);
+1 -1
View File
@@ -241,7 +241,7 @@ protected:
Vector CalculatePosition(void);
Vector CalculateOrientation(void);
float CalculateFov(void);
virtual void bind(Entity *master, qboolean use_my_angles = false);
virtual void bind(Entity *master, qboolean use_my_angles = false) override;
void unbind(void) override;
public:
+1 -1
View File
@@ -39,7 +39,7 @@ public:
void Setup(Event *ev);
void Damaged(Event *ev);
void Killed(Event *ev);
void Killed(Event *ev) override;
void KillTrace(Event *ev);
void SpawnOrientedBoundingBox(Event *ev);
void EventSetKillThread(Event *ev);
+626 -748
View File
File diff suppressed because it is too large. Load diff
+2 -4
View File
@@ -22,8 +22,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
// debuglines.h:
#ifndef __DEBUGLINES_H__
#define __DEBUGLINES_H__
#pragma once
#include "g_local.h"
@@ -40,6 +39,7 @@ void G_BeginLine( void );
void G_Vertex( Vector v );
void G_EndLine( void );
void G_DebugBBox( Vector org, Vector mins, Vector maxs, float r, float g, float b, float alpha );
void G_DebugRotatedBBox(Vector org, Vector ang, Vector mins, Vector maxs, float r, float g, float b, float alpha);
void G_DrawDebugNumber( Vector org, float number, float scale, float r, float g, float b, int precision = 0 );
void G_DebugCircle( float *org, float radius, float r, float g, float b, float alpha, qboolean horizontal = qfalse );
void G_DebugOrientedCircle( Vector org, float radius, float r, float g, float b, float alpha, Vector angles );
@@ -67,5 +67,3 @@ void G_DebugHighlightFacet( Vector org, Vector mins, Vector maxs, facet_t facet,
extern debugline_t *DebugLines;
extern debugstring_t *DebugStrings;
#endif /* !__DEBUGLINES_H__ */
+31 -23
View File
@@ -271,7 +271,8 @@ void DM_Team::AddKills(Player *player, int numKills)
if (m_teamnumber > TEAM_FREEFORALL) {
m_iKills += numKills;
if ((g_gametype->integer >= GT_TEAM_ROUNDS && g_gametype->integer <= GT_TOW) || g_gametype->integer == GT_LIBERATION) {
if ((g_gametype->integer >= GT_TEAM_ROUNDS && g_gametype->integer <= GT_TOW)
|| g_gametype->integer == GT_LIBERATION) {
player->AddDeaths(numKills);
} else {
m_teamwins += numKills;
@@ -285,7 +286,8 @@ void DM_Team::AddDeaths(Player *player, int numDeaths)
return;
}
if ((g_gametype->integer >= GT_TEAM_ROUNDS && g_gametype->integer <= GT_TOW) || g_gametype->integer == GT_LIBERATION) {
if ((g_gametype->integer >= GT_TEAM_ROUNDS && g_gametype->integer <= GT_TOW)
|| g_gametype->integer == GT_LIBERATION) {
return;
}
@@ -626,7 +628,11 @@ Event EV_DM_Manager_DoRoundTransition
);
Event EV_DM_Manager_FinishRoundTransition
(
"finishroundtransition", EV_DEFAULT, NULL, NULL, "delayed function call to do the actual restart for the next round"
"finishroundtransition",
EV_DEFAULT,
NULL,
NULL,
"delayed function call to do the actual restart for the next round"
);
CLASS_DECLARATION(Listener, DM_Manager, NULL) {
@@ -667,7 +673,7 @@ DM_Manager::DM_Manager()
m_csTeamBombPlantSide = STRING_DRAW;
m_iNumTargetsToDestroy = 1;
m_iNumTargetsDestroyed = 0;
m_iNumBombsPlanted = 0;
m_iNumBombsPlanted = 0;
m_bAllowAxisRespawn = true;
m_bAllowAlliedRespawn = true;
m_bRoundActive = false;
@@ -1048,11 +1054,11 @@ void DM_Manager::InitGame(void)
}
for (i = 1; i <= level.m_SimpleArchivedEntities.NumObjects(); i++) {
SimpleArchivedEntity* const ent = level.m_SimpleArchivedEntities.ObjectAt(i);
const char* const classname = ent->getClassID();
SimpleArchivedEntity *const ent = level.m_SimpleArchivedEntities.ObjectAt(i);
const char *const classname = ent->getClassID();
if (!Q_stricmp(classname, "info_player_deathmatch")) {
PlayerStart* const spawnpoint = static_cast<PlayerStart*>(ent);
PlayerStart *const spawnpoint = static_cast<PlayerStart *>(ent);
m_team_spectator.m_spawnpoints.AddObject(spawnpoint);
m_team_freeforall.m_spawnpoints.AddObject(spawnpoint);
@@ -1062,16 +1068,16 @@ void DM_Manager::InitGame(void)
}
} else if (!Q_stricmp(classname, "info_player_allied")) {
if (g_gametype->integer >= GT_TEAM) {
PlayerStart* const spawnpoint = static_cast<PlayerStart*>(ent);
PlayerStart *const spawnpoint = static_cast<PlayerStart *>(ent);
m_team_allies.m_spawnpoints.AddObject(spawnpoint);
}
} else if (!Q_stricmp(classname, "info_player_axis")) {
if (g_gametype->integer >= GT_TEAM) {
PlayerStart* const spawnpoint = static_cast<PlayerStart*>(ent);
PlayerStart *const spawnpoint = static_cast<PlayerStart *>(ent);
m_team_axis.m_spawnpoints.AddObject(spawnpoint);
}
} else if (!Q_stricmp(classname, "info_player_intermission")) {
PlayerStart* const spawnpoint = static_cast<PlayerStart*>(ent);
PlayerStart *const spawnpoint = static_cast<PlayerStart *>(ent);
m_team_freeforall.m_spawnpoints.AddObject(spawnpoint);
}
}
@@ -1100,10 +1106,10 @@ void DM_Manager::InitGame(void)
m_bRoundBasedGame = false;
} else {
if (g_gametype->integer == GT_TOW || g_gametype->integer == GT_LIBERATION) {
m_bAllowRespawns = true;
m_bAllowRespawns = true;
m_bRoundBasedGame = true;
} else {
m_bAllowRespawns = false;
m_bAllowRespawns = false;
m_bRoundBasedGame = true;
}
@@ -1534,7 +1540,7 @@ void DM_Manager::StartRound(void)
}
m_fRoundEndTime = 0.0f;
m_bRoundActive = true;
m_bRoundActive = true;
// respawn all players
for (i = 0, ent = g_entities; i < game.maxclients; i++, ent++) {
@@ -1620,7 +1626,8 @@ float DM_Manager::GetMatchStartTime(void)
return m_fRoundTime;
}
if (g_gametype->integer == GT_TEAM_ROUNDS || g_gametype->integer == GT_OBJECTIVE || g_gametype->integer == GT_LIBERATION) {
if (g_gametype->integer == GT_TEAM_ROUNDS || g_gametype->integer == GT_OBJECTIVE
|| g_gametype->integer == GT_LIBERATION) {
if (m_fRoundTime > 0 && (m_team_allies.IsEmpty() || m_team_allies.IsEmpty())) {
m_fRoundTime = 0;
return -1;
@@ -1796,15 +1803,15 @@ void DM_Manager::InsertEntry(const char *entry)
}
}
void DM_Manager::InsertEntryNoCount(const char* entry)
void DM_Manager::InsertEntryNoCount(const char *entry)
{
size_t len = strlen(entry);
size_t len = strlen(entry);
if (scoreLength + len < MAX_STRING_CHARS) {
strcpy(scoreString + scoreLength, entry);
if (scoreLength + len < MAX_STRING_CHARS) {
strcpy(scoreString + scoreLength, entry);
scoreLength += len;
}
scoreLength += len;
}
}
void DM_Manager::InsertEmpty(void)
@@ -1864,7 +1871,7 @@ void DM_Manager::BuildTeamInfo_ver6(DM_Team *dmTeam)
Com_sprintf(entry, sizeof(entry), "%i %i \"\" \"\" \"\" \"\" ", -1, dmTeam->m_teamnumber);
}
} else {
Com_sprintf(entry, sizeof(entry), "%i \"\" \"\" \"\" \"\" \"\" ", -1 - dmTeam->m_teamnumber);
Com_sprintf(entry, sizeof(entry), "%i \"\" \"\" \"\" \"\" ", -1 - dmTeam->m_teamnumber);
}
InsertEntry(entry);
@@ -1916,7 +1923,7 @@ void DM_Manager::BuildTeamInfo_ver15(DM_Team *dmTeam)
iPing
);
} else {
Com_sprintf(entry, sizeof(entry), "%i %i \"\" \"\" \"\" \"\" \"\" ", -1, dmTeam->m_teamnumber);
Com_sprintf(entry, sizeof(entry), "%i %i \"\" \"\" \"\" \"\" ", -1, dmTeam->m_teamnumber);
}
} else {
Com_sprintf(entry, sizeof(entry), "%i \"\" \"\" \"\" \"\" ", -1 - dmTeam->m_teamnumber);
@@ -1977,7 +1984,8 @@ void DM_Manager::BuildPlayerTeamInfo(DM_Team *dmTeam, int *iPlayerList, DM_Team
bool DM_Manager::IsAlivePlayer(Player *player) const
{
return !player->IsDead() && !player->IsSpectator() && !player->IsInJail() || player->GetDM_Team() == &m_team_spectator;
return !player->IsDead() && !player->IsSpectator() && !player->IsInJail()
|| player->GetDM_Team() == &m_team_spectator;
}
CTeamSpawnClock::CTeamSpawnClock()
+61 -41
View File
@@ -578,6 +578,10 @@ void Door::OpenEnd(Event *ev)
} else {
StopSound(CHAN_VOICE);
}
// Added in 2.30
// Notify scripts that the door has finished opening
Unregister(STRING_DONE);
previous_state = state;
SetState(STATE_OPEN);
@@ -593,6 +597,12 @@ void Door::OpenEnd(Event *ev)
void Door::CloseEnd(Event *ev)
{
// Fixed in 2.0
// Since this version, the area portal state is changed before sound
if (master == this) {
gi.AdjustAreaPortalState(this->edict, false);
}
if (sound_close_end.length() > 1) {
BroadcastAIEvent();
Sound(sound_close_end, CHAN_VOICE);
@@ -600,15 +610,15 @@ void Door::CloseEnd(Event *ev)
StopSound(CHAN_VOICE);
}
if (master == this) {
gi.AdjustAreaPortalState(this->edict, false);
}
setContents(CONTENTS_SOLID);
setSolidType(SOLID_BSP);
previous_state = state;
SetState(STATE_CLOSED);
// Added in 2.30
// Notify scripts that the door has finished closing
Unregister(STRING_DONE);
}
void Door::Close(Event *ev)
@@ -843,6 +853,8 @@ void Door::DoorBlocked(Event *ev)
void Door::FieldTouched(Event *ev)
{
Entity *other;
Actor* otherActor;
float dist;
other = ev->GetEntity(1);
@@ -850,41 +862,45 @@ void Door::FieldTouched(Event *ev)
return;
}
if (other->IsSubclassOfActor()) {
Actor* otherActor = static_cast<Actor*>(other);
float dist;
otherActor->m_Path.ForceShortLookahead();
if (state == STATE_OPENING) {
otherActor->m_maxspeed = speed * 64;
}
if ((state != STATE_OPEN) && !(spawnflags & DOOR_AUTO_OPEN) && !other->isSubclassOf(Actor)) {
if (!other->IsSubclassOfActor()) {
if ((spawnflags & DOOR_TOGGLE) || (state != STATE_OPEN && !(spawnflags & DOOR_AUTO_OPEN))) {
return;
}
dist = VectorLength2D(other->velocity) * 0.25f;
if (other->absmin[0] > absmax[0] + dist) {
return;
}
if (other->absmin[1] > absmax[1] + dist) {
return;
}
if (other->absmin[2] > absmax[2]) {
return;
}
TryOpen(ev);
return;
}
if (other->absmax[0] < absmin[0] - dist) {
return;
}
if (other->absmax[1] < absmin[1] - dist) {
return;
}
if (other->absmax[2] < absmin[2]) {
return;
}
} else if ((state != STATE_OPEN) && !(spawnflags & DOOR_AUTO_OPEN) && !other->isSubclassOf(Actor)) {
otherActor = static_cast<Actor*>(other);
otherActor->m_Path.ForceShortLookahead();
if (state == STATE_OPENING) {
otherActor->m_maxspeed = speed * 64;
}
if (((spawnflags & DOOR_TOGGLE) || (state != STATE_OPEN && !(spawnflags & DOOR_AUTO_OPEN))) && (state == STATE_OPEN || state == STATE_OPENING)) {
return;
}
dist = VectorLength2D(other->velocity) * 0.25f;
if (other->absmin[0] > absmax[0] + dist) {
return;
}
if (other->absmin[1] > absmax[1] + dist) {
return;
}
if (other->absmin[2] > absmax[2]) {
return;
}
if (other->absmax[0] < absmin[0] - dist) {
return;
}
if (other->absmax[1] < absmin[1] - dist) {
return;
}
if (other->absmax[2] < absmin[2]) {
return;
}
@@ -1095,10 +1111,7 @@ void Door::LinkDoors(Event *ev)
return;
}
// Don't spawn trigger field when set to toggle
if (!(spawnflags & DOOR_TOGGLE)) {
SpawnTriggerField(cmins, cmaxs);
}
SpawnTriggerField(cmins, cmaxs);
}
void Door::SetTime(Event *ev)
@@ -1311,8 +1324,6 @@ void RotatingDoor::DoOpen(Event *ev)
} else {
diropened = 0 - init_door_direction;
}
} else {
diropened = -init_door_direction;
}
if (diropened < 0.0f) {
@@ -1321,7 +1332,16 @@ void RotatingDoor::DoOpen(Event *ev)
ang = startangle - Vector(0.0f, angle, 0.0f);
}
if (localangles.yaw() + 360 <= ang.yaw()) {
localangles.setYaw(localangles.yaw() + 360);
} else if (localangles.yaw() - 360 >= ang.yaw()) {
localangles.setYaw(localangles.yaw() - 360);
}
MoveTo(origin, ang, fabs(speed * angle), EV_Door_OpenEnd);
setContents(CONTENTS_SOLID);
setSolidType(SOLID_BSP);
}
void RotatingDoor::DoClose(Event *ev)
+2 -2
View File
@@ -133,7 +133,7 @@ ViewJitter::ViewJitter()
m_fDuration = 0;
m_bDoneDeath = qfalse;
m_bDoneDeath = false;
}
ViewJitter::ViewJitter( Vector vOrigin, float fRadius, float fEdgeEffect, Vector vStrength, float fDuration, Vector vTimeDecay, float fStartDecay )
@@ -154,7 +154,7 @@ ViewJitter::ViewJitter( Vector vOrigin, float fRadius, float fEdgeEffect, Vector
m_fDuration = fDuration;
m_bDoneDeath = false;
m_bDoneDeath = true;
m_fTimeRunning = 0;
PostEvent( EV_ViewJitter_Think, fStartDecay );
+153 -66
View File
@@ -1471,6 +1471,7 @@ Event EV_Entity_SetDHack
"Enable or disable depth hack.",
EV_NORMAL
);
/*
Event EV_Entity_GetZone
(
"getzone",
@@ -1498,6 +1499,7 @@ Event EV_Entity_IsInZone
"Returns 1 if the entity is in the specified zone. 0 otherwise",
EV_RETURN
);
*/
Event EV_Entity_SetHintRequireLookAt
(
"setuselookat",
@@ -1645,8 +1647,8 @@ CLASS_DECLARATION(SimpleEntity, Entity, NULL) {
{&EV_ConnectPaths, &Entity::EventConnectPaths },
{&EV_DisconnectPaths, &Entity::EventDisconnectPaths },
{&EV_Remove, &Entity::Remove },
{&EV_Delete, &Entity::Remove },
{&EV_ScriptRemove, &Entity::Remove },
{&EV_Delete, &Listener::ScriptRemove },
{&EV_ScriptRemove, &Listener::ScriptRemove },
{&EV_VolumeDamage, &Entity::EventVolumeDamage },
{&EV_GetNormalHealth, &Entity::EventGetNormalHealth },
{&EV_NormalDamage, &Entity::EventNormalDamage },
@@ -1667,9 +1669,11 @@ CLASS_DECLARATION(SimpleEntity, Entity, NULL) {
{&EV_ShootableOnly, &Entity::EventShootableOnly },
{&EV_SetShaderTime, &Entity::SetShaderTime },
{&EV_NoTarget, &Entity::NoTarget },
/*
{&EV_Entity_GetZone, &Entity::GetZone },
{&EV_Entity_Zone, &Entity::GetZone },
{&EV_Entity_IsInZone, &Entity::IsInZone },
*/
{&EV_Entity_SetDHack, &Entity::SetDepthHack },
{&EV_Entity_SetHintRequireLookAt, &Entity::SetHintRequireLookAt },
{&EV_Entity_SetHintString, &Entity::SetHintString },
@@ -1843,8 +1847,8 @@ Entity::~Entity()
}
if (m_BlockedPaths) {
delete m_BlockedPaths;
m_BlockedPaths = 0;
delete[] m_BlockedPaths;
m_BlockedPaths = NULL;
}
level.FreeEdict(edict);
@@ -3217,6 +3221,15 @@ void Entity::LoopSound(Event *ev)
return;
}
if (level.spawning) {
// If the server is currently spawning
// repost the event as loopsound wouldn't work properly
// on the client
Event* newev = new Event(*ev);
PostEvent(newev, level.frametime);
return;
}
// Get parameters
sound_name = ev->GetString(1);
@@ -3267,10 +3280,10 @@ void Entity::LoopSound(str sound_name, float volume, float min_dist, float max_d
// Add the looping sound to the entity
edict->s.loopSound = gi.soundindex(name, aliasstreamed);
edict->s.loopSoundVolume = aliasvolume;
edict->s.loopSoundMinDist = aliasmin_dist;
edict->s.loopSoundMaxDist = aliasmax_dist;
edict->s.loopSoundPitch = aliaspitch;
edict->s.loopSoundVolume = volume < 0 ? (aliasvolume) : (aliasvolume * volume);
edict->s.loopSoundMinDist = min_dist < 0 ? (aliasmin_dist) : (min_dist);
edict->s.loopSoundMaxDist = max_dist < 0 ? (aliasmax_dist) : (max_dist);
edict->s.loopSoundPitch = pitch < 0 ? (aliaspitch) : (aliaspitch * pitch);
// Local sound will always be heard
edict->s.loopSoundFlags = aliaschannel == CHAN_LOCAL;
@@ -3297,7 +3310,7 @@ void Entity::ProcessSoundEvent(Event *ev, qboolean checkSubtitle)
{
str sound_name;
str wait;
int waitTillDone = 0;
bool waitTillDone = false;
float volume;
int channel = 0;
@@ -3317,30 +3330,24 @@ void Entity::ProcessSoundEvent(Event *ev, qboolean checkSubtitle)
wait = ev->GetString(2);
}
if (Q_stricmp(wait.c_str(), "wait")) {
if (!Q_stricmp(wait.c_str(), "volume")) {
if (ev->NumArgs() != 3) {
ScriptError("Entity::Sound: volume not followed by a float");
}
volume = ev->GetFloat(3);
}
} else {
waitTillDone = 1;
if (!Q_stricmp(wait.c_str(), "wait")) {
waitTillDone = true;
if (ev->NumArgs() == 3) {
volume = ev->GetFloat(3);
}
} else if (!Q_stricmp(wait.c_str(), "volume")) {
if (ev->NumArgs() != 3) {
ScriptError("Entity::Sound: volume not followed by a float");
}
volume = ev->GetFloat(3);
}
if (volume == DEFAULT_VOL) {
if (wait.length()) {
channel = atoi(wait.c_str());
}
Sound(sound_name, channel, volume, 0, NULL, 0, 0, waitTillDone, checkSubtitle, -1.0f);
Sound(sound_name, CHAN_AUTO, volume, 0, NULL, 0, 0, waitTillDone, checkSubtitle, -1.0f);
} else {
Sound(sound_name, -1.0f, volume, -1.0f, NULL, -1.0f, 1, waitTillDone, checkSubtitle, -1.0f);
Sound(sound_name, -1, volume, -1.0f, NULL, -1.0f, 1, waitTillDone, checkSubtitle, -1.0f);
}
}
@@ -3602,6 +3609,11 @@ void Entity::Sound(
static cvar_t *g_subtitle = NULL;
static bool _tmp = false;
int num;
int aliaschannel;
float aliasvolume;
float aliasmin_dist;
float aliasmax_dist;
float aliaspitch;
if (!_tmp) {
g_subtitle = gi.Cvar_Get("g_subtitle", "0", CVAR_ARCHIVE);
@@ -3630,6 +3642,12 @@ void Entity::Sound(
if (name != NULL) {
if (ret) {
aliaschannel = ret->channel;
aliasvolume = G_Random() * ret->volumeMod + ret->volume;
aliaspitch = G_Random() * ret->pitchMod + ret->pitch;
aliasmin_dist = ret->dist;
aliasmax_dist = ret->maxDist;
if (channel < 0) {
channel = ret->channel;
}
@@ -3646,51 +3664,72 @@ void Entity::Sound(
}
}
if (argstype == 0) {
volume = G_Random() * ret->volumeMod + ret->volume;
pitch = G_Random() * ret->pitchMod + ret->pitch;
min_dist = ret->dist;
max_dist = ret->maxDist;
} else if (argstype == 1) {
switch (argstype) {
case 0:
volume = aliasvolume;
pitch = aliaspitch;
min_dist = aliasmin_dist;
max_dist = aliasmax_dist;
channel = aliaschannel;
break;
case 1:
if (volume >= 0.0f) {
volume = G_Random() * ret->volumeMod + volume;
volume = volume * aliasvolume;
} else {
volume = G_Random() * ret->volumeMod + volume;
volume = aliasvolume;
}
if (pitch >= 0.0f) {
pitch = G_Random() * ret->pitchMod + pitch;
pitch = pitch * aliaspitch;
} else {
pitch = G_Random() * ret->pitchMod + ret->pitch;
}
} else {
if (volume <= 0.0f) {
volume = G_Random() * ret->volumeMod + ret->volume;
}
if (pitch >= 0.0f) {
pitch = G_Random() * ret->pitchMod + pitch;
} else {
pitch = G_Random() * ret->pitchMod + ret->pitch;
pitch = aliaspitch;
}
if (min_dist < 0.0f) {
min_dist = ret->dist;
min_dist = aliasmin_dist;
}
if (max_dist < 0.0f) {
max_dist = ret->maxDist;
max_dist = aliasmax_dist;
}
if (channel < 0) {
channel = aliaschannel;
}
break;
default:
if (volume < 0.0) {
volume = aliasvolume;
}
if (pitch < 0.0) {
pitch = aliaspitch;
}
if (min_dist < 0.0) {
min_dist = aliasmin_dist;
}
if (max_dist < 0.0) {
max_dist = aliasmax_dist;
}
if (channel < 0) {
channel = aliaschannel;
}
break;
}
if (g_gametype->integer == GT_SINGLE_PLAYER && (!checkSubtitle || g_subtitle->integer) && ret->subtitle) {
if ((!checkSubtitle || g_subtitle->integer) && ret->subtitle) {
Entity *p = G_GetEntity(0);
if (g_subtitle->integer == 2 || max_dist * max_dist > DistanceSquared(org, p->edict->s.origin)) {
if (g_subtitle->integer == 2 || Square(max_dist) > DistanceSquared(org, p->edict->s.origin)) {
cvar_t *curSubtitle = gi.Cvar_Get("curSubtitle", "0", 0);
int curSub;
gi.cvar_set(va("subtitle%d", curSubtitle->integer), va("%s", ret->subtitle));
gi.cvar_set("curSubtitle", va("%d", curSubtitle->integer + 1));
curSub = curSubtitle->integer + 1;
if (curSubtitle->integer + 1 < 0) {
curSub = curSubtitle->integer + MAX_SUBTITLES;
}
gi.cvar_set("curSubtitle", va("%d", (curSubtitle->integer + 1) - MAX_SUBTITLES * (curSub >> 2)));
}
}
@@ -4096,7 +4135,7 @@ void Entity::BroadcastAIEvent(int iType, float rad)
return;
}
G_BroadcastAIEvent(this, origin, iType, rad);
G_BroadcastAIEvent(this, centroid, iType, rad);
}
void Entity::BroadcastAIEvent(Event *ev)
@@ -4380,11 +4419,17 @@ void Entity::AttachModelEvent(Event *ev)
if (obj->attach(this->entnum, tagnum, true, offset)) {
obj->NewAnim("idle");
} else {
delete obj;
warning("AttachModelEvent", "Could not attach model %s to tag \"%s\" on entnum #%d (targetname = %s)", modelname.c_str(), bone.c_str(), entnum, targetname.c_str());
if (g_iInThinks) {
PostEvent(EV_Remove, 0);
} else {
delete obj;
}
return;
}
} else {
warning("AttachModelEvent", "Tag %s not found", bone.c_str());
obj->NewAnim("idle");
}
}
@@ -5317,7 +5362,7 @@ void Entity::GetTagPositionAndOrientation(int tagnum, orientation_t *new_or)
VectorCopy(origin, new_or->origin);
for (i = 0; i < 3; i++) {
VectorMA(new_or->origin, tag_or.origin[i], tag_or.axis[i], new_or->origin);
VectorMA(new_or->origin, tag_or.origin[i], axis[i], new_or->origin);
}
MatrixMultiply(tag_or.axis, axis, new_or->axis);
@@ -5461,7 +5506,7 @@ void Entity::MPrintf(const char *fmt, ...)
va_list argptr;
char msg[MAXPRINTMSG];
if (g_monitorNum->integer == entnum && g_monitor->string == targetname) {
if (g_monitorNum->integer == entnum || g_monitor->string[0] && g_monitor->string == targetname) {
va_start(argptr, fmt);
Q_vsnprintf(msg, sizeof(msg), fmt, argptr);
va_end(argptr);
@@ -5624,7 +5669,7 @@ void Entity::ConnectPaths(void)
m_iNumBlockedPaths = 0;
if (m_BlockedPaths) {
delete m_BlockedPaths;
delete[] m_BlockedPaths;
m_BlockedPaths = NULL;
}
}
@@ -5927,7 +5972,7 @@ void Entity::DrawBoundingBox(int showbboxes)
switch (showbboxes) {
case 1:
if (edict->s.solid) {
G_DebugBBox(origin, mins, maxs, 1, 1, 0, 1);
G_DebugRotatedBBox(origin, angles, mins, maxs, 1, 1, 0, 1);
}
break;
case 2:
@@ -5937,13 +5982,48 @@ void Entity::DrawBoundingBox(int showbboxes)
break;
case 3:
if (edict->tiki && !(edict->s.renderfx & RF_DONTDRAW)) {
G_DebugBBox(origin, mins, maxs, 1, 1, 0, 1);
G_DebugRotatedBBox(origin, angles, mins, maxs, 1, 1, 0, 1);
}
break;
case 4:
G_DebugBBox(origin, mins, maxs, 1, 1, 0, 1);
G_DebugRotatedBBox(origin, angles, mins, maxs, 1, 1, 0, 1);
break;
case 7:
if (edict->tiki && !(edict->s.renderfx & RF_DONTDRAW)) {
Vector vMins, vMaxs;
gi.TIKI_CalculateBounds(edict->tiki, edict->s.scale, vMins, vMaxs);
if (!VectorCompare(vMins, vec_zero) || !VectorCompare(vMaxs, vec_zero)) {
if (edict->s.parent != ENTITYNUM_NONE && edict->s.tag_num >= 0) {
int i;
Vector vAng;
orientation_t oTag, oBox;
Entity* pParent;
pParent = G_GetEntity(edict->s.parent);
AnglesToAxis(pParent->angles, pParent->orientation);
oTag = G_TIKI_Orientation(pParent->edict, edict->s.tag_num & TAG_MASK);
VectorCopy(pParent->origin, oBox.origin);
for (i = 0; i < 3; i++) {
VectorMA(oBox.origin, oTag.origin[i], pParent->orientation[i], oBox.origin);
}
MatrixMultiply(oTag.axis, pParent->orientation, oBox.axis);
MatrixToEulerAngles(oBox.axis, vAng);
G_DebugRotatedBBox(oBox.origin, vAng, vMins, vMaxs, 0, 1, 1, 1);
} else {
G_DebugRotatedBBox(origin, angles, vMins, vMaxs, 0, 1, 1, 1);
}
}
}
break;
case 8:
if (edict->tiki && !(edict->s.renderfx & RF_DONTDRAW)) {
G_DebugRotatedBBox(origin, angles, mins, maxs, 1, 1, 0, 1);
G_DebugBBox(origin, Vector(-4, -4, -4), Vector(4, 4, 4), 0, 1, 1, 1);
}
break;
case 5:
default:
if (IsSubclassOfAnimate() && edict->tiki) {
Animate *anim;
@@ -5957,6 +6037,8 @@ void Entity::DrawBoundingBox(int showbboxes)
}
break;
}
// FIXME: not implemented (implement the rest...)
}
qboolean Entity::IsDead(void) const
@@ -6078,7 +6160,7 @@ void Entity::EventGetRotatedBbox(Event *ev)
void Entity::EventSinglePlayerCommand(Event *ev)
{
if (g_gametype->integer == GT_SINGLE_PLAYER && !g_realismmode->integer) {
Event *newev = new Event(ev->GetToken(1));
Event *newev = new Event(ev->GetToken(1), ev->NumArgs() - 1);
for (int i = 2; i <= ev->NumArgs(); i++) {
newev->AddToken(ev->GetToken(i));
@@ -6091,7 +6173,7 @@ void Entity::EventSinglePlayerCommand(Event *ev)
void Entity::EventMultiPlayerCommand(Event *ev)
{
if (g_gametype->integer != GT_SINGLE_PLAYER && !g_realismmode->integer) {
Event *newev = new Event(ev->GetToken(1));
Event *newev = new Event(ev->GetToken(1), ev->NumArgs() - 1);
for (int i = 2; i <= ev->NumArgs(); i++) {
newev->AddToken(ev->GetToken(i));
@@ -6104,7 +6186,7 @@ void Entity::EventMultiPlayerCommand(Event *ev)
void Entity::EventRealismModeCommand(Event *ev)
{
if (g_realismmode->integer) {
Event *newev = new Event(ev->GetToken(1));
Event *newev = new Event(ev->GetToken(1), ev->NumArgs() - 1);
for (int i = 2; i <= ev->NumArgs(); i++) {
newev->AddToken(ev->GetToken(i));
@@ -6116,8 +6198,8 @@ void Entity::EventRealismModeCommand(Event *ev)
void Entity::EventSPRealismModeCommand(Event *ev)
{
if (g_realismmode->integer && g_gametype->integer == GT_SINGLE_PLAYER) {
Event *newev = new Event(ev->GetToken(1));
if (g_gametype->integer == GT_SINGLE_PLAYER && g_realismmode->integer) {
Event *newev = new Event(ev->GetToken(1), ev->NumArgs() - 1);
for (int i = 2; i <= ev->NumArgs(); i++) {
newev->AddToken(ev->GetToken(i));
@@ -6129,8 +6211,8 @@ void Entity::EventSPRealismModeCommand(Event *ev)
void Entity::EventDMRealismModeCommand(Event *ev)
{
if (g_realismmode->integer && g_gametype->integer != GT_SINGLE_PLAYER) {
Event *newev = new Event(ev->GetToken(1));
if (g_gametype->integer != GT_SINGLE_PLAYER && g_realismmode->integer) {
Event *newev = new Event(ev->GetToken(1), ev->NumArgs() - 1);
for (int i = 2; i <= ev->NumArgs(); i++) {
newev->AddToken(ev->GetToken(i));
@@ -6302,6 +6384,11 @@ void Entity::PlayNonPvsSound(const str& soundName, float volume)
AliasListNode_t* ret;
str name;
if (g_gametype->integer == GT_SINGLE_PLAYER) {
// Ignore in single-player
return;
}
if (edict->r.num_nonpvs_sounds >= MAX_NONPVS_SOUNDS) {
return;
}
+3 -2
View File
@@ -81,7 +81,8 @@ enum eAIEvent {
AI_EVENT_MISC_LOUD,
AI_EVENT_FOOTSTEP,
AI_EVENT_GRENADE,
AI_EVENT_BADPLACE // Added in 2.0
AI_EVENT_BADPLACE, // Added in 2.0
AI_EVENT_MAX
};
//deadflag
@@ -502,7 +503,7 @@ public:
void BroadcastAIEvent(int iType = AI_EVENT_MISC, float rad = SOUND_RADIUS);
void BroadcastAIEvent(Event *ev);
void Kill(Event *ev);
void Killed(Event *ev);
virtual void Killed(Event *ev);
void SurfaceModelEvent(Event *ev);
void SurfaceCommand(const char *surf_name, const char *token);
virtual void Postthink(void);
+43 -6
View File
@@ -172,11 +172,11 @@ void G_AddBot(unsigned int num, saved_bot_t* saved)
void G_RemoveBot(unsigned int num)
{
num = Q_min(atoi(gi.Argv(1)), sv_maxbots->integer);
num = Q_min(num, sv_maxbots->integer);
for( int n = 0; n < num; n++ )
{
gentity_t *e = &g_entities[ game.maxclients - 1 - n ];
gentity_t *e = &g_entities[maxclients->integer + n];
if( e->inuse && e->client )
{
G_ClientDisconnect( e );
@@ -230,6 +230,27 @@ void G_RestoreBots() {
saved_bots = NULL;
}
int G_CountClients() {
gentity_t* other;
unsigned int n;
unsigned int count = 0;
for (n = 0; n < maxclients->integer; n++) {
other = &g_entities[n];
if (other->inuse && other->client) {
Player* p = static_cast<Player*>(other->entity);
if (p->GetTeam() == teamtype_t::TEAM_NONE || p->GetTeam() == teamtype_t::TEAM_SPECTATOR) {
// ignore spectators
continue;
}
count++;
}
}
return count;
}
void G_ResetBots() {
G_SaveBots();
@@ -237,13 +258,29 @@ void G_ResetBots() {
}
void G_SpawnBots() {
unsigned int numClients;
unsigned int numBotsToSpawn;
if (saved_bots) {
G_RestoreBots();
}
if (sv_numbots->integer > current_bot_count) {
G_AddBot(sv_numbots->integer - current_bot_count);
} else if (sv_numbots->integer < current_bot_count) {
G_RemoveBot(current_bot_count - sv_numbots->integer);
//
// Check the minimum bot count
//
numClients = G_CountClients() + sv_numbots->integer;
if (numClients < sv_minPlayers->integer) {
numBotsToSpawn = sv_minPlayers->integer - numClients;
} else {
numBotsToSpawn = sv_numbots->integer;
}
//
// Spawn bots
//
if (numBotsToSpawn > current_bot_count) {
G_AddBot(numBotsToSpawn - current_bot_count);
} else if (numBotsToSpawn < current_bot_count) {
G_RemoveBot(current_bot_count - numBotsToSpawn);
}
}
+51 -16
View File
@@ -578,6 +578,10 @@ Chooses a player start, deathmatch start, etc
PlayerStart *SelectSpawnPoint(Player *player)
{
PlayerStart *spot = NULL;
PlayerStart *spawnpoint;
const char *classID;
int i;
int nFound;
switch (g_gametype->integer) {
case GT_SINGLE_PLAYER:
@@ -602,15 +606,38 @@ PlayerStart *SelectSpawnPoint(Player *player)
// find a single player start spot
if (!spot) {
while ((spot = (PlayerStart *)G_FindArchivedClass(spot, "info_player_start")) != NULL) {
if (level.spawnpoint.icmp(spot->TargetName()) == 0) {
break;
for (i = 1; i <= level.m_SimpleArchivedEntities.NumObjects(); i++) {
SimpleArchivedEntity *arc = level.m_SimpleArchivedEntities.ObjectAt(i);
classID = arc->classinfo()->classID;
if (!Q_stricmp(classID, "info_player_start")) {
spawnpoint = static_cast<PlayerStart *>(arc);
if (!str::icmp(level.spawnpoint, spawnpoint->TargetName())) {
spot = spawnpoint;
break;
}
}
}
if (!spot && !level.spawnpoint.length()) {
// there wasn't a spawnpoint without a target, so use any
spot = (PlayerStart *)G_FindArchivedClass(NULL, "info_player_start");
nFound = 0;
for (i = 1; i <= level.m_SimpleArchivedEntities.NumObjects(); i++) {
SimpleArchivedEntity *arc = level.m_SimpleArchivedEntities.ObjectAt(i);
classID = arc->classinfo()->classID;
if (!Q_stricmp(classID, "info_player_start")) {
int randVal;
spawnpoint = static_cast<PlayerStart *>(arc);
nFound++;
randVal = rand();
if (randVal == randVal / nFound * nFound) {
spot = spawnpoint;
}
}
}
}
if (!spot) {
@@ -786,7 +813,7 @@ void G_ClientUserinfoChanged(gentity_t *ent, const char *u)
Q_strncpyz(client->pers.userinfo, u, sizeof(client->pers.userinfo));
}
void G_BotConnect(int clientNum, const char* userinfo)
void G_BotConnect(int clientNum, const char *userinfo)
{
gclient_t *client;
gentity_t *ent;
@@ -800,7 +827,7 @@ void G_BotConnect(int clientNum, const char* userinfo)
// read the session data
memset(client, 0, sizeof(*client));
G_InitSessionData(client, userinfo);
G_InitClientPersistant(client, userinfo);
Q_strncpyz(client->pers.ip, "localhost", sizeof(client->pers.ip));
client->pers.port = 0;
@@ -828,7 +855,7 @@ to the server machine, but qfalse on map changes and tournement
restarts.
============
*/
const char *G_ClientConnect(int clientNum, qboolean firstTime)
const char *G_ClientConnect(int clientNum, qboolean firstTime, qboolean differentMap)
{
char *ip, *port, *value;
gclient_t *client;
@@ -836,9 +863,11 @@ const char *G_ClientConnect(int clientNum, qboolean firstTime)
char userinfo[MAX_INFO_STRING];
gi.DPrintf("TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT\n");
if (!g_gametype->integer) {
return NULL;
}
// Removed in OPM
// Accepts remote clients
//if (g_gametype->integer == GT_SINGLE_PLAYER) {
// return NULL;
//}
ent = &g_entities[clientNum];
@@ -852,6 +881,7 @@ const char *G_ClientConnect(int clientNum, qboolean firstTime)
port = Info_ValueForKey(userinfo, "port");
// FIXME: what is fucking wrong with G_FilterPacket...
// NOTE: IP banning is directly handled by the server
//if ( G_FilterPacket( value ) ) {
// return "Banned IP";
//}
@@ -862,7 +892,7 @@ const char *G_ClientConnect(int clientNum, qboolean firstTime)
if ((strcmp(ip, "localhost") != 0)) {
// check for a password
value = Info_ValueForKey(userinfo, "password");
if (password->string[0] && Q_stricmp(password->string, "none") && strcmp(password->string, value) != 0) {
if (strcmp(sv_privatePassword->string, value) != 0 && *password->string && strcmp(password->string, value) != 0) {
return "Invalid password";
}
}
@@ -873,9 +903,14 @@ const char *G_ClientConnect(int clientNum, qboolean firstTime)
// read or initialize the session data
if (firstTime) {
memset(client, 0, sizeof(*client));
G_InitSessionData(client, userinfo);
if (!game.autosaved) {
G_InitClientPersistant(client, userinfo);
}
} else {
G_ReadSessionData(client);
G_ReadClientSessionData(client);
if (differentMap) {
client->pers.dm_primary[0] = 0;
}
}
Q_strncpyz(client->pers.ip, ip, sizeof(client->pers.ip));
@@ -895,7 +930,7 @@ const char *G_ClientConnect(int clientNum, qboolean firstTime)
#endif
// don't do the "xxx connected" messages if they were caried over from previous level
if (firstTime && g_gametype->integer) {
if (firstTime && g_gametype->integer != GT_SINGLE_PLAYER) {
if (dedicated->integer) {
gi.Printf("%s is preparing for deployment\n", client->pers.netname);
}
@@ -944,7 +979,7 @@ void G_ClientBegin(gentity_t *ent, usercmd_t *cmd)
} else {
ent->client->pers.enterTime = level.svsFloatTime;
if (g_gametype->integer) {
if (g_gametype->integer != GT_SINGLE_PLAYER) {
// send effect if in a multiplayer game
if (dedicated->integer) {
gi.Printf("%s has entered the battle\n", ent->client->pers.netname);
+8 -9
View File
@@ -22,8 +22,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//
// g_local.h -- local definitions for game module
#ifndef __G_LOCAL_H__
#define __G_LOCAL_H__
#pragma once
#include "q_shared.h"
#include "bg_public.h"
@@ -417,14 +416,14 @@ void G_RunThink(gentity_t *ent);
void QDECL G_LogPrintf(const char *fmt, ...);
void SendScoreboardMessageToAllClients(void);
void QDECL G_Printf(const char *fmt, ...);
void QDECL G_Error(const char *fmt, ...);
void QDECL G_Error(errorParm_t type, const char *fmt, ...);
void QDECL G_Error(const char *fmt, ...) __attribute__ ((noreturn, format(printf, 1, 2)));
void QDECL G_Error(errorParm_t type, const char *fmt, ...) __attribute__((noreturn, format(printf, 2, 3)));
//
// g_client.c
//
void G_BotConnect(int clientNum, const char* userinfo);
const char *G_ClientConnect(int clientNum, qboolean firstTime);
const char *G_ClientConnect(int clientNum, qboolean firstTime, qboolean differentMap);
void G_ClientUserinfoChanged(gentity_t *ent, const char *userinfo);
void G_ClientDisconnect(gentity_t *ent);
void G_ClientBegin(gentity_t *ent, usercmd_t *cmd);
@@ -437,6 +436,8 @@ void G_ClientCommand(gentity_t *ent);
void G_ClientThink(gentity_t *ent, usercmd_t *cmd, usereyes_t *eyeinfo);
void ClientEndFrame(gentity_t *ent);
void G_ClientEndServerFrames(void);
void G_ClientDoBlends(void);
void FindIntermissionPoint(void);
void G_RunClient(gentity_t *ent);
//
@@ -456,8 +457,8 @@ void Svcmd_GameMem_f(void);
//
// g_session.c
//
void G_ReadSessionData(gclient_t *client);
void G_InitSessionData(gclient_t *client, const char *userinfo);
void G_ReadClientSessionData(gclient_t *client);
void G_InitClientPersistant(gclient_t *client, const char *userinfo);
void G_InitWorldSession(void);
void G_WriteSessionData(void);
@@ -530,5 +531,3 @@ extern gentity_t *g_entities;
#define FOFS(x) ((size_t) & (((gentity_t *)0)->x))
#include "g_utils.h"
#endif /* g_local.h */
+242 -32
View File
@@ -83,6 +83,11 @@ void (*SV_Free)(void *ptr);
qboolean LevelArchiveValid(Archiver& arc);
void ClosePlayerLogFile(void);
/*
===============
G_Printf
===============
*/
void QDECL G_Printf(const char *fmt, ...)
{
va_list argptr;
@@ -95,6 +100,11 @@ void QDECL G_Printf(const char *fmt, ...)
gi.Printf(text);
}
/*
===============
G_Error
===============
*/
void QDECL G_Error(const char *fmt, ...)
{
va_list argptr;
@@ -107,6 +117,11 @@ void QDECL G_Error(const char *fmt, ...)
gi.Error(ERR_DROP, text);
}
/*
===============
G_Error
===============
*/
void QDECL G_Error(int type, const char *fmt, ...)
{
va_list argptr;
@@ -360,7 +375,11 @@ Called when server finished initializating
*/
void G_ServerSpawned(void)
{
level.ServerSpawned();
try {
level.ServerSpawned();
} catch (const ScriptException& e) {
G_ExitWithError(e.string.c_str());
}
}
/*
@@ -426,7 +445,6 @@ void G_RunFrame(int levelTime, int frameTime)
qboolean showentnums;
unsigned long long start;
unsigned long long end;
int i;
static int processed[MAX_GENTITIES] = {0};
static int processedFrameID = 0;
@@ -456,16 +474,9 @@ void G_RunFrame(int levelTime, int frameTime)
if (level.intermissiontime || level.died_already) {
L_ProcessPendingEvents();
G_ClientDoBlends();
for (i = 0, edict = g_entities; i < game.maxclients; i++, edict++) {
if (!edict->inuse || !edict->client || !edict->entity) {
continue;
}
edict->entity->CalcBlend();
}
if (g_gametype->integer && g_maxintermission->value != 0.0f) {
if (g_gametype->integer != GT_SINGLE_PLAYER && g_maxintermission->value != 0.0f) {
if (level.time - level.intermissiontime > g_maxintermission->value) {
level.exitintermission = true;
}
@@ -733,11 +744,71 @@ void G_ClientDrawBoundingBoxes(void)
/*
=================
G_ClientDrawTags
Added in 2.0.
This draws tag position and orientation
for entities in a radius of 1000 units.
=================
*/
void G_ClientDrawTags(void)
{
// FIXME: unimplemented
Entity* player;
Entity* ent;
const char* tagName;
Vector origin;
orientation_t ori;
int numTags;
int i;
if (!sv_showtags->string || !sv_showtags->string[0]) {
return;
}
if (sv_showtags->string[0] != '*' && !sv_showtags->string[1] && sv_showtags->integer == 0) {
// The variable is defined but set to 0
return;
}
if (g_gametype->integer != GT_SINGLE_PLAYER && !sv_cheats->integer) {
return;
}
player = G_GetEntity(0);
origin = player->origin;
for (ent = findradius(NULL, origin, 1000); ent; ent = findradius(ent, origin, 1000)) {
if (!ent->edict->tiki) {
continue;
}
if (ent == player) {
continue;
}
numTags = gi.TIKI_NumTags(ent->edict->tiki);
for (i = 0; i < numTags; i++) {
tagName = gi.Tag_NameForNum(ent->edict->tiki, i);
if (Q_stricmp(sv_showtags->string, "*")) {
//
// If it's not a wildcard, check to see if
// the tag name partially matches
//
if (Q_stricmpn(tagName, sv_showtags->string, strlen(sv_showtags->string))) {
continue;
}
}
ent->GetTagPositionAndOrientation(i, &ori);
G_DebugString(ori.origin + Vector(0, 0, 8), 1, 1, 1, 0, "%s", tagName);
G_DebugCircle(ori.origin, 10, 1, 1, 1, 1, true);
G_DebugLine(ori.origin, ori.origin + Vector(ori.axis[0]) * 32, 1, 0, 0, 1);
G_DebugLine(ori.origin, ori.origin + Vector(ori.axis[1]) * 32, 0, 1, 0, 1);
G_DebugLine(ori.origin, ori.origin + Vector(ori.axis[2]) * 32, 0, 0, 1, 1);
}
}
}
// Used to tell the server about the edict pose, such as the player pose
@@ -1211,7 +1282,7 @@ G_ArchiveLevel
=================
*/
qboolean G_ArchiveLevel(const char *filename, qboolean autosave, qboolean loading)
qboolean G_ArchiveLevel(const char *filename, byte** savedCgameState, size_t *savedCgameStateSize, qboolean autosave, qboolean loading)
{
try {
int i;
@@ -1255,19 +1326,34 @@ qboolean G_ArchiveLevel(const char *filename, qboolean autosave, qboolean loadin
L_ArchiveEvents(arc);
}
if (!arc.Saving()) {
arc.ArchiveInteger(&num);
*savedCgameStateSize = num;
if (*savedCgameStateSize) {
*savedCgameState = (byte*)gi.Malloc(*savedCgameStateSize);
} else {
*savedCgameState = NULL;
}
} else {
num = (int)*savedCgameStateSize;
arc.ArchiveInteger(&num);
}
arc.ArchiveRaw(*savedCgameState, *savedCgameStateSize);
if (arc.Saving()) {
str s;
num = 0;
for (cvar = gi.NextCvar(NULL); cvar != NULL; cvar = gi.NextCvar(cvar)) {
if (cvar->flags & CVAR_ROM) {
if (cvar->flags & CVAR_SAVEGAME) {
num++;
}
}
arc.ArchiveInteger(&num);
for (cvar = gi.NextCvar(NULL); cvar != NULL; cvar = gi.NextCvar(cvar)) {
if (cvar->flags & CVAR_ROM) {
if (cvar->flags & CVAR_SAVEGAME) {
s = cvar->name;
arc.ArchiveString(&s);
@@ -1357,23 +1443,35 @@ qboolean G_ArchiveLevel(const char *filename, qboolean autosave, qboolean loadin
}
}
//
// simple archived entities
//
if (!arc.Loading()) {
num = level.m_SimpleArchivedEntities.NumObjects();
}
arc.ArchiveInteger(&num);
if (arc.Saving()) {
for (i = 1; i <= num; i++) {
arc.ArchiveObject(level.m_SimpleArchivedEntities.ObjectAt(i));
}
} else {
for (i = 1; i <= num; i++) {
arc.ReadObject();
}
}
ArchiveAliases(arc);
// Added in 2.0
G_ArchiveSmokeSprites(arc);
currentArc = &arc;
gi.ArchiveLevel(arc.Loading());
currentArc = NULL;
PathSearch::ArchiveDynamic(arc);
if (arc.Loading()) {
arc.Close();
LoadingSavegame = false;
gi.Printf(HUD_MESSAGE_YELLOW "%s\n", gi.LV_ConvertString("Game Loaded"));
} else {
arc.Close();
gi.Printf(HUD_MESSAGE_YELLOW "%s\n", gi.LV_ConvertString("Game Saved"));
}
if (arc.Loading()) {
// Make sure all code that needs to setup the player after they have been loaded is run
@@ -1387,6 +1485,15 @@ qboolean G_ArchiveLevel(const char *filename, qboolean autosave, qboolean loadin
}
}
if (arc.Loading()) {
arc.Close();
LoadingSavegame = false;
gi.Printf(HUD_MESSAGE_YELLOW "%s\n", gi.LV_ConvertString("Game Loaded"));
} else {
arc.Close();
gi.Printf(HUD_MESSAGE_YELLOW "%s\n", gi.LV_ConvertString("Game Saved"));
}
return qtrue;
}
@@ -1402,10 +1509,10 @@ G_WriteLevel
=================
*/
void G_WriteLevel(const char *filename, qboolean autosave)
void G_WriteLevel(const char *filename, qboolean autosave, byte** savedCgameState, size_t* savedCgameStateSize)
{
game.autosaved = autosave;
G_ArchiveLevel(filename, autosave, qfalse);
G_ArchiveLevel(filename, savedCgameState, savedCgameStateSize, autosave, qfalse);
game.autosaved = false;
}
@@ -1424,11 +1531,11 @@ calling ReadLevel.
No clients are connected yet.
=================
*/
qboolean G_ReadLevel(const char *filename)
qboolean G_ReadLevel(const char *filename, byte** savedCgameState, size_t* savedCgameStateSize)
{
qboolean status;
status = G_ArchiveLevel(filename, qfalse, qtrue);
status = G_ArchiveLevel(filename, savedCgameState, savedCgameStateSize, qfalse, qtrue);
// if the level load failed make sure that these variables are not set
if (!status) {
LoadingSavegame = false;
@@ -1535,32 +1642,95 @@ void G_ClientEndServerFrames(void)
}
}
void G_ClientDoBlends()
/*
===============
G_ClientDoBlends
===============
*/
void G_ClientDoBlends(void)
{
// FIXME: unimplemented
gentity_t* edict;
int i;
for (i = 0, edict = g_entities; i < game.maxclients; i++, edict++) {
if (!edict->inuse || !edict->client || !edict->entity) {
continue;
}
edict->entity->CalcBlend();
}
}
void FindIntermissionPoint()
/*
===============
FindIntermissionPoint
===============
*/
void FindIntermissionPoint(void)
{
// FIXME: unimplemented
SimpleEntity* sent;
SimpleEntity* starget;
vec3_t dir;
sent = static_cast<SimpleEntity*>(G_FindClass(NULL, "info_player_intermission"));
if (!sent) {
level.m_intermission_origin = vec_zero;
level.m_intermission_angle = vec_zero;
return;
}
level.m_intermission_origin = sent->origin;
level.m_intermission_angle = sent->angles;
if (!sent->target.length()) {
return;
}
starget = static_cast<SimpleEntity*>(G_FindTarget(NULL, sent->Target()));
if (!starget) {
return;
}
VectorSubtract(starget->origin, level.m_intermission_origin, dir);
vectoangles(dir, level.m_intermission_angle);
}
/*
===============
G_MoveClientToIntermission
===============
*/
void G_MoveClientToIntermission(Entity *ent)
{
G_DisplayScores(ent);
ent->flags |= FL_IMMOBILE;
}
/*
===============
G_DisplayScores
===============
*/
void G_DisplayScores(Entity *ent)
{
ent->client->ps.pm_flags |= PMF_INTERMISSION;
}
/*
===============
G_HideScores
===============
*/
void G_HideScores(Entity *ent)
{
ent->client->ps.pm_flags &= ~PMF_INTERMISSION;
}
/*
===============
G_BeginIntermission2
===============
*/
void G_BeginIntermission2(void)
{
gentity_t *client;
@@ -1596,6 +1766,11 @@ void G_BeginIntermission2(void)
}
}
/*
===============
G_BeginIntermission
===============
*/
void G_BeginIntermission(const char *map_name, INTTYPE_e transtype, bool no_fade)
{
Entity *camera;
@@ -1643,6 +1818,11 @@ void G_BeginIntermission(const char *map_name, INTTYPE_e transtype, bool no_fade
}
}
/*
===============
G_ExitLevel
===============
*/
void G_ExitLevel(void)
{
static const char *seps = " ,\n\r";
@@ -1744,6 +1924,11 @@ void G_ExitLevel(void)
G_ClientEndServerFrames();
}
/*
===============
G_CheckIntermissionExit
===============
*/
void G_CheckIntermissionExit(void)
{
if (!level.exitintermission && g_maxintermission->value > level.time - level.intermissiontime) {
@@ -1761,11 +1946,21 @@ void G_CheckIntermissionExit(void)
}
}
/*
===============
G_ExitIntermission
===============
*/
void G_ExitIntermission(void)
{
level.exitintermission = qtrue;
}
/*
===============
G_CheckStartRules
===============
*/
void G_CheckStartRules(void)
{
if ((!dmManager.IsGameActive()) && (!dmManager.WaitingForPlayers())) {
@@ -1773,6 +1968,11 @@ void G_CheckStartRules(void)
}
}
/*
===============
G_CheckExitRules
===============
*/
void G_CheckExitRules(void)
{
if (g_gametype->integer) {
@@ -1784,6 +1984,11 @@ void G_CheckExitRules(void)
}
}
/*
===============
G_DisplayScoresToAllClients
===============
*/
void G_DisplayScoresToAllClients(void)
{
gentity_t *ent;
@@ -1798,6 +2003,11 @@ void G_DisplayScoresToAllClients(void)
}
}
/*
===============
G_HideScoresToAllClients
===============
*/
void G_HideScoresToAllClients(void)
{
gentity_t *ent;
+15 -7
View File
@@ -211,6 +211,8 @@ qboolean MM_SlideMove(qboolean gravity)
//
// modify velocity so it parallels all of the clip planes
//
VectorCopy(trace.plane.normal, planes[numplanes]);
numplanes++;
// find a plane that it enters
for (i = 0; i < numplanes; i++) {
@@ -227,10 +229,14 @@ qboolean MM_SlideMove(qboolean gravity)
continue;
}
// slide along the plane
MM_ClipVelocity(mm->velocity, planes[j], clipVelocity, OVERCLIP);
if (DotProduct(clipVelocity, planes[j]) >= 0.1) {
continue; // move doesn't interact with the plane
}
if (DotProduct(clipVelocity, planes[j]) >= 0.0f) {
// slide along the plane
MM_ClipVelocity(clipVelocity, planes[j], clipVelocity, OVERCLIP);
if (DotProduct(clipVelocity, planes[i]) >= 0) {
continue; // move doesn't interact with the plane
}
@@ -246,7 +252,7 @@ qboolean MM_SlideMove(qboolean gravity)
continue;
}
if (DotProduct(clipVelocity, planes[k]) >= 0.1f) {
if (DotProduct(clipVelocity, planes[k]) >= 0.1) {
continue; // move doesn't interact with the plane
}
@@ -398,12 +404,14 @@ void MM_StepSlideMove(void)
bWasOnGoodGround = qfalse;
}
start_o[2] += 18;
VectorCopy(start_o, up);
up[2] += 18;
VectorCopy(mm->origin, nostep_o);
VectorCopy(mm->velocity, nostep_v);
memcpy(&nostep_groundTrace, &mml.groundTrace, sizeof(trace_t));
VectorCopy(start_o, mm->origin);
VectorCopy(up, mm->origin);
VectorCopy(start_v, mm->velocity);
first_hit_wall = mm->hit_obstacle;
@@ -419,7 +427,7 @@ void MM_StepSlideMove(void)
down[2] -= STEPSIZE * 2;
// test the player position if they were a stepheight higher
gi.trace(&trace, start_o, mm->mins, mm->maxs, down, mm->entityNum, mm->tracemask, qtrue, qfalse);
gi.trace(&trace, mm->origin, mm->mins, mm->maxs, down, mm->entityNum, mm->tracemask, qtrue, qfalse);
if (trace.entityNum != ENTITYNUM_WORLD && trace.entityNum != ENTITYNUM_NONE) {
VectorCopy(nostep_o, mm->origin);
VectorCopy(nostep_v, mm->velocity);
Loaded 100 of 348 files, more files were not shown because too many files have changed in this diff. Show more