Compare commits

...
480 Commits
Author SHA1 Message Date
smallmodel 20282ffa56 Fixed +speed having inverted up/down 2023-08-20 14:44:46 +02:00
smallmodel ff4987cc81 Added more screenshots 2023-08-20 14:29:50 +02:00
smallmodel 80a22ca2ed Fixed pm error 2023-08-20 14:13:34 +02:00
smallmodel 51ca0a06a7 Fixed death message color on mohaas/mohaab 2023-08-20 14:11:34 +02:00
smallmodel 010794418c Fixed GetSpectateFollowOrientation using forward rather than right 2023-08-20 14:02:55 +02:00
smallmodel 51b5b2571a Set lean info per game for Pmove 2023-08-20 14:02:33 +02:00
smallmodel 182a677337 Script: use AngleVector rather than AngleVectorsLeft for angles methods 2023-08-20 14:02:04 +02:00
smallmodel 17f6c25bc7 Fixed leaning values in mohaas/mohaab 2023-08-20 13:54:25 +02:00
smallmodel 31d19cb0f6 Fixed score entries on FFA gametype 2023-08-20 13:27:09 +02:00
smallmodel 6c65bba279 Fixed MSG_WritePackedAnimTime not writing the animation time sometimes 2023-08-20 02:33:08 +02:00
smallmodel 8ae15be0de Create AnimationEvent with predefined args 2023-08-20 02:32:10 +02:00
smallmodel 11fb5ee2af Fixed removebot never working 2023-08-20 02:23:49 +02:00
smallmodel b68992e55e Added numArgs parameter 2023-08-20 02:23:41 +02:00
smallmodel 007a7681eb G_ClientDisconnect should print differently on mohaas/mohaab 2023-08-20 02:23:29 +02:00
smallmodel 7d4cdac52c Use WaitTillAllowed for waitTillTimeout, waitTillAny and WaitTillAnyTimeout 2023-08-20 01:46:38 +02:00
smallmodel 916f38e1b2 "roundstart" misspell 2023-08-20 01:43:59 +02:00
smallmodel 39ae88a2ab Remove "roundstart" waittill after the round has started 2023-08-20 01:43:37 +02:00
DJs3000 24f82e8e36 Add new arch (#61)
* Update q_platform.h

add e2k arch

* Update TargetArch.cmake

add e2k arch
2023-08-19 21:59:26 +00:00
smallmodel 247d09a09d Fixed strip on windows 2023-08-19 23:29:23 +02:00
smallmodel 030b291af1 Fixed library locations 2023-08-19 23:29:19 +02:00
smallmodel 9d0a5faed3 Fixed errors 2023-08-19 23:23:36 +02:00
smallmodel 261b15851f Fixed string() when no SDL 2023-08-19 23:10:48 +02:00
smallmodel 2929bd82a5 Removed func_expr as it's not used 2023-08-19 23:08:00 +02:00
smallmodel 4939927975 Fixed length decrease with an higher value 2023-08-19 23:07:47 +02:00
smallmodel f9ef6733b9 Fixed errors on CMake 3.5 2023-08-19 23:07:12 +02:00
smallmodel de08fe7ca3 Fixed linux compile error 2023-08-19 21:21:41 +02:00
smallmodel 482536ff1c Added g_bot.h file 2023-08-19 21:21:32 +02:00
smallmodel 3089cc8bc3 Avoid assigning the token to an str 2023-08-19 21:17:52 +02:00
smallmodel a307450e17 Made sourceLine argument optional to avoid string allocation 2023-08-19 21:12:03 +02:00
smallmodel 50cfc7e5ad Added STRING_VIEWMODELANIM_DONE 2023-08-19 21:06:25 +02:00
smallmodel 5b82cc4f11 Made Event::ErrorInternal const
Fixed ProcessEvent() not handling exceptions
2023-08-19 21:00:04 +02:00
smallmodel a83a76da95 Create an event with the argument count 2023-08-19 20:49:39 +02:00
smallmodel 2e4759ab1f Using m_RunLabel instead of trying to get the game script everytime 2023-08-19 20:49:20 +02:00
smallmodel af056d7646 Create an event with pcmd->num_args 2023-08-19 20:49:03 +02:00
smallmodel 46e57f0a1f Added maxDataSize so the event can be preallocated 2023-08-19 20:48:46 +02:00
smallmodel fe5473bc85 Added Set and SetScript with const_str
Fixed try/catch
2023-08-19 20:48:03 +02:00
smallmodel 1a03288144 SetFastData: Move the ScriptVariable instead of copying it 2023-08-19 20:47:36 +02:00
smallmodel 0c2326480b Avoid reallocation if the assigned ScriptVariable is the same as the other ScriptVariable 2023-08-19 20:47:14 +02:00
smallmodel 24f3b3bc93 Added anyValue union field 2023-08-19 20:46:42 +02:00
smallmodel 459aa89ca2 Check if sourceLength is -1 instead 2023-08-19 20:46:24 +02:00
smallmodel ec8eaacc69 Fixed "vstr" in the nextmap argument 2023-08-19 19:49:28 +02:00
smallmodel 84f55f627e Updated README 2023-08-19 19:41:53 +02:00
smallmodel a30f78e834 Prevent sv_maxbots + sv_maxclients from reaching MAX_CLIENTS 2023-08-19 19:35:20 +02:00
smallmodel d22cda594f Fixed TeamHitScoreLimit() (should use m_teamwins) 2023-08-19 19:34:57 +02:00
smallmodel 8cfa909b73 Reset bots on CleanUp
Fixed issues with WaitTill registration
2023-08-19 18:22:01 +02:00
smallmodel 86a6dd020f Check for WaitTillAllowed instead 2023-08-19 18:21:32 +02:00
smallmodel 556133fa11 Use STRING_ROUNDSTART instead of "roundstart" 2023-08-19 18:20:26 +02:00
smallmodel 4001de1dde Implemented WaitTillAllowed for all classes 2023-08-19 18:10:38 +02:00
smallmodel 7a57a25c58 Reworked the bot system 2023-08-19 17:58:54 +02:00
smallmodel d95cdcc142 Moved bot functions to g_bot.cpp 2023-08-19 16:03:42 +02:00
smallmodel d2a967e577 Don't use the explicit class name to access Entry_allocator 2023-08-19 15:48:50 +02:00
smallmodel 84adaa07e0 Removed reverse_label_list (use label_list enumeration instead) 2023-08-19 15:48:29 +02:00
smallmodel 2efeb7e972 Don't call Unregister with "delete" and "remove" in the destructor as UnregisterAll() will already do it
Don't call CancelPendingEvents() if the event system hasn't started
2023-08-19 15:39:59 +02:00
smallmodel b9655e3f19 Fixed memory leaks: free all memory allocated by the game module 2023-08-19 15:24:37 +02:00
smallmodel dce004ef13 Don't FreeAll() when destructing the block allocator, because it could be executed before containers destruction 2023-08-19 15:24:12 +02:00
smallmodel b9f1530eec G_ShutdownGame: shutdown events and deallocate game data 2023-08-19 15:23:48 +02:00
smallmodel 9b15b27f28 Removed CRT check debug flag 2023-08-19 13:36:54 +02:00
smallmodel ff2e64a742 Fixed a tiny mistake present in all mohaa versions, with a possible overflow in client index in PF_centerprintf and PF_locationprintf 2023-08-19 13:36:12 +02:00
smallmodel 4e38b803fb Fixed G_Random/G_CRandom 2023-08-19 13:32:32 +02:00
smallmodel 9825e1e6f2 Formatted source files 2023-08-19 03:02:30 +02:00
smallmodel b278f2eafa Var integer access fix 2023-08-19 03:00:19 +02:00
smallmodel 25912079db Return NULL for ulist::GetPosition 2023-08-19 03:00:07 +02:00
smallmodel b1753df1ed Reworked con_set and con_arrayset so that they have their own Entry class 2023-08-19 02:56:51 +02:00
smallmodel 03143d1341 Added a compilation flag to debug memory 2023-08-19 02:19:09 +02:00
smallmodel 843b49d56b Allow operator new and operator delete to be called when debugging memory 2023-08-19 02:19:01 +02:00
smallmodel 00644e7605 Alloc() and Free() will call malloc directly when debugging memory 2023-08-19 02:18:41 +02:00
smallmodel 93814bd05b Fixed Skel_Alloc and Skel_Free macros when debugging memory 2023-08-19 02:18:11 +02:00
smallmodel 438ed2c0ea Added a way to debug CRT heap (currently only on Windows with MSVC) 2023-08-19 02:17:45 +02:00
smallmodel 0310475957 Don't make "addbot", "removebot" and "bot" public commands 2023-08-19 02:17:12 +02:00
smallmodel 435bfe1271 Initialize angular_delta to 0 2023-08-19 01:38:38 +02:00
smallmodel 7ca532f0e4 FL_ANIMATE is 0x100000 2023-08-19 01:38:25 +02:00
smallmodel 8c3997f13b Implemented Projectile::Think from mohaas/mohaab 2023-08-19 01:32:54 +02:00
smallmodel d8ae1ce6b9 Added NULL to the end of SmokeGrenade event responses 2023-08-19 01:32:33 +02:00
smallmodel 5cb1e5de84 Fixed Vector_DotProduct returning wrong values 2023-08-19 01:02:18 +02:00
smallmodel 7fd2aff17b Fixed entity trace with no valid trace 2023-08-19 00:58:06 +02:00
smallmodel b9f3ee867b Fixed switch label with "default" case 2023-08-19 00:57:29 +02:00
smallmodel f16b992a97 Fixed assignments with case-insensitive event names 2023-08-19 00:57:19 +02:00
smallmodel 9ba5710412 Fixed variable comparison operators with VARIABLE_CHAR 2023-08-19 00:57:02 +02:00
smallmodel 7e6854f96b Fixed EventPointsWithinDist taking the wrong argument number for the distance 2023-08-19 00:35:48 +02:00
smallmodel aa25ef6c68 Removed EV_Player_UseHeld as there is already EV_GetUseHeld 2023-08-19 00:35:32 +02:00
smallmodel 9db1076603 Fixed VM_StepSlideMove using wrong start/end for gi.trace 2023-08-19 00:35:10 +02:00
smallmodel 7b39218af5 Fixed MASK_VEHICLE 2023-08-19 00:34:56 +02:00
smallmodel ba5b2adf94 Fixed rcon command not working 2023-08-19 00:34:47 +02:00
smallmodel ded7d941ea Call SetAngles(ev) when setting the angles 2023-08-19 00:34:27 +02:00
smallmodel 09ed4e4a1d Fixed grammar priorities of the unuary and complement 2023-08-19 00:34:14 +02:00
smallmodel 9b3aaa0f87 Using string+5 rather than string+(4+1) 2023-08-19 00:33:55 +02:00
smallmodel a274325f43 Fixed wrong bounce sound 2023-08-18 15:30:18 +02:00
smallmodel b0da0b8321 Removed nomonsters
Removed some serverinfo cvars
2023-08-18 15:25:26 +02:00
smallmodel a241ea20fa Removed nomonsters 2023-08-18 15:25:17 +02:00
smallmodel f8d5a5ecd2 Fixed TeamWin with the axis team 2023-08-18 15:13:47 +02:00
smallmodel f20b47ebc0 Fixed newlines when printing the teamwin 2023-08-18 15:10:35 +02:00
smallmodel de10ab8df3 Fixed "is preparing for deployment" message location on mohaas/mohaab 2023-08-18 15:10:23 +02:00
smallmodel 47c7c5a5e3 Renamed centerprint to stringToPrint 2023-08-18 15:10:10 +02:00
smallmodel 80ada3225d Fixed centerprint not working as intended 2023-08-18 15:09:32 +02:00
smallmodel a1745829b2 Added product extension, as breakthrough clients rely on the extension word (like "Spearhead") to set g_servertype variable 2023-08-18 14:54:17 +02:00
smallmodel b2853465ed Capitalize first letter in PRODUCT_EXTENSION 2023-08-18 14:53:39 +02:00
smallmodel c89091b4cd Send gamever and serverType in SVC_Info 2023-08-18 14:53:26 +02:00
smallmodel e5beb0d9b9 Explicitly use GT_SINGLE_PLAYER 2023-08-18 14:53:12 +02:00
smallmodel 80ab513d76 Fixed size() returning 0 when the type is VARIABLE_NONE (must return -1) 2023-08-18 14:14:32 +02:00
smallmodel 854136d85b Fixed spelling mistake 2023-08-18 14:14:11 +02:00
smallmodel 25c417187b Removed flex/bison source files from build
Flex/Bison must be used to generate those files
2023-08-18 01:46:16 +02:00
smallmodel e3e9328ba3 Fixed small mistake when comparing with nextTime 2023-08-18 01:46:00 +02:00
smallmodel 3cc0c41b7b Added ScriptArrayHolder constructor 2023-08-18 01:42:10 +02:00
smallmodel 697013bbbf Fixed grammar priorities with const array 2023-08-18 01:18:18 +02:00
smallmodel 0080d4b9a8 Using ScriptError 2023-08-18 01:18:07 +02:00
smallmodel 8c391ef880 set cvar_modifiedFlags to the difference between flags 2023-08-18 01:09:24 +02:00
smallmodel e6d3ca32f4 In CheckEndMatch, don't put any flag in cvars 2023-08-18 01:09:09 +02:00
smallmodel fab78f933e Using SHORT2ANGLE for ucmd angles 2023-08-17 22:44:27 +02:00
smallmodel 5cd7d89e72 Fixed wrong sv flags being used 2023-08-17 22:38:25 +02:00
smallmodel 15e8146306 Don't hide the HUD when in turret or vehicle 2023-08-17 22:38:09 +02:00
smallmodel 250f1d090e Fixed SanitizeName 2023-08-17 22:37:35 +02:00
smallmodel 03c5864034 Fixed secondarycharge animation 2023-08-17 22:37:09 +02:00
smallmodel 07b7f10912 Fixed UnlimitedAmmo() behavior (use the behavior from mohaas/mohaab) 2023-08-17 21:31:22 +02:00
smallmodel 0e1837db31 Fixed smoke and rifle grenade max ammo 2023-08-17 21:30:57 +02:00
smallmodel 070fe17473 G_PushEntity: use cylinder 2023-08-17 21:30:34 +02:00
smallmodel ba607a0aad Ignore the owner of the passEnt entity 2023-08-17 21:30:21 +02:00
smallmodel 2b38a0f48e Fixed wrong opcode for method event 2023-08-17 21:29:55 +02:00
smallmodel a1fb3b283c Remove clipmask flags for physics_on if it has second parameter specified 2023-08-17 20:13:58 +02:00
smallmodel 12e85aba45 Also check if the groundentity has no movetype 2023-08-17 20:05:30 +02:00
smallmodel 44fe18fef1 Added MASK_SCRIPT_SLAVE 2023-08-17 20:04:58 +02:00
smallmodel 28de2543ec Removed listenerVars as it can cause issues 2023-08-17 19:51:53 +02:00
smallmodel 4435984b81 Renamed label to m_Thread 2023-08-17 19:29:03 +02:00
smallmodel 1435489a43 Fixed floats with negative values 2023-08-17 19:17:16 +02:00
smallmodel 3d20b3a232 Using MASK_SHOT_TRIG for BulletAttack, so it touches triggers 2023-08-17 19:17:02 +02:00
smallmodel 97543622bf Added MASK_SHOT_TRIG
Fixed MASK_SHOT values
2023-08-17 19:16:49 +02:00
smallmodel a9374f068b Added a check to avoid packed from being out of bounds in MSG_PackCoord() 2023-08-17 18:24:50 +02:00
smallmodel d80e9d80e7 Fixed getcvar returning wrong values sometimes 2023-08-17 18:24:30 +02:00
smallmodel 4f757445c4 Set vehicle to be in godmode if the player is in godmode 2023-08-17 18:24:20 +02:00
smallmodel 2749ab92b2 trigger_hurt inherits from Trigger and not TriggerUse 2023-08-17 18:23:53 +02:00
smallmodel 011bee9f33 Implemented MSG_HandleCGMBufferOverflow
Fixed CGM buffer error for non-connected clients
2023-08-17 18:23:24 +02:00
smallmodel 1b86e60548 Implemented all mohaas/mohaab features like animated farplanes, skybox speed/farplane, etc. 2023-08-17 17:39:54 +02:00
smallmodel 23e01fc1a7 Make sure to set m_data.containerValue when copying the value 2023-08-17 17:39:26 +02:00
smallmodel 2c9c80d7bc Don't set the targetname if world doesn't exist
Prevent world from being retargeted
2023-08-17 17:39:12 +02:00
smallmodel 5146b1f36b Made SetTargetName virtual functions 2023-08-17 17:37:43 +02:00
smallmodel bc81fe78b2 Check if the ent is inside the hit entity (this fixes trigger_hurt issues in mp_stadt_dm 2023-08-17 16:10:29 +02:00
smallmodel 4de1b7c73b When showing entities number, add maxs.z offset 2023-08-17 16:09:46 +02:00
smallmodel 3c8c4e9f97 Call SetSize() directly from setModel() 2023-08-17 16:09:29 +02:00
smallmodel c366c10530 Fixed level/parm/game vars being overwritten 2023-08-17 16:09:09 +02:00
smallmodel 6f5106803d Made firstLeafBrush and firstLeafSurface as intptr_t, as sometimes it's an offset to an unrelated memory location (in 64-bit, it could be a very far away memory location) 2023-08-17 16:08:40 +02:00
smallmodel 55a6b7956a Changed event priorities 2023-08-17 16:07:51 +02:00
smallmodel 911d1f1706 Fixed OP_STORE_FIELD and OP_STORE_FIELD_REF 2023-08-17 16:07:38 +02:00
smallmodel 56fba733f3 Always cast targetlist to const array value, so the iteration remains untouched 2023-08-17 03:18:41 +02:00
smallmodel a3c65ef7e4 Fixed containerValue allocation (mustn't allocate a new one) 2023-08-17 03:18:19 +02:00
smallmodel 73bc196592 Fixed cmd execution while iterating over a target list 2023-08-17 03:04:01 +02:00
smallmodel 8487099264 Fixed crash due to improper ScriptPointer usage 2023-08-17 03:03:40 +02:00
smallmodel bdcd0dbd56 Fixed EventEnd copying and adding pointer value 2023-08-17 03:03:26 +02:00
smallmodel 3c2600648c Fixed "immediateremove" wrong spelling 2023-08-17 03:03:08 +02:00
smallmodel f1abfeced6 Fixed grammar for if/while/for statements with a single line and a semi-colon 2023-08-17 02:59:54 +02:00
smallmodel 99bce5a11a Fixed identifiers like "break_formation" being treated as "break" and "_formation" separately 2023-08-17 01:08:37 +02:00
smallmodel ab5a3604bf Fixed grammar like "$(value).field"
Fixed newline in if statements
Fixed if/else being ambiguous
2023-08-17 01:05:55 +02:00
smallmodel fab7d8539c Fixed an extremely nasty bug with libmad: mad.h defines SIZEOF_INT to 4, libmad c files don't include this mad.h file, which mean libmad c files will use 8-bytes int, and snd_codec_mp3.c will use 4-bytes int 2023-08-16 20:53:20 +02:00
smallmodel 0347a5ca0b Renamed MAX_CHANNELS to MAX_SKELETOR_CHANNELS to avoid conflict with sound channels (MAX_CHANNELS) 2023-08-16 20:51:19 +02:00
smallmodel 42ad1cb41c Removed libmad from includes 2023-08-16 20:50:26 +02:00
smallmodel 64e3c18fb9 Removed assertion (not present in mohaa) 2023-08-16 19:22:10 +02:00
smallmodel 7e113359b3 Fixed crash with healrate 2023-08-16 19:14:05 +02:00
smallmodel 467802c466 Fixed crash when loading savegame 2023-08-16 19:13:52 +02:00
smallmodel ce1b3aaee9 Fixed ArchiveAliases
Archive PathSearch
2023-08-16 19:13:38 +02:00
smallmodel 1a53bdd584 Implemented PathSearch::ArchiveDynamic 2023-08-16 18:48:38 +02:00
smallmodel 5521e7654d Fixed number of script classes being replaced by the number of threads, causing archive read to go wrong 2023-08-16 18:29:36 +02:00
smallmodel 73716dd624 Fixed silly mistake in the container archive function 2023-08-16 18:29:06 +02:00
smallmodel 840d23dcac Fixed sizeof(index) 2023-08-16 18:28:50 +02:00
smallmodel 525a0c7c82 Renamed and moved soundSystem_t to snd_local_new.h 2023-08-16 18:14:06 +02:00
smallmodel 46c35057fb Made omohserver an interface 2023-08-16 18:13:47 +02:00
smallmodel 6d03b9763a Using S_LoadData 2023-08-16 18:13:30 +02:00
smallmodel 9eaecb0a2a Fixed a crash when loading a script, on non-MSVC binaries 2023-08-16 16:07:42 +02:00
smallmodel c274af839e Updated README 2023-08-16 13:27:29 +02:00
smallmodel f9232840e4 Fixed sprint not working 2023-08-16 13:17:01 +02:00
smallmodel 3ea40fda82 Fixed runspeed values 2023-08-16 13:16:56 +02:00
smallmodel c357c2614a Added DEBUG_DROP_ASSERT CMake definition 2023-08-16 13:16:04 +02:00
smallmodel efed6d0eac Fixed script developer printf 2023-08-16 02:43:22 +02:00
smallmodel 244220f031 Fixed spawnpoint issues due to trace mask 2023-08-16 02:37:57 +02:00
smallmodel 7ce87575bc Added MASK_PLAYERSTART 2023-08-16 02:37:25 +02:00
smallmodel 401cfeda65 Make sure to not call CanSeeEnemy() if the enemy is NULL 2023-08-16 02:31:30 +02:00
smallmodel a45a8c7742 Fixed sentient linking/unlinking 2023-08-16 02:31:12 +02:00
smallmodel c80b360918 Fixed "ignoreclock" event name 2023-08-16 02:22:39 +02:00
smallmodel 8514ef6ef8 Fixed Objective::SetText event parameter 2023-08-16 02:18:23 +02:00
smallmodel 9b1dc34ea1 Fixed score data for mohaas/mohaab 2023-08-16 02:08:00 +02:00
smallmodel f5490321e7 Set default explosion to "fx/fx_explosion.tik" 2023-08-16 02:04:28 +02:00
smallmodel 1f4393e3b2 Call DM_Team::AddKills when the player got killed 2023-08-16 01:32:53 +02:00
smallmodel 8aa6a16a27 Export g_TOWObjectiveMan 2023-08-16 01:32:07 +02:00
smallmodel 286f553a54 Fixed uninitialized variable 2023-08-16 01:06:51 +02:00
smallmodel f0ec50e37b Implemented UIRadar::Draw() 2023-08-16 00:45:40 +02:00
smallmodel c1ee0332e3 Fixed parameter of Draw_StretchPic2 2023-08-16 00:45:26 +02:00
smallmodel d2737f2b40 Fixed CL_UnpackNonPVSClient not unpacking the clientNum 2023-08-16 00:45:12 +02:00
smallmodel 0d501ec38a Fixed CG_SameTeam always returning true 2023-08-16 00:44:44 +02:00
smallmodel d39e6421fe Call CG_UpdateRadarClient() in CG_AddCEntity 2023-08-16 00:44:30 +02:00
smallmodel c2125947ab Removed R_RegisterSkin 2023-08-16 00:20:16 +02:00
smallmodel 953a33a6ff Call CG_InitRadar and restore saved cgame state 2023-08-16 00:20:10 +02:00
smallmodel 883e7884c4 Updated README 2023-08-16 00:19:30 +02:00
smallmodel 508903c3b1 Moved console_spam_filter to Com_Init 2023-08-16 00:08:35 +02:00
smallmodel 9116063d3f Added CL_RestoreSavedCgameState and CL_RestoreSavedCgameState 2023-08-16 00:08:24 +02:00
smallmodel e2a0d2d01e Fixed function parameter 2023-08-16 00:07:45 +02:00
smallmodel 5343949254 Implemented Draw_StretchPic2 2023-08-15 23:52:22 +02:00
smallmodel c17454b124 Renamed bValid to teamShader 2023-08-15 23:24:23 +02:00
smallmodel 4f8dc5dc2a Added radar variables 2023-08-15 22:47:11 +02:00
smallmodel 0fea47bb69 Added Draw_StretchPic2 2023-08-15 22:44:37 +02:00
smallmodel 47665fcd70 Added CL_ReadNonPVSClient and CL_UnpackNonPVSClient 2023-08-15 22:22:35 +02:00
smallmodel 968b073338 Implemented client-game radar code 2023-08-15 22:21:44 +02:00
smallmodel 03582bb59a Added radars and radarShaders in cg_t 2023-08-15 22:21:24 +02:00
smallmodel 149d3ce2fc Added CL_InitRadar 2023-08-15 22:21:01 +02:00
smallmodel fe5e151d89 Added YawToAxis 2023-08-15 22:20:33 +02:00
smallmodel 06a7341eda Moved radarUnpacked_t from server.h to q_shared.h 2023-08-15 22:20:25 +02:00
smallmodel 456ed42e14 Implemented the radar system for non-pvs clients 2023-08-15 19:29:12 +02:00
smallmodel 2337f93df8 Added console_spam_filter 2023-08-15 19:28:38 +02:00
smallmodel ad675b05ac Better wording 2023-08-15 18:09:22 +02:00
smallmodel 44f6de9524 Added riscv and riscv64 2023-08-15 16:45:13 +02:00
smallmodel e25605b898 Updated README 2023-08-15 16:02:02 +02:00
smallmodel 919d14e329 Fixed README 2023-08-15 15:24:56 +02:00
smallmodel 8fc64cd1b1 Using libsdl-org/setup-sdl Github Actions 2023-08-15 15:16:00 +02:00
smallmodel 028a7d6125 Setup SDL for CodeQL 2023-08-15 13:35:16 +02:00
smallmodel 60b9a6e2e0 renamed to playerstart.h 2023-08-15 13:16:36 +02:00
smallmodel 9ad515335a Added g_utils.h 2023-08-15 13:04:18 +02:00
pryon 7593ea53f9 Fix generated executable/lib names missing the -dbg postfix on Visual Studio (#55)
* Fix generated executable/lib names missing the -dbg postfix on Visual Studio

* Spaces to tabs
2023-08-15 10:57:36 +00:00
smallmodel 07374ba1ed Compilation errors fixes 2023-08-15 12:47:49 +02:00
smallmodel 2deba01a5f Updated the README 2023-08-15 01:42:49 +02:00
smallmodel 3daee90b5b Moved functions from game.cpp/game.h to where they should be (g_main, g_utils) 2023-08-15 01:41:35 +02:00
smallmodel c4ba60afbd Added TRANS_BSP to G_BeginIntermission 2023-08-15 01:38:55 +02:00
smallmodel 81e9ce10cd Fixed warning spam if the default value is different 2023-08-15 01:27:54 +02:00
smallmodel c4738966fe Using g_utils.cpp from fakk 2023-08-15 01:27:35 +02:00
smallmodel 0eedc4e2f8 Fixed compilation warnings 2023-08-15 01:26:58 +02:00
smallmodel 14f9368575 Implemented all setters/getters
7 remaining important methods to implement
2023-08-15 00:24:07 +02:00
smallmodel 394546dee7 Added means of death strings 2023-08-14 23:37:14 +02:00
smallmodel e86e5c0d80 Renamed MOD_MINE to MOD_LANDMINE
Added MOD_AAGUN
2023-08-14 23:37:05 +02:00
smallmodel e0b5a62c4f Allow obj maps to be loaded in any game types 2023-08-14 20:44:46 +02:00
smallmodel 7fb42cf655 Fixed message printing on mohaas/mohaab 2023-08-14 20:44:28 +02:00
smallmodel 819f6bcf71 Using DM_Manager::CheckEndMatch() algorithm from mohaab 2.40 2023-08-14 20:35:23 +02:00
smallmodel ad47f8855b Implemented TOW Entities 2023-08-14 19:54:50 +02:00
smallmodel a50102ef52 Changed CONTROLLER_BOTH to CONTROLLER_DRAW
Added GetObjectiveIndex()
2023-08-14 19:53:35 +02:00
smallmodel 0b2a0634f5 Moved eController to Entities.h 2023-08-14 19:21:17 +02:00
smallmodel 8ea32fee31 Added Entities with all classes, methods and events (unimplemented) 2023-08-14 19:20:53 +02:00
smallmodel f0571385d5 Export events for AISpawnPoint 2023-08-14 19:00:16 +02:00
smallmodel 83318af532 Export EV_Weapon_SetProjectile 2023-08-14 17:43:28 +02:00
smallmodel 860c9b33ef Made AddObjective and SetCurrentObjective static 2023-08-14 15:02:25 +02:00
smallmodel ecbd6ae282 Renamed WITH_CLIENT to BUILD_NO_CLIENT 2023-08-14 13:31:42 +02:00
smallmodel 3ec799d150 Compiled parser 2023-08-14 03:15:48 +02:00
smallmodel 72715c1a85 Fixed CL_Disconnect being passed with arguments 2023-08-14 03:15:42 +02:00
smallmodel 16d262f6ee Fixed floats being interpreted as integers sometimes 2023-08-14 03:09:38 +02:00
smallmodel 49850940d6 Using objective flags enumeration 2023-08-14 02:39:32 +02:00
smallmodel e634fb5022 Using objective flags enum 2023-08-14 02:34:06 +02:00
smallmodel c0726f0634 Added objective status and flags enum 2023-08-14 02:33:59 +02:00
smallmodel 91dc3e5884 Fixed configstring index because of denormalization 2023-08-14 02:24:48 +02:00
smallmodel ba2c3ed5fd Fixed lean on protocols before 2.0 2023-08-14 02:12:30 +02:00
smallmodel 161f7e3313 Fixed wrong current objective
Added support for objective location per team
2023-08-14 02:11:26 +02:00
smallmodel f2f7afadef Don't resend the game state if the serverId is the same as the restarted server Id 2023-08-14 01:57:02 +02:00
smallmodel 0898bffb43 Fixed getboundkey1/getboundkey2 crashing when the key is null 2023-08-14 01:56:43 +02:00
smallmodel 99dc7bf7f2 Fixed CL_MapLoading always flushing 2023-08-14 01:56:25 +02:00
smallmodel 64acea9018 Call SV_CheckSaveGame in Com_Frame 2023-08-14 01:27:25 +02:00
smallmodel 8e05347ba0 Moved CL_FinishedIntro and SV_CheckSaveGame to qcommon.h 2023-08-14 01:27:13 +02:00
smallmodel 07e90d37ee Fixed bad angle 2023-08-14 00:22:25 +02:00
smallmodel 71bd04e5b2 Fixed weapon bullet trace
Fixed projectile being always removed in single-player mode
2023-08-14 00:22:05 +02:00
smallmodel 95510279ed Fixed trigger having no contents when a model is set 2023-08-14 00:21:44 +02:00
smallmodel f1502833b2 Fixed primary/secondary attacks not working 2023-08-13 23:21:11 +02:00
smallmodel e6448697d3 Let cg cleanup temp models
Fixed server restart
2023-08-13 23:20:51 +02:00
smallmodel 5a96d6dd96 Added snd_local_new for new local functions 2023-08-13 23:20:15 +02:00
smallmodel 8d6b3d0bd8 Added cg_archive and cg_radar (unimplemented) 2023-08-13 23:20:00 +02:00
smallmodel 1fd0cd097f Fixed the objective index 2023-08-13 22:08:10 +02:00
smallmodel 421126db38 Optimized ScriptVM::EventGoto 2023-08-13 22:07:33 +02:00
smallmodel 7258a2e972 Fixed CG_DrawObjectives stack overflow 2023-08-13 22:07:19 +02:00
smallmodel df66ab0339 Fixed EmitField bug
Clear the previous opcode when a new label is emitted
2023-08-13 21:55:22 +02:00
smallmodel c49d0c7afa Fixed iprintln(bold) not working properly with multiple arguments 2023-08-13 20:22:39 +02:00
smallmodel 421b3d6375 Fixed crouch on mohaa and mohaas/mohaab 2023-08-13 20:20:36 +02:00
smallmodel 11ef489225 Added basic implementation of sound callback
Implemented S_IsSoundPlaying
2023-08-13 20:20:17 +02:00
smallmodel e1da6797c5 Using S_FLAG_DO_CALLBACK 2023-08-13 20:19:51 +02:00
smallmodel 430c7d1a57 Fixed ScriptCheck always failing regardless of the g_scriptcheck value 2023-08-13 20:19:40 +02:00
smallmodel d3794c0dd9 Fixed bad event when using '$' key 2023-08-13 20:19:26 +02:00
smallmodel eef1368083 using g_gametype variable directly instead of using Cvar_VariableValue 2023-08-13 20:19:03 +02:00
smallmodel 6dfefa04f5 Fixed SV_AllowSaveGame always returning true 2023-08-13 20:18:46 +02:00
smallmodel 8b17d81545 Fixed variables improperly used on stack under some circumstances 2023-08-13 20:17:59 +02:00
smallmodel ec58ca0f13 Added S_FLAG_DO_CALLBACK 2023-08-13 20:17:33 +02:00
smallmodel 3fd87f90a2 Fixed objectives not showing properly 2023-08-13 20:17:23 +02:00
smallmodel 9f268b0f6a Using Director.Pause() instead 2023-08-13 17:59:59 +02:00
smallmodel f857116f75 Fixed script crashes 2023-08-13 17:59:49 +02:00
smallmodel ea78d96bc3 Fixed disabled view model animation
Fixed pmove viewheight
2023-08-13 17:59:41 +02:00
smallmodel 0be9e69833 Added protocol for pmove_t for PM_CheckDuck 2023-08-13 17:59:21 +02:00
smallmodel 8171641e3a Fixed "dmmessage" not being logged (it's a bug in all versions of mohaas/mohaab) 2023-08-13 16:13:08 +02:00
smallmodel ee6014a30f Fixed Player::CondCheckMovementSpeed returning wrong value (expects it to return true if below the weapon's max fire movement) 2023-08-13 16:11:59 +02:00
smallmodel 16c22a3ee5 Added "idle0", "idle1", "idle2" view model animations
Fixed respawn time after death
Fixed Sentient not switching to the primary weapon when spawning
Fixed weapon select not showing
Initialize all Player variables
Remove projectiles when switching teams
Set viewmodelanim to disabled when reaching the weapon's max fire movement
2023-08-13 16:11:25 +02:00
smallmodel 571e48fecf Call Weapon::Charge in Sentient::ChargeWeapon
Don't charge again if sentient is already charging weapon
2023-08-13 16:07:46 +02:00
smallmodel 973d7c5f34 Implemented Weapon::Charge
Cancel overcooked events in Weapon::ReleaseFire
2023-08-13 16:07:11 +02:00
smallmodel a1c5ca288a Renamed m_iOwnerTeam to m_iTeam
Implemented SetFuse, ArcToTarget, BecomeBomb, and DieInwater
Fixed projectile life being wrong when charging
2023-08-13 16:06:49 +02:00
smallmodel e330d00565 Added dmmessage monitoring 2023-08-13 14:19:14 +02:00
smallmodel 6feeb21e21 Fixed uninitialized angular delta variable 2023-08-13 14:19:05 +02:00
smallmodel bb5cf24d5f Fixed "isabandoned" mispelling 2023-08-13 03:34:28 +02:00
smallmodel 0dda70cca1 Fixed event parameters being wrong 2023-08-13 03:34:19 +02:00
smallmodel 5e83e03e33 Major grammar/lexer/compiler fixes 2023-08-13 03:34:09 +02:00
smallmodel d2b3f6c12b Added stub yacc / lex 2023-08-12 20:00:12 +02:00
smallmodel f5af33b181 Major script engine fixes 2023-08-12 19:59:40 +02:00
smallmodel 0da1ed8764 Fixed canseenoents having the wrong name 2023-08-12 19:59:17 +02:00
smallmodel 8aa6f29c4c Added all script functions from mohaas/mohaab 2023-08-12 14:02:43 +02:00
smallmodel 1b7a4442d3 Added no_fade parameter to G_BeginIntermission 2023-08-12 14:00:14 +02:00
smallmodel a163df993c Added MOD_MINE_EXPLOSION 2023-08-12 13:59:56 +02:00
smallmodel 2787007b9d Cleaned up class 2023-08-12 03:10:10 +02:00
smallmodel cea2c178b5 Fixed header 2023-08-12 03:05:06 +02:00
smallmodel 77a9cd5a9a Call Director.Unpause() to execute running scripts 2023-08-12 03:04:31 +02:00
smallmodel ec3259271e Removed THREAD_CONTEXT_SWITCH 2023-08-12 03:03:34 +02:00
smallmodel ae02abba3b Cleaned up ScriptMaster 2023-08-12 03:03:26 +02:00
smallmodel bf960f6f32 Cleaned up ScriptThread 2023-08-12 02:40:30 +02:00
smallmodel 66a1087099 Moved ScriptMaster methods here 2023-08-12 02:40:03 +02:00
smallmodel c1a431f857 Added all mohaas/mohaab features (SetWeaponIdleState, PingForMines, ForceLandmineMeasure, ForceDropWeapon and ForceDropHealth)
Set m_fDamageMultipliers depending on whether or not g_realismmode is set
Minor fixes in the sentient constructor
2023-08-12 00:49:07 +02:00
smallmodel dac5279a59 Archive is_paused and angular_delta 2023-08-12 00:47:39 +02:00
smallmodel a175ea27d7 Cleanup weapon class
Added ShowInfo, SetItemSlot and SetIdleState
2023-08-12 00:10:47 +02:00
smallmodel ddac42e21e Call Weapon::GetZoom() instead 2023-08-11 23:54:43 +02:00
smallmodel 34535ad415 Moved AnimationEvent from Animate to a separate source file 2023-08-11 21:48:25 +02:00
smallmodel c0597e441c Moved AnimationEvent from Animate to a separate source file
Implemented whole animate class from mohaas/mohaab
2023-08-11 21:30:47 +02:00
smallmodel 04b66684dd Added a function to get an animation's angular delta over time 2023-08-11 21:11:16 +02:00
smallmodel 244a2e66f9 Added TIKI_Anim_DeltaOverTime 2023-08-11 21:10:29 +02:00
smallmodel 55b737e730 Set global channel from local to -1 2023-08-11 21:10:14 +02:00
smallmodel 059dacf2a7 Added GetAngularDeltaOverTime() to return the animation's angular delta over time 2023-08-11 21:09:47 +02:00
smallmodel 41f7003747 Fixed SetPlayerView, SetupView, PlayerAngles
UpdateStats changes:
- Added support for allied and axis objective locations
- Vehicle health
- Healrate
- Secondary ammo
2023-08-11 03:13:36 +02:00
smallmodel 64ba900511 Use GetRemoteOwner() properly 2023-08-11 03:09:33 +02:00
smallmodel e371b4bbd3 Replaced unused stats 2023-08-11 03:09:19 +02:00
smallmodel aa44150525 Added some mohaas/mohaab methods (stubs) 2023-08-11 03:09:10 +02:00
smallmodel 3572be718a Use usercmd_s instead of usercmd_t 2023-08-11 03:08:56 +02:00
smallmodel a56d74814b Try to play pain animation in DamageFeedback 2023-08-11 01:58:22 +02:00
smallmodel 8d41b58635 Using hitloc enum instead of macros 2023-08-11 01:34:21 +02:00
smallmodel e80f326ee6 Proper implementation of DamageFeedback 2023-08-11 01:21:50 +02:00
smallmodel c5bd64912a Added MOVETYPE_PORTABLE_TURRET 2023-08-11 01:21:29 +02:00
smallmodel 8a808b616e Apply fall damage differently on mohaas/mohaab
Ignore world effects if no-cliping
2023-08-11 00:54:15 +02:00
smallmodel 91bb2f2e0b Enable god mode for the vehicle the player is in 2023-08-11 00:48:09 +02:00
smallmodel aa4e6a0651 Removed SpawnDamageEffect
DoUse: Call RemoveFromVehiclesAndTurretsInternal() directly
Use G_PMDrawTrace if sv_drawtrace is above 1
Set allow lean while moving
Disable movement prediction if player is glued onto something
Multiply the speed by the weapon movement speed
Added Teamkill warn and kick
Added support for invulnerability, sprint and team spawn
Added support for heal rate
Added talk icon
2023-08-11 00:43:40 +02:00
smallmodel 8e9ff2b289 Added G_PMDrawTrace 2023-08-11 00:13:29 +02:00
smallmodel d53ab8540e Fixed Unix compilation warnings/errors 2023-08-10 23:06:03 +02:00
smallmodel 7b133e5b2f Fixed const param 2023-08-10 23:04:47 +02:00
smallmodel 2b72959935 Call Obituary if there is also an inflictor
Clear pain animation when killed
Increment team kills count when a teammate was killed
2023-08-10 21:38:37 +02:00
smallmodel 82d0b62631 Implemented EndAnim_Pain 2023-08-10 21:37:53 +02:00
smallmodel 7205e27c8c Using death messages implementation from mohaas/mohaab 2023-08-10 21:26:28 +02:00
smallmodel c8d1248d86 Added MOD_MINE means of death 2023-08-10 21:26:07 +02:00
smallmodel 845e4556ef Added g_obituarylocation (openmohaa-specific parameter) 2023-08-10 21:23:10 +02:00
smallmodel a92bfbde40 Fixed variable names 2023-08-10 21:22:50 +02:00
smallmodel 999b6409b3 Fixed InitEdict, InitHealth
InitModel: IT/SC skins support, and voiceType fix
Respawn: Set invulnerability
2023-08-10 20:14:34 +02:00
smallmodel 0ae0be4047 Added more ammo to initialize
Added stopwatch parameter for mohaas/mohaab
Initialize mine variables in InitState
2023-08-10 19:36:14 +02:00
smallmodel fc7029c271 Added stopwatch type 2023-08-10 19:32:21 +02:00
smallmodel 307ee117bd Initialize invulnerability
Set the player view accordingly when choosing a spawn point
Don't set m_fDamageMultipliers in realism mode
Score isn't processed in single-player anymore
2023-08-10 19:14:51 +02:00
smallmodel 087d28eb9a Added GT_TOW and GT_LIBERATION for SelectSpawnPoint() 2023-08-10 19:11:39 +02:00
smallmodel 1deea345bc Renamed team to teamnum 2023-08-10 18:49:57 +02:00
smallmodel e0fa706f6c Implemented EquipWeapons, Stats, TickTeamSpawn, UserSelectWeapon, AllowTeamRespawn and EventKillAxis 2023-08-10 18:48:46 +02:00
smallmodel cf794d2b95 Added DF_OLD_SNIPER and DF_DISALLOW_KAR98_MORTAR 2023-08-10 18:42:13 +02:00
smallmodel 391e82bb92 Formatted source files 2023-08-10 18:41:49 +02:00
smallmodel 83a44b3158 Implemented RemoveFromVehiclesAndTurretsInternal 2023-08-10 17:01:55 +02:00
smallmodel 8cd0e6c5bf Added FixedTurret, PortableTurret and CarryableTurret (unimplemented) 2023-08-10 17:01:43 +02:00
smallmodel 619ab00035 Added player-specific methods 2023-08-10 17:01:19 +02:00
smallmodel 4ded5c3380 Added EV_Weapon_SetAmmoClipSize declaration 2023-08-10 17:00:51 +02:00
smallmodel 85fa2185f8 Added DetachRemoteOwner 2023-08-10 17:00:38 +02:00
smallmodel ab39259bbe Moved vote options stuff to bg_voteoptions.h 2023-08-10 17:00:17 +02:00
smallmodel 9bf2065d18 Implemented battle language methods and GetTeamDialogPrefix/GetNationalityPrefix 2023-08-10 14:18:40 +02:00
smallmodel ceb121d588 Added MASK_BATTLELANGUAGE 2023-08-10 14:14:50 +02:00
smallmodel e7dbc25ca0 Made entity parameter a constant instance 2023-08-10 14:14:39 +02:00
smallmodel 7386784765 Renamed clientPersistant_t to client_persistant_t
Named client_peristant_t fields correctly
2023-08-10 13:34:04 +02:00
smallmodel 9062952539 Implemented GiveNewWeaponsCheat, GetSpectateFollowOrientation, EnsurePlayerHasAllowedWeapons, SetPlayerSpectateRandom, RetrieveVoteOptions and GetNationalityPrefix
mohaas/mohaab fixes
2023-08-10 13:31:35 +02:00
smallmodel 9f0a479c3b added playerAnimSlot_t enum 2023-08-10 13:30:32 +02:00
smallmodel 517b9296dc Using sv_walkspeedmult instead of sv_walkspeed 2023-08-10 12:09:07 +02:00
smallmodel 3ca09613e1 Fixed string constants 2023-08-10 12:08:53 +02:00
smallmodel ba931cbedf Added all mohaas/mohaab cvars 2023-08-10 12:04:45 +02:00
smallmodel 090b354b23 Added all mohaas/mohaab events, methods (partially implemented) 2023-08-10 03:56:13 +02:00
smallmodel dd30bfde15 Set protocol from com_protocol 2023-08-10 03:55:50 +02:00
smallmodel 477735cb3d Cleanup player class
Added all mohaas/mohaab methods (partially implemented)
2023-08-10 03:46:28 +02:00
smallmodel 38599f2181 Added more cvars 2023-08-10 03:45:38 +02:00
smallmodel bd794fb286 Cleanup Level 2023-08-10 03:10:51 +02:00
smallmodel ce34b78113 Added CL_LV_ConvertString
Only CL messages are localized now (see comment)
2023-08-10 02:42:57 +02:00
smallmodel b8a87dc6ea Using dm_manager.h instead of dm_team.h 2023-08-10 02:31:48 +02:00
smallmodel 7bdc30936c Added G_SetClientConfigString 2023-08-10 02:31:09 +02:00
smallmodel 9e635a7207 Rearranged DM_Manager
Moved dm_team.cpp code to dm_manager.cpp
2023-08-10 02:31:01 +02:00
smallmodel e5626378ef Added m_bIgnoreClock 2023-08-10 01:42:24 +02:00
smallmodel 73921c116d Made FireWeapon and EventUseWeaponClass virtual methods 2023-08-10 01:42:06 +02:00
smallmodel d4b98ef9dd Added sprint, invulnerable and team spawn variables 2023-08-10 01:41:03 +02:00
smallmodel 40318f052a Set GAMEVERSION to OPENMOHAA 2023-08-09 23:49:47 +02:00
smallmodel a130f45c62 Added GetViewAngles, SetFov and GetFov
Removed SwingAngles
2023-08-09 23:49:38 +02:00
smallmodel e687d97660 Fixed compile errors 2023-08-09 23:48:37 +02:00
smallmodel e4a0406fc2 Removed Player::PlayerDone
Using Player::DeadBody with the event parameter
2023-08-09 23:11:39 +02:00
smallmodel ef18c389be Cleanup entity class
Added new parameter for CanSee
Added Entity::SafeSolid and Entity::Sink
2023-08-09 23:09:09 +02:00
smallmodel 85099801ab Call Player::DeadBody() with the event function instead 2023-08-09 22:09:04 +02:00
smallmodel 3472657f92 Added MASK_SAFESOLID 2023-08-09 22:08:37 +02:00
smallmodel c197513ff3 Fixed mismatched endif 2023-08-09 21:00:56 +02:00
smallmodel 9dca77c2cf Fixed setModel() virtual function 2023-08-09 20:58:36 +02:00
smallmodel f08a7fa21e Removed Player::useWeapon 2023-08-09 20:58:07 +02:00
smallmodel 2df56c810d Set Entity's entnum directly 2023-08-09 20:57:53 +02:00
smallmodel 8c6098f730 Removed SimpleEntity::SetTargetViewAngles() 2023-08-09 20:57:45 +02:00
smallmodel 1462d4f8d9 Removed StunAttack (useless) 2023-08-09 20:57:26 +02:00
smallmodel 5bd49304d7 Cleaned up SimpleEntity 2023-08-09 20:57:17 +02:00
smallmodel f52d648d6f Added InteractObject and ThrowObject 2023-08-09 20:49:43 +02:00
smallmodel 987af7eb81 Cleaned up Sentient class
Moved combat stuff to sentient_combat.cpp
Formatted source files
2023-08-09 19:45:39 +02:00
smallmodel f313b6a058 Formatted item source files 2023-08-09 16:54:38 +02:00
smallmodel 99b989bb63 Added DynItem
Removed unused features
Added remaining mohaa functions
2023-08-09 16:37:08 +02:00
smallmodel 7ebbba6ce5 Made Class::warning and Class::error const methods 2023-08-09 01:53:45 +02:00
smallmodel c2a6db15a6 Reordered and removed useless functions 2023-08-09 01:32:23 +02:00
smallmodel aa58bcf948 Using const_str for trigger 2023-08-09 00:54:06 +02:00
smallmodel fa5b030522 Cleaned up trigger source file 2023-08-09 00:42:09 +02:00
smallmodel 3e44049abf Removed unused trigger features 2023-08-08 23:51:46 +02:00
smallmodel 94c501e71b Formatted document 2023-08-08 23:46:45 +02:00
smallmodel 484b2a8900 Implemented TriggerAll 2023-08-08 23:35:01 +02:00
smallmodel e8ff4fb9a7 Fixed wrong TRIGGER_DAMAGE value 2023-08-08 23:06:28 +02:00
smallmodel b89e10fd5c Reordered conditions 2023-08-08 22:40:23 +02:00
smallmodel d86ea606eb Formatted source files 2023-08-04 00:21:19 +02:00
smallmodel 2135be12b8 Implemented all unimplemented conditions 2023-08-04 00:20:28 +02:00
smallmodel ae5d51f2e9 Reworked the player class
Added player_animation.cpp and player_conditionals.cpp
Renamed conditions functions and moved them to player_conditionals.cpp
2023-08-04 00:04:29 +02:00
smallmodel 6eaf25ff80 Using const for CurrentAnim() and CurrentTime() 2023-08-04 00:03:55 +02:00
smallmodel 17c371c15e Added Entity::BlocksAIMovement 2023-08-03 21:44:16 +02:00
smallmodel 13febc125e Renamed weapon to dm_primary 2023-08-03 21:44:05 +02:00
smallmodel b0f26acc18 Fixed max movement time 2023-08-03 21:43:50 +02:00
smallmodel 8ffa5f15e6 Implemented BulletAttack from mohaas/mohaab
Added more explosion effects
2023-08-03 21:43:38 +02:00
smallmodel f6bcc1ab86 Increased MAX_WEAPONS to 64 2023-08-03 20:14:33 +02:00
smallmodel a4d6442526 Call BulletAttack_Stat instead of putting everything in BulletAttack
Fixed some BulletAttack bugs
2023-08-02 23:09:18 +02:00
smallmodel b7fac3a5b0 Added BulletAttack_Stat 2023-08-02 21:58:47 +02:00
smallmodel 64ebf3ed05 Implemented all landmine related functions 2023-08-02 21:50:11 +02:00
smallmodel 9933612607 Added ScriptVariableList::VariableExists 2023-08-02 21:49:03 +02:00
smallmodel 22ff072b54 Made findKeyValue and findKeyEntry const 2023-08-02 21:48:54 +02:00
smallmodel 73b0a84ad0 Added MASK_LANDMINE_PLACE 2023-08-02 21:05:49 +02:00
smallmodel 7b03f953bf Added Level::RoundStarted 2023-08-02 21:02:19 +02:00
smallmodel 367d6ff6fc Added and implemented TriggerNoDamage, TriggerEntity and TriggerLandmine 2023-08-02 21:00:16 +02:00
smallmodel ca61fde54b Added ScriptThreadLabel::Execute() with safeptr listener, and optionally another listener 2023-08-02 20:59:54 +02:00
smallmodel f739588c73 Cleaned up Player class from all unused action anim
Added all mohaas/mohaab fields
Added m_sDmPrimary to get the player's primary weapon
2023-08-02 20:59:19 +02:00
smallmodel ce02d782c4 Removed Player::FindEnemyInFOV and Player::FindEnemyInFOVFromTagWithOffset (unused) 2023-08-02 20:59:15 +02:00
smallmodel a498b11e20 Added MASK_LANDMINE 2023-08-02 20:56:19 +02:00
smallmodel ffa5a91cd2 Added Landmine and Defuse fire types for Shoot
Added GetUseCrosshair()
2023-08-02 19:53:14 +02:00
smallmodel ae680ffd5d Added Landmine functions from mohaab
Added more parameters for BulletAttack and FakeBulletAttack from mohaas/mohaab
2023-08-02 19:52:04 +02:00
smallmodel 4c17d12fc6 Added new fire types
Added GetFireAnim()
Using m_sTagBarrel rather than an hardcoded tag name
2023-08-01 21:18:35 +02:00
smallmodel 0259f1a251 Reworked Weapon::ReadyToFire and Weapon::PickupWeapon with mohaas/mohaab features 2023-08-01 20:36:52 +02:00
smallmodel 04708aeb67 Fixed CurrentFrame() not found error 2023-08-01 19:59:32 +02:00
smallmodel a47eb1653e Override animation functions from entity 2023-08-01 19:59:19 +02:00
smallmodel 10fda39430 Added animation functions 2023-08-01 19:59:05 +02:00
smallmodel b2be03cce3 Initialize all weapon vars, including mohaas/mohaab variables 2023-08-01 19:31:25 +02:00
smallmodel 84ecf838d4 Optimized G_Command_ProcessFile a little bit 2023-08-01 19:31:08 +02:00
smallmodel c115796137 Optimized GetValue() so it moves value instead of copying it 2023-08-01 19:30:28 +02:00
smallmodel 7e054c8beb Implemented all mohaas/mohaab events 2023-07-31 23:41:53 +02:00
smallmodel e8df36998e Added mohaas/mohaab variables 2023-07-31 23:41:45 +02:00
smallmodel 0cc558f757 Added overcooked field 2023-07-31 23:41:01 +02:00
smallmodel 5c9bc074f4 Removed fov variable (was useless) 2023-07-31 23:40:39 +02:00
smallmodel d89175ebc8 Added "always" parameter for alias registration 2023-07-30 23:02:13 +02:00
smallmodel 727eb71995 Added all mohaas/mohaab entity events 2023-07-30 21:21:00 +02:00
smallmodel 3d48c00902 Added g_realismmode 2023-07-30 20:21:18 +02:00
smallmodel 963318264c Added SV_HitEntity from mohaab 2023-07-30 20:21:08 +02:00
smallmodel d9123799d6 Added CONTENTS_CLAYPIDGEON 2023-07-30 19:48:43 +02:00
smallmodel 6562bcb164 Added mohaas/mohaab weapon events (unimplemented) 2023-07-30 19:41:11 +02:00
smallmodel 4fa8af3b30 Smoke system implementation from mohaas/mohaab 2023-07-30 16:09:54 +02:00
smallmodel 3f4be4f8ef Added MASK_SMOKE_SPRITE 2023-07-30 16:09:36 +02:00
smallmodel 09c7badf4f Added g_debugsmoke cvar 2023-07-30 16:09:22 +02:00
smallmodel 7b9b371cf6 Added RotatePointAroundAxis 2023-07-30 15:42:59 +02:00
smallmodel 25e44e7a45 Added stub source files from mohaas/mohaab 2023-07-30 14:28:58 +02:00
smallmodel 51374729d3 Clear g_iInThinks each frame
Display the memory usage if the g_showmem cvar is set
2023-07-30 14:27:15 +02:00
smallmodel 5a19f7f574 Added LightClass 2023-07-30 14:26:52 +02:00
smallmodel 40ac8a1557 Added watchstring from mohaab 2023-07-30 14:09:22 +02:00
smallmodel ca42a3e08e Implemented View3D::DrawLetterbox, View3D::DrawFades, View3D::DrawSoundOverlay, View3D::ClearCenterPrint, View3D::UpdateCenterPrint, View3D::UpdateLocationPrint, View3D::LetterboxActive, View3D::InitSubtitle 2023-07-30 11:47:20 +02:00
smallmodel 3a04357b71 Fixed enum values and enum names 2023-07-30 11:40:50 +02:00
smallmodel 078223c1b6 Centerprint when screenshotting 2023-07-30 11:40:33 +02:00
smallmodel 3fe7cbf725 Fixed vertex colors spam 2023-07-30 11:38:59 +02:00
smallmodel d6059e42ba Export sound_overlay for View3D 2023-07-30 11:38:41 +02:00
smallmodel 02c1fbe4fc Export LV_ConvertString to ref 2023-07-30 11:38:31 +02:00
smallmodel 6f8fee47f2 Using const char* for LV_ConvertString 2023-07-30 11:38:18 +02:00
smallmodel 6c247b300e Updated README 2023-07-30 11:37:41 +02:00
smallmodel 3627760748 Removed parent entity not found message in CG_GetOrigin 2023-07-30 01:10:26 +02:00
smallmodel f3affb3d4c Implemented DontLocalize and FadeSequence from mohaas 2023-07-30 00:56:54 +02:00
smallmodel a86ed01ba3 Fixed shader tiling being bad with virtual scaling on mohaas/mohaab 2023-07-29 23:18:31 +02:00
smallmodel d40755eb7c Added MouseAwayCommand. (this fixes main menu with items staying hovered in mohaas/mohaab) 2023-07-29 23:18:22 +02:00
smallmodel ce7599cb02 Set column padding 2023-07-29 22:31:16 +02:00
smallmodel 68bf89c522 Fixed entity axis index crash (was using i instead of j) 2023-07-29 21:26:28 +02:00
smallmodel 0c5b57ee05 Fixed MASK_SURF_TYPE not matching all surfaces 2023-07-29 21:25:39 +02:00
smallmodel 69a10da52c Version number increment 2023-07-29 19:57:16 +02:00
smallmodel ab534623c4 Fixed crash due to trace.allSolid not being initialized 2023-07-29 19:56:54 +02:00
smallmodel ae4ea14b35 Fixed crash related to backEnd.currentEntity being null 2023-07-29 19:56:36 +02:00
smallmodel ea3c48af02 Fixed double-click not working 2023-07-29 19:41:29 +02:00
smallmodel 9df0c023ed Fixed the server list
Fully implemented the server list
Added support for mohaas/mohaab server list
2023-07-29 19:31:16 +02:00
smallmodel a5259ebc05 Using MASTER_SERVER_HOST macro 2023-07-29 19:30:39 +02:00
smallmodel add59ad12a Implemented UIListBase::TrySelectItem and UIListBase::KeyEvent 2023-07-29 19:30:22 +02:00
smallmodel 53eecb4d4c Fixed compare function being wrong 2023-07-29 19:29:52 +02:00
smallmodel 77fb47451c Added game_version cvar so it shows on the UI on mohaas/mohaab 2023-07-29 19:29:38 +02:00
smallmodel 80ae39c2a7 Fixed mouse wheel not working 2023-07-29 19:29:13 +02:00
smallmodel 118ce0d550 Implemented all unimplemented functions/methods 2023-07-29 00:47:05 +02:00
smallmodel dfd9afceba Added Cvar_VariableFloatValue 2023-07-28 22:34:29 +02:00
smallmodel 6f7eb93645 Export UI_SetReturnMenuToCurrent() 2023-07-28 22:34:22 +02:00
smallmodel a5268cbd24 Implemented FAKKServerListItem class
Implemented UIFAKKServerList::RefreshServerList, UIFAKKServerList::RefreshLANServerList, UIFAKKServerList::NewServerList, UIFAKKServerList::ServerCompareFunction and UIFAKKServerList::SortByColumn
2023-07-28 21:51:37 +02:00
smallmodel c732ed66b2 Set default alpha to 1.0 2023-07-28 21:45:19 +02:00
smallmodel 10981f706f Added functions to get game key, game name and game ID 2023-07-28 21:45:07 +02:00
smallmodel d61218d7e2 Fixed const parameters 2023-07-28 21:44:43 +02:00
smallmodel 615032bc25 Fixed cross-platform errors 2023-07-27 23:13:57 +02:00
smallmodel ea70be07a2 Added FAKKServerListItem class (with unimplemented methods) 2023-07-27 23:02:39 +02:00
smallmodel 1884d3d23c Using a const char* for ServerListAuxUpdate 2023-07-27 23:00:27 +02:00
smallmodel 3f036cca5e Added GameSpy server list 2023-07-27 22:43:51 +02:00
smallmodel 3e02fe340b Implemented UIFAKKServerList's constructor 2023-07-27 22:43:41 +02:00
smallmodel 50d62f1505 Exported EV_UIListBase_ItemDoubleClicked and EV_UIListBase_ItemSelected 2023-07-27 22:43:24 +02:00
smallmodel 60511ace99 Set maximum parallel job to 1 when publishing a new release 2023-07-25 23:59:20 +02:00
263 changed files with 67273 additions and 64681 deletions

No files matched your search

+26 -44
View File
@@ -27,19 +27,6 @@ jobs:
name: "Building for platform linux-${{matrix.architecture.name}}"
runs-on: ubuntu-22.04
# container:
# image: ubuntu:22.04
# volumes:
# - ${{github.workspace}}:${{github.workspace}}
#
# steps:
# - name: Install required packages
# run: apt update && apt install -y clang-15 cmake ninja-build flex bison git
#
# - name: Install required cross-platform packages (${{ matrix.architecture.triple }})
# if: matrix.architecture.name != 'amd64'
# run: apt install -y gcc-12-${{ matrix.architecture.triple }} g++-12-${{ matrix.architecture.triple }}
steps:
- name: Settings
working-directory: ${{github.workspace}}
@@ -54,22 +41,18 @@ jobs:
- name: Install required cross-platform packages (${{ matrix.architecture.triple }})
if: matrix.architecture.name != 'amd64'
run: sudo apt install -y gcc-12-${{ matrix.architecture.triple }} g++-12-${{ matrix.architecture.triple }}
- name: Install dependencies
working-directory: ${{github.workspace}}
run: |
echo Using triple: ${{ matrix.architecture.triple }}
mkdir -p thirdparties && cd thirdparties
git clone --depth 1 --single-branch --branch SDL2 https://github.com/libsdl-org/SDL.git
cmake -B SDL-build \
-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
-DCMAKE_C_FLAGS=--target=${{ matrix.architecture.triple }} \
-DCMAKE_CXX_FLAGS=--target=${{ matrix.architecture.triple }} \
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/thirdparties/SDL-install' \
./SDL
cmake --build SDL-build --config Release
cmake --install SDL-build
# Setup SDL
- name: Set up SDL
id: sdl
uses: libsdl-org/setup-sdl@main
with:
version: sdl2-latest
build-type: Release
cmake-arguments: "-DCMAKE_C_COMPILER=clang
-DCMAKE_CXX_COMPILER=clang++
-DCMAKE_C_FLAGS=--target=${{ matrix.architecture.triple }}
-DCMAKE_CXX_FLAGS=--target=${{ matrix.architecture.triple }}"
- uses: actions/checkout@v3
with:
@@ -84,9 +67,7 @@ jobs:
-DCMAKE_CXX_COMPILER=clang++ \
-DCMAKE_C_FLAGS=--target=${{ matrix.architecture.triple }} \
-DCMAKE_CXX_FLAGS=--target=${{ matrix.architecture.triple }} \
-DGIT_REVISION_BUILD_NUMBER=${{ github.run_number }} \
-DSDL2_DIR='${{github.workspace}}/thirdparties/SDL-install/lib/cmake/SDL2' \
-DWITH_CLIENT=1" >> $GITHUB_ENV
-DGIT_REVISION_BUILD_NUMBER=${{ github.run_number }}" >> $GITHUB_ENV
- name: Configure CMake
working-directory: ${{github.workspace}}
@@ -111,7 +92,7 @@ jobs:
# Install to the directory defined in CMAKE_INSTALL_PREFIX
run: |
cmake --install ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
cp '${{github.workspace}}/thirdparties/SDL-install/lib/libSDL2.so' '${{github.workspace}}/install'
cp '${{steps.sdl.outputs.prefix}}/lib/libSDL2.so' '${{github.workspace}}/install'
- uses: actions/upload-artifact@v3
with:
@@ -138,14 +119,19 @@ jobs:
run: |
echo "CMAKE_BUILD_PARALLEL_LEVEL=$((Get-CimInstance Win32_ComputerSystem).NumberOfLogicalProcessors * 16)" >> $GITHUB_ENV
- name: Install required packages
# Setup SDL
- name: Set up SDL
id: sdl
uses: libsdl-org/setup-sdl@main
with:
version: sdl2-latest
build-type: Release
cmake-arguments: "-A ${{ matrix.architecture.config }}"
- name: Install Flex/Bison
working-directory: ${{github.workspace}}
run: |
mkdir thirdparties && cd thirdparties
git clone --depth 1 --single-branch --branch SDL2 https://github.com/libsdl-org/SDL.git
cmake -B SDL-build -A ${{ matrix.architecture.config }} -DCMAKE_INSTALL_PREFIX='${{github.workspace}}/thirdparties/SDL-install' ./SDL
cmake --build SDL-build --config Release --parallel
cmake --install SDL-build
git clone --depth 1 --single-branch --branch v2.5.25 https://github.com/lexxmark/winflexbison.git
cmake -B winflexbison-build -DCMAKE_INSTALL_PREFIX='${{github.workspace}}/thirdparties/winflexbison-install' ./winflexbison
cmake --build winflexbison-build --config Release --parallel
@@ -161,13 +147,9 @@ jobs:
--log-level=VERBOSE `
-DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} `
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/install' `
-DCMAKE_C_COMPILER=clang `
-DCMAKE_CXX_COMPILER=clang++ `
-DGIT_REVISION_BUILD_NUMBER=${{ github.run_number }} `
-DSDL2_DIR='${{github.workspace}}/thirdparties/SDL-install/cmake' `
-DBISON_EXECUTABLE='${{github.workspace}}/thirdparties/winflexbison-install/win_bison.exe' `
-DFLEX_EXECUTABLE='${{github.workspace}}/thirdparties/winflexbison-install/win_flex.exe' `
-DWITH_CLIENT=1".Replace("`r", "").Replace("`n", "") >> $env:GITHUB_ENV
-DFLEX_EXECUTABLE='${{github.workspace}}/thirdparties/winflexbison-install/win_flex.exe'".Replace("`r", "").Replace("`n", "") >> $env:GITHUB_ENV
- name: Configure CMake
working-directory: ${{github.workspace}}
@@ -192,7 +174,7 @@ jobs:
# Install to the directory defined in CMAKE_INSTALL_PREFIX
run: |
cmake --install ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
Copy-Item "${{github.workspace}}/thirdparties/SDL-install/bin/*.dll" -Destination "${{github.workspace}}/install"
Copy-Item '${{steps.sdl.outputs.prefix}}/bin/*.dll' -Destination '${{github.workspace}}/install'
- uses: actions/upload-artifact@v3
with:
+7
View File
@@ -43,6 +43,13 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v3
# Setup SDL
- name: Set up SDL
id: sdl
uses: libsdl-org/setup-sdl@main
with:
version: sdl2-latest
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
+3
View File
@@ -18,6 +18,9 @@ jobs:
deploy_all:
strategy:
# Set the maximum number of parallel jobs to 1, to avoid a race-condition
# while creating a new release
max-parallel: 1
matrix:
target_os: [
'linux-amd64',
+10 -6
View File
@@ -12,6 +12,7 @@ endif()
set(TARGET_BASE_GAME "main")
set(CMAKE_DEBUG_POSTFIX "-dbg")
if(MSVC)
add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE)
@@ -21,6 +22,10 @@ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
add_compile_options(-Wno-pointer-bool-conversion)
endif()
if(DEBUG_MEMORY)
add_definitions(-D_DEBUG_MEM)
endif()
IF("${TARGET_ARCH}" STREQUAL "i386")
set(TARGET_ARCH_SUFFIX "x86")
ELSE()
@@ -40,7 +45,6 @@ ELSE()
ENDIF()
IF(CMAKE_BUILD_TYPE MATCHES Debug)
set(TARGET_CONFIG_SUFFIX "-dbg")
add_definitions(-D_DEBUG)
#if(UNIX)
@@ -48,8 +52,6 @@ IF(CMAKE_BUILD_TYPE MATCHES Debug)
# set(CMAKE_ENABLE_EXPORTS ON)
# message(STATUS "Enabling exports on Unix for backtrace")
#endif()
ELSE()
set(TARGET_CONFIG_SUFFIX "")
ENDIF()
# Common stuff
@@ -73,7 +75,8 @@ target_link_libraries(omohaaded PRIVATE syslib)
target_link_libraries(omohaaded PRIVATE qcommon qcommon_standalone)
# Gamespy dependency
target_include_directories(omohaaded PUBLIC "code/qcommon" "code/script" "code/gamespy" "code/server")
set_target_properties(omohaaded PROPERTIES OUTPUT_NAME "omohaaded${TARGET_BASE_SUFFIX}${TARGET_ARCH_SUFFIX}${TARGET_CONFIG_SUFFIX}")
set_target_properties(omohaaded PROPERTIES OUTPUT_NAME "omohaaded${TARGET_BASE_SUFFIX}${TARGET_ARCH_SUFFIX}")
set_target_properties(omohaaded PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
if (MSVC)
target_link_options(omohaaded PRIVATE "/MANIFEST:NO")
@@ -82,7 +85,7 @@ endif()
INSTALL(TARGETS omohaaded DESTINATION "./")
if (WITH_CLIENT)
if (NOT BUILD_NO_CLIENT)
## Client app
add_subdirectory("code/renderer")
@@ -103,7 +106,8 @@ if (WITH_CLIENT)
### Gamespy dependency
target_include_directories(openmohaa PUBLIC "code/qcommon" "code/script" "code/gamespy" "code/server" "code/client" "code/uilib" "code/jpeg-8c")
set_target_properties(openmohaa PROPERTIES OUTPUT_NAME "openmohaa${TARGET_BASE_SUFFIX}${TARGET_ARCH_SUFFIX}${TARGET_CONFIG_SUFFIX}")
set_target_properties(openmohaa PROPERTIES OUTPUT_NAME "openmohaa${TARGET_BASE_SUFFIX}${TARGET_ARCH_SUFFIX}")
set_target_properties(openmohaa PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
target_link_libraries(openmohaa PRIVATE jpeg8)
if (USE_OPENAL)
+42 -32
View File
@@ -17,7 +17,7 @@
## Current State
OpenMoHAA is still in its early days. The singleplayer part is not working correctly, the current usage is multiplayer.
OpenMoHAA is still under development. The single-player campaign is not yet functional due to AI not being fully implemented, and due to the script engine having a few issues. But the `training` map can be played from start to end. The current focus is on multiplayer.
## Running
@@ -37,53 +37,64 @@ https://learn.microsoft.com/en-US/cpp/windows/latest-supported-vc-redist?view=ms
You can now start a local OpenMOHAA server or play on a server.
To play expansions, append to the executable `+set com_target_game 1` for Spearhead, and `+set com_target_game 2` for Breakthrough. On windows you can make a shortcut.
**Medal of Honor: Allied Assault Spearhead** and **Medal of Honor: Allied Assault Breakthrough** are supported in OpenMoHAA using the `com_target_game` variable. To play an expansion, append the following command-line arguments to the executable:
- `+set com_target_game 1` for Spearhead (mohaas/mohta)
- `+set com_target_game 2` for Breakthrough (mohaab/mohtt)
On Windows, you can create a shortcut to OpenMoHAA with these command-line arguments.
The default value of `com_target_game` is 0 for the base game.
With `com_target_game`, OpenMoHAA will support the network protocol accordingly
### Playing with bots
OpenMoHAA has a basic bot system that emulates real players. The maximum number of bots is defined by the `sv_maxbots` variable, and the number of initial bots is defined by the `sv_numbots` variable. Bots can also be added or removed using the `addbot` and `removebot` commands.
This feature is a great way to test the gameplay and mods.
## Builds
### Server
The server version can successfully be built.
Some stuff are not working as intended, such as Actor or Vehicle. These systems are both almost fully implemented, but not really in stable state.
The server version can be built successfully, but some features are not functional. For example, the Actor and Vehicle systems are almost fully implemented, but they are not yet stable. This means that they may not work as expected and could cause crashes.
Overall the server part and the game module are almost fully implemented, but the stability may vary, there may be some minor bugs and crashes.
Overall, the server and the fgame components are almost fully implemented, but they may not be completely stable. There could be some minor bugs (and rare crashes), but the game should be playable.
### Client
The client version of OpenMoHAA is partially implemented and not stable currently. The cgame module is partially implemented as well, but is compatible with the original MOH:AA game. Credits to **Heavy Metal: F.A.K.K. 2**'s SDK for the cgame module.
The client version of OpenMoHAA has undergone partial implementation, with the cgame module being nearly completed. Credits to the SDK of **Heavy Metal: F.A.K.K. 2** both the cgame and fgame modules.
Here is the current working state for each part of the engine:
The current operational status for each component is as follow:
| Part name | Full | Almost | Half | Early | Bad | Not working | Comment |
| Component | Full | Almost | Half | Early | Bad | Not working | Comment |
|-------------------------|------|--------|------|-------|-----|-------------|-------------------------------------------------------------------|
| Audio | | | | | x | | Very basic implementation from Quake III |
| CG Module | | x | | | | | Missing FX, Marks and decals |
| Client | | | x | | | | Missing GameSpy, server list, binds, map picker, ... |
| Client | | x | | | | | Missing GameSpy, server list, binds, map picker, ... |
| Collision | x | | | | | | |
| Model/TIKI/Skeletor | x | | | | | | |
| Renderer | | | | x | | | Missing ghost, marks, sphere lights, sky portal, sun flare, swipe |
| Renderer | | x | | | | | Missing ghost, marks, sphere lights, sky portal, sun flare, swipe |
| Server | | x | | | | | Probably a few bugs remaining |
| Server module (fgame) | | x | | | | | Actor, vehicle, and few gameplay bugs |
| UI | | | | x | | | Has core features only (menu, widgets, console, hud, urc loading) |
**Medal of Honor: Allied Assault Spearhead** and **Medal of Honor: Allied Assault Breakthrough** are supported in OpenMoHAA with the `com_target_game` variable. See the **Running** section for the usage.
| UI | | | x | | | | Has core features only (menu, widgets, console, hud, urc loading) |
## Compiling
OpenMoHAA supports both x86 and x64 architectures, and although the target platform is Windows, it still can be compiled for other platforms, and even other architectures.
OpenMoHAA supports any architecture, thanks to the CMake build system and cross-platform code/libraries. While the most common little-Endian architectures (arm, aarch64, x86, x86_64) have been tested and confirmed to work, big-Endian architectures should be supported as well; however, they remain untested.
These are the tools required for all platforms :
The following tools are required for all platforms:
- CMake >= 3.5
- Flex and Bison (currently not used)
- A C++11 compiler is required.
- Flex and Bison
- A C++11 compiler is also required.
The installation directory can be set to MOHAA directory.
The installation directory can be set to the MOHAA directory.
The client build can be built by adding `-DWITH_CLIENT=1` to the CMake command line. This will compile the cgame module and the full app with rendering, ui and sound suppport, alongside the dedicated server version.
By default, the build will produce both the client and dedicated server versions. The client build can be excluded by appending `-DBUILD_NO_CLIENT=1` to the CMake command-line arguments. Using this parameter will result in only the server portion being built.
### Linux
These are the tools required on Unix :
These are the tools required on Linux :
- Clang >= 3.3 or GCC >= 4.8.1
**clang-3.5** and **gcc-4.8.5** should work (tested on Ubuntu 16.04). Use the latest possible version of those compilers.
@@ -95,19 +106,24 @@ SDL2 library is required (libsdl2-dev).
Example with **CMake**, **clang-15** and **ninja-build** installed:
```sh
mkdir .cmake && cd .cmake
cmake -DCMAKE_C_COMPILER=clang-15 -DCMAKE_CXX_COMPILER=clang++-15 -DWITH_CLIENT=1 -G Ninja
cmake -DCMAKE_C_COMPILER=clang-15 -DCMAKE_CXX_COMPILER=clang++-15 -G Ninja
```
### Windows
Visual Studio (2019 or 2022) is generally preferred.
Flex and Bison can be downloaded from here: https://github.com/lexxmark/winflexbison/releases/tag/v2.5.25
Append `-DFLEX_EXECUTABLE=...\win_flex.exe -DBISON_EXECUTABLE=...\win_bison.exe` to the CMake command-line to use the package from the link above.
## Screenshots
| | |
|-------------------------------------------------------------------------------|-----------------------------------------------------------------|
| ![](docs/images/opmtt-x86_64_0.56.0_1.png "Playing on a Breakthrough server") | ![](docs/images/opmtt-x86_64_0.56.0_2.png) |
| ![](docs/images/opmtt-x86_64_0.56.0_3.png) | ![](docs/images/opm-arm_53_tt_1.png "OpenMoHAA on Raspberry") |
| | |
|-------------------------------------------------------------------------------|----------------------------------------------------------------------|
| ![](docs/images/opmtt-x86_64_0.56.0_1.png "Playing on a Breakthrough server") | ![](docs/images/opmtt-x86_64_0.56.0_2.png) |
| ![](docs/images/opmtt-x86_64_0.56.0_3.png) | ![](docs/images/opm-arm_53_tt_1.png "OpenMoHAA on Raspberry Pi 4 B") |
| ![](docs/images/opm-x86_64_0.58.0_1.png "Playing Freeze-Tag mode with bots") | ![](docs/images/opm-x86_64_0.58.0_2.png "Single-Player training") |
## Third party
@@ -116,20 +132,14 @@ Visual Studio (2019 or 2022) is generally preferred.
http://www.libsdl.org/
download Source code, compile
### OpenAL
https://www.openal.org/ download OpenAL soft source
run cmake on OpenAL, compile
https://www.openal.org/
### LibMAD
http://www.underbit.com/products/mad/
download source code, compile
### cURL
https://curl.se/
+24 -16
View File
@@ -1,36 +1,44 @@
set(archdetect_c_code "
#if defined(__i386) || defined(__i386__) || defined(_M_IX86)
#error cmake_ARCH x86
# error cmake_ARCH x86
#elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64)
#error cmake_ARCH x86_64
# error cmake_ARCH x86_64
#elif defined(__ppc64__) || defined(__powerpc64__)
#error cmake_ARCH ppc64
# error cmake_ARCH ppc64
#elif defined(__ppc__) || defined(__ppc) || defined(__powerpc__)
#error cmake_ARCH ppc
# error cmake_ARCH ppc
#elif defined __s390__
#error cmake_ARCH s390
# error cmake_ARCH s390
#elif defined __s390x__
#error cmake_ARCH s390x
# error cmake_ARCH s390x
#elif defined __ia64__
#error cmake_ARCH ia64
# error cmake_ARCH ia64
#elif defined __e2k__
# error cmake_ARCH e2k
#elif defined __alpha__
#error cmake_ARCH alpha
# error cmake_ARCH alpha
#elif defined __sparc__
#error cmake_ARCH sparc
# error cmake_ARCH sparc
#elif defined __arm__ || defined (_M_ARM)
#error cmake_ARCH arm
# error cmake_ARCH arm
#elif defined(__aarch64__) || defined(__ARM64__) || defined(_M_ARM64)
#error cmake_ARCH aarch64
# error cmake_ARCH aarch64
#elif defined __cris__
#error cmake_ARCH cris
# error cmake_ARCH cris
#elif defined __hppa__
#error cmake_ARCH hppa
# error cmake_ARCH hppa
#elif defined __mips__
#error cmake_ARCH mips
# error cmake_ARCH mips
#elif defined __sh__
#error cmake_ARCH sh
# error cmake_ARCH sh
#elif defined __riscv
# if __UINTPTR_MAX__ == __UINT64_MAX__
# error cmake_ARCH riscv64
# else
# error cmake_ARCH riscv
# endif
#else
#error cmake_ARCH unknown
# error cmake_ARCH unknown
#endif
")
+4 -4
View File
@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.5)
project(fgame)
project(cgame)
# Shared source files for modules
set(SOURCES_SHARED
@@ -28,13 +28,13 @@ target_compile_features(cgame PUBLIC c_variadic_macros)
target_link_libraries(cgame PUBLIC qcommon)
set_target_properties(cgame PROPERTIES PREFIX "${TARGET_PLATFORM_PREFIX}")
set_target_properties(cgame PROPERTIES OUTPUT_NAME "cgame${TARGET_ARCH_SUFFIX}${TARGET_CONFIG_SUFFIX}")
set_target_properties(cgame PROPERTIES OUTPUT_NAME "cgame${TARGET_ARCH_SUFFIX}")
set_target_properties(cgame PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TARGET_BASE_GAME}")
INSTALL(
TARGETS cgame
DESTINATION "${TARGET_BASE_GAME}"
ARCHIVE EXCLUDE_FROM_ALL
LIBRARY DESTINATION "${TARGET_BASE_GAME}"
RUNTIME DESTINATION "${TARGET_BASE_GAME}"
)
if(MSVC)
+64
View File
@@ -0,0 +1,64 @@
/*
===========================================================================
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include "cg_local.h"
#include "cg_archive.h"
void CG_ArchiveStuff(MemArchiver& archiver, int svsTime)
{
// FIXME: unimplemented
}
void CG_SaveStateToBuffer(void** out, int svsTime)
{
// FIXME: unimplemented
}
void CG_LoadStateToBuffer(void* state, int size, int svsTime)
{
// FIXME: unimplemented
}
void CG_ArchiveStringContainer(MemArchiver& archiver, Container<str>* container)
{
// FIXME: unimplemented
}
void CG_ArchiveTikiPointer(MemArchiver& archiver, dtiki_t** pTiki)
{
// FIXME: unimplemented
}
void CG_ArchiveModelHandle(MemArchiver& archiver, qhandle_t* handle)
{
// FIXME: unimplemented
}
void CG_ArchiveShaderHandle(MemArchiver& archiver, qhandle_t* handle)
{
// FIXME: unimplemented
}
void CG_ArchiveRefEntity(MemArchiver& archiver, refEntity_t* ref)
{
// FIXME: unimplemented
}
+55
View File
@@ -0,0 +1,55 @@
/*
===========================================================================
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// DESCRIPTION:
// Memory archiver
#pragma once
#ifdef __cplusplus
#include "../qcommon/container.h"
#include "../qcommon/str.h"
class MemArchiver {
};
extern "C" {
#endif
void CG_SaveStateToBuffer(void** out, int svsTime);
void CG_LoadStateToBuffer(void* state, int size, int svsTime);
#ifdef __cplusplus
void CG_ArchiveStuff(MemArchiver& archiver, int svsTime);
void CG_ArchiveStringContainer(MemArchiver& archiver, Container<str>* container);
void CG_ArchiveTikiPointer(MemArchiver& archiver, dtiki_t** pTiki);
void CG_ArchiveModelHandle(MemArchiver& archiver, qhandle_t* handle);
void CG_ArchiveShaderHandle(MemArchiver& archiver, qhandle_t* handle);
void CG_ArchiveRefEntity(MemArchiver& archiver, refEntity_t* ref);
#endif
#ifdef __cplusplus
}
#endif
+11 -1
View File
@@ -4316,7 +4316,7 @@ void ClientGameCommandManager::UpdateEmitter(
VectorCopy(current_entity->origin, m_spawnthing->linked_origin);
for (j = 0; j < 3; j++) {
VectorMA(m_spawnthing->linked_origin, ori.origin[i], current_entity->axis[i], m_spawnthing->linked_origin);
VectorMA(m_spawnthing->linked_origin, ori.origin[i], current_entity->axis[j], m_spawnthing->linked_origin);
}
MatrixMultiply(ori.axis, current_entity->axis, m_spawnthing->linked_axis);
}
@@ -4548,6 +4548,11 @@ void ClientGameCommandManager::FreeAllTempModels(void)
}
}
void ClientGameCommandManager::FreeSomeTempModels(void)
{
// FIXME: unimplemented
}
//===============
// FreeAllEmitters
//===============
@@ -4564,6 +4569,11 @@ void CG_RestartCommandManager()
commandManager.FreeAllTempModels();
}
void CG_CleanUpTempModels()
{
commandManager.FreeSomeTempModels();
}
//=================
// CG_ProcessInitCommands
//=================
+1
View File
@@ -883,6 +883,7 @@ public:
spawnthing_t *InitializeSpawnthing(spawnthing_t *ep);
void SpawnEffect(int count, spawnthing_t *sp);
void FreeAllTempModels(void);
void FreeSomeTempModels(void);
void RestartAllEmitters(void);
void InitializeTempModels(void);
+2 -2
View File
@@ -110,8 +110,8 @@ void CG_ScoresDown_f(void)
void CG_ScoresUp_f(void)
{
if (cgs.gametype == GT_SINGLE_PLAYER) {
if (!cg.scoresRequestTime) {
cg.scoresRequestTime = cg.time;
if (cg.scoresRequestTime) {
cg.scoresRequestTime = 0;
CG_SetDesiredObjectiveAlpha(0.0f);
}
+11 -10
View File
@@ -687,10 +687,11 @@ void CG_DrawObjectives()
iCurrentObjective = atoi(CG_ConfigString(CS_CURRENT_OBJECTIVE));
fTimeDelta = cg.ObjectivesAlphaTime - cg.time;
if (fTimeDelta > 0.0) {
cg.ObjectivesCurrentAlpha = cg.ObjectivesDesiredAlpha;
if (fTimeDelta > 0) {
cg.ObjectivesCurrentAlpha =
(cg.ObjectivesBaseAlpha - cg.ObjectivesDesiredAlpha) * sin(fTimeDelta * 0.0062831854)
+ cg.ObjectivesCurrentAlpha;
(cg.ObjectivesBaseAlpha - cg.ObjectivesDesiredAlpha) * sin(fTimeDelta / (M_PI * 50.f + 2.f))
+ cg.ObjectivesDesiredAlpha;
}
if (cg.ObjectivesCurrentAlpha < 0.02) {
@@ -702,12 +703,12 @@ void CG_DrawObjectives()
iNumLines[i] = 0;
for (ii = 0; ii < MAX_STRING_CHARS; ii++) {
if (cg.Objectives[i].text[ii] == 10) {
if (cg.Objectives[i].text[ii] == '\n') {
iTotalNumLines++;
iNumLines[ii]++;
iNumLines[i]++;
} else if (!cg.Objectives[i].text[ii]) {
iTotalNumLines++;
iNumLines[ii]++;
iNumLines[i]++;
break;
}
}
@@ -740,17 +741,17 @@ void CG_DrawObjectives()
for (i = 0; i < MAX_OBJECTIVES; ++i) {
qhandle_t hBoxShader;
if ((cg.Objectives[i].flags & 1) || !cg.Objectives[i].flags) {
if ((cg.Objectives[i].flags & OBJ_FLAG_HIDDEN) || !cg.Objectives[i].flags) {
continue;
}
if ((cg.Objectives[i].flags & 2) != 0) {
if ((cg.Objectives[i].flags & OBJ_FLAG_CURRENT) != 0) {
vColor[0] = 1.0;
vColor[1] = 1.0;
vColor[2] = 1.0;
vColor[3] = cg.ObjectivesCurrentAlpha;
hBoxShader = cgs.media.uncheckedBoxShader;
} else if ((cg.Objectives[i].flags & 4) != 0) {
} else if ((cg.Objectives[i].flags & OBJ_FLAG_COMPLETED) != 0) {
vColor[0] = 0.75;
vColor[1] = 0.75;
vColor[2] = 0.75;
@@ -763,7 +764,7 @@ void CG_DrawObjectives()
vColor[3] = cg.ObjectivesCurrentAlpha;
hBoxShader = cgs.media.uncheckedBoxShader;
}
if (i == iCurrentObjective && (cg.Objectives[i].flags & 4) == 0) {
if (i == iCurrentObjective && !(cg.Objectives[i].flags & OBJ_FLAG_COMPLETED)) {
vColor[0] = 1.0;
vColor[1] = 1.0;
vColor[2] = 0.0;
+5 -2
View File
@@ -23,6 +23,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
// cg_ents.c -- present snapshot entities, happens every single frame
#include "cg_local.h"
#include "cg_radar.h"
/*
==========================================================================
@@ -551,7 +552,10 @@ void CG_AddCEntity(centity_t *cent)
break;
case ET_PLAYER:
CG_Player(cent);
CG_Splash(cent);
CG_Splash(cent);
CG_ModelAnim(cent, qfalse);
CG_UpdateRadarClient(cent);
break;
case ET_ITEM:
CG_ModelAnim(cent, qfalse);
break;
@@ -666,7 +670,6 @@ void CG_GetOrigin(centity_t *cent, vec3_t origin)
parent = cgi.R_GetRenderEntity(cent->currentState.parent);
if (!parent) {
cgi.DPrintf("CG_GetOrigin: Could not find parent entity\n");
return;
}
+4 -1
View File
@@ -341,7 +341,9 @@ extern "C" {
// misc
crain_t rain;
clientInfo_t clientinfo[MAX_CLIENTS];
clientInfo_t clientinfo[MAX_CLIENTS];
radarClient_t radars[MAX_CLIENTS];
qhandle_t radarShaders[2];
} cg_t;
typedef struct {
@@ -519,6 +521,7 @@ extern "C" {
void CG_EndTiki(dtiki_t *tiki);
qboolean CG_Command_ProcessFile(const char *filename, qboolean quiet, dtiki_t *curTiki);
void CG_RestartCommandManager();
void CG_CleanUpTempModels();
qboolean CG_ProcessEntityCommands(int frame, int anim, int entnum, refEntity_t *ent, centity_t *cent);
void CG_ClientCommands(refEntity_t *ent, centity_t *cent, int slot);
float RandomizeRange(float start, float end);
+7
View File
@@ -25,6 +25,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "cg_local.h"
#include "cg_parsemsg.h"
#include "cg_archive.h"
#include "cg_radar.h"
#ifdef _WIN32
# include <windows.h>
@@ -677,6 +679,11 @@ clientGameExport_t *GetCGameAPI(void)
cge.CG_GetObjectiveAlpha = CG_GetObjectiveAlpha;
cge.CG_WeaponCommandButtonBits = CG_WeaponCommandButtonBits;
cge.CG_CheckCaptureKey = CG_CheckCaptureKey;
cge.CG_ReadNonPVSClient = CG_ReadNonPVSClient;
cge.CG_UpdateRadar = CG_UpdateRadar;
cge.CG_SaveStateToBuffer = CG_SaveStateToBuffer;
cge.CG_LoadStateToBuffer = CG_LoadStateToBuffer;
cge.CG_CleanUpTempModels = CG_CleanUpTempModels;
// FIXME
//cge.profStruct = NULL;
+18 -2
View File
@@ -477,8 +477,24 @@ void CG_PredictPlayerState(void)
}
cg_pmove.noFootsteps = (cgs.dmflags & DF_NO_FOOTSTEPS) > 0;
// Leaning while moving is allowed in mohta and mohtt only with a specific dm flag bit set
cg_pmove.alwaysAllowLean = (cg_protocol < PROTOCOL_MOHTA_MIN) || (cgs.dmflags & DF_ALLOW_LEAN_MOVEMENT);
if (cg_protocol >= PROTOCOL_MOHTA_MIN) {
// Leaning while moving is allowed in mohta and mohtt only with a specific dm flag bit set
cg_pmove.alwaysAllowLean = (cgs.dmflags & DF_ALLOW_LEAN_MOVEMENT) ? qtrue : qfalse;
cg_pmove.leanMax = 45.f;
cg_pmove.leanAdd = 6.f;
cg_pmove.leanRecoverSpeed = 8.5f;
cg_pmove.leanSpeed = 2.f;
} else {
cg_pmove.alwaysAllowLean = qtrue;
cg_pmove.leanMax = 40.f;
cg_pmove.leanAdd = 10.f;
cg_pmove.leanRecoverSpeed = 15.f;
cg_pmove.leanSpeed = 4.f;
}
cg_pmove.protocol = cg_protocol;
// save the state before the pmove so we can detect transitions
oldPlayerState = cg.predicted_player_state;
+16 -6
View File
@@ -23,8 +23,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
// DESCRIPTION:
// client game public interfaces
#ifndef __CG_PUBLIC_H__
#define __CG_PUBLIC_H__
#pragma once
#include "../renderercommon/tr_types.h"
#ifdef __cplusplus
extern "C" {
@@ -67,7 +68,7 @@ extern "C" {
typedef struct stopWatch_s {
int iStartTime;
int iEndTime;
int eType;
} stopWatch_t;
typedef struct AliasList_s AliasList_t;
@@ -283,7 +284,6 @@ functions exported to the main executable
qhandle_t (*R_SpawnEffectModel)(const char *name, vec3_t pos, vec3_t axis[3]);
qhandle_t (*R_RegisterServerModel)(const char *name);
void (*R_UnregisterServerModel)(qhandle_t hModel);
qhandle_t (*R_RegisterSkin)(const char *name);
qhandle_t (*R_RegisterShader)(const char *name);
qhandle_t (*R_RegisterShaderNoMip)(const char *name);
void (*R_AddRefEntityToScene)(const refEntity_t *ent, int parentEntityNumber);
@@ -419,9 +419,12 @@ functions exported to the main executable
);
void (*UI_DeleteScoreBoardItems)(int maxIndex);
void (*UI_ToggleDMMessageConsole)(int consoleMode);
void (*CL_InitRadar)(radarClient_t* radars, qhandle_t* shaders, int clientNum); // Added in 2.0
dtiki_t *(*TIKI_FindTiki)(const char *path);
void (*LoadResource)(const char *name);
void (*FS_CanonicalFilename)(char *name);
void (*CL_RestoreSavedCgameState)();
void (*CL_ClearSavedCgameState)();
cvar_t *fsDebug;
hdelement_t *HudDrawElements;
@@ -491,6 +494,15 @@ functions exported to the main executable
int (*CG_WeaponCommandButtonBits)();
int (*CG_CheckCaptureKey)(int key, qboolean down, unsigned int time);
//
// Added in 2.0
//
void (*CG_ReadNonPVSClient)(radarUnpacked_t* radarUnpacked);
void (*CG_UpdateRadar)();
void (*CG_SaveStateToBuffer)(void** out, int svsTime);
void (*CG_LoadStateToBuffer)(void** state, int size, int svsTime);
void (*CG_CleanUpTempModels)();
// FIXME
//prof_cgame_t* profStruct;
@@ -510,5 +522,3 @@ functions exported to the main executable
#ifdef __cplusplus
}
#endif
#endif // __CG_PUBLIC_H__
+168
View File
@@ -0,0 +1,168 @@
/*
===========================================================================
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include "cg_local.h"
#include "cg_radar.h"
void CG_InitRadar()
{
int i;
cg.radarShaders[0] = cgi.R_RegisterShader("textures/hud/radar_allies.tga");
cg.radarShaders[1] = cgi.R_RegisterShader("textures/hud/radar_axis.tga");
for (i = 0; i < MAX_CLIENTS; i++)
{
cg.radars[i].time = 0;
cg.radars[i].lastSpeakTime = 0;
}
cgi.CL_InitRadar(cg.radars, cg.radarShaders, cg.snap->ps.clientNum);
}
bool CG_InTeamGame(centity_t *ent)
{
return ent->currentState.solid && cg.clientinfo[ent->currentState.number].team;
}
bool CG_SameTeam(centity_t *ent)
{
return cg.clientinfo[ent->currentState.number].team == cg.clientinfo[cg.snap->ps.clientNum].team;
}
bool CG_IsTeamGame()
{
return cgs.gametype >= GT_TEAM;
}
bool CG_ValidRadarClient(centity_t *ent)
{
if (!cg.snap) {
return qfalse;
}
if (!CG_IsTeamGame()) {
return false;
}
if (!CG_InTeamGame(&cg_entities[cg.snap->ps.clientNum])) {
return false;
}
if (!CG_InTeamGame(ent)) {
return false;
}
return CG_SameTeam(ent);
}
int CG_RadarIcon()
{
switch (cg.clientinfo[cg.snap->ps.clientNum].team)
{
case TEAM_ALLIES:
return 0;
default:
case TEAM_AXIS:
return 1;
}
}
void CG_UpdateRadarClient(centity_t* ent)
{
radarClient_t* radar;
radar = &cg.radars[ent->currentState.number];
if (!CG_ValidRadarClient(ent)) {
radar->time = 0;
return;
}
radar->time = cg.time;
radar->teamShader = CG_RadarIcon();
if (cg.snap->ps.clientNum == ent->currentState.number)
{
radar->origin[0] = cg.refdef.vieworg[0];
radar->origin[1] = cg.refdef.vieworg[1];
radar->axis[0] = cg.refdef.viewaxis[0][0];
radar->axis[1] = cg.refdef.viewaxis[0][1];
VectorNormalize2D(radar->axis);
}
else
{
float axis[2];
radar->origin[0] = ent->currentState.origin[0];
radar->origin[1] = ent->currentState.origin[1];
YawToAxis(ent->currentState.angles[1], axis);
radar->axis[0] = axis[0];
radar->axis[1] = axis[1];
VectorNormalize2D(radar->axis);
}
}
void CG_ReadNonPVSClient(radarUnpacked_t* radarUnpacked)
{
radarClient_t* radar;
float axis[2];
if (!CG_ValidRadarClient(&cg_entities[radarUnpacked->clientNum])) {
return;
}
radar = &cg.radars[radarUnpacked->clientNum];
radar->time = cg.time;
radar->teamShader = CG_RadarIcon();
// copy origin
radar->origin[0] = radarUnpacked->x;
radar->origin[1] = radarUnpacked->y;
// copy yaw
YawToAxis(radarUnpacked->yaw, axis);
radar->axis[0] = axis[0];
radar->axis[1] = axis[1];
VectorNormalize2D(radar->axis);
}
void CG_UpdateRadar()
{
int i;
for (i = 0; i < MAX_CLIENTS; i++)
{
if (cg.radars[i].time)
{
if (!CG_ValidRadarClient(&cg_entities[i])) {
cg.radars[i].time = 0;
}
}
}
}
void CG_RadarClientSpeaks(int num)
{
if (!CG_ValidRadarClient(&cg_entities[num])) {
return;
}
cg.radars[num].lastSpeakTime = cg.time;
}
+42
View File
@@ -0,0 +1,42 @@
/*
===========================================================================
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// DESCRIPTION:
// Radar client
#pragma once
#include "cg_local.h"
#ifdef __cplusplus
extern "C" {
#endif
void CG_InitRadar();
void CG_UpdateRadarClient(centity_t* ent);
void CG_ReadNonPVSClient(radarUnpacked_t* radarUnpacked);
void CG_UpdateRadar();
void CG_RadarClientSpeaks(int num);
#ifdef __cplusplus
}
#endif
+21 -14
View File
@@ -241,6 +241,13 @@ static void CG_Stopwatch_f()
if (cg_protocol >= PROTOCOL_MOHTA_MIN) {
cgi.stopWatch->iStartTime = atoi(cgi.Argv(1));
if (cgi.Argc() > 3) {
cgi.stopWatch->eType = atoi(cgi.Argv(3));
} else {
// Normal stop watch
cgi.stopWatch->eType = SWT_NORMAL;
}
} else {
// The base game has it wrong
cgi.stopWatch->iStartTime = 1000 * atoi(cgi.Argv(1));
@@ -291,19 +298,19 @@ static void CG_ServerCommand(void)
}
return;
} else if (!strcmp(cmd, "printdeathmsg")) {
const char *s1, *s2, *s3, *s4, *s5;
const char *s1, *s2, * attackerName, * victimName, *type;
const char *result1, *result2;
int hudColor;
result1 = NULL;
result2 = NULL;
s1 = cgi.Argv(1);
s2 = cgi.Argv(2);
s3 = cgi.Argv(3);
s4 = cgi.Argv(4);
s5 = cgi.Argv(5);
s1 = cgi.Argv(1);
s2 = cgi.Argv(2);
attackerName = cgi.Argv(3);
victimName = cgi.Argv(4);
type = cgi.Argv(5);
if (*s5 == tolower(*s5)) {
if (*type == tolower(*type)) {
hudColor = 4;
} else {
hudColor = 5;
@@ -315,16 +322,16 @@ static void CG_ServerCommand(void)
if (*s2 != 'x') {
result2 = cgi.LV_ConvertString(s2);
}
if (tolower(*s5) == 's') {
cgi.Printf("%c%s %s\n", hudColor, s4, result1);
} else if (tolower(*s5) == 'p') {
if (tolower(*type) == 's') {
cgi.Printf("%c%s %s\n", hudColor, victimName, result1);
} else if (tolower(*type) == 'p') {
if (*s2 == 'x') {
cgi.Printf("%c%s %s %s\n", hudColor, s4, result1, s3);
cgi.Printf("%c%s %s %s\n", hudColor, victimName, result1, attackerName);
} else {
cgi.Printf("%c%s %s %s%s\n", hudColor, s4, result1, s3, result2);
cgi.Printf("%c%s %s %s%s\n", hudColor, victimName, result1, attackerName, result2);
}
} else if (tolower(*s5) == 'w') {
cgi.Printf("%c%s %s\n", hudColor, s4, result1);
} else if (tolower(*type) == 'w') {
cgi.Printf("%c%s %s\n", hudColor, victimName, result1);
} else {
cgi.Printf("%s", cgi.Argv(1));
}
+3
View File
@@ -161,6 +161,9 @@ void CG_SetInitialSnapshot(snapshot_t *snap)
cgi.MUSIC_UpdateMood(snap->ps.current_music_mood, snap->ps.fallback_music_mood);
cgi.MUSIC_UpdateVolume(snap->ps.music_volume, snap->ps.music_volume_fade_time);
cgi.S_SetReverb(snap->ps.reverb_type, snap->ps.reverb_level);
CG_InitRadar();
cgi.CL_RestoreSavedCgameState();
}
/*
+1
View File
@@ -287,6 +287,7 @@ qboolean VSS_SourcePhysics(cvssource_t *pSource, float ftime)
pSource->lastOrigin = pSource->newOrigin;
if (pSource->flags & 0x800) {
trace.allsolid = qfalse;
CG_ClipMoveToEntities(
pSource->newOrigin, vec3_origin, vec3_origin, pSource->newOrigin, -1, MASK_VOLUMETRIC_SMOKE, &trace, qfalse
);
+1 -2
View File
@@ -19,5 +19,4 @@ target_link_libraries(omohclient INTERFACE gcd)
target_compile_definitions(omohclient INTERFACE USE_CODEC_MP3)
add_subdirectory("../libmad-0.15.1b" "./libmad")
target_link_libraries(omohclient INTERFACE libmad)
target_include_directories(omohclient INTERFACE "../libmad-0.15.1b")
target_link_libraries(omohclient INTERFACE libmad)
+35 -8
View File
@@ -23,6 +23,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "client.h"
#include "cl_ui.h"
#include "cl_uiradar.h"
#include "../qcommon/tiki.h"
#include "../qcommon/localization.h"
#include "../qcommon/bg_compat.h"
@@ -540,6 +541,29 @@ void CL_StartLocalSound(const char* soundName, qboolean forceLoad) {
S_StartLocalSound(soundName, qfalse );
}
/*
====================
CL_RestoreSavedCgameState
====================
*/
void CL_RestoreSavedCgameState() {
if (cls.savedCgameState) {
cge->CG_LoadStateToBuffer(&cls.savedCgameState, cls.savedCgameStateSize, cl.snap.serverTime);
}
}
/*
====================
CL_ClearSavedCgameState
====================
*/
void CL_ClearSavedCgameState() {
if (cls.savedCgameState) {
cls.savedCgameState = NULL;
cls.savedCgameStateSize = 0;
}
}
/*
====================
CL_InitCGameDLL
@@ -745,11 +769,14 @@ void CL_InitCGameDLL( clientGameImport_t *cgi, clientGameExport_t **cge ) {
cgi->UI_SetScoreBoardItem = UI_SetScoreBoardItem;
cgi->UI_DeleteScoreBoardItems = UI_DeleteScoreBoardItems;
cgi->UI_ToggleDMMessageConsole = UI_ToggleDMConsole;
cgi->CL_InitRadar = CL_InitRadar;
cgi->TIKI_FindTiki = TIKI_FindTiki;
cgi->LoadResource = UI_LoadResource;
cgi->FS_CanonicalFilename = FS_CanonicalFilename;
cgi->CL_RestoreSavedCgameState = CL_RestoreSavedCgameState;
cgi->CL_ClearSavedCgameState = CL_ClearSavedCgameState;
cgi->fsDebug = fs_debug;
cgi->HudDrawElements = cls.HudDrawElements;
@@ -904,8 +931,6 @@ qboolean CL_GameCommand( void ) {
return cge->CG_ConsoleCommand();
}
/*
=====================
CL_CGameRendering
@@ -920,6 +945,10 @@ void CL_CGameRendering( stereoFrame_t stereo ) {
cge->CG_DrawActiveFrame( cl.serverTime, cl.serverTime - cl.oldServerTime, stereo, clc.demoplaying );
cl.oldServerTime = cl.serverTime;
//
// Let cgame clean up temp models
//
cge->CG_CleanUpTempModels();
}
/*
@@ -1095,16 +1124,14 @@ void CL_SetCGameTime( void ) {
return;
}
// FIXME
//if( ( cl.snap.snapFlags ^ lastSnapFlags ) & SNAPFLAG_SERVERCOUNT ) {
// CL_ServerRestarted();
//} else {
if( ( cl.snap.snapFlags ^ lastSnapFlags ) & SNAPFLAG_SERVERCOUNT ) {
CL_ServerRestarted();
} else {
if( cl.snap.serverTime < cl.oldFrameServerTime ) {
assert( 0 );
Com_Error( ERR_DROP, "cl.snap.serverTime < cl.oldFrameServerTime" );
}
//}
}
cl.oldFrameServerTime = cl.snap.serverTime;
+2 -2
View File
@@ -1051,8 +1051,8 @@ void CL_InitInput( void ) {
Cmd_AddCommand("-leanleft", IN_LeanLeftUp);
Cmd_AddCommand("+leanright", IN_LeanRightDown);
Cmd_AddCommand("-leanright", IN_LeanRightUp);
Cmd_AddCommand("+speed", IN_SpeedUp);
Cmd_AddCommand("-speed", IN_SpeedDown);
Cmd_AddCommand("+speed", IN_SpeedDown);
Cmd_AddCommand("-speed", IN_SpeedUp);
Cmd_AddCommand("+button0", IN_Button0Down);
Cmd_AddCommand("-button0", IN_Button0Up);
Cmd_AddCommand("+button1", IN_Button1Down);
+1 -1
View File
@@ -1153,7 +1153,7 @@ void CL_KeyEvent (int key, qboolean down, unsigned time) {
}
}
if (!in_guimouse || key <= K_MOUSE3 || key > K_JOY1)
if (!in_guimouse || key <= K_MWHEELUP || key > K_JOY1)
{
// keys can still be used for bound actions
if (down && (key <= K_BACKSPACE || key == K_MOUSE4) &&
+15 -1
View File
@@ -26,6 +26,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "cl_ui.h"
#include "../qcommon/tiki.h"
#include "../qcommon/cm_terrain.h"
#include "../qcommon/localization.h"
#include "../sys/sys_local.h"
#ifdef USE_RENDERER_DLL
#include "../sys/sys_loadlib.h"
@@ -102,6 +103,9 @@ cvar_t *cl_inGameVideo;
cvar_t *cl_serverStatusResendTime;
cvar_t *cl_trn;
cvar_t *cl_langamerefreshstatus;
cvar_t *cl_radar_icon_size;
cvar_t *cl_radar_speak_time;
cvar_t *cl_radar_blink_time;
cvar_t *cl_lanForcePackets;
@@ -816,6 +820,11 @@ void CL_MapLoading( qboolean flush, const char *pszMapName ) {
UI_ClearState();
UI_ForceMenuOff(false);
if (!flush) {
// Don't do anything if it's not flushingb
return;
}
if (pszMapName) {
// if we are already connected to the local host, stay connected
if (clc.state >= CA_CONNECTED && !Q_stricmp(cls.servername, "localhost")) {
@@ -1398,7 +1407,8 @@ void CL_Rcon_f( void ) {
message[1] = -1;
message[2] = -1;
message[3] = -1;
message[4] = 0;
message[4] = 2; // direction
message[5] = 0;
Q_strcat (message, MAX_RCON_MESSAGE, "rcon ");
@@ -2796,6 +2806,7 @@ void CL_InitRef( void ) {
ri.Printf = CL_RefPrintf;
ri.Error = Com_Error;
ri.Milliseconds = CL_ScaledMilliseconds;
ri.LV_ConvertString = Sys_LV_CL_ConvertString;
ri.Malloc = CL_RefMalloc;
ri.Free = Z_Free;
ri.Clear = CL_RefClear;
@@ -3239,6 +3250,9 @@ void CL_Init( void ) {
cl_motdString = Cvar_Get( "cl_motdString", "", CVAR_ROM );
cl_langamerefreshstatus = Cvar_Get( "cl_langamerefreshstatus", "Ready", 0 );
cl_radar_icon_size = Cvar_Get("cl_radar_icon_size", "10", CVAR_ARCHIVE);
cl_radar_speak_time = Cvar_Get("cl_radar_speak_time", "3", CVAR_ARCHIVE);
cl_radar_blink_time = Cvar_Get("cl_radar_blink_time", "0.333", CVAR_ARCHIVE);
cg_gametype = Cvar_Get( "cg_gametype", "0", 0 );
cl_lanForcePackets = Cvar_Get ("cl_lanForcePackets", "1", CVAR_ARCHIVE);
+66
View File
@@ -194,6 +194,69 @@ void CL_ParsePacketEntities( msg_t *msg, clSnapshot_t *oldframe, clSnapshot_t *n
}
}
/*
================
CL_UnpackNonPVSClient
Unpack info about non-visible client.
================
*/
qboolean CL_UnpackNonPVSClient(int* packed, radarUnpacked_t* unpacked) {
int x, y;
int yaw;
qboolean bValid;
float range;
unpacked->clientNum = *packed & (MAX_CLIENTS - 1);
if (unpacked->clientNum == cl.snap.ps.clientNum) {
return qfalse;
}
x = ((*packed >> 6) & 0x7F) - (MAX_CLIENTS - 1);
y = ((*packed >> 13) & 0x7F) - (MAX_CLIENTS - 1);
yaw = (*packed >> 20) & 0x1F;
bValid = (*packed >> 25) & 1;
if (com_radar_range && com_radar_range->value) {
range = com_radar_range->value;
} else {
range = 0;
}
unpacked->x = x * range / 63.f;
unpacked->y = y * range / 63.f;
if (!bValid)
{
unpacked->x = x * range / 63.f * 1024;
unpacked->y = y * range / 63.f * 1024;
}
unpacked->yaw = yaw * 11.25f;
return qtrue;
}
/*
================
CL_ReadNonPVSClient
Reads packed info about non-visible client.
================
*/
void CL_ReadNonPVSClient(int radarInfo) {
radarUnpacked_t unpacked;
if (!cge) {
return;
}
if (CL_UnpackNonPVSClient(&radarInfo, &unpacked)) {
unpacked.x += cl.snap.ps.origin[0];
unpacked.y += cl.snap.ps.origin[1];
cge->CG_ReadNonPVSClient(&unpacked);
}
}
/*
================
@@ -332,6 +395,9 @@ void CL_ParseSnapshot( msg_t *msg ) {
}
cl.newSnapshots = qtrue;
// read radar info about invisible clients
CL_ReadNonPVSClient(cl.snap.ps.radarInfo);
}
+5
View File
@@ -3732,6 +3732,7 @@ CL_FillUIImports
void CL_FillUIImports( void ) {
uii.Rend_DrawBox = re.DrawBox;
uii.Rend_DrawPicStretched = re.DrawStretchPic;
uii.Rend_DrawPicStretched2 = re.DrawStretchPic2;
uii.Rend_DrawPicTiled = re.DrawTilePic;
uii.Rend_GetShaderHeight = re.GetShaderHeight;
uii.Rend_GetShaderWidth = re.GetShaderWidth;
@@ -5274,6 +5275,10 @@ void CL_InitializeUI( void ) {
UI_LoadInventory_f();
UI_CreateScoreboard();
// New since mohta
// Version number
Cvar_Set("game_version", va("v%s", com_target_version->string));
// Add all commands
Cmd_AddCommand( "pushmenu", UI_PushMenu_f );
Cmd_AddCommand( "pushmenu_sp", UI_PushMenuSP_f );
+2
View File
@@ -35,6 +35,7 @@ typedef struct {
//
extern cvar_t* ui_health_start;
extern cvar_t* ui_health_end;
extern cvar_t* sound_overlay;
//
// initialization
@@ -66,6 +67,7 @@ void UI_ForceMenuOff( bool force );
void UI_PushMenu( const char *name );
void UI_ForceMenu( const char *name );
qboolean UI_BindActive( void );
void UI_SetReturnMenuToCurrent(void);
void UI_ActivateView3D( void );
void UI_MenuEscape( const char *name );
void UI_CreateScoreboard( void );
+133
View File
@@ -20,7 +20,22 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// cl_uiradar.cpp: draw teammates
// since 2.0
#include "cl_uiradar.h"
#include "client.h"
radarClient_t* g_radarClients;
qhandle_t* g_radarShaders;
int g_radarClientNum;
void CL_InitRadar(radarClient_t* radars, qhandle_t* shaders, int clientNum)
{
g_radarClients = radars;
g_radarShaders = shaders;
g_radarClientNum = clientNum;
}
CLASS_DECLARATION( UIWidget, UIRadar, NULL )
{
@@ -30,5 +45,123 @@ CLASS_DECLARATION( UIWidget, UIRadar, NULL )
UIRadar::UIRadar()
{
m_fRadius = 32.f;
g_radarClients = NULL;
}
UIRadar::~UIRadar()
{
}
void UIRadar::Draw(void)
{
radarClient_t* radar;
float inv;
float iconSize;
int blinkTime, speakTime;
float origin[2], axis[2];
float halfScale;
int i;
if (!g_radarClients) {
return;
}
if (!cl.snap.valid) {
return;
}
if (g_radarClientNum < 0) {
return;
}
cge->CG_UpdateRadar();
radar = &g_radarClients[g_radarClientNum];
if (!radar->time) {
return;
}
if (com_radar_range && com_radar_range->value > 0) {
inv = 1.f / com_radar_range->value;
} else {
inv = 0;
}
if (cl_radar_icon_size->value > 0) {
iconSize = cl_radar_icon_size->value;
} else {
iconSize = 0;
}
axis[0] = radar->axis[0];
axis[1] = radar->axis[1];
origin[0] = radar->origin[0];
origin[1] = radar->origin[1];
blinkTime = cl_radar_blink_time->value * 1000;
speakTime = cl_radar_speak_time->value * 1000;
if (blinkTime < 100) blinkTime = 100;
halfScale = iconSize * 0.5f;
for (i = 0; i < MAX_CLIENTS; i++) {
float delta[2];
float newOrg[2];
float screenOrg[2];
float length;
radar = &g_radarClients[i];
if (i == g_radarClientNum) {
continue;
}
if (!g_radarClients[i].time) {
continue;
}
if (cl.snap.serverTime - radar->time >= 5000) {
continue;
}
if (radar->lastSpeakTime) {
int delta = cl.snap.serverTime - radar->lastSpeakTime;
// make the icon blink
if (delta >= 0 && delta < speakTime && ((delta / blinkTime) % 2) == 0) {
continue;
}
}
radar->lastSpeakTime = 0;
delta[0] = radar->origin[0] - origin[0];
delta[1] = radar->origin[1] - origin[1];
newOrg[0] = -(delta[0] * axis[0] + delta[1] * axis[1]) * inv;
newOrg[1] = (delta[0] * axis[1] + delta[1] * -axis[0]) * inv;
length = VectorLength2D(newOrg);
if (length > 1)
{
newOrg[0] = -(delta[0] * axis[0] + delta[1] * axis[1]) * inv * (1.f / length);
newOrg[1] = (delta[0] * axis[1] + delta[1] * -axis[0]) * inv * (1.f / length);
}
screenOrg[0] = -((halfScale * (1.141f * newOrg[1] + m_vVirtualScale[0])) - ((1.f + newOrg[1]) * 0.5f * m_frame.size.width));
screenOrg[1] = -((halfScale * (1.141f * newOrg[0] + m_vVirtualScale[1])) - ((1.f + newOrg[0]) * 0.5f * m_frame.size.height));
uii.Rend_DrawPicStretched2(
screenOrg[0],
screenOrg[1],
m_vVirtualScale[0] * iconSize,
m_vVirtualScale[1] * iconSize,
0,
0,
1,
1,
radar->axis[0] * axis[0] - (-radar->axis[1] * axis[1]),
radar->axis[0] * axis[1] + (-radar->axis[1] * axis[0]),
g_radarShaders[radar->teamShader]
);
}
}
+6
View File
@@ -21,6 +21,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "../uilib/uiwidget.h"
#include "../cgame/cg_public.h"
class UIRadar : public UIWidget {
public:
@@ -28,7 +29,12 @@ public:
public:
UIRadar();
~UIRadar();
void Draw(void) override;
private:
float m_fRadius;
};
void CL_InitRadar(radarClient_t* radars, qhandle_t* shaders, int clientNum);
File diff suppressed because it is too large. Load diff
+3 -6
View File
@@ -20,20 +20,19 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#ifndef __CL_UISERVERLIST_H__
#define __CL_UISERVERLIST_H__
#pragma once
class UIFAKKServerList : public UIListCtrl {
protected:
// need a new struct instead of gamespy
void *m_serverList;
struct GServerListImplementation *m_serverList[2];
bool m_bHasList;
bool m_bLANListing;
public:
CLASS_PROTOTYPE( UIFAKKServerList );
bool m_bGettingList;
bool m_bGettingList[2];
bool m_bUpdatingList;
protected:
@@ -54,5 +53,3 @@ public:
void Draw( void ) override;
void SortByColumn( int column ) override;
};
#endif /* __CL_UISERVERLIST_H__ */
+82 -13
View File
@@ -30,6 +30,15 @@ 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];
float subLife[MAX_SUBTITLES];
float alpha[MAX_SUBTITLES];
char oldStrings[MAX_SUBTITLES][2048];
View3D::View3D()
{
// set as transparent
@@ -66,7 +75,22 @@ void View3D::DrawLetterbox
)
{
// FIXME: stub
float frac;
vec4_t col;
col[0] = col[1] = col[2] = 0;
col[3] = 1;
frac = cl.snap.ps.stats[STAT_LETTERBOX] / 32767.0;
if (frac > 0.0) {
m_letterbox_active = true;
re.SetColor(col);
re.DrawBox(0.0, 0.0, m_screenframe.size.width, m_screenframe.size.height);
re.DrawBox(0.0, m_screenframe.size.height - m_screenframe.size.height * frac, m_screenframe.size.width, m_screenframe.size.height);
} else {
m_letterbox_active = false;
}
}
void View3D::DrawFades
@@ -75,7 +99,14 @@ void View3D::DrawFades
)
{
// FIXME: stub
if (cl.snap.ps.blend[3] > 0) {
re.SetColor(cl.snap.ps.blend);
if (cl.snap.ps.stats[STAT_ADDFADE]) {
re.AddBox(0.0, 0.0, m_screenframe.size.width, m_screenframe.size.height);
} else {
re.DrawBox(0.0, 0.0, m_screenframe.size.width, m_screenframe.size.height);
}
}
}
void View3D::Draw2D
@@ -200,7 +231,7 @@ void View3D::DrawProf
)
{
// FIXME: stub
// Normal empty function
}
void View3D::PrintSound
@@ -215,7 +246,7 @@ void View3D::PrintSound
)
{
// FIXME: stub
// FIXME: unimplemented
}
void View3D::DrawSoundOverlay
@@ -224,7 +255,13 @@ void View3D::DrawSoundOverlay
)
{
// FIXME: stub
setFont("verdana-14");
m_font->setColor(UWhite);
if (sound_overlay->integer) {
Com_Printf("sound_overlay isn't supported with OpenAL/SDL right now.\n");
Cvar_Set("sound_overlay", "0");
}
}
void View3D::CenterPrint
@@ -233,7 +270,7 @@ void View3D::CenterPrint
)
{
// FIXME: stub
// FIXME: unimplemented
}
void View3D::LocationPrint
@@ -242,7 +279,7 @@ void View3D::LocationPrint
)
{
// FIXME: stub
// FIXME: unimplemented
}
void View3D::OnActivate
@@ -287,7 +324,7 @@ void View3D::DrawSubtitleOverlay
)
{
// FIXME: stub
// FIXME: unimplemented
}
void View3D::ClearCenterPrint
@@ -296,7 +333,7 @@ void View3D::ClearCenterPrint
)
{
// FIXME: stub
m_printfadetime = 0.0;
}
void View3D::UpdateCenterPrint
@@ -306,7 +343,17 @@ void View3D::UpdateCenterPrint
)
{
// FIXME: stub
m_printstring = s;
if (s[0] == '@') {
m_print_mat = uWinMan.RegisterShader(s + 1);
} else {
m_print_mat = NULL;
}
m_printalpha = alpha;
m_printfadetime = 4000.0;
m_locationprint = qfalse;
}
void View3D::UpdateLocationPrint
@@ -318,7 +365,12 @@ void View3D::UpdateLocationPrint
)
{
// FIXME: stub
m_printstring = s;
m_printalpha = alpha;
m_printfadetime = 4000.0;
m_x_coord = x;
m_y_coord = y;
m_locationprint = qtrue;
}
qboolean View3D::LetterboxActive
@@ -330,13 +382,30 @@ qboolean View3D::LetterboxActive
return m_letterbox_active;
}
float avWidth = 0.0;
void View3D::InitSubtitle
(
void
)
{
// FIXME: stub
float totalWidth;
for (int i = 0; i < 4; i++) {
subs[i] = Cvar_Get(va("subtitle%d", i), "", 0);
teams[i] = Cvar_Get(va("subteam%d", i), "0", 0);
strcpy(oldStrings[i], subs[i]->string);
fadeTime[i] = 4000.0;
subLife[i] = 4000.0;
}
totalWidth = 0.0;
for (char j = 'A'; j <= 'Z'; j++) {
totalWidth += m_font->getCharWidth(j);
}
avWidth = totalWidth / 26.0;
}
void View3D::FrameInitialized
@@ -370,6 +439,6 @@ void ConsoleView::Draw
)
{
// FIXME: stub
// FIXME: unimplemented
}
+4
View File
@@ -437,6 +437,9 @@ extern cvar_t *cl_inGameVideo;
extern cvar_t *cl_lanForcePackets;
extern cvar_t *cl_langamerefreshstatus;
extern cvar_t *cl_radar_icon_size;
extern cvar_t *cl_radar_speak_time;
extern cvar_t *cl_radar_blink_time;
extern cvar_t *cl_autoRecordDemo;
extern cvar_t *cl_r_fullscreen;
@@ -570,6 +573,7 @@ void CL_FavoriteServers_f( void );
void CL_Ping_f( void );
void CL_SaveShot_f( void );
void CL_Dialog_f( void );
void CL_ServerRestarted( void );
qboolean CL_UpdateVisiblePings_f( int source );
+64
View File
@@ -0,0 +1,64 @@
/*
===========================================================================
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
int iFlags;
char szName[64];
} soundSfx_t;
typedef struct {
qboolean bPlaying;
int iStatus;
soundSfx_t sfx;
int iEntNum;
int iEntChannel;
float vOrigin[3];
float fVolume;
int iBaseRate;
float fNewPitchMult;
float fMinDist;
float fMaxDist;
int iStartTime;
int iTime;
int iNextCheckObstructionTime;
int iEndTime;
int iFlags;
int iOffset;
int iLoopCount;
} channelbasesavegame_t;
typedef struct {
channelbasesavegame_t Channels[MAX_CHANNELS];
} soundsystemsavegame_t;
void S_ChannelFree_Callback(channel_t* v);
void S_LoadData(soundsystemsavegame_t* pSave);
#ifdef __cplusplus
}
#endif
+48 -5
View File
@@ -1,3 +1,25 @@
/*
===========================================================================
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include "../snd_local.h"
void S_Init2()
@@ -90,11 +112,16 @@ void S_StopSound(int entnum, int channel)
S_IsSoundPlaying
=================
*/
int S_IsSoundPlaying(int channelNumber, const char* name)
qboolean S_IsSoundPlaying(int channelNumber, const char* name)
{
// FIXME: unimplemented
STUB();
return 0;
channel_t* v;
if (channelNumber >= MAX_CHANNELS) {
return qfalse;
}
v = &s_channels[channelNumber];
return v->thesfx ? qtrue : qfalse;
}
/*
@@ -379,4 +406,20 @@ void S_FadeSound(float fTime)
void S_TriggeredMusic_PlayIntroMusic() {
// FIXME: unimplemented
}
}
void callbackServer(int entnum, int channel_number, const char* name) {
if (com_sv_running->integer) {
SV_SoundCallback(entnum, channel_number, name);
}
}
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);
}
}
void S_LoadData(soundsystemsavegame_t* pSave) {
// FIXME: unimplemented
}
+23 -1
View File
@@ -1,3 +1,25 @@
/*
===========================================================================
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#pragma once
#ifdef __cplusplus
@@ -46,7 +68,7 @@ void S_StopSound(int entnum, int channel);
float S_GetSoundTime(sfxHandle_t handle);
void S_SetGlobalAmbientVolumeLevel(float volume);
void S_SetReverb(int reverb_type, float reverb_level);
int S_IsSoundPlaying(int channelNumber, const char* name);
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);
+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 <mad.h>
#include "../libmad-0.15.1b/synth.h"
#define MP3_SAMPLE_WIDTH 2
#define MP3_PCMSAMPLES_PERSLICE 32
+1
View File
@@ -181,6 +181,7 @@ void S_Base_SoundList( void ) {
void S_ChannelFree(channel_t *v) {
S_ChannelFree_Callback(v);
v->thesfx = NULL;
*(channel_t **)v = freelist;
freelist = (channel_t*)v;
+3
View File
@@ -21,6 +21,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// snd_local.h -- private sound definations
#pragma once
#include "../qcommon/q_shared.h"
#include "../qcommon/qcommon.h"
@@ -275,6 +276,8 @@ qboolean S_AL_Init( soundInterface_t *si );
void S_PaintChannelFrom16_altivec( portable_samplepair_t paintbuffer[PAINTBUFFER_SIZE], int snd_vol, channel_t *ch, const sfx_t *sc, int count, int sampleOffset, int bufferOffset );
#endif
#include "new/snd_local_new.h"
#ifdef __cplusplus
}
#endif
+11 -4
View File
@@ -16,7 +16,14 @@ set(SOURCES_SHARED
"../qcommon/str.cpp"
)
file(GLOB_RECURSE SOURCES_GAME "./*.c*" "../parser/*.c*" "../script/*.c*")
file(
GLOB_RECURSE
SOURCES_GAME
"./*.c*"
"../script/*.c*"
"../parser/generated/*.c*"
"../parser/parsetree.cpp"
)
add_library(fgame SHARED ${SOURCES_GAME})
@@ -44,13 +51,13 @@ target_compile_features(fgame PUBLIC c_variadic_macros)
target_link_libraries(fgame PUBLIC qcommon)
set_target_properties(fgame PROPERTIES PREFIX "${TARGET_PLATFORM_PREFIX}")
set_target_properties(fgame PROPERTIES OUTPUT_NAME "game${TARGET_ARCH_SUFFIX}${TARGET_CONFIG_SUFFIX}")
set_target_properties(fgame PROPERTIES OUTPUT_NAME "game${TARGET_ARCH_SUFFIX}")
set_target_properties(fgame PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TARGET_BASE_GAME}")
INSTALL(
TARGETS fgame
DESTINATION "${TARGET_BASE_GAME}"
ARCHIVE EXCLUDE_FROM_ALL
LIBRARY DESTINATION "${TARGET_BASE_GAME}"
RUNTIME DESTINATION "${TARGET_BASE_GAME}"
)
if(MSVC)
+26
View File
@@ -0,0 +1,26 @@
/*
===========================================================================
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include "DrivableVehicleTandem.h"
// FIXME: unimplemented
+23
View File
@@ -0,0 +1,23 @@
/*
===========================================================================
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#pragma once
File diff suppressed because it is too large. Load diff
+460
View File
@@ -0,0 +1,460 @@
/*
===========================================================================
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#pragma once
#include "entity.h"
#include "animate.h"
typedef enum {
CONTROLLER_ALLIES,
CONTROLLER_AXIS,
CONTROLLER_DRAW
} eController;
#define PT_SPAWNFLAG_PLAY_FIRE_SOUND 1
#define PT_SPAWNFLAG_TARGET_RANDOM 4
#define PT_SPAWNFLAG_TURN_ON 8
#define PT_SPAWNFLAG_SET_YAW 16
#define PT_SPAWNFLAG_SET_ROLL 32
#define PT_SPAWNFLAG_TARGET_PLAYER 64
#define PT_SPAWNFLAG_HIDDEN 128
void ClearProjectileTargets();
class ProjectileTarget : public Entity
{
private:
int m_iTarget;
public:
CLASS_PROTOTYPE(ProjectileTarget);
ProjectileTarget();
void EventSetId(Event *ev);
int GetTarget() const;
};
#define MAX_PROJECTILE_GENERATOR_TARGETS 16
class ProjectileGenerator : public Animate
{
protected:
int m_iId;
int m_iCycles;
float m_fMinDuration;
float m_fMaxDuration;
int m_iMinNumShots;
int m_iMaxNumShots;
float m_fMinDelay;
float m_fMaxDelay;
float m_fAccuracy;
str m_sLaunchSound;
bool m_bFireOnStartUp;
qboolean m_bIsDonut;
float m_fArcDonut;
float m_fMinDonut;
float m_fMaxDonut;
float m_fCycleTime;
float m_fShotsPerSec;
float m_fCurrentTime;
int m_iTargetIndex;
float m_fLastShotTime;
int m_iAnimSlot;
bool m_bIsTurnedOn;
int m_iCurrentCycle;
Entity *m_pTarget;
Container<ProjectileTarget *> m_projectileTargets;
Entity *m_pCurrent;
Vector m_vTargetOrg;
public:
CLASS_PROTOTYPE(ProjectileGenerator);
ProjectileGenerator();
virtual void SetupNextCycle();
virtual void BeginCycle(Event *ev);
virtual void TickCycle(Event *ev);
virtual void EndCycle(Event *ev);
bool ShouldStartOn() const;
bool ShouldHideModel() const;
bool ShouldPlayFireSound() const;
void EventIsTurnedOn(Event *ev);
void EventGetTargetEntity(Event *ev);
void EventLaunchSound(Event *ev);
void SetTarget(Event *ev);
void OnInitialize(Event *ev);
void TurnOff(Event *ev);
void TurnOn(Event *ev);
bool ShouldTargetRandom() const;
void ChooseTarget();
void GetLocalTargets();
bool ShouldTargetPlayer() const;
void GetTargetPos(Entity *target);
void EventAccuracy(Event *ev);
void EventMaxDelay(Event *ev);
void EventMinDelay(Event *ev);
void EventFireOnStartUp(Event *ev);
void EventMaxNumShots(Event *ev);
void EventMinNumShots(Event *ev);
void EventCycles(Event *ev);
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);
virtual bool Attack(int count);
void Archive(Archiver& arc) override;
};
class ProjectileGenerator_Projectile : public ProjectileGenerator
{
private:
str m_sProjectileModel;
str m_sPreImpactSound;
float m_fImpactSoundTime;
float m_fImpactSoundProbability;
public:
CLASS_PROTOTYPE(ProjectileGenerator_Projectile);
ProjectileGenerator_Projectile();
void SetPreImpactSoundProbability(Event *ev);
void SetPreImpactSoundTime(Event *ev);
void SetPreImpactSound(Event *ev);
void PlayPreImpactSound(Event *ev);
void SetProjectileModel(Event *ev);
bool Attack(int count) override;
void Archive(Archiver& arc) override;
};
class ProjectileGenerator_Gun : public ProjectileGenerator
{
private:
float m_fBulletRange;
float m_fBulletDamage;
int m_iBulletCount;
Vector m_vBulletSpread;
int m_iTracerFrequency;
int m_iBulletLarge;
qboolean m_bFakeBullets;
int m_iMeansOfDeath;
float m_fBulletThroughWood;
float m_fBulletThroughMetal;
float m_iBulletKnockback;
int m_iAttackCount;
float m_fFireDelay;
float m_fTracerSpeed;
public:
CLASS_PROTOTYPE(ProjectileGenerator_Gun);
ProjectileGenerator_Gun();
void SetFireDelay(Event *ev);
void SetMeansOfDeath(Event *ev);
void SetBulletThroughWood(Event *ev);
void SetBulletThroughMetal(Event *ev);
void SetBulletKnockback(Event *ev);
void SetTracerSpeed(Event *ev);
void SetBulletLarge(Event *ev);
void SetFakeBullets(Event *ev);
void SetBulletCount(Event *ev);
void SetBulletDamage(Event *ev);
void SetTracerFrequency(Event *ev);
void SetBulletSpread(Event *ev);
void SetBulletRange(Event *ev);
bool Attack(int count) override;
void TickCycle(Event *ev) override;
void Archive(Archiver& arc) override;
};
class ProjectileGenerator_Heavy : public ProjectileGenerator
{
private:
str m_sProjectileModel;
public:
CLASS_PROTOTYPE(ProjectileGenerator_Heavy);
ProjectileGenerator_Heavy();
void SetProjectileModel(Event *ev);
bool Attack(int count) override;
void Archive(Archiver& arc) override;
};
class ThrobbingBox_Explosive : public Animate
{
protected:
str m_sUsedModel;
str m_sSound;
bool m_bUsed;
float m_fExplosionDamage;
float m_fRadius;
float m_fStopwatchDuration;
str m_sActivateSound;
str m_sTickSound;
str m_sDestroyedModel;
ScriptThreadLabel m_thread;
ScriptThreadLabel m_useThread;
str m_sEffect;
Vector m_vOffset;
public:
CLASS_PROTOTYPE(ThrobbingBox_Explosive);
ThrobbingBox_Explosive();
void SetExplosionOffset(Event *ev);
void SetExplosionEffect(Event *ev);
void SetTriggered(Event *ev);
void DoExplosion(Event *ev);
void SetUseThread(Event *ev);
void SetThread(Event *ev);
void SetStopWatchDuration(Event *ev);
void SetRadius(Event *ev);
void SetDamage(Event *ev);
void TickSound(Event *ev);
void ActivateSound(Event *ev);
void ExplosionSound(Event *ev);
void UsedModel(Event *ev);
void SetDestroyModel(Event *ev);
void OnBlowUp(Event *ev);
void OnUse(Event *ev);
void Archive(Archiver& arc) override;
};
class ThrobbingBox_ExplodePlayerFlak88 : public ThrobbingBox_Explosive
{
public:
CLASS_PROTOTYPE(ThrobbingBox_ExplodePlayerFlak88);
};
class ThrobbingBox_ExplodeFlak88 : public ThrobbingBox_Explosive
{
public:
CLASS_PROTOTYPE(ThrobbingBox_ExplodeFlak88);
};
class ThrobbingBox_ExplodeNebelwerfer : public ThrobbingBox_Explosive
{
public:
CLASS_PROTOTYPE(ThrobbingBox_ExplodeNebelwerfer);
};
class ThrobbingBox_ExplodePlayerNebelwerfer : public ThrobbingBox_Explosive
{
public:
CLASS_PROTOTYPE(ThrobbingBox_ExplodePlayerNebelwerfer);
};
#define TBE_SPAWNFLAG_DESTROYED_MODEL 1
#define TBE_SPAWNFLAG_MAKE_WET 2
class ThrobbingBox_Stickybomb : public ThrobbingBox_Explosive
{
private:
float m_fStopwatchStartTime;
public:
CLASS_PROTOTYPE(ThrobbingBox_Stickybomb);
void OnStickyBombWet(Event *ev);
void OnStickyBombUse(Event *ev);
void Archive(Archiver& arc) override;
};
#define OBJECTIVE_SPAWNFLAG_TURN_ON 1
class Objective : public Entity
{
private:
str m_sText;
int m_iObjectiveIndex;
public:
CLASS_PROTOTYPE(Objective);
Objective();
void Archive(Archiver &arc) override;
void TurnOn(Event *ev);
void TurnOff(Event *ev);
void Complete(Event *ev);
void SetCurrent(Event *ev);
Vector GetOrigin() const;
void SetObjectiveNbr(Event *ev);
void SetText(Event *ev);
int GetObjectiveIndex() const;
};
class FencePost : public Entity
{
public:
CLASS_PROTOTYPE(FencePost);
};
class AISpawnPoint : public SimpleArchivedEntity
{
private:
str m_sModel;
int m_iHealth;
str m_sEnemyName;
float m_iAccuracy;
int m_iAmmoGrenade;
float m_iBalconyHeight;
int m_iDisguiseLevel;
float m_fDisguisePeriod;
float m_fDisguiseRange;
float m_fEnemyShareRange;
float m_fFixedLeash;
float m_fGrenadeAwareness;
str m_sGun;
float m_fMaxNoticeTimeScale;
float m_fSoundAwareness;
str m_sTypeAttack;
str m_sTypeDisguise;
str m_sTypeGrenade;
str m_sTypeIdle;
bool m_bPatrolWaitTrigger;
float m_fHearing;
float m_fSight;
float m_fFov;
float m_fLeash;
float m_fMinDist;
float m_fMaxDist;
float m_fInterval;
bool m_bDontDropWeapons;
bool m_bDontDropHealth;
str m_sFavoriteEnemy;
bool m_bNoSurprise;
str m_sPatrolPath;
str m_sTurret;
str m_sAlarmNode;
str m_sWeapon;
str m_sTarget;
str m_sVoiceType;
bool m_bForceDropWeapon;
bool m_bForceDropHealth;
public:
CLASS_PROTOTYPE(AISpawnPoint);
AISpawnPoint();
void GetForceDropHealth(Event *ev);
void SetForceDropHealth(Event *ev);
void GetForceDropWeapon(Event *ev);
void SetForceDropWeapon(Event *ev);
void GetVoiceType(Event *ev);
void SetVoiceType(Event *ev);
void GetTarget(Event *ev);
void SetTarget(Event *ev);
void GetWeapon(Event *ev);
void SetWeapon(Event *ev);
void GetAlarmNode(Event *ev);
void SetAlarmNode(Event *ev);
void GetTurret(Event *ev);
void SetTurret(Event *ev);
void GetPatrolPath(Event *ev);
void SetPatrolPath(Event *ev);
void GetNoSurprise(Event *ev);
void SetNoSurprise(Event *ev);
void SetFavoriteEnemy(Event *ev);
void GetFavoriteEnemy(Event *ev);
void GetDontDropHealth(Event *ev);
void SetDontDropHealth(Event *ev);
void GetDontDropWeapons(Event *ev);
void SetDontDropWeapons(Event *ev);
void GetInterval(Event *ev);
void SetInterval(Event *ev);
void GetMaxDistance(Event *ev);
void SetMaxDistance(Event *ev);
void GetMinDistance(Event *ev);
void SetMinDistance(Event *ev);
void GetLeash(Event *ev);
void SetLeash(Event *ev);
void GetFov(Event *ev);
void SetFov(Event *ev);
void SetSight(Event *ev);
void GetSight(Event *ev);
void GetHearing(Event *ev);
void SetHearing(Event *ev);
void GetPatrolWaitTrigger(Event *ev);
void SetPatrolWaitTrigger(Event *ev);
void GetTypeIdle(Event *ev);
void SetTypeIdle(Event *ev);
void GetTypeGrenade(Event *ev);
void SetTypeGrenade(Event *ev);
void GetTypeDisguise(Event *ev);
void SetTypeDisguise(Event *ev);
void GetTypeAttack(Event *ev);
void SetTypeAttack(Event *ev);
void SetSoundAwareness(Event *ev);
void GetSoundAwareness(Event *ev);
void SetMaxNoticeTimeScale(Event *ev);
void GetMaxNoticeTimeScale(Event *ev);
void GetGun(Event *ev);
void SetGun(Event *ev);
void GetGrenadeAwareness(Event *ev);
void SetGrenadeAwareness(Event *ev);
void SetFixedLeash(Event *ev);
void GetFixedLeash(Event *ev);
void GetEnemyShareRange(Event *ev);
void SetEnemyShareRange(Event *ev);
void GetDisguiseRange(Event *ev);
void SetDisguiseRange(Event *ev);
void GetDisguisePeriod(Event *ev);
void SetDisguisePeriod(Event *ev);
void GetDisguiseLevel(Event *ev);
void SetDisguiseLevel(Event *ev);
void GetBalconyHeight(Event *ev);
void SetBalconyHeight(Event *ev);
void GetAmmoGrenade(Event *ev);
void SetAmmoGrenade(Event *ev);
void GetAccuracy(Event *ev);
void SetAccuracy(Event *ev);
void GetEnemyName(Event *ev);
void SetEnemyName(Event *ev);
void GetHealth(Event *ev);
void SetHealth(Event *ev);
void GetModel(Event *ev);
void SetModel(Event *ev);
void Archive(Archiver& arc) override;
};
+272
View File
@@ -0,0 +1,272 @@
/*
===========================================================================
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include "Tow_Entities.h"
#include "player.h"
#include "scriptthread.h"
TOWObjectiveMan g_TOWObjectiveMan;
TOWObjectiveMan::TOWObjectiveMan()
{
Reset();
}
void TOWObjectiveMan::Reset()
{
m_towObjectives.ClearObjectList();
m_iNumAxisObjectives = 0;
m_iNumAlliesObjectives = 0;
}
void TOWObjectiveMan::AddObjective(TOWObjective *objective)
{
if (!objective) {
return;
}
switch (objective->GetController()) {
case CONTROLLER_ALLIES:
m_iNumAlliesObjectives++;
break;
case CONTROLLER_AXIS:
m_iNumAxisObjectives++;
break;
}
m_towObjectives.AddObject(objective);
}
void TOWObjectiveMan::TakeOverObjective(eController controller, eController controllingTeam)
{
int i;
if (controllingTeam == CONTROLLER_DRAW) {
return;
}
switch (controllingTeam) {
case CONTROLLER_ALLIES:
m_iNumAlliesObjectives++;
if (m_iNumAxisObjectives) {
m_iNumAxisObjectives--;
}
dmManager.CheckEndMatch();
break;
case CONTROLLER_AXIS:
m_iNumAxisObjectives++;
if (m_iNumAlliesObjectives) {
m_iNumAlliesObjectives--;
}
dmManager.CheckEndMatch();
break;
default:
break;
}
for (i = 0; i < game.maxclients; i++) {
gentity_t *ent = &g_entities[i];
Player *player;
bool bSameTeam;
if (!ent->inuse || !ent->entity) {
continue;
}
player = static_cast<Player *>(ent->entity);
switch (controllingTeam) {
case CONTROLLER_ALLIES:
bSameTeam = player->GetTeam() == TEAM_ALLIES;
break;
case CONTROLLER_AXIS:
bSameTeam = player->GetTeam() == TEAM_AXIS;
break;
default:
break;
}
// play a different sound for the losing team
if (bSameTeam) {
player->PlayInstantMessageSound("success");
} else {
player->PlayInstantMessageSound("failure");
}
}
}
Event EV_SetController("ControlledBy", EV_DEFAULT, "i", "ControlledBy", "Sets the team controlling the objective");
Event EV_TakeOver(
"TakeOver", EV_DEFAULT, "i", "TeamNum", "Sets the team controlling the objective. 0 = Axis, 1 = Allies"
);
Event EV_SetAxisObjNum("AxisObjNum", EV_DEFAULT, "i", "AxisObjNum", "Sets the objective number for the axis team");
Event EV_SetAlliesObjNum(
"AlliesObjNum", EV_DEFAULT, "i", "AlliesObjNum", "Sets the objective number for the allies team"
);
static Event EV_Initialize("initialize", EV_DEFAULT, 0, 0, "Initialize object");
static Event EV_SetCurrent(
"SetCurrent", EV_DEFAULT, "i", "TeamNum", "Set this objective as the current objective for the specified team."
);
Event EV_GetController("ControlledBy", EV_DEFAULT, 0, 0, "Objective controller", EV_GETTER);
CLASS_DECLARATION(Objective, TOWObjective, "func_towobjective") {
{&EV_SetController, &TOWObjective::SetController },
{&EV_TakeOver, &TOWObjective::TakeOver },
{&EV_SetAxisObjNum, &TOWObjective::SetAxisObjNum },
{&EV_SetAlliesObjNum, &TOWObjective::SetAlliesObjNum},
{&EV_Initialize, &TOWObjective::OnInitialize },
{&EV_SetCurrent, &TOWObjective::SetCurrent },
{&EV_GetController, &TOWObjective::GetController },
{NULL, NULL }
};
TOWObjective::TOWObjective()
{
m_eController = CONTROLLER_DRAW;
m_eLeadingController = CONTROLLER_DRAW;
m_bNoRespawnForLeading = false;
m_iAxisObjNum = 1;
m_iAlliesObjNum = 1;
m_sAxisObjName = "default";
m_sAlliesObjName = "default";
if (spawnflags & TOWOBJECTIVE_SPAWNFLAG_NO_RESPAWN) {
m_bNoRespawnForLeading = true;
}
PostEvent(EV_Initialize, 0.001f);
}
void TOWObjective::SetController(Event *ev)
{
m_eController = static_cast<eController>(ev->GetInteger(1));
if (m_bNoRespawnForLeading) {
m_eLeadingController = m_eController;
}
if (m_eController != CONTROLLER_ALLIES && m_eController != CONTROLLER_AXIS) {
m_eController = CONTROLLER_DRAW;
}
}
void TOWObjective::GetController(Event *ev)
{
ev->AddInteger(m_eController);
}
void TOWObjective::TakeOver(Event *ev)
{
eController controller = static_cast<eController>(ev->GetInteger(1));
if (controller == m_eController || controller == CONTROLLER_DRAW) {
return;
}
switch (controller) {
case CONTROLLER_ALLIES:
gi.cvar_set(m_sAxisObjName.c_str(), "1");
gi.cvar_set(m_sAlliesObjName.c_str(), "0");
break;
case CONTROLLER_AXIS:
gi.cvar_set(m_sAxisObjName.c_str(), "0");
gi.cvar_set(m_sAlliesObjName.c_str(), "1");
break;
default:
break;
}
g_TOWObjectiveMan.TakeOverObjective(m_eController, controller);
if (m_bNoRespawnForLeading) {
//
// Disable team respawn for the leading team
//
dmManager.StopTeamRespawn(m_eLeadingController);
}
}
void TOWObjective::SetAlliesObjNum(Event *ev)
{
m_iAlliesObjNum = ev->GetInteger(1);
}
void TOWObjective::SetAxisObjNum(Event *ev)
{
m_iAxisObjNum = ev->GetInteger(1);
}
void TOWObjective::OnInitialize(Event *ev)
{
m_sAlliesObjName = "tow_allied_obj" + str(m_iAlliesObjNum);
m_sAxisObjName = "tow_allied_obj" + str(m_iAxisObjNum);
switch (m_eController) {
case CONTROLLER_ALLIES:
gi.cvar_set(m_sAxisObjName.c_str(), "1");
gi.cvar_set(m_sAlliesObjName.c_str(), "0");
break;
case CONTROLLER_AXIS:
gi.cvar_set(m_sAxisObjName.c_str(), "0");
gi.cvar_set(m_sAlliesObjName.c_str(), "1");
break;
case CONTROLLER_DRAW:
gi.cvar_set(m_sAxisObjName.c_str(), "0");
gi.cvar_set(m_sAlliesObjName.c_str(), "0");
break;
}
if (!LoadingSavegame) {
g_TOWObjectiveMan.AddObjective(this);
}
}
void TOWObjective::SetCurrent(Event *ev)
{
eController controller = static_cast<eController>(ev->GetInteger(1));
switch (controller) {
case CONTROLLER_ALLIES:
ScriptThread::SetCurrentObjective(GetObjectiveIndex(), TEAM_ALLIES);
break;
case CONTROLLER_AXIS:
ScriptThread::SetCurrentObjective(GetObjectiveIndex(), TEAM_AXIS);
break;
default:
SetCurrent(ev);
break;
}
}
int TOWObjective::GetController() const
{
return m_eController;
}
void TOWObjective::Archive(Archiver& arc)
{
arc.ArchiveInteger(&m_iAxisObjNum);
arc.ArchiveInteger(&m_iAlliesObjNum);
ArchiveEnum(m_eController, eController);
ArchiveEnum(m_eLeadingController, eController);
arc.ArchiveBool(&m_bNoRespawnForLeading);
arc.ArchiveString(&m_sAxisObjName);
arc.ArchiveString(&m_sAlliesObjName);
}
+73
View File
@@ -0,0 +1,73 @@
/*
===========================================================================
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#pragma once
#include "Entities.h"
#define TOWOBJECTIVE_SPAWNFLAG_NO_RESPAWN 2
class TOWObjective : public Objective
{
private:
int m_iAxisObjNum;
int m_iAlliesObjNum;
eController m_eController;
eController m_eLeadingController;
bool m_bNoRespawnForLeading;
str m_sAxisObjName;
str m_sAlliesObjName;
public:
CLASS_PROTOTYPE(TOWObjective);
TOWObjective();
void SetController(Event *ev);
void GetController(Event *ev);
void TakeOver(Event *ev);
void SetAlliesObjNum(Event *ev);
void SetAxisObjNum(Event *ev);
void OnInitialize(Event *ev);
void SetCurrent(Event *ev);
int GetController() const;
void Archive(Archiver& arc) override;
};
class TOWObjectiveMan
{
private:
Container<TOWObjective *> m_towObjectives;
int m_iNumAxisObjectives;
int m_iNumAlliesObjectives;
public:
TOWObjectiveMan();
void Reset();
void AddObjective(TOWObjective *objective);
void TakeOverObjective(eController controller, eController controllingTeam);
};
extern TOWObjectiveMan g_TOWObjectiveMan;
+12 -21
View File
@@ -2573,7 +2573,7 @@ Actor::Actor()
setMoveType( MOVETYPE_WALK );
mass = 175;
flags |= FL_THINK;
flags &= ~FL_UNKNOWN;
flags &= ~FL_ANIMATE;
setContentsSolid();
setSolidType( SOLID_BBOX );
m_fFov = 90.0f;
@@ -3230,7 +3230,7 @@ void Actor::SetEnemy
{
//this cansee call changes m_bEnemyVisible and m_bEnemyInFOV
//FIXME: macro
CanSee(m_Enemy, 0, 0.828 * world->farplane_distance);
CanSee(m_Enemy, 0, 0.828 * world->farplane_distance, false);
}
}
@@ -4512,12 +4512,8 @@ void Actor::UpdateAnim
Com_Printf("ChangeAnim\n");
ChangeAnim();
}
Director.iPaused--;
if (!Director.iPaused)
{
Director.ExecuteRunning();
}
Director.iPaused++;
Director.Unpause();
Director.Pause();
if (m_csSayAnim != STRING_EMPTY)
{
@@ -5534,9 +5530,7 @@ void Actor::Think
m_bNeedReload = false;
mbBreakSpecialAttack = false;
Director.iPaused--;
if (!Director.iPaused)
Director.ExecuteRunning();
Director.Unpause();
//gi.DPrintf("Actor::Think 5: entnum %d, classname: %s\n", entnum, G_GetEntity(0) ? G_GetEntity(0)->getClassname() : "");
}
@@ -6791,10 +6785,11 @@ bool Actor::CanSee
(
Entity *e1,
float fov,
float vision_distance
float vision_distance,
bool bNoEnts
)
{
bool canSee = Sentient::CanSee(e1, fov, vision_distance);
bool canSee = Sentient::CanSee(e1, fov, vision_distance, false);
if (e1 == m_Enemy)
{
m_iEnemyVisibleCheckTime = level.inttime;
@@ -7147,7 +7142,7 @@ bool Actor::CanSeeEnemy
{
//FIXME: macro
if (level.inttime > iMaxDirtyTime + m_iEnemyVisibleCheckTime)
CanSee(m_Enemy, 0, 0.828 * world->farplane_distance);
CanSee(m_Enemy, 0, 0.828 * world->farplane_distance, false);
return m_bEnemyVisible;
}
@@ -7667,7 +7662,7 @@ bool Actor::NoticeShot
if (pTarget)
{
if (DoesTheoreticPathExist(pShooter->origin, fDist * 1.5) || CanSee(pTarget, 0, 0.828 * world->farplane_distance))
if (DoesTheoreticPathExist(pShooter->origin, fDist * 1.5) || CanSee(pTarget, 0, 0.828 * world->farplane_distance, false))
{
m_PotentialEnemies.ConfirmEnemy(this, pTarget);
}
@@ -8233,13 +8228,9 @@ void Actor::IdleTurn
SafePtr<SimpleEntity> prevTurnEntity = m_pTurnEntity;
Director.iPaused--;
if (!Director.iPaused)
{
Director.ExecuteRunning();
}
Director.Unpause();
Unregister(STRING_TURNDONE);
Director.iPaused++;
Director.Pause();
if (m_pTurnEntity == prevTurnEntity)
+99 -27
View File
@@ -35,31 +35,103 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "grenadehint.h"
#include "parm.h"
extern Event EV_Actor_Start;
extern Event EV_Actor_Dead;
extern Event EV_Actor_LookAt;
extern Event EV_Actor_TurnTo;
extern Event EV_Actor_FinishedBehavior;
extern Event EV_Actor_NotifyBehavior;
extern Event EV_Actor_FinishedMove;
extern Event EV_Actor_FinishedAnim;
extern Event EV_Actor_WalkTo;
extern Event EV_Actor_RunTo;
extern Event EV_Actor_Anim;
extern Event EV_Actor_AttackFinished;
extern Event EV_Actor_Attack;
extern Event EV_Actor_AttackPlayer;
extern Event EV_Actor_AIOn;
extern Event EV_Actor_AIOff;
extern Event EV_Actor_AIDeaf;
extern Event EV_Actor_AIDumb;
extern Event EV_ActorIncomingProjectile;
extern Event EV_Anim_Done;
extern Event EV_ActorOnlyShootable;
extern Event EV_Actor_BounceOff;
extern Event EV_Actor_Push;
extern Event EV_Actor_Statemap;
extern Event EV_Actor_SetTargetable;
//
// Export these events for AISpawnPoint (since 2.30)
//
extern Event EV_Actor_SetGun;
extern Event EV_Actor_SetGun2;
extern Event EV_Actor_GetGun;
extern Event EV_Actor_GetSight;
extern Event EV_Actor_SetSight;
extern Event EV_Actor_SetSight2;
extern Event EV_Actor_GetHearing;
extern Event EV_Actor_SetHearing;
extern Event EV_Actor_SetHearing2;
extern Event EV_Actor_GetFov;
extern Event EV_Actor_SetFov;
extern Event EV_Actor_SetFov2;
extern Event EV_Actor_SetTypeIdle;
extern Event EV_Actor_SetTypeIdle2;
extern Event EV_Actor_GetTypeIdle;
extern Event EV_Actor_SetTypeAttack;
extern Event EV_Actor_SetTypeAttack2;
extern Event EV_Actor_GetTypeAttack;
extern Event EV_Actor_SetTypeDisguise;
extern Event EV_Actor_SetTypeDisguise2;
extern Event EV_Actor_GetTypeDisguise;
extern Event EV_Actor_SetDisguiseLevel;
extern Event EV_Actor_SetDisguiseLevel2;
extern Event EV_Actor_GetDisguiseLevel;
extern Event EV_Actor_SetTypeGrenade;
extern Event EV_Actor_SetTypeGrenade2;
extern Event EV_Actor_GetTypeGrenade;
extern Event EV_Actor_SetPatrolPath;
extern Event EV_Actor_SetPatrolPath2;
extern Event EV_Actor_GetPatrolPath;
extern Event EV_Actor_SetPatrolWaitTrigger;
extern Event EV_Actor_SetPatrolWaitTrigger2;
extern Event EV_Actor_GetPatrolWaitTrigger;
extern Event EV_Actor_SetAlarmNode;
extern Event EV_Actor_SetAlarmNode2;
extern Event EV_Actor_GetAlarmNode;
extern Event EV_Actor_SetAccuracy;
extern Event EV_Actor_SetAccuracy2;
extern Event EV_Actor_GetAccuracy;
extern Event EV_Actor_SetMinDistance;
extern Event EV_Actor_SetMinDistance2;
extern Event EV_Actor_GetMinDistance;
extern Event EV_Actor_SetMaxDistance;
extern Event EV_Actor_SetMaxDistance2;
extern Event EV_Actor_GetMaxDistance;
extern Event EV_Actor_GetLeash;
extern Event EV_Actor_SetLeash;
extern Event EV_Actor_SetLeash2;
extern Event EV_Actor_GetInterval;
extern Event EV_Actor_SetInterval;
extern Event EV_Actor_SetInterval2;
extern Event EV_Actor_SetDisguiseRange;
extern Event EV_Actor_SetDisguiseRange2;
extern Event EV_Actor_GetDisguiseRange;
extern Event EV_Actor_SetDisguisePeriod;
extern Event EV_Actor_SetDisguisePeriod2;
extern Event EV_Actor_GetDisguisePeriod;
extern Event EV_Actor_SetGrenadeAwareness;
extern Event EV_Actor_SetGrenadeAwareness2;
extern Event EV_Actor_GetGrenadeAwareness;
extern Event EV_Actor_SetTurret;
extern Event EV_Actor_SetTurret2;
extern Event EV_Actor_GetTurret;
extern Event EV_Actor_SetSoundAwareness;
extern Event EV_Actor_SetSoundAwareness2;
extern Event EV_Actor_GetSoundAwareness;
extern Event EV_Actor_SetGrenadeAwareness;
extern Event EV_Actor_SetGrenadeAwareness2;
extern Event EV_Actor_SetAmmoGrenade;
extern Event EV_Actor_SetAmmoGrenade2;
extern Event EV_Actor_GetAmmoGrenade;
extern Event EV_Actor_GetMaxNoticeTimeScale;
extern Event EV_Actor_SetMaxNoticeTimeScale;
extern Event EV_Actor_SetMaxNoticeTimeScale2;
extern Event EV_Actor_GetFixedLeash;
extern Event EV_Actor_SetFixedLeash;
extern Event EV_Actor_SetFixedLeash2;
extern Event EV_Actor_GetEnemyShareRange;
extern Event EV_Actor_SetEnemyShareRange;
extern Event EV_Actor_SetEnemyShareRange2;
extern Event EV_Actor_SetWeapon;
extern Event EV_Actor_GetWeapon;
extern Event EV_Actor_GetVoiceType;
extern Event EV_Actor_SetVoiceType;
extern Event EV_Actor_SetVoiceType2;
extern Event EV_Actor_GetFavoriteEnemy;
extern Event EV_Actor_SetFavoriteEnemy;
extern Event EV_Actor_SetFavoriteEnemy2;
extern Event EV_Actor_SetBalconyHeight;
extern Event EV_Actor_SetBalconyHeight2;
extern Event EV_Actor_GetBalconyHeight;
extern Event EV_Actor_GetNoSurprise;
extern Event EV_Actor_SetNoSurprise;
extern Event EV_Actor_SetNoSurprise2;
extern Event EV_Actor_DeathEmbalm;
// Bones used by actor
@@ -981,7 +1053,7 @@ public:
void NotifySquadmateKilled( Sentient *pSquadMate, Sentient *pAttacker );
void RaiseAlertnessForEventType( int iType );
void RaiseAlertness( float fAmount );
virtual bool CanSee( Entity *e1, float fov, float vision_distance ) override;
virtual bool CanSee( Entity *e1, float fov, float vision_distance, bool bNoEnts ) override;
virtual Vector GunPosition( void ) override;
bool WithinVisionDistance( Entity *ent ) const;
bool InFOV( Vector pos, float check_fov, float check_fovdot );
@@ -1178,7 +1250,7 @@ public:
bool ShortenPathToAttack( float fMinDist );
void StrafeToAttack( float fDist, vec3_t vDir );
virtual Vector GunTarget( bool bNoCollision ) override;
virtual qboolean setModel( void );
virtual qboolean setModel( void ) override;
void EventSetHeadModel( Event *ev );
void EventGetHeadModel( Event *ev );
void EventSetHeadSkin( Event *ev );
+1 -1
View File
@@ -465,7 +465,7 @@ void Actor::State_Cover_Shoot
if (level.inttime > m_iStateTime + 10000)
{
gi.Cvar_Set("g_monitornum", va("%i", entnum));
gi.cvar_set("g_monitornum", va("%i", entnum));
assert(!"anim/shoot.scr took over 10 seconds");
Com_Error(ERR_DROP, "anim/shoot.scr took over 10 seconds, entnum = %i, targetname = %s", entnum, targetname.c_str());
}
+1 -1
View File
@@ -224,7 +224,7 @@ void Actor::Think_Curious
return;
}
if (m_Enemy || CanSeeEnemy(100))
if (!m_Enemy || CanSeeEnemy(100))
{
ClearPath();
Anim_Stand();
+2 -2
View File
@@ -313,7 +313,7 @@ float ActorEnemy::UpdateLMRF
*pbInFovAndRange = true;
if (!pSelf->CanSee(m_pEnemy, 0, 0))
if (!pSelf->CanSee(m_pEnemy, 0, 0, false))
{
return 8.0;
}
@@ -684,7 +684,7 @@ void ActorEnemySet::ConfirmEnemyIfCanSeeSharerOrEnemy
if (!pSelf->CanSee(
pSharer,
pSelf->m_bSilent ? 90.0f : 0,
0.828 * world->farplane_distance))
0.828 * world->farplane_distance, false))
return;
}
pActorEnemy->m_fVisibility = 1.0;
+713 -607
View File
File diff suppressed because it is too large. Load diff
+130 -128
View File
@@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@@ -24,10 +24,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#ifndef __ANIMATE_H__
#define __ANIMATE_H__
#if defined ( GAME_DLL )
#include "entity.h"
#elif defined ( CGAME_DLL )
#include "script/canimate.h"
#if defined(GAME_DLL)
# include "entity.h"
#elif defined(CGAME_DLL)
# include "script/canimate.h"
#endif
#include "archive.h"
@@ -35,177 +35,179 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
extern Event EV_SetAnim;
extern Event EV_SetSyncTime;
#define ANIM_PAUSED 1
#define ANIM_SYNC 2
#define ANIM_FINISHED 4
#define ANIM_NOEXIT 8
#define ANIM_NODELTA 16
#define ANIM_LOOP 32
#define ANIM_NOACTION 64
#define ANIM_PAUSED 1
#define ANIM_SYNC 2
#define ANIM_FINISHED 4
#define ANIM_NOEXIT 8
#define ANIM_NODELTA 16
#define ANIM_LOOP 32
#define ANIM_NOACTION 64
#define MINIMUM_DELTA_MOVEMENT 8
#define MINIMUM_DELTA_MOVEMENT_PER_FRAME ( MINIMUM_DELTA_MOVEMENT / 20.0f )
#define MINIMUM_DELTA_MOVEMENT 8
#define MINIMUM_DELTA_MOVEMENT_PER_FRAME (MINIMUM_DELTA_MOVEMENT / 20.0f)
#define FLAGGED_ANIMATE_SLOT 20
#define FLAGGED_ANIMATE_SLOT 20
class Animate;
typedef SafePtr<Animate> AnimatePtr;
class AnimationEvent : public Event
{
private:
short anim_number;
short anim_frame;
public:
CLASS_PROTOTYPE( AnimationEvent );
void *operator new( size_t size );
void operator delete( void *ptr );
AnimationEvent( str name ) : Event( name ) { anim_number = 0; anim_frame = 0; }
AnimationEvent( const Event& ev ) : Event( ev ) { anim_number = 0; anim_frame = 0; }
AnimationEvent() {}
void SetAnimationFrame( int frame ) { anim_frame = frame; };
void SetAnimationNumber( int num ) { anim_number = num; };
};
class Animate : public Entity
{
protected:
int animFlags[ MAX_FRAMEINFOS ];
int animFlags[MAX_FRAMEINFOS];
float syncTime;
float syncRate;
int pauseSyncTime;
float syncTime;
float syncRate;
int pauseSyncTime;
bool is_paused;
Event *doneEvents[ MAX_FRAMEINFOS ];
Event *doneEvents[MAX_FRAMEINFOS];
float animtimes[ MAX_FRAMEINFOS ];
float frametimes[ MAX_FRAMEINFOS ];
float animtimes[MAX_FRAMEINFOS];
float frametimes[MAX_FRAMEINFOS];
public:
Vector frame_delta;
Vector frame_delta;
float angular_delta;
public:
CLASS_PROTOTYPE( Animate );
CLASS_PROTOTYPE(Animate);
Animate();
~Animate();
Animate();
~Animate();
void DoExitCommands( int slot = 0 );
void NewAnim( int animnum, int slot = 0, float weight = 1.0f );
void NewAnim( int animnum, Event *endevent, int slot = 0, float weight = 1.0f );
void NewAnim( int animnum, Event &endevent, int slot = 0, float weight = 1.0f );
void NewAnim( const char *animname, int slot = 0, float weight = 1.0f );
void NewAnim( const char *animname, Event *endevent, int slot = 0, float weight = 1.0f );
void NewAnim( const char *animname, Event &endevent, int slot = 0, float weight = 1.0f );
void SetFrame( void );
qboolean HasAnim( const char *animname );
Event *AnimDoneEvent( int slot = 0 );
void SetAnimDoneEvent( Event &event, int slot = 0 );
void SetAnimDoneEvent( Event *event, int slot = 0 );
int NumFrames( int slot = 0 );
int NumAnims( void );
const char *AnimName( int slot = 0 );
float AnimTime( int slot = 0 );
virtual void AnimFinished( int slot = 0 );
void SetTime( int slot = 0, float time = 0.0f );
void SetNormalTime( int slot = 0, float normal = 1.0f );
float GetTime( int slot = 0 );
float GetNormalTime( int slot = 0 );
void SetWeight( int slot = 0, float weight = 1.0f );
float GetWeight( int slot = 0 );
void SetRepeatType( int slot = 0 );
void SetOnceType( int slot = 0 );
void SetSyncRate( float rate );
void SetSyncTime( float s );
void UseSyncTime(int slot, int sync);
void NewAnim(int animnum, int slot = 0, float weight = 1.0f);
void NewAnim(int animnum, Event *endevent, int slot = 0, float weight = 1.0f);
void NewAnim(int animnum, Event &endevent, int slot = 0, float weight = 1.0f);
void NewAnim(const char *animname, int slot = 0, float weight = 1.0f);
void NewAnim(const char *animname, Event *endevent, int slot = 0, float weight = 1.0f);
void NewAnim(const char *animname, Event &endevent, int slot = 0, float weight = 1.0f);
void SetFrame(void);
qboolean HasAnim(const char *animname);
Event *AnimDoneEvent(int slot = 0);
void SetAnimDoneEvent(Event &event, int slot = 0);
void SetAnimDoneEvent(Event *event, int slot = 0);
int NumAnims(void);
const char *AnimName(int slot = 0);
float AnimTime(int slot = 0);
void Pause( int slot = 0, int pause = 1 );
void StopAnimating( int slot = 0 );
void StopAnimatingAtEnd( int slot = 0 );
virtual int CurrentAnim( int slot = 0 );
virtual float CurrentTime( int slot = 0 );
int CurrentAnim(int slot = 0) const override;
float CurrentTime(int slot = 0) const override;
void PreAnimate( void ) override;
void PostAnimate( void ) override;
void Archive(Archiver &arc) override;
virtual void AnimFinished(int slot = 0);
virtual void DumpAnimInfo( void );
void Archive( Archiver &arc ) override;
void PreAnimate(void) override;
void PostAnimate(void) override;
void SetTime(int slot = 0, float time = 0.0f);
void SetNormalTime(int slot = 0, float normal = 1.0f);
float GetTime(int slot = 0);
float GetNormalTime(int slot = 0);
void SetWeight(int slot = 0, float weight = 1.0f);
float GetWeight(int slot = 0);
void SetRepeatType(int slot = 0);
void SetOnceType(int slot = 0);
bool IsRepeatType(int slot);
void Pause(int slot = 0, int pause = 1);
void StopAnimating(int slot = 0);
void UseSyncTime(int slot, int sync);
void SetSyncTime(float s);
float GetSyncTime();
void SetSyncRate(float rate);
void FrameDeltaEvent( Event *ev );
void ForwardExec( Event *ev );
void EventSetSyncTime( Event *ev );
void EventIsLoopingAnim( Event *ev );
void StopAnimating( Event *ev );
float GetSyncRate();
void PauseSyncTime(int pause);
float GetYawOffset();
float GetCrossTime(int slot);
void DoExitCommands(int slot = 0);
void ForwardExec(Event *ev);
void EventSetSyncTime(Event *ev);
void EventIsLoopingAnim(Event *ev);
void EventSetYawFromBone(Event *ev);
void EventPlayerSpawn(Event *ev);
void EventPlayerSpawnUtility(Event *ev);
void EventPauseAnim(Event *ev);
virtual void DumpAnimInfo();
void SlotChanged(int slot);
// FIXME: delete this, fakk2 remnant
int NumFrames(int slot = 0);
};
extern MEM_BlockAlloc<AnimationEvent> AnimationEvent_allocator;
inline int Animate::CurrentAnim( int slot )
inline void Animate::SetWeight(int slot, float weight)
{
return edict->s.frameInfo[ slot ].index;
edict->s.frameInfo[slot].weight = weight;
}
inline float Animate::CurrentTime( int slot )
inline float Animate::GetWeight(int slot)
{
return edict->s.frameInfo[ slot ].time;
return edict->s.frameInfo[slot].weight;
}
inline int Animate::NumFrames( int slot )
inline bool Animate::IsRepeatType(int slot)
{
return gi.Anim_NumFrames( edict->tiki, edict->s.frameInfo[ slot ].index );
return (animFlags[slot] & ANIM_LOOP) != 0;
}
inline float Animate::AnimTime( int slot )
inline float Animate::GetSyncTime()
{
return animtimes[ slot ];
return syncTime;
}
inline int Animate::NumAnims( void )
inline float Animate::GetSyncRate()
{
return gi.TIKI_NumAnims( edict->tiki );
return syncRate;
}
inline const char *Animate::AnimName( int slot )
inline void Animate::PauseSyncTime(int pause)
{
return gi.Anim_NameForNum( edict->tiki, edict->s.frameInfo[ slot ].index );
pauseSyncTime = pause;
}
inline Event *Animate::AnimDoneEvent( int slot )
inline void Animate::Archive(Archiver& arc)
{
return doneEvents[ slot ];
Entity::Archive(arc);
for (int i = MAX_FRAMEINFOS - 1; i >= 0; i--) {
arc.ArchiveInteger(&animFlags[i]);
}
arc.ArchiveFloat(&syncTime);
arc.ArchiveFloat(&syncRate);
arc.ArchiveInteger(&pauseSyncTime);
arc.ArchiveBool(&is_paused);
for (int i = MAX_FRAMEINFOS - 1; i >= 0; i--) {
arc.ArchiveEventPointer(&doneEvents[i]);
}
for (int i = MAX_FRAMEINFOS - 1; i >= 0; i--) {
arc.ArchiveFloat(&animtimes[i]);
}
for (int i = MAX_FRAMEINFOS - 1; i >= 0; i--) {
arc.ArchiveFloat(&frametimes[i]);
}
arc.ArchiveVector(&frame_delta);
arc.ArchiveFloat(&angular_delta);
}
inline void Animate::Archive( Archiver &arc )
inline void Animate::SlotChanged(int slot)
{
Entity::Archive( arc );
animFlags[slot] = (animFlags[slot] | ANIM_NODELTA) & ~ANIM_FINISHED;
}
for( int i = MAX_FRAMEINFOS - 1; i >= 0; i-- )
{
arc.ArchiveInteger( &animFlags[ i ] );
}
arc.ArchiveFloat( &syncTime );
arc.ArchiveFloat( &syncRate );
arc.ArchiveInteger( &pauseSyncTime );
for( int i = MAX_FRAMEINFOS - 1; i >= 0; i-- )
{
arc.ArchiveEventPointer( &doneEvents[ i ] );
}
for( int i = MAX_FRAMEINFOS - 1; i >= 0; i-- )
{
arc.ArchiveFloat( &animtimes[ i ] );
}
for( int i = MAX_FRAMEINFOS - 1; i >= 0; i-- )
{
arc.ArchiveFloat( &frametimes[ i ] );
}
arc.ArchiveVector( &frame_delta );
inline float Animate::CurrentTime(int slot) const
{
return edict->s.frameInfo[slot].time;
}
inline Event *Animate::AnimDoneEvent(int slot)
{
return doneEvents[slot];
}
inline int Animate::NumFrames(int slot)
{
return gi.Anim_NumFrames(edict->tiki, edict->s.frameInfo[slot].index);
}
#endif /* animate.h */
+76
View File
@@ -0,0 +1,76 @@
/*
===========================================================================
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include "animationevent.h"
#include "../qcommon/mem_blockalloc.h"
MEM_BlockAlloc<AnimationEvent> AnimationEvent_allocator;
CLASS_DECLARATION(Event, AnimationEvent, NULL) {
{NULL, NULL}
};
AnimationEvent::AnimationEvent(str command, int numArgs)
: Event(command, numArgs)
{
anim_number = 0;
anim_frame = 0;
}
AnimationEvent::AnimationEvent(const Event& ev)
: Event(ev)
{
anim_number = 0;
anim_frame = 0;
}
AnimationEvent::AnimationEvent() {}
void *AnimationEvent::operator new(size_t size)
{
return AnimationEvent_allocator.Alloc();
}
void AnimationEvent::operator delete(void *ptr)
{
return AnimationEvent_allocator.Free(ptr);
}
int AnimationEvent::GetAnimationFrame() const
{
return anim_frame;
}
int AnimationEvent::GetAnimationNumber() const
{
return anim_number;
}
void AnimationEvent::SetAnimationFrame(int frame)
{
anim_frame = frame;
};
void AnimationEvent::SetAnimationNumber(int num)
{
anim_number = num;
};
+48
View File
@@ -0,0 +1,48 @@
/*
===========================================================================
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// animate.h -- Animation event
#include "../qcommon/listener.h"
class AnimationEvent : public Event
{
private:
short anim_number;
short anim_frame;
public:
CLASS_PROTOTYPE(AnimationEvent);
void *operator new(size_t size);
void operator delete(void *ptr);
AnimationEvent(str command, int numArgs = 0);
AnimationEvent(const Event& ev);
AnimationEvent();
int GetAnimationFrame() const;
int GetAnimationNumber() const;
void SetAnimationFrame(int frame);
void SetAnimationNumber(int num);
};
extern MEM_BlockAlloc<AnimationEvent> AnimationEvent_allocator;
+4 -4
View File
@@ -814,7 +814,7 @@ SafePtrBase * ptr
{
pointer_fixup_t *fixup;
ArchiveData( ARC_SafePointer, &index, sizeof( &index ) );
ArchiveData( ARC_SafePointer, &index, sizeof( index ) );
// Check for a NULL pointer
assert( ptr );
@@ -984,11 +984,11 @@ void Archiver::ArchiveConfigString( int cs )
if( archivemode == ARCHIVE_READ )
{
ArchiveString( &s );
glbs.SetConfigstring( cs, s.c_str() );
glbs.setConfigstring( cs, s.c_str() );
}
else
{
s = glbs.GetConfigstring( cs );
s = glbs.getConfigstring( cs );
ArchiveString( &s );
}
#endif
@@ -1133,7 +1133,7 @@ void Archiver::ArchiveObject
}
ArchiveInteger( &entnum );
( ( Entity * )obj )->SetEntNum( entnum );
( ( Entity * )obj )->entnum = entnum;
//
// make sure to setup spawnflags properly
//
+5 -6
View File
@@ -226,7 +226,7 @@ inline void Container<Type>::Archive
numobjects = num;
}
ArchiveFunc( arc, &objlist[ i ] );
ArchiveFunc( arc, &objlist[ i - 1 ] );
}
}
@@ -348,7 +348,7 @@ void con_set< key, value >::Archive
Archiver& arc
)
{
Entry< key, value > *e;
Entry *e;
int hash;
int i;
@@ -361,18 +361,17 @@ void con_set< key, value >::Archive
{
if( tableLength != 1 )
{
table = new Entry< key, value > *[ tableLength ]();
memset( table, 0, tableLength * sizeof( Entry< key, value > * ) );
table = new Entry *[ tableLength ]();
memset( table, 0, tableLength * sizeof( Entry * ) );
}
for( i = 0; i < count; i++ )
{
e = new Entry< key, value >;
e = new Entry;
e->Archive( arc );
hash = HashCode< key >( e->key ) % tableLength;
e->index = i;
e->next = table[ hash ];
table[ hash ] = e;
}
+68 -47
View File
@@ -50,7 +50,6 @@ float PM_NOCLIPfriction = 5.0f;
int c_pmove = 0;
/*
===============
PM_AddEvent
@@ -1100,35 +1099,57 @@ static void PM_CheckDuck( void )
return;
}
if( ( pm->ps->pm_flags & ( PMF_DUCKED | PMF_VIEW_PRONE ) ) == ( PMF_DUCKED | PMF_VIEW_PRONE ) )
{
pm->maxs[ 2 ] = 54.0f;
}
else if( pm->ps->pm_flags & PMF_DUCKED )
{
pm->maxs[ 2 ] = 60.0f;
pm->ps->viewheight = CROUCH_VIEWHEIGHT;
}
else if( pm->ps->pm_flags & PMF_VIEW_PRONE )
{
pm->maxs[ 2 ] = 20.0f;
pm->ps->viewheight = PRONE_VIEWHEIGHT;
}
else if( pm->ps->pm_flags & PMF_VIEW_DUCK_RUN )
{
pm->maxs[ 2 ] = 94.0f;
pm->mins[ 2 ] = 54.0f;
pm->ps->viewheight = DEFAULT_VIEWHEIGHT;
}
else if( pm->ps->pm_flags & PMF_VIEW_JUMP_START )
{
pm->maxs[ 2 ] = 94.0f;
pm->ps->viewheight = JUMP_START_VIEWHEIGHT;
}
else
{
pm->maxs[ 2 ] = 94.0f;
pm->ps->viewheight = DEFAULT_VIEWHEIGHT;
if (pm->protocol >= protocol_e::PROTOCOL_MOHTA_MIN) {
//
// Prone was removed in 2.0
//
if (pm->ps->pm_flags & PMF_DUCKED)
{
pm->maxs[2] = 54.f;
pm->ps->viewheight = CROUCH_VIEWHEIGHT;
}
else if (pm->ps->pm_flags & PMF_VIEW_JUMP_START)
{
pm->maxs[2] = 94.0f;
pm->ps->viewheight = JUMP_START_VIEWHEIGHT;
}
else
{
pm->maxs[2] = 94.0f;
pm->ps->viewheight = DEFAULT_VIEWHEIGHT;
}
} else {
if ((pm->ps->pm_flags & (PMF_DUCKED | PMF_VIEW_PRONE)) == (PMF_DUCKED | PMF_VIEW_PRONE))
{
pm->maxs[2] = 54.0f;
pm->ps->viewheight = CROUCH_VIEWHEIGHT;
}
else if (pm->ps->pm_flags & PMF_DUCKED)
{
pm->maxs[2] = 60.0f;
pm->ps->viewheight = CROUCH_VIEWHEIGHT;
}
else if (pm->ps->pm_flags & PMF_VIEW_PRONE)
{
pm->maxs[2] = 20.0f;
pm->ps->viewheight = PRONE_VIEWHEIGHT;
}
else if (pm->ps->pm_flags & PMF_VIEW_DUCK_RUN)
{
pm->maxs[2] = 94.0f;
pm->mins[2] = 54.0f;
pm->ps->viewheight = DEFAULT_VIEWHEIGHT;
}
else if (pm->ps->pm_flags & PMF_VIEW_JUMP_START)
{
pm->maxs[2] = 94.0f;
pm->ps->viewheight = JUMP_START_VIEWHEIGHT;
}
else
{
pm->maxs[2] = 94.0f;
pm->ps->viewheight = DEFAULT_VIEWHEIGHT;
}
}
}
@@ -1450,17 +1471,17 @@ void PmoveSingle( pmove_t *pmove )
{
if( pm->cmd.buttons & BUTTON_LEAN_LEFT )
{
if( pm->ps->fLeanAngle <= -40.0f )
if( pm->ps->fLeanAngle <= -pm->leanMax)
{
pm->ps->fLeanAngle = -40.0f;
pm->ps->fLeanAngle = -pm->leanMax;
}
else
{
float fAngle = pml.frametime * ( -40.0f - pm->ps->fLeanAngle );
float fLeanAngle = pml.frametime * -4.0f;
float fAngle = pml.frametime * ( -pm->leanMax - pm->ps->fLeanAngle ) * pm->leanAdd;
float fLeanAngle = pml.frametime * -pm->leanSpeed;
if( fAngle * 10.0f <= fLeanAngle ) {
fLeanAngle = fAngle * 10.0f;
if( fAngle <= fLeanAngle ) {
fLeanAngle = fAngle;
}
pm->ps->fLeanAngle += fLeanAngle;
@@ -1468,19 +1489,19 @@ void PmoveSingle( pmove_t *pmove )
}
else
{
if( pm->ps->fLeanAngle >= 40.0f )
if( pm->ps->fLeanAngle >= pm->leanMax )
{
pm->ps->fLeanAngle = 40.0f;
pm->ps->fLeanAngle = pm->leanMax;
}
else
{
float fAngle = 40.0f - pm->ps->fLeanAngle;
float fLeanAngle = pml.frametime * 4.0f;
float fMult = pml.frametime * fAngle;
float fAngle = pm->leanMax - pm->ps->fLeanAngle;
float fLeanAngle = pml.frametime * pm->leanSpeed;
float fMult = pml.frametime * fAngle * pm->leanAdd;
if( fLeanAngle <= fMult * 10.0f )
if( fLeanAngle <= fMult )
{
fLeanAngle = fMult * 10.0f;
fLeanAngle = fMult;
}
else
{
@@ -1493,11 +1514,11 @@ void PmoveSingle( pmove_t *pmove )
}
else if( pm->ps->fLeanAngle )
{
float fAngle = pm->ps->fLeanAngle * pml.frametime * 15.0f;
float fAngle = pm->ps->fLeanAngle * pml.frametime * pm->leanRecoverSpeed;
if( pm->ps->fLeanAngle <= 0.0f )
{
float fLeanAngle = -4.0f * pml.frametime;
float fLeanAngle = pml.frametime * -pm->leanSpeed;
if( fAngle <= fLeanAngle )
{
@@ -1508,9 +1529,9 @@ void PmoveSingle( pmove_t *pmove )
}
else
{
float fLeanAngle = pml.frametime * 4.0f;
float fLeanAngle = pml.frametime * pm->leanSpeed;
if( fLeanAngle <= fAngle ) {
if(fAngle >= fLeanAngle) {
fLeanAngle = fAngle;
}
+652 -561
View File
File diff suppressed because it is too large. Load diff
+25
View File
@@ -0,0 +1,25 @@
/*
===========================================================================
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include "bg_voteoptions.h"
// FIXME: unimplemented
+76
View File
@@ -0,0 +1,76 @@
/*
===========================================================================
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#pragma once
#include "listener.h"
#include "g_public.h"
typedef enum voteoptiontype_e {
/** No input. */
VOTE_NO_CHOICES,
/** List of choices. */
VOTE_OPTION_LIST,
/** Text input type command. */
VOTE_OPTION_TEXT,
/** Accepts an integer as an input. */
VOTE_OPTION_INTEGER,
/** Accepts a float number as input. */
VOTE_OPTION_FLOAT,
/** A list of clients, one to choose. */
VOTE_OPTION_CLIENT,
/** A list of clients (excluding self), one to choose. */
VOTE_OPTION_CLIENT_NOT_SELF,
} voteoptiontype_t;
class VoteOptionListItem
{
str m_sItemName;
str m_sCommand;
class VoteOptionListItem *m_pNext;
};
class SingleVoteOption
{
str m_sVoteName;
str m_sCommand;
voteoptiontype_t m_optionType;
VoteOptionListItem *m_pListItem;
class SingleVoteOption *m_pNext;
};
class VoteOptions : public Class
{
public:
CLASS_PROTOTYPE(VoteOptions);
public:
str m_sFileName;
str m_sBuffer;
SingleVoteOption *m_pHeadOption;
int field_5;
float field_6;
float field_7;
float field_8;
float field_9;
float field_10;
};
+104 -78
View File
@@ -115,7 +115,7 @@ void CameraMoveState::DoNodeEvents
ent = NULL;
do
{
ent = ( Entity * )G_FindTarget( ( SimpleEntity * )ent, node->triggertarget.c_str() );
ent = G_FindTarget( ent, node->triggertarget.c_str() );
if( !ent )
{
break;
@@ -486,6 +486,16 @@ Event EV_Camera_NoWatch
"if fadeTime is specified, camera will fade over that time",
EV_NORMAL
);
Event EV_Camera_WatchString
(
"watchstring",
EV_CONSOLE,
"sF",
"string fadeTime",
"Makes the camera watch based on a string.\n"
"if fadeTime is specified, camera will fade over that time",
EV_NORMAL
);
//
// Camera positioning events
@@ -679,46 +689,47 @@ LEVEL_EXIT if the camera is being used, the level exit state will be set
******************************************************************************/
CLASS_DECLARATION( Entity, Camera, "func_camera" )
{
{ &EV_Camera_CameraThink, &Camera::CameraThink },
{ &EV_Activate, &Camera::StartMoving },
{ &EV_Camera_StartMoving, &Camera::StartMoving },
{ &EV_Camera_StopMoving, &Camera::StopMoving },
{ &EV_Camera_Pause, &Camera::Pause },
{ &EV_Camera_Continue, &Camera::Continue },
{ &EV_Camera_SetSpeed, &Camera::SetSpeed },
{ &EV_Camera_SetFollowDistance, &Camera::SetFollowDistance },
{ &EV_Camera_SetFollowYaw, &Camera::SetFollowYaw },
{ &EV_Camera_AbsoluteYaw, &Camera::AbsoluteYaw },
{ &EV_Camera_RelativeYaw, &Camera::RelativeYaw },
{ &EV_Camera_SetOrbitHeight, &Camera::SetOrbitHeight },
{ &EV_Camera_SetFOV, &Camera::SetFOV },
{ &EV_Camera_Orbit, &Camera::OrbitEvent },
{ &EV_Camera_Follow, &Camera::FollowEvent },
{ &EV_Camera_Watch, &Camera::WatchEvent },
{ &EV_Camera_WatchPath, &Camera::WatchPathEvent },
{ &EV_Camera_WatchNodes, &Camera::WatchNodesEvent },
{ &EV_Camera_NoWatch, &Camera::NoWatchEvent },
{ &EV_Camera_LookAt, &Camera::LookAt },
{ &EV_Camera_TurnTo, &Camera::TurnTo },
{ &EV_Camera_MoveToEntity, &Camera::MoveToEntity },
{ &EV_Camera_MoveToPos, &Camera::MoveToPos },
{ &EV_Camera_Cut, &Camera::Cut },
{ &EV_Camera_FadeTime, &Camera::FadeTime },
{ &EV_Camera_SetNextCamera, &Camera::SetNextCamera },
{ &EV_Camera_SetupCamera, &Camera::SetupCamera },
{ &EV_SetAngles, &Camera::SetAnglesEvent },
{ &EV_Camera_SetAutoState, &Camera::SetAutoStateEvent },
{ &EV_Camera_SetAutoRadius, &Camera::SetAutoRadiusEvent },
{ &EV_Camera_SetAutoStartTime, &Camera::SetAutoStartTimeEvent },
{ &EV_Camera_SetAutoStopTime, &Camera::SetAutoStopTimeEvent },
{ &EV_Camera_SetMaximumAutoFOV, &Camera::SetMaximumAutoFOVEvent },
{ &EV_Camera_SetAutoActive, &Camera::SetAutoActiveEvent },
{ &EV_Camera_SetShowQuakes, &Camera::SetShowQuakes },
CLASS_DECLARATION(Entity, Camera, "func_camera")
{
{ &EV_Camera_CameraThink, &Camera::CameraThink },
{ &EV_Activate, &Camera::StartMoving },
{ &EV_Camera_StartMoving, &Camera::StartMoving },
{ &EV_Camera_StopMoving, &Camera::StopMoving },
{ &EV_Camera_Pause, &Camera::Pause },
{ &EV_Camera_Continue, &Camera::Continue },
{ &EV_Camera_SetSpeed, &Camera::SetSpeed },
{ &EV_Camera_SetFollowDistance, &Camera::SetFollowDistance },
{ &EV_Camera_SetFollowYaw, &Camera::SetFollowYaw },
{ &EV_Camera_AbsoluteYaw, &Camera::AbsoluteYaw },
{ &EV_Camera_RelativeYaw, &Camera::RelativeYaw },
{ &EV_Camera_SetOrbitHeight, &Camera::SetOrbitHeight },
{ &EV_Camera_SetFOV, &Camera::SetFOV },
{ &EV_Camera_Orbit, &Camera::OrbitEvent },
{ &EV_Camera_Follow, &Camera::FollowEvent },
{ &EV_Camera_Watch, &Camera::WatchEvent },
{ &EV_Camera_WatchPath, &Camera::WatchPathEvent },
{ &EV_Camera_WatchNodes, &Camera::WatchNodesEvent },
{ &EV_Camera_NoWatch, &Camera::NoWatchEvent },
{ &EV_Camera_LookAt, &Camera::LookAt },
{ &EV_Camera_TurnTo, &Camera::TurnTo },
{ &EV_Camera_MoveToEntity, &Camera::MoveToEntity },
{ &EV_Camera_MoveToPos, &Camera::MoveToPos },
{ &EV_Camera_Cut, &Camera::Cut },
{ &EV_Camera_FadeTime, &Camera::FadeTime },
{ &EV_Camera_SetNextCamera, &Camera::SetNextCamera },
{ &EV_Camera_SetupCamera, &Camera::SetupCamera },
{ &EV_SetAngles, &Camera::SetAnglesEvent },
{ &EV_Camera_SetAutoState, &Camera::SetAutoStateEvent },
{ &EV_Camera_SetAutoRadius, &Camera::SetAutoRadiusEvent },
{ &EV_Camera_SetAutoStartTime, &Camera::SetAutoStartTimeEvent },
{ &EV_Camera_SetAutoStopTime, &Camera::SetAutoStopTimeEvent },
{ &EV_Camera_SetMaximumAutoFOV, &Camera::SetMaximumAutoFOVEvent },
{ &EV_Camera_SetAutoActive, &Camera::SetAutoActiveEvent },
{ &EV_Camera_WatchString, &Camera::WatchStringEvent },
{ &EV_Camera_SetShowQuakes, &Camera::EventShowQuakes },
{ NULL, NULL }
};
{ NULL, NULL }
};
Camera::Camera()
{
@@ -1935,20 +1946,47 @@ void Camera::WatchEvent
Event *ev
)
{
float time;
{
float time;
if ( ev->NumArgs() > 1 )
{
time = ev->GetFloat( 2 );
}
else
{
time = fadeTime;
}
if (ev->NumArgs() > 1)
{
time = ev->GetFloat(2);
}
else
{
time = fadeTime;
}
Watch( ev->GetString( 1 ), time );
}
// fixed since mohaab v2.30
// use the entity instead
Watch(ev->GetEntity(1), time);
}
void Camera::WatchStringEvent(Event* ev) {
float time;
if (ev->NumArgs() > 1)
{
time = ev->GetFloat(2);
}
else
{
time = fadeTime;
}
Watch(ev->GetString(1), time);
}
void Camera::EventShowQuakes(Event* ev)
{
if (ev->NumArgs() > 0)
{
m_bShowquakes = ev->GetBoolean(1);
} else {
m_bShowquakes = qtrue;
}
}
Entity * GetWatchEntity
(
@@ -2174,18 +2212,6 @@ void Camera::NoWatchEvent
newstate.watch.watchNodes = false;
}
void Camera::SetShowQuakes( Event * ev )
{
if( ev->NumArgs() > 0 )
{
m_bShowquakes = ev->GetBoolean( 1 );
}
else
{
m_bShowquakes = 1;
}
}
void SetCamera
(
Entity *ent,
@@ -2604,36 +2630,36 @@ void CameraManager::UpdateUI
//
// set path name
//
gi.Cvar_Set( "cam_filename", pathName );
gi.cvar_set( "cam_filename", pathName );
if ( current )
{
gi.Cvar_Set( "cam_origin", va( "%.2f %.2f %.2f", current->origin[ 0 ], current->origin[ 1 ], current->origin[ 2 ] ) );
gi.Cvar_Set( "cam_angles_yaw", va( "%.1f", current->angles[ YAW ] ) );
gi.Cvar_Set( "cam_angles_pitch", va( "%.1f", current->angles[ PITCH ] ) );
gi.Cvar_Set( "cam_angles_roll", va( "%.1f", current->angles[ ROLL ] ) );
gi.Cvar_Set( "cam_thread", current->thread.c_str() );
gi.Cvar_Set( "cam_target", current->triggertarget.c_str() );
gi.Cvar_Set( "cam_watch", current->watchEnt.c_str() );
gi.cvar_set( "cam_origin", va( "%.2f %.2f %.2f", current->origin[ 0 ], current->origin[ 1 ], current->origin[ 2 ] ) );
gi.cvar_set( "cam_angles_yaw", va( "%.1f", current->angles[ YAW ] ) );
gi.cvar_set( "cam_angles_pitch", va( "%.1f", current->angles[ PITCH ] ) );
gi.cvar_set( "cam_angles_roll", va( "%.1f", current->angles[ ROLL ] ) );
gi.cvar_set( "cam_thread", current->thread.c_str() );
gi.cvar_set( "cam_target", current->triggertarget.c_str() );
gi.cvar_set( "cam_watch", current->watchEnt.c_str() );
temp = current->GetFov();
if ( temp )
{
gi.Cvar_Set( "cam_fov", va( "%.1f", temp ) );
gi.cvar_set( "cam_fov", va( "%.1f", temp ) );
}
else
{
gi.Cvar_Set( "cam_fov", "Default" );
gi.cvar_set( "cam_fov", "Default" );
}
temp = current->GetFadeTime();
if ( temp != -1 )
{
gi.Cvar_Set( "cam_fadetime", va( "%.2f", temp ) );
gi.cvar_set( "cam_fadetime", va( "%.2f", temp ) );
}
else
{
gi.Cvar_Set( "cam_fadetime", "Default" );
gi.cvar_set( "cam_fadetime", "Default" );
}
gi.Cvar_Set( "cam_speed", va( "%.1f", current->speed ) );
gi.cvar_set( "cam_speed", va( "%.1f", current->speed ) );
//
// set node num
@@ -2645,7 +2671,7 @@ void CameraManager::UpdateUI
next = next->GetNext();
num++;
}
gi.Cvar_Set( "cam_nodenum", va( "%d", num ) );
gi.cvar_set( "cam_nodenum", va( "%d", num ) );
}
}
+5 -3
View File
@@ -227,7 +227,6 @@ class Camera : public Entity
// Miscellaneous
Vector m_vPosOffset;
bool m_bShowquakes;
protected:
CameraState currentstate;
@@ -242,6 +241,8 @@ class Camera : public Entity
float followFadeTime; // time for fov transition
float watchFadeTime; // time for fov transition
bool m_bShowquakes;
str nextCamera;
qboolean showcamera;
@@ -285,9 +286,11 @@ class Camera : public Entity
void OrbitEvent( Event *ev );
void FollowEvent( Event *ev );
void WatchEvent( Event *ev );
void WatchStringEvent( Event *ev );
void WatchPathEvent( Event *ev );
void WatchNodesEvent( Event *ev );
void NoWatchEvent( Event *ev );
void NoWatchEvent(Event* ev);
void EventShowQuakes(Event* ev);
void LookAt( Event *ev );
void MoveToEntity( Event *ev );
void MoveToPos( Event *ev );
@@ -306,7 +309,6 @@ class Camera : public Entity
void SetAutoStopTimeEvent( Event * ev );
void SetMaximumAutoFOVEvent( Event * ev );
void SetAutoActiveEvent( Event * ev );
void SetShowQuakes( Event * ev );
str& NextCamera( void );
float Fov( void );
File diff suppressed because it is too large. Load diff
+264 -319
View File
@@ -29,390 +29,335 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "entity.h"
#include "script.h"
enum testcondition_t
{
TC_ISTRUE, // no prefix
TC_ISFALSE, // !
TC_EDGETRUE, // +
TC_EDGEFALSE // -
};
enum movecontrol_t
{
MOVECONTROL_NONE,
MOVECONTROL_USER, // Quake style
MOVECONTROL_LEGS, // Quake style, legs state system active
MOVECONTROL_USER_MOVEANIM,
MOVECONTROL_ANIM, // move based on animation, with full collision testing
MOVECONTROL_ABSOLUTE, // move based on animation, with full collision testing but no turning
MOVECONTROL_HANGING, // move based on animation, with full collision testing, hanging
MOVECONTROL_ROPE_GRAB,
MOVECONTROL_ROPE_RELEASE,
MOVECONTROL_ROPE_MOVE,
MOVECONTROL_PICKUPENEMY,
MOVECONTROL_PUSH,
MOVECONTROL_CLIMBWALL,
MOVECONTROL_USEANIM,
MOVECONTROL_CROUCH,
MOVECONTROL_LOOPUSEANIM,
MOVECONTROL_USEOBJECT,
MOVECONTROL_COOLOBJECT,
enum testcondition_t {
TC_ISTRUE, // no prefix
TC_ISFALSE, // !
TC_EDGETRUE, // +
TC_EDGEFALSE // -
};
enum cameratype_t
{
CAMERA_TOPDOWN,
CAMERA_BEHIND,
CAMERA_FRONT,
CAMERA_SIDE,
CAMERA_BEHIND_FIXED,
CAMERA_SIDE_LEFT,
CAMERA_SIDE_RIGHT,
CAMERA_BEHIND_NOPITCH
enum movecontrol_t {
MOVECONTROL_NONE,
MOVECONTROL_USER, // Quake style
MOVECONTROL_LEGS, // Quake style, legs state system active
MOVECONTROL_USER_MOVEANIM,
MOVECONTROL_ANIM, // move based on animation, with full collision testing
MOVECONTROL_ABSOLUTE, // move based on animation, with full collision testing but no turning
MOVECONTROL_HANGING, // move based on animation, with full collision testing, hanging
MOVECONTROL_ROPE_GRAB,
MOVECONTROL_ROPE_RELEASE,
MOVECONTROL_ROPE_MOVE,
MOVECONTROL_PICKUPENEMY,
MOVECONTROL_PUSH,
MOVECONTROL_CLIMBWALL,
MOVECONTROL_USEANIM,
MOVECONTROL_CROUCH,
MOVECONTROL_LOOPUSEANIM,
MOVECONTROL_USEOBJECT,
MOVECONTROL_COOLOBJECT,
};
#define DEFAULT_MOVETYPE MOVECONTROL_NONE
#define DEFAULT_CAMERA CAMERA_BEHIND
enum cameratype_t {
CAMERA_TOPDOWN,
CAMERA_BEHIND,
CAMERA_FRONT,
CAMERA_SIDE,
CAMERA_BEHIND_FIXED,
CAMERA_SIDE_LEFT,
CAMERA_SIDE_RIGHT,
CAMERA_BEHIND_NOPITCH
};
#define DEFAULT_MOVETYPE MOVECONTROL_NONE
#define DEFAULT_CAMERA CAMERA_BEHIND
class Conditional;
template< class Type >
struct Condition
{
const char *name;
qboolean ( Type::*func )( Conditional &condition );
};
template<class Type>
struct Condition {
const char *name;
qboolean (Type::*func)(Conditional& condition);
};
class Conditional : public Class
{
private :
qboolean result;
qboolean previous_result;
bool checked;
public :
CLASS_PROTOTYPE( Conditional );
Condition<Class> condition;
Container<str> parmList;
bool getResult( testcondition_t test, Entity &ent );
const char *getName( void );
Conditional( Condition<Class> &condition );
Conditional();
const char *getParm( int number );
void addParm( str parm );
int numParms( void );
void clearCheck( void );
void clearPrevious( void );
};
inline void Conditional::addParm
(
str parm
)
{
parmList.AddObject( parm );
}
inline const char *Conditional::getParm
(
int number
)
{
if ( ( number < 1 ) || ( number > parmList.NumObjects() ) )
{
gi.Error( ERR_DROP, "Parm #%d out of range on %s condition\n", number, condition.name );
}
return parmList.ObjectAt( number ).c_str();
}
inline int Conditional::numParms
(
void
)
{
return parmList.NumObjects();
}
inline void Conditional::clearCheck
(
void
)
{
checked = false;
}
inline void Conditional::clearPrevious
(
void
)
{
previous_result = 0;
}
inline const char *Conditional::getName
(
void
)
{
return condition.name;
}
inline bool Conditional::getResult
(
testcondition_t test,
Entity &ent
)
{
if ( condition.func && !checked )
{
checked = true;
previous_result = result;
result = ( ent.*condition.func )( *this );
}
private:
qboolean result;
qboolean previous_result;
bool checked;
switch( test )
{
case TC_ISFALSE :
return !result;
public:
CLASS_PROTOTYPE(Conditional);
case TC_EDGETRUE:
return result && !previous_result;
Condition<Class> condition;
Container<str> parmList;
case TC_EDGEFALSE:
return !result && previous_result;
bool getResult(testcondition_t test, Entity &ent);
const char *getName(void);
case TC_ISTRUE :
default:
return result != false;
}
Conditional(Condition<Class>& condition);
Conditional();
const char *getParm(int number);
void addParm(str parm);
int numParms(void);
void clearCheck(void);
void clearPrevious(void);
};
inline void Conditional::addParm(str parm)
{
parmList.AddObject(parm);
}
inline const char *Conditional::getParm(int number)
{
if ((number < 1) || (number > parmList.NumObjects())) {
gi.Error(ERR_DROP, "Parm #%d out of range on %s condition\n", number, condition.name);
}
return parmList.ObjectAt(number).c_str();
}
inline int Conditional::numParms(void)
{
return parmList.NumObjects();
}
inline void Conditional::clearCheck(void)
{
checked = false;
}
inline void Conditional::clearPrevious(void)
{
previous_result = 0;
}
inline const char *Conditional::getName(void)
{
return condition.name;
}
inline bool Conditional::getResult(testcondition_t test, Entity& ent)
{
if (condition.func && !checked) {
checked = true;
previous_result = result;
result = (ent.*condition.func)(*this);
}
switch (test) {
case TC_ISFALSE:
return !result;
case TC_EDGETRUE:
return result && !previous_result;
case TC_EDGEFALSE:
return !result && previous_result;
case TC_ISTRUE:
default:
return result != false;
}
}
class State;
class StateMap;
class Expression : public Class
{
private :
struct condition_t
{
testcondition_t test;
int condition_index;
};
{
private:
struct condition_t {
testcondition_t test;
int condition_index;
};
str value;
Container<condition_t> conditions;
str value;
Container<condition_t> conditions;
public :
Expression();
Expression( Expression &exp );
Expression( Script &script, State &state );
public:
Expression();
Expression(Expression& exp);
Expression(Script& script, State& state);
void operator=( const Expression &exp );
void operator=(const Expression& exp);
bool getResult( State &state, Entity &ent, Container<Conditional *> *sent_conditionals );
const char *getValue( void );
};
bool getResult(State &state, Entity &ent, Container<Conditional *> *sent_conditionals);
const char *getValue(void);
};
inline void Expression::operator=
(
const Expression &exp
)
{
int i;
inline void Expression::operator=(const Expression& exp)
value = exp.value;
{
int i;
conditions.FreeObjectList();
for( i = 1; i <= exp.conditions.NumObjects(); i++ )
{
conditions.AddObject( exp.conditions.ObjectAt( i ) );
}
}
value = exp.value;
inline const char *Expression::getValue
(
void
)
conditions.FreeObjectList();
for (i = 1; i <= exp.conditions.NumObjects(); i++) {
conditions.AddObject(exp.conditions.ObjectAt(i));
}
}
{
return value.c_str();
}
inline const char *Expression::getValue(void)
{
return value.c_str();
}
class State : public Class
{
private :
Container<int> condition_indexes;
{
private:
Container<int> condition_indexes;
StateMap &statemap;
StateMap& statemap;
str name;
str name;
str nextState;
movecontrol_t movetype;
cameratype_t cameratype;
str nextState;
movecontrol_t movetype;
cameratype_t cameratype;
str behaviorName;
Container<str> behaviorParmList;
str behaviorName;
Container<str> behaviorParmList;
float minTime;
float maxTime;
float minTime;
float maxTime;
Container<Expression> legAnims;
Container<Expression> m_actionAnims;
int m_iActionAnimType;
Container<Expression> legAnims;
Container<Expression> m_actionAnims;
int m_iActionAnimType;
Container<Expression> states;
Container<str> entryCommands;
Container<str> exitCommands;
Container<Expression> states;
Container<str> entryCommands;
Container<str> exitCommands;
void readNextState( Script &script );
void readMoveType( Script &script );
void readCamera( Script &script );
void readLegs( Script &script );
void readAction( Script &script );
void readBehavior( Script &script );
void readTime( Script &script );
void readStates( Script &script );
void readCommands( Script &script, Container<str> &container );
void readNextState(Script& script);
void readMoveType(Script& script);
void readCamera(Script& script);
void readLegs(Script& script);
void readAction(Script& script);
void readBehavior(Script& script);
void readTime(Script& script);
void readStates(Script& script);
void readCommands(Script& script, Container<str>& container);
void ParseAndProcessCommand( str command, Entity *target );
void ParseAndProcessCommand(str command, Entity *target);
public :
State( const char *name, Script &script, StateMap &map );
public:
State(const char *name, Script& script, StateMap& map);
State *Evaluate( Entity &ent, Container<Conditional *> *ent_conditionals );
int addCondition( const char *name, Script &script );
void CheckStates( void );
State *Evaluate(Entity& ent, Container<Conditional *> *ent_conditionals);
int addCondition(const char *name, Script &script);
void CheckStates(void);
const char *getName( void );
const char *getName(void);
const char *getLegAnim( Entity &ent, Container<Conditional *> *sent_conditionals );
const char *getActionAnim( Entity &ent, Container<Conditional *> *sent_conditionals, int *piAnimType = NULL );
const char *getBehaviorName( void );
State *getNextState( void );
movecontrol_t getMoveType( void );
cameratype_t getCameraType( void );
qboolean setCameraType( str ctype );
const char *getLegAnim(Entity &ent, Container<Conditional *> *sent_conditionals);
const char *getActionAnim(Entity &ent, Container<Conditional *> *sent_conditionals, int *piAnimType = NULL);
const char *getBehaviorName(void);
State *getNextState(void);
movecontrol_t getMoveType(void);
cameratype_t getCameraType(void);
qboolean setCameraType(str ctype);
const char *getBehaviorParm( int number=1 );
void addBehaviorParm( str parm );
int numBehaviorParms( void );
const char *getBehaviorParm(int number = 1);
void addBehaviorParm(str parm);
int numBehaviorParms(void);
float getMinTime( void );
float getMaxTime( void );
void ProcessEntryCommands( Entity *target );
void ProcessExitCommands( Entity *target );
void GetLegAnims( Container<const char *> *c );
void GetActionAnims( Container<const char *> *c );
};
float getMinTime(void);
float getMaxTime(void);
void ProcessEntryCommands(Entity *target);
void ProcessExitCommands(Entity *target);
void GetLegAnims(Container<const char *> *c);
void GetActionAnims(Container<const char *> *c);
};
inline void State::addBehaviorParm
(
str parm
)
inline void State::addBehaviorParm(str parm)
{
behaviorParmList.AddObject( parm );
}
{
behaviorParmList.AddObject(parm);
}
inline const char *State::getBehaviorParm
(
int number
)
inline const char *State::getBehaviorParm(int number)
{
return behaviorParmList.ObjectAt( number ).c_str();
}
{
return behaviorParmList.ObjectAt(number).c_str();
}
inline int State::numBehaviorParms
(
void
)
inline int State::numBehaviorParms(void)
{
return behaviorParmList.NumObjects();
}
{
return behaviorParmList.NumObjects();
}
class StateMap : public Class
{
private :
Container<State *> stateList;
Condition<Class> *current_conditions;
Container<Conditional *> *current_conditionals;
str filename;
public :
StateMap( const char *filename, Condition<Class> *conditions, Container<Conditional *> *conditionals );
~StateMap();
{
private:
Container<State *> stateList;
Condition<Class> *current_conditions;
Container<Conditional *> *current_conditionals;
str filename;
Condition<Class> *getCondition( const char *name );
int findConditional( Conditional *condition );
int addConditional( Conditional *condition );
Conditional *getConditional( const char *name );
void GetAllAnims( Container<const char *> *c );
State *FindState( const char *name );
const char *Filename();
};
public:
StateMap(const char *filename, Condition<Class> *conditions, Container<Conditional *> *conditionals);
~StateMap();
inline const char *StateMap::Filename
(
void
)
Condition<Class> *getCondition(const char *name);
int findConditional(Conditional *condition);
int addConditional(Conditional *condition);
Conditional *getConditional(const char *name);
void GetAllAnims(Container<const char *> *c);
State *FindState(const char *name);
const char *Filename();
};
{
return filename.c_str();
}
inline const char *StateMap::Filename(void)
inline const char *State::getName
(
void
)
{
return filename.c_str();
}
{
return name.c_str();
}
inline const char *State::getName(void)
inline State *State::getNextState
(
void
)
{
return name.c_str();
}
{
return statemap.FindState( nextState.c_str() );
}
inline State *State::getNextState(void)
inline movecontrol_t State::getMoveType
(
void
)
{
return statemap.FindState(nextState.c_str());
}
{
return movetype;
}
inline movecontrol_t State::getMoveType(void)
inline cameratype_t State::getCameraType
(
void
)
{
return movetype;
}
{
return cameratype;
}
inline cameratype_t State::getCameraType(void)
void ClearCachedStatemaps( void );
StateMap *GetStatemap( str filename, Condition<Class> *conditions, Container<Conditional *> *conditionals, qboolean reload, qboolean cache_only = false );
void CacheStatemap( str filename, Condition<Class> *conditions );
{
return cameratype;
}
void ClearCachedStatemaps(void);
StateMap *GetStatemap(
str filename,
Condition<Class> *conditions,
Container<Conditional *> *conditionals,
qboolean reload,
qboolean cache_only = false
);
void CacheStatemap(str filename, Condition<Class> *conditions);
#endif /* !__CHARACTERSTATE_H__ */
+2 -2
View File
@@ -57,7 +57,7 @@ void ConsoleEvent::SetConsoleEdict(gentity_t* edict)
GetConsoleEdict
=======================
*/
gentity_t* ConsoleEvent::GetConsoleEdict(void)
gentity_t* ConsoleEvent::GetConsoleEdict(void) const
{
if (m_consoleedict)
return m_consoleedict;
@@ -70,7 +70,7 @@ gentity_t* ConsoleEvent::GetConsoleEdict(void)
ErrorInternal
=======================
*/
void ConsoleEvent::ErrorInternal(Listener* l, str text)
void ConsoleEvent::ErrorInternal(Listener* l, str text) const
{
gentity_t* edict = GetConsoleEdict();
str eventname = getName();
+2 -2
View File
@@ -19,9 +19,9 @@ public:
ConsoleEvent(str name) : Event(name) { m_consoleedict = NULL; }
void SetConsoleEdict(gentity_t* edict);
gentity_t* GetConsoleEdict(void);
gentity_t* GetConsoleEdict(void) const;
void ErrorInternal(Listener* l, str text) override;
void ErrorInternal(Listener* l, str text) const override;
};
extern MEM_BlockAlloc<ConsoleEvent> ConsoleEvent_allocator;
+26
View File
@@ -0,0 +1,26 @@
/*
===========================================================================
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include "damagemodel.h"
// FIXME: unimplemented
+23
View File
@@ -0,0 +1,23 @@
/*
===========================================================================
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#pragma once
+33
View File
@@ -865,3 +865,36 @@ void G_DebugHighlightFacet
break;
}
}
void G_DebugString(Vector pos, float scale, float r, float g, float b, const char* pszText, ...)
{
debugstring_t* string;
va_list va;
char szTemp[32768];
if (!g_numdebugstrings) {
return;
}
if (*gi.numDebugStrings < g_numdebugstrings->integer) {
string = (debugstring_t*)&DebugStrings[*gi.numDebugStrings];
(*gi.numDebugStrings)++;
va_start(va, pszText);
vsprintf(szTemp, pszText, va);
va_end(va);
VectorCopy(pos, string->pos);
string->scale = scale;
string->color[0] = r;
string->color[1] = g;
string->color[2] = b;
string->color[3] = 1.0f;
strncpy(string->szText, szTemp, sizeof(string->szText));
string->szText[sizeof(string->szText) - 1] = 0;
}
else {
gi.DPrintf("G_DebugString: Exceeded g_numdebugstrings\n");
}
}
+1765 -1085
View File
File diff suppressed because it is too large. Load diff
+231 -102
View File
@@ -21,149 +21,278 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// dm_manager.h: Deathmatch Manager.
#ifndef __DM_MANAGER_H__
#define __DM_MANAGER_H__
#pragma once
#include "listener.h"
#include "dm_team.h"
#include "Tow_Entities.h"
extern cvar_t *g_tempaxisscore;
extern cvar_t *g_tempaxiswinsinrow;
extern cvar_t *g_tempalliesscore;
extern cvar_t *g_tempallieswinsinrow;
class PlayerStart;
class Player;
class DM_Team : public Listener
{
public:
Container<PlayerStart *> m_spawnpoints;
Container<Player *> m_players;
int m_maxplayers;
str m_teamname;
int m_teamnumber;
int m_index;
int m_countdown;
int m_teamwins;
int m_wins_in_a_row;
int m_iKills;
int m_iDeaths;
qboolean m_bHasSpawnedPlayers;
public:
CLASS_PROTOTYPE(DM_Team);
DM_Team();
~DM_Team();
void Reset(void);
void AddPlayer(Player *player);
void RemovePlayer(Player *player);
void setName(str name);
str getName(void);
void setNumber(int num);
int getNumber(void);
void setIndex(int index);
int getIndex(void);
void TeamWin(void);
void TeamLoss(void);
void AddDeaths(Player *player, int numDeaths);
void AddKills(Player *player, int numKills);
void UpdateTeamStatus(void);
void TeamInvulnerable(void);
void BeginFight(void);
float PlayersRangeFromSpot(PlayerStart *spot);
bool IsDead(void) const;
bool IsEmpty(void) const;
bool IsReady(void) const;
int NumNotReady(void) const;
int NumLivePlayers(void) const;
int TotalPlayersKills(void) const;
PlayerStart *GetRandomFfaSpawnpoint(Player *player);
PlayerStart *GetRandomTeamSpawnpoint(Player *player);
PlayerStart *GetRandomObjectiveSpawnpoint(Player *player);
void InitSpawnPoints(void);
protected:
PlayerStart *FarthestSpawnPoint(void);
PlayerStart *GetRandomSpawnpoint(void);
PlayerStart *GetRandomSpawnpointWithMetric(
Player *player, float (*MetricFunction)(const float *, DM_Team *dmTeam, const Player *player)
);
};
using DM_TeamPtr = SafePtr<DM_Team>;
inline void DM_Team::setName(str name)
{
m_teamname = name;
};
inline str DM_Team::getName(void)
{
return m_teamname;
};
inline void DM_Team::setNumber(int num)
{
m_teamnumber = num;
}
inline int DM_Team::getNumber(void)
{
return m_teamnumber;
}
inline void DM_Team::setIndex(int index)
{
m_index = index;
}
inline int DM_Team::getIndex(void)
{
return m_index;
}
inline bool DM_Team::IsReady(void) const
{
return !NumNotReady();
}
class SimpleAmmoType : public Class
{
public:
str type;
int amount;
public:
SimpleAmmoType();
};
class Player;
class DM_Manager : public Listener
{
private:
Container< Player * > m_players;
Container< DM_TeamPtr > m_teams;
Container<Player *> m_players;
Container<DM_TeamPtr> m_teams;
DM_Team m_team_spectator;
DM_Team m_team_freeforall;
DM_Team m_team_allies;
DM_Team m_team_axis;
DM_Team m_team_spectator;
DM_Team m_team_freeforall;
DM_Team m_team_allies;
DM_Team m_team_axis;
float m_fRoundTime;
float m_fRoundEndTime;
float m_fRoundTime;
float m_fRoundEndTime;
bool m_bAllowRespawns;
bool m_bRoundBasedGame;
int m_iDefaultRoundLimit;
bool m_bAllowRespawns;
bool m_bRoundBasedGame;
bool m_bIgnoringClockForBomb;
int m_iTeamWin;
int m_iDefaultRoundLimit;
const_str m_csTeamClockSide;
const_str m_csTeamBombPlantSide;
const_str m_csTeamClockSide;
const_str m_csTeamBombPlantSide;
int m_iNumTargetsToDestroy;
int m_iNumTargetsDestroyed;
int m_iNumBombsPlanted;
int m_iTotalMapTime;
int m_iNumTargetsToDestroy;
int m_iNumTargetsDestroyed;
int m_iNumBombsPlanted;
int m_iTotalMapTime;
int m_iTeamWin;
bool m_bIgnoringClockForBomb;
bool m_bAllowAxisRespawn;
bool m_bAllowAlliedRespawn;
// scoreboard data
char scoreString[ MAX_STRING_CHARS ];
size_t scoreLength;
int scoreEntries;
// scoreboard data
char scoreString[MAX_STRING_CHARS];
size_t scoreLength;
int scoreEntries;
private:
void BuildTeamInfo( DM_Team *dmTeam );
void BuildPlayerTeamInfo( DM_Team *dmTeam, int *iPlayerList, DM_Team *ignoreTeam = NULL );
void InsertEntry( const char *entry );
void InsertEmpty( void );
void BuildTeamInfo(DM_Team *dmTeam);
void BuildTeamInfo_ver6(DM_Team *dmTeam);
void BuildTeamInfo_ver15(DM_Team *dmTeam);
void BuildPlayerTeamInfo(DM_Team *dmTeam, int *iPlayerList, DM_Team *ignoreTeam = NULL);
void InsertEntry(const char *entry);
void InsertEntryNoCount(const char *entry);
void InsertEmpty(void);
bool IsAlivePlayer(Player* player) const;
public:
CLASS_PROTOTYPE( DM_Manager );
CLASS_PROTOTYPE(DM_Manager);
DM_Manager();
~DM_Manager();
DM_Manager();
~DM_Manager();
void Reset( void );
void InitGame(void);
void AddPlayer(Player *player);
bool JoinTeam(Player *player, teamtype_t teamType);
void LeaveTeam(Player *player);
void RebuildTeamConfigstrings(void);
void RemovePlayer(Player *player);
void PlayerKilled(Player *player);
DM_Team *GetTeam( str name );
DM_Team *GetTeam( teamtype_t team );
void Countdown(Event *ev);
void Reset(void);
void Score(Player *player);
bool JoinTeam( Player *player, teamtype_t teamType );
void LeaveTeam( Player *player );
void PrintAllClients(str s);
bool CheckEndMatch(void);
bool TeamHitScoreLimit(void);
bool PlayerHitScoreLimit(void);
void EventDoRoundTransition(Event *ev);
void EventFinishRoundTransition(Event *ev);
void TeamWin(int teamnum);
void StartRound(void);
void EndRound(void);
bool GameHasRounds(void) const;
bool GameAllowsRespawns(void) const;
void SetGameAllowsRespawns(bool bAllow);
bool AllowRespawn(void) const;
int GetRoundLimit(void) const;
void SetDefaultRoundLimit(int round_limit);
const_str GetClockSide(void) const;
void SetClockSide(const_str s);
const_str GetBombPlantTeam(void) const;
void SetBombPlantTeam(const_str s);
int GetTargetsToDestroy(void) const;
void SetTargetsToDestroy(int);
int GetTargetsDestroyed(void) const;
void SetTargetsDestroyed(int);
int GetBombsPlanted(void) const;
void SetBombsPlanted(int);
int GetTeamWin(void);
bool WaitingForPlayers(void) const;
bool IsGameActive(void) const;
int PlayerCount(void) const;
Player *GetPlayer(int index) const;
teamtype_t GetAutoJoinTeam(void);
Player *GetPlayer( int num );
void InitGame( void );
DM_Team *GetTeamAllies(void);
DM_Team *GetTeamAxis(void);
void AddPlayer( Player *player );
void RemovePlayer( Player *player );
void PlayerKilled( Player *player );
float GetMatchStartTime(void);
void StopTeamRespawn(eController controller);
bool AllowTeamRespawn(int teamnum) const;
int GetTeamSpawnTimeLeft() const;
void RebuildTeamConfigstrings( void );
DM_Team *GetTeam(str name);
DM_Team *GetTeam(teamtype_t team);
static int compareScores( const void *elem1, const void *elem2 );
void Score( Player *player );
void PrintAllClients( str s );
bool CheckEndMatch( void );
bool TeamHitScoreLimit( void );
bool PlayerHitScoreLimit( void );
void EventDoRoundTransition( Event *ev );
void EventFinishRoundTransition( Event *ev );
void TeamWin( int teamnum );
void StartRound( void );
void EndRound( void );
bool GameHasRounds( void ) const;
bool GameAllowsRespawns( void ) const;
void SetGameAllowsRespawns( bool bAllow );
bool AllowRespawn( void ) const;
int GetRoundLimit( void ) const;
void SetDefaultRoundLimit( int round_limit );
const_str GetClockSide( void ) const;
void SetClockSide( const_str s );
const_str GetBombPlantTeam( void ) const;
void SetBombPlantTeam( const_str s );
int GetTargetsToDestroy( void ) const;
void SetTargetsToDestroy( int );
int GetTargetsDestroyed( void ) const;
void SetTargetsDestroyed( int );
int GetBombsPlanted( void ) const;
void SetBombsPlanted( int );
int GetTeamWin( void );
bool WaitingForPlayers( void ) const;
bool IsGameActive( void ) const;
int PlayerCount( void ) const;
teamtype_t GetAutoJoinTeam( void );
DM_Team *GetTeamAllies( void );
DM_Team *GetTeamAxis( void );
float GetMatchStartTime( void );
protected:
static int compareScores(const void *elem1, const void *elem2);
};
inline
bool DM_Manager::GameHasRounds
(
void
)
const
inline int DM_Manager::GetTeamWin(void)
{
return m_bRoundBasedGame;
return m_iTeamWin;
}
inline
bool DM_Manager::GameAllowsRespawns
(
void
)
const
inline DM_Team *DM_Manager::GetTeamAllies(void)
{
return m_bAllowRespawns;
return &m_team_allies;
}
inline
void DM_Manager::SetGameAllowsRespawns
(
bool bAllow
)
inline DM_Team *DM_Manager::GetTeamAxis(void)
{
m_bAllowRespawns = bAllow;
return &m_team_axis;
}
inline bool DM_Manager::GameHasRounds(void) const
{
return m_bRoundBasedGame;
}
inline bool DM_Manager::GameAllowsRespawns(void) const
{
return m_bAllowRespawns;
}
inline void DM_Manager::SetGameAllowsRespawns(bool bAllow)
{
m_bAllowRespawns = bAllow;
}
extern DM_Manager dmManager;
#endif /* __DM_MANAGER_H__ */
-764
View File
@@ -1,764 +0,0 @@
/*
===========================================================================
Copyright (C) 2015 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
===========================================================================
*/
// dm_team.cpp: Deathmatch Team Manager.
#include "player.h"
#include "dm_team.h"
#include "dm_manager.h"
#include "playerstart.h"
typedef struct spawnsort_s {
PlayerStart *spawnpoint;
float fMetric;
} spawnsort_t;
static qboolean SpotWouldTelefrag( float *origin )
{
static Vector mins = Vector( -16, -16, 1 );
static Vector maxs = Vector( 16, 16, 97 );
trace_t trace;
trace = G_Trace( Vector(origin), mins, maxs, Vector(origin), NULL, MASK_PLAYERSOLID, qfalse, "SpotWouldTelefrag" );
if( trace.startsolid || trace.allsolid )
return qtrue;
else
return qfalse;
}
static int compare_spawnsort( const void *pe1, const void *pe2 )
{
float fDelta = ( ( spawnsort_t * )pe1 )->fMetric - ( ( spawnsort_t * )pe2 )->fMetric;
if( fDelta >= -0.001f )
{
if( fDelta <= 0.001f )
{
return 0;
}
else
{
return -1;
}
}
else
{
return 1;
}
}
static PlayerStart *GetRandomSpawnpointFromList( spawnsort_t *pSpots, int nSpots )
{
int i = nSpots;
float fTotalMetric;
float fMinPosMetric;
float fChosen;
if( nSpots <= 0 ) {
return NULL;
}
qsort( pSpots, nSpots, sizeof( spawnsort_t ), compare_spawnsort );
if( pSpots[ 0 ].fMetric > 0.0f )
{
if( nSpots > 5 ) {
nSpots = 5;
}
fMinPosMetric = pSpots[ 0 ].fMetric * nSpots;
fTotalMetric = fMinPosMetric;
if( nSpots <= 1 )
{
fChosen = fMinPosMetric;
}
else
{
i = 0;
fTotalMetric = 0.0f;
for( i = 0; i < nSpots; i++ )
{
if( pSpots[ i ].fMetric <= 0.0f ) {
break;
}
fChosen = pSpots[ i ].fMetric * ( nSpots - i );
fTotalMetric += fChosen;
i++;
}
if( i < nSpots )
{
fChosen = fMinPosMetric;
}
fMinPosMetric = fTotalMetric;
}
fTotalMetric = ( fMinPosMetric - i * fChosen * 0.90f ) * G_Random();
for( i = 0; i < nSpots - 1; i++ )
{
fTotalMetric -= ( nSpots - i ) * pSpots[ i ].fMetric - ( fChosen * 0.90f );
if( fTotalMetric <= 0.0f ) {
break;
}
}
return pSpots[ i ].spawnpoint;
}
else
{
// return the spot anyway
return pSpots[ 0 ].spawnpoint;
}
}
void DM_Team::Reset( void )
{
m_spawnpoints.ClearObjectList();
m_players.ClearObjectList();
}
void DM_Team::AddDeaths( Player *player, int numDeaths )
{
if( level.intermissiontime || dmManager.GetTeamWin() )
return;
if( g_gametype->integer == GT_TEAM_ROUNDS || g_gametype->integer == GT_OBJECTIVE )
return;
player->AddDeaths( numDeaths );
if( m_teamnumber > TEAM_FREEFORALL )
m_iDeaths += numDeaths;
}
void DM_Team::AddKills( Player *player, int numKills )
{
if( level.intermissiontime || dmManager.GetTeamWin() )
return;
player->AddKills( numKills );
if( m_teamnumber > TEAM_FREEFORALL )
{
m_iKills += numKills;
if( g_gametype->integer == GT_TEAM_ROUNDS || g_gametype->integer == GT_OBJECTIVE )
player->AddDeaths( numKills );
else
m_teamwins += numKills;
}
}
void DM_Team::AddPlayer( Player *player )
{
m_players.AddObject( player );
}
void DM_Team::RemovePlayer( Player *player )
{
m_players.RemoveObject( player );
}
void DM_Team::TeamWin( void )
{
m_teamwins++;
m_wins_in_a_row++;
for( int i = 1; i <= m_players.NumObjects(); i++ )
{
m_players.ObjectAt( i )->WonMatch();
}
UpdateTeamStatus();
if( m_teamnumber == TEAM_ALLIES )
{
gi.Cvar_Set( "g_scoreboardpicover", "textures/hud/allieswin" );
}
else if( m_teamnumber == TEAM_AXIS )
{
gi.Cvar_Set( "g_scoreboardpicover", "textures/hud/axiswin" );
}
}
void DM_Team::TeamLoss( void )
{
m_wins_in_a_row = 0;
for( int i = 1; i <= m_players.NumObjects(); i++ )
{
m_players.ObjectAt( i )->LostMatch();
}
UpdateTeamStatus();
}
bool DM_Team::IsDead( void ) const
{
Player *player;
if( IsEmpty() )
{
if( dmManager.IsGameActive() ) {
return true;
}
return false;
}
if( !m_bHasSpawnedPlayers ) {
return false;
}
if( dmManager.AllowRespawn() ) {
return false;
}
for( int i = m_players.NumObjects(); i > 0; i-- )
{
player = m_players.ObjectAt( i );
if( player->IsSpectator() ) {
continue;
}
if( !player->IsDead() )
{
return false;
}
}
return true;
}
bool DM_Team::IsEmpty( void ) const
{
return m_players.NumObjects() <= 0;
}
bool DM_Team::IsReady( void ) const
{
return !NumNotReady();
}
int DM_Team::NumNotReady( void ) const
{
Player *player;
int num = 0;
for( int i = 1; i <= m_players.NumObjects(); i++ )
{
player = m_players.ObjectAt( i );
if( player->IsReady() && !player->IsDead() )
i++;
}
return num;
}
int DM_Team::NumLivePlayers( void ) const
{
Player *player;
int num = 0;
for( int i = 1; i <= m_players.NumObjects(); i++ )
{
player = m_players.ObjectAt( i );
if( !player->IsDead() && !player->IsSpectator() )
{
num++;
}
}
return num;
}
int DM_Team::TotalPlayersKills( void ) const
{
Player *player;
int iKills = 0;
for( int i = 1; i <= m_players.NumObjects(); i++ )
{
player = m_players.ObjectAt( i );
if( !player->IsDead() && !player->IsSpectator() )
{
iKills += player->GetNumKills();
}
}
return iKills;
}
void DM_Team::TeamInvulnerable( void )
{
for( int i = 1; i <= m_players.NumObjects(); i++ )
{
m_players.ObjectAt( i )->takedamage = DAMAGE_NO;
}
}
void DM_Team::BeginFight( void )
{
for( int i = 1; i <= m_players.NumObjects(); i++ )
{
m_players.ObjectAt( i )->BeginFight();
}
}
void DM_Team::UpdateTeamStatus( void )
{
for( int i = 1; i <= m_players.NumObjects(); i++ )
{
m_players.ObjectAt( i )->UpdateStatus( va( "%d wins (%d in a row)", m_teamwins, m_wins_in_a_row ) );
}
}
float SpawnpointMetric_Ffa( const float *origin, DM_Team *dmTeam, const Player *player )
{
float fMinEnemyDistSquared = 23170.0f * 23170.0f;
int i;
int nPlayers = dmManager.PlayerCount();
float fDist;
for( i = 1; i < nPlayers; i++ )
{
Player *teammate = dmManager.GetPlayer( i );
if( teammate == player || teammate->IsDead() || teammate->IsSpectator() ) {
continue;
}
fDist = ( teammate->origin - Vector( origin ) ).lengthSquared();
if( fMinEnemyDistSquared > fDist ) {
fMinEnemyDistSquared = fDist;
}
}
return fMinEnemyDistSquared - ( G_Random( 0.25f ) + 1.0f ) * ( 1024.0f * 1024.0f );
}
float SpawnpointMetric_Team( const float *origin, DM_Team *dmTeam, const Player *player )
{
float fMinEnemyDistSquared = 23170.0f * 23170.0f;
float fSumFriendDistSquared = 0.0f;
float fDistSquared;
float fMetric;
int i;
int nPlayers = dmManager.PlayerCount();
int nFriends = 0;
for( i = 1; i < nPlayers; i++ )
{
Player *teammate = dmManager.GetPlayer( i );
if( teammate == player || teammate->IsDead() || teammate->IsSpectator() ) {
continue;
}
fDistSquared = ( teammate->origin - Vector( origin ) ).lengthSquared();
if( teammate->GetDM_Team() == dmTeam )
{
nFriends++;
fSumFriendDistSquared += fDistSquared;
}
else
{
if( fMinEnemyDistSquared > fDistSquared ) {
fMinEnemyDistSquared = fDistSquared;
}
}
}
fMetric = fMinEnemyDistSquared - ( G_Random( 0.25f ) + 1.0f ) * ( 1024.0f * 1024.0f );
if( nFriends )
{
fMetric += 0.25f * ( ( 23170.0f * 23170.0f ) - fSumFriendDistSquared / nFriends );
}
return fMetric;
}
float SpawnpointMetric_Objective( const float *origin, DM_Team *dmTeam, const Player *player )
{
return rand() * 0.0000000005f;
}
PlayerStart *DM_Team::GetRandomFfaSpawnpoint( Player *player )
{
return GetRandomSpawnpointWithMetric( player, SpawnpointMetric_Ffa );
}
PlayerStart *DM_Team::GetRandomTeamSpawnpoint( Player *player )
{
return GetRandomSpawnpointWithMetric( player, SpawnpointMetric_Team );
}
PlayerStart *DM_Team::GetRandomObjectiveSpawnpoint( Player *player )
{
return GetRandomSpawnpointWithMetric( player, SpawnpointMetric_Objective );
}
float DM_Team::PlayersRangeFromSpot( PlayerStart *spot )
{
float bestplayerdistance = 9999999.0f;
Vector vDist;
int i;
gentity_t *ent;
Player *player;
if( g_gametype->integer > GT_FFA ) {
return bestplayerdistance;
}
// find the nearest player from the post
for( i = 0, ent = g_entities; i < game.maxclients; i++, ent++ )
{
if( !ent->client || !ent->entity ) {
continue;
}
player = ( Player * )ent->entity;
if( !player->IsDead() && !player->IsSpectator() && m_teamnumber != player->GetTeam() )
{
vDist = spot->origin - player->origin;
if( bestplayerdistance > vDist.length() )
bestplayerdistance = vDist.length();
}
}
return bestplayerdistance;
}
PlayerStart *DM_Team::FarthestSpawnPoint( void )
{
int i;
int iNumPoints;
float bestdistance;
float bestplayerdistance;
PlayerStart *pSpot;
PlayerStart *pBestSpot;
PlayerStart *pSpot2;
PlayerStart *pSpot3;
bestplayerdistance = 0.0f;
pBestSpot = NULL;
pSpot2 = NULL;
pSpot3 = NULL;
iNumPoints = m_spawnpoints.NumObjects();
for( i = 1; i <= iNumPoints; i++ )
{
pSpot = m_spawnpoints.ObjectAt( i );
bestdistance = PlayersRangeFromSpot( m_spawnpoints.ObjectAt( i ) );
if( bestdistance > bestplayerdistance )
{
bestplayerdistance = bestdistance;
pSpot3 = pSpot2;
pSpot2 = pBestSpot;
pBestSpot = pSpot;
}
}
if( pSpot3 && G_Random() < 0.2f )
{
return pSpot3;
}
else if( pSpot2 && G_Random() < 0.3f )
{
return pSpot2;
}
else
{
return pBestSpot;
}
}
PlayerStart *DM_Team::GetRandomSpawnpoint( void )
{
PlayerStart *spot = NULL;
int numPoints = m_spawnpoints.NumObjects();
if( numPoints )
{
spot = FarthestSpawnPoint();
if( !spot )
{
spot = m_spawnpoints.ObjectAt( ( int )( G_Random( numPoints ) + 1.0f ) );
}
}
else
{
warning( "DM_Team::GetRandomSpawnpoint", "No spawnpoints found\n" );
spot = NULL;
}
return spot;
}
PlayerStart *DM_Team::GetRandomSpawnpointWithMetric( Player *player, float( *MetricFunction ) ( const float *origin, DM_Team *dmTeam, const Player *player ) )
{
static float offset[ 4 ][ 3 ];
spawnsort_t points[ 1024 ];
PlayerStart *spot = NULL;
int numSpots = 0;
int iPoint = 0;
for( int i = 1; i <= m_spawnpoints.NumObjects(); i++ )
{
spot = m_spawnpoints.ObjectAt( i );
if( spot->m_bForbidSpawns || player->GetLastSpawnpoint() == spot ) {
continue;
}
if( !SpotWouldTelefrag( spot->origin ) )
{
points[ numSpots ].spawnpoint = spot;
points[ numSpots ].fMetric = MetricFunction( spot->origin, this, player );
numSpots++;
if( numSpots >= ( sizeof( points ) / sizeof( points[ 0 ] ) ) ) {
break;
}
}
}
spot = GetRandomSpawnpointFromList( points, numSpots );
if( spot ) {
return spot;
}
numSpots = 0;
for( int i = 1; i <= m_spawnpoints.NumObjects(); i++ )
{
spot = m_spawnpoints.ObjectAt( i );
if( spot->m_bForbidSpawns ) {
continue;
}
for( int j = 0; j < sizeof( offset ) / sizeof( offset[ 0 ] ); j++ )
{
Vector vNewSpawn = spot->origin + offset[ j ];
if( G_SightTrace(
spot->origin,
player->mins,
player->maxs,
vNewSpawn,
( Entity * )NULL,
( Entity * )NULL,
MASK_PLAYERSOLID,
qfalse,
"DM_Team::GetRandomSpawnpointWithMetric" ) == 1 )
{
Vector vEnd = vNewSpawn - Vector( 0, 0, 64 );
trace_t trace = G_Trace(
vNewSpawn,
player->mins,
player->maxs,
vEnd,
player,
MASK_PLAYERSOLID,
qfalse,
"TempSpawnPoint" );
if( !trace.allsolid && !trace.startsolid &&
trace.fraction != 1.0f && trace.fraction != 1.0f &&
trace.plane.dist >= 0.8f )
{
points[ numSpots ].spawnpoint = new PlayerStart;
points[ numSpots ].spawnpoint->setOrigin( trace.endpos );
points[ numSpots ].spawnpoint->setAngles( spot->angles );
points[ numSpots ].fMetric = MetricFunction( vNewSpawn, this, player );
if( numSpots >= ( sizeof( points ) / sizeof( points[ 0 ] ) ) ) {
break;
}
}
}
}
}
spot = GetRandomSpawnpointFromList( points, numSpots );
for( int i = 0; i < numSpots; i++ )
{
// delete all created spawnpoint
if( points[ numSpots ].spawnpoint != spot ) {
delete points[ numSpots ].spawnpoint;
}
}
if( spot ) {
return spot;
}
numSpots = 0;
for( int i = 1; i <= m_spawnpoints.NumObjects(); i++ )
{
spot = m_spawnpoints.ObjectAt( i );
if( !spot->m_bForbidSpawns && player->GetLastSpawnpoint() != spot ) {
continue;
}
if( !SpotWouldTelefrag( spot->origin ) )
{
points[ numSpots ].spawnpoint = spot;
points[ numSpots ].fMetric = MetricFunction( spot->origin, this, player );
if( numSpots >= ( sizeof( points ) / sizeof( points[ 0 ] ) ) ) {
break;
}
}
}
return GetRandomSpawnpointFromList( points, numSpots );
}
void DM_Team::InitSpawnPoints
(
void
)
{
int i;
if( teamType == TEAM_SPECTATOR )
{
for( i = level.m_SimpleArchivedEntities.NumObjects(); i > 0; i-- )
{
PlayerStart *spawnpoint = ( PlayerStart * )level.m_SimpleArchivedEntities.ObjectAt( i );
const char *classname = spawnpoint->getClassID();
if( !Q_stricmp( classname, "info_player_deathmatch" ) )
{
m_spawnpoints.AddObject( spawnpoint );
}
else if( !Q_stricmp( classname, "info_player_intermission" ) )
{
m_spawnpoints.AddObject( spawnpoint );
}
}
return;
}
if( g_gametype->integer <= GT_FFA )
{
for( i = level.m_SimpleArchivedEntities.NumObjects(); i > 0; i-- )
{
PlayerStart *spawnpoint = ( PlayerStart * )level.m_SimpleArchivedEntities.ObjectAt( i );
const char *classname = spawnpoint->getClassID();
if( !Q_stricmp( classname, "info_player_deathmatch" ) )
{
m_spawnpoints.AddObject( spawnpoint );
}
}
if( m_spawnpoints.NumObjects() <= 1 )
{
// Try with team spawnpoints
for( i = level.m_SimpleArchivedEntities.NumObjects(); i > 0; i-- )
{
PlayerStart *spawnpoint = ( PlayerStart * )level.m_SimpleArchivedEntities.ObjectAt( i );
const char *classname = spawnpoint->getClassID();
if( !Q_stricmp( classname, "info_player_allied" ) )
{
m_spawnpoints.AddObject( spawnpoint );
}
else if( !Q_stricmp( classname, "info_player_axis" ) )
{
m_spawnpoints.AddObject( spawnpoint );
}
}
}
}
else if( g_gametype->integer >= GT_TEAM )
{
if( teamType >= TEAM_ALLIES )
{
for( i = level.m_SimpleArchivedEntities.NumObjects(); i > 0; i-- )
{
PlayerStart *spawnpoint = ( PlayerStart * )level.m_SimpleArchivedEntities.ObjectAt( i );
const char *classname = spawnpoint->getClassID();
if( teamType == TEAM_ALLIES && !Q_stricmp( classname, "info_player_allied" ) )
{
m_spawnpoints.AddObject( spawnpoint );
}
else if( teamType == TEAM_AXIS && !Q_stricmp( classname, "info_player_axis" ) )
{
m_spawnpoints.AddObject( spawnpoint );
}
}
}
if( !m_spawnpoints.NumObjects() )
{
// Try with info_player_deathmatch
for( int i = level.m_SimpleArchivedEntities.NumObjects(); i > 0; i-- )
{
PlayerStart *spawnpoint = ( PlayerStart * )level.m_SimpleArchivedEntities.ObjectAt( i );
const char *classname = spawnpoint->getClassID();
if( !Q_stricmp( classname, "info_player_deathmatch" ) )
{
m_spawnpoints.AddObject( spawnpoint );
}
}
}
}
}
DM_Team::DM_Team()
{
m_countdown = 0;
m_teamwins = 0;
m_wins_in_a_row = 0;
m_teamnumber = -1;
m_iKills = 0;
m_iDeaths = 0;
m_bHasSpawnedPlayers = false;
}
DM_Team::~DM_Team()
{
}
CLASS_DECLARATION( Listener, DM_Team, NULL )
{
{ NULL, NULL }
};
-107
View File
@@ -1,107 +0,0 @@
/*
===========================================================================
Copyright (C) 2015 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
===========================================================================
*/
// dm_team.cpp: Deathmatch Team Manager.
#ifndef __DM_TEAM_H__
#define __DM_TEAM_H__
#include "listener.h"
class PlayerStart;
class Player;
class DM_Team : public Listener
{
public:
Container< PlayerStart * > m_spawnpoints;
Container< Player * > m_players;
int m_maxplayers;
str m_teamname;
int m_teamnumber;
teamtype_t teamType;
int m_countdown;
int m_teamwins;
int m_wins_in_a_row;
int m_iKills;
int m_iDeaths;
qboolean m_bHasSpawnedPlayers;
public:
CLASS_PROTOTYPE( DM_Team );
DM_Team();
~DM_Team();
void Reset( void );
void AddDeaths( Player *player, int numDeaths );
void AddKills( Player *player, int numKills );
void AddPlayer( Player *player );
void RemovePlayer( Player *player );
void setName( str name ) { m_teamname = name; };
str getName( void ) { return m_teamname; };
void setNumber( int num ) { m_teamnumber = num; };
int getNumber( void ) { return m_teamnumber; };
void setIndex( int index );
int getIndex( void );
void TeamWin( void );
void TeamLoss( void );
bool IsDead( void ) const;
bool IsEmpty( void ) const;
bool IsReady( void ) const;
int NumNotReady( void ) const;
int NumLivePlayers( void ) const;
int TotalPlayersKills( void ) const;
void TeamInvulnerable( void );
void BeginFight( void );
float PlayersRangeFromSpot( PlayerStart *spot );
void UpdateTeamStatus( void );
void InitSpawnPoints( void );
PlayerStart *GetRandomFfaSpawnpoint( Player *player );
PlayerStart *GetRandomTeamSpawnpoint( Player *player );
PlayerStart *GetRandomObjectiveSpawnpoint( Player *player );
protected:
PlayerStart *FarthestSpawnPoint( void );
PlayerStart *GetRandomSpawnpoint( void );
PlayerStart *GetRandomSpawnpointWithMetric( Player *player, float( *MetricFunction ) ( float const *, DM_Team *dmTeam, const Player *player ) );
};
typedef SafePtr< DM_Team > DM_TeamPtr;
#endif /* __DM_TEAM_H__ */
+1 -27
View File
@@ -965,12 +965,7 @@ qboolean Door::CanBeOpenedBy
return master->CanBeOpenedBy( ent );
}
if ( !locked && !key.length() )
{
return true;
}
if ( ent && ent->isSubclassOf( Sentient ) && ( ( Sentient * )ent )->HasItem( key.c_str() ) )
if ( !locked )
{
return true;
}
@@ -1036,30 +1031,9 @@ void Door::TryOpen
if ( !CanBeOpenedBy( other ) )
{
Item *item;
ClassDef *cls;
if ( other->isClient() )
{
cls = getClass( key.c_str() );
if ( !cls )
{
gi.DPrintf( "No item named '%s'\n", key.c_str() );
return;
}
item = ( Item * )cls->newInstance();
item->CancelEventsOfType( EV_Item_DropToFloor );
item->CancelEventsOfType( EV_Remove );
item->ProcessPendingEvents();
gi.centerprintf ( other->edict, "You need the %s", item->getName().c_str() );
delete item;
}
return;
}
// once we're opened by an item, we no longer need that item to open the door
key = "";
if ( Message().length() )
{
gi.centerprintf( other->edict, Message().c_str() );
+5510 -6080
View File
File diff suppressed because it is too large. Load diff
+612 -736
View File
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -105,7 +105,7 @@ void CreateExplosion
if( !explosionModel )
{
explosionModel = "fx_explosion.tik";
explosionModel = "fx/fx_explosion.tik";
}
explosion = new Explosion;
+68
View File
@@ -0,0 +1,68 @@
/*
===========================================================================
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include "fixedturret.h"
CLASS_DECLARATION(VehicleTank, FixedTurret, NULL) {
{NULL, NULL}
};
FixedTurret::FixedTurret()
{
// FIXME: unimplemented
}
void FixedTurret::Archive(Archiver& arc)
{
// FIXME: unimplemented
}
qboolean FixedTurret::Drive(usercmd_t *ucmd)
{
// FIXME: unimplemented
return qfalse;
}
void FixedTurret::DetachRemoteOwner()
{
// FIXME: unimplemented
}
void FixedTurret::EventDamage(Event *ev)
{
// FIXME: unimplemented
}
void FixedTurret::AttachDriverSlot(int slot, Entity *ent, Vector vExitPosition)
{
// FIXME: unimplemented
}
void FixedTurret::DetachDriverSlot(int slot, Vector vExitPosition, Vector *vExitAngles)
{
// FIXME: unimplemented
}
void FixedTurret::EventSetCollisionModel(Event *ev)
{
// FIXME: unimplemented
}
+43
View File
@@ -0,0 +1,43 @@
/*
===========================================================================
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#pragma once
#include "vehicle.h"
class FixedTurret : public VehicleTank
{
public:
CLASS_PROTOTYPE(FixedTurret);
public:
FixedTurret();
void Archive(Archiver& arc) override;
qboolean Drive(usercmd_t *ucmd) override;
void DetachRemoteOwner() override;
void EventDamage(Event *ev);
void AttachDriverSlot(int slot, Entity *ent, Vector vExitPosition) override;
void DetachDriverSlot(int slot, Vector vExitPosition, Vector *vExitAngles) override;
void EventSetCollisionModel(Event *ev);
};
+8 -32
View File
@@ -242,10 +242,10 @@ void ClientThink_real( gentity_t *ent ) {
}
if ( pmove_msec.integer < 8 ) {
gi.Cvar_Set("pmove_msec", "8");
gi.cvar_set("pmove_msec", "8");
}
else if (pmove_msec.integer > 33) {
gi.Cvar_Set("pmove_msec", "33");
gi.cvar_set("pmove_msec", "33");
}
if ( pmove_fixed.integer || client->pers.pmoveFixed ) {
@@ -341,8 +341,8 @@ void ClientThink_real( gentity_t *ent ) {
else {
pm.tracemask = MASK_PLAYERSOLID;
}
pm.trace = gi.Trace;
pm.pointcontents = gi.PointContents;
pm.trace = gi.trace;
pm.pointcontents = gi.pointcontents;
pm.debugLevel = g_debugMove.integer;
pm.noFootsteps = ( dmflags->integer & DF_NO_FOOTSTEPS ) > 0;
@@ -707,7 +707,7 @@ void ClientUse(gentity_t *ent) {
CalcMuzzlePoint(ent, forward, right, up, g_muzzle);
VectorMA(g_muzzle, 96.f, forward, right);
gi.Trace(&tr, g_muzzle, NULL, NULL, right, ent - g_entities, MASK_SOLID,0,false);
gi.trace(&tr, g_muzzle, NULL, NULL, right, ent - g_entities, MASK_SOLID,0,false);
if (tr.fraction == 1.f || tr.entityNum == ENTITYNUM_NONE || tr.entityNum == ENTITYNUM_WORLD) {
ent->lastUseEntity = tr.entityNum;
@@ -763,8 +763,8 @@ void SpectatorThink( gentity_t *ent, usercmd_t *ucmd ) {
pm.ps = &client->ps;
pm.cmd = *ucmd;
pm.tracemask = MASK_PLAYERSOLID & ~CONTENTS_BODY; // spectators can fly through bodies
pm.trace = gi.Trace;
pm.pointcontents = gi.PointContents;
pm.trace = gi.trace;
pm.pointcontents = gi.pointcontents;
// perform a pmove
Pmove (&pm);
@@ -875,7 +875,7 @@ void G_TouchTriggers( gentity_t *ent )
Event *ev;
// dead things don't activate triggers!
if( ( ent->client || ( ent->r.svFlags & SVF_BOT ) ) && ( ent->entity->health <= 0 ) )
if( ( ent->client || ( ent->r.svFlags & SVF_MONSTER ) ) && ( ent->entity->health <= 0 ) )
{
return;
}
@@ -930,27 +930,3 @@ void G_ClientThink( gentity_t *ent, usercmd_t *cmd, usereyes_t *eyeinfo )
}
}
/*
=================
G_ClientEndServerFrames
=================
*/
void G_ClientEndServerFrames( void )
{
int i;
gentity_t *ent;
// calc the player views now that all pushing
// and damage has been added
for( i = 0; i < game.maxclients; i++ )
{
ent = g_entities + i;
if( !ent->inuse || !ent->client || !ent->entity )
{
continue;
}
ent->entity->EndFrame();
}
}
+192 -1
View File
@@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@@ -24,6 +24,11 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "g_local.h"
#include "entity.h"
#include "playerbot.h"
#include "g_bot.h"
static gentity_t* firstBot = NULL;
static saved_bot_t* saved_bots = NULL;
static unsigned int current_bot_count = 0;
void G_BotBegin
(
@@ -56,3 +61,189 @@ void G_BotThink
G_ClientThink( ent, &ucmd, &eyeinfo );
}
gentity_t* G_GetFirstBot()
{
return firstBot;
}
void G_AddBot(unsigned int num, saved_bot_t* saved)
{
int n;
int i;
int clientNum = -1;
gentity_t *e;
char botName[ MAX_NETNAME ];
char challenge[ MAX_STRING_TOKENS ];
char userinfo[MAX_INFO_STRING]{ 0 };
Event* teamEv;
num = Q_min(num, sv_maxbots->integer);
for( n = 0; n < num; n++ )
{
for( i = maxclients->integer; i < game.maxclients; i++ )
{
e = &g_entities[ i ];
if( !e->inuse && e->client )
{
clientNum = i;
break;
}
}
if( clientNum == -1 )
{
gi.Printf( "No free slot for a bot\n" );
return;
}
if( gi.Argc() > 2 )
{
Q_strncpyz( botName, gi.Argv( 2 ), sizeof( botName ) );
}
else
{
sprintf( botName, "bot%d", clientNum - maxclients->integer + 1 );
}
sprintf( challenge, "%d", clientNum - maxclients->integer + 1 );
e->s.clientNum = clientNum;
e->s.number = clientNum;
if (saved) {
strncpy(userinfo, saved->pers.userinfo, ARRAY_LEN(userinfo));
} else {
Info_SetValueForKey(userinfo, "name", botName);
Info_SetValueForKey(userinfo, "dm_playermodel", "allied_pilot");
Info_SetValueForKey(userinfo, "dm_playergermanmodel", "german_afrika_officer");
Info_SetValueForKey(userinfo, "fov", "80");
Info_SetValueForKey(userinfo, "protocol", "8");
Info_SetValueForKey(userinfo, "ip", "0.0.0.0");
Info_SetValueForKey(userinfo, "qport", "0");
Info_SetValueForKey(userinfo, "challenge", challenge);
Info_SetValueForKey(userinfo, "snaps", "1");
Info_SetValueForKey(userinfo, "rate", "1");
Info_SetValueForKey(userinfo, "dmprimary", "smg");
}
current_bot_count++;
G_BotConnect( clientNum, userinfo );
if (saved) {
e->client->pers = saved->pers;
}
if( !firstBot )
firstBot = e;
G_BotBegin( e );
if (saved) {
/*
switch (saved->team)
{
case TEAM_ALLIES:
teamEv = new Event(EV_Player_JoinDMTeam);
teamEv->AddString("allies");
break;
case TEAM_AXIS:
teamEv = new Event(EV_Player_JoinDMTeam);
teamEv->AddString("axis");
break;
default:
teamEv = new Event(EV_Player_AutoJoinDMTeam);
break;
}
*/
} else {
teamEv = new Event(EV_Player_AutoJoinDMTeam);
e->entity->PostEvent(teamEv, level.frametime);
Event* ev = new Event(EV_Player_PrimaryDMWeapon);
ev->AddString("smg");
e->entity->PostEvent(ev, level.frametime);
}
}
}
void G_RemoveBot(unsigned int num)
{
num = Q_min(atoi(gi.Argv(1)), sv_maxbots->integer);
for( int n = 0; n < num; n++ )
{
gentity_t *e = &g_entities[ game.maxclients - 1 - n ];
if( e->inuse && e->client )
{
G_ClientDisconnect( e );
current_bot_count--;
}
}
}
void G_SaveBots() {
unsigned int n;
if (saved_bots) {
delete[] saved_bots;
saved_bots = NULL;
}
if (!current_bot_count) {
return;
}
saved_bots = new saved_bot_t[current_bot_count];
for (n = 0; n < current_bot_count; n++) {
gentity_t* e = &g_entities[game.maxclients - sv_maxbots->integer + n];
saved_bot_t& saved = saved_bots[n];
if (e->inuse && e->client)
{
Player* player = static_cast<Player*>(e->entity);
saved.bValid = true;
//saved.team = player->GetTeam();
saved.pers = player->client->pers;
}
}
}
void G_RestoreBots() {
unsigned int n;
if (!saved_bots) {
return;
}
for (n = 0; n < sv_numbots->integer; n++) {
saved_bot_t& saved = saved_bots[n];
G_AddBot(1, &saved);
}
delete[] saved_bots;
saved_bots = NULL;
}
void G_ResetBots() {
G_SaveBots();
current_bot_count = 0;
}
void G_SpawnBots() {
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);
}
}
+40
View File
@@ -0,0 +1,40 @@
/*
===========================================================================
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#pragma once
struct saved_bot_t {
client_persistant_t pers;
bool bValid;
saved_bot_t()
: bValid(false)
{}
};
void G_BotBegin(gentity_t* ent);
void G_BotThink(gentity_t* ent, int msec);
gentity_t* G_GetFirstBot();
void G_AddBot(unsigned int num, saved_bot_t* saved = NULL);
void G_RemoveBot(unsigned int num);
void G_ResetBots();
void G_SpawnBots();
+375 -401
View File
@@ -28,8 +28,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
// g_client.c -- client functions that don't happen every frame
static vec3_t playerMins = {-15, -15, -24};
static vec3_t playerMaxs = {15, 15, 32};
static vec3_t playerMins = {-15, -15, -24};
static vec3_t playerMaxs = {15, 15, 32};
// FIXME: OLD Q3 CODE
@@ -439,7 +439,6 @@ void SetClientViewAngle( gentity_t *ent, vec3_t angle ) {
#endif
/*
=======================================================================
@@ -455,31 +454,31 @@ SelectNearestDeathmatchSpawnPoint
Find the spot that we DON'T want to use
================
*/
#define MAX_SPAWN_POINTS 128
Entity *SelectNearestDeathmatchSpawnPoint( vec3_t from ) {
Entity *spot;
vec3_t delta;
float dist, nearestDist;
Entity *nearestSpot;
#define MAX_SPAWN_POINTS 128
nearestDist = 999999;
nearestSpot = NULL;
spot = NULL;
Entity *SelectNearestDeathmatchSpawnPoint(vec3_t from)
{
Entity *spot;
vec3_t delta;
float dist, nearestDist;
Entity *nearestSpot;
while( ( spot = ( Entity * )G_FindClass( spot, "info_player_deathmatch" ) ) != NULL ) {
nearestDist = 999999;
nearestSpot = NULL;
spot = NULL;
VectorSubtract( spot->origin, from, delta );
dist = VectorLength( delta );
if ( dist < nearestDist ) {
nearestDist = dist;
nearestSpot = spot;
}
}
while ((spot = (Entity *)G_FindClass(spot, "info_player_deathmatch")) != NULL) {
VectorSubtract(spot->origin, from, delta);
dist = VectorLength(delta);
if (dist < nearestDist) {
nearestDist = dist;
nearestSpot = spot;
}
}
return nearestSpot;
return nearestSpot;
}
/*
================
SelectRandomDeathmatchSpawnPoint
@@ -487,66 +486,57 @@ SelectRandomDeathmatchSpawnPoint
go to a random point that doesn't telefrag
================
*/
Entity *SelectRandomDeathmatchSpawnPoint( str spawnpoint_type )
Entity *SelectRandomDeathmatchSpawnPoint(str spawnpoint_type)
{
Entity *spot = NULL;
Entity *spot1 = NULL;
Entity *spot2 = NULL;
int count = 0;
int selection;
float range;
float range1 = 99999.0f;
float range2 = 99999.0f;
Entity *spot = NULL;
Entity *spot1 = NULL;
Entity *spot2 = NULL;
int count = 0;
int selection;
float range;
float range1 = 99999.0f;
float range2 = 99999.0f;
while( ( spot = ( Entity * )G_FindClass( spot, spawnpoint_type ) ) )
{
count++;
while ((spot = (Entity *)G_FindClass(spot, spawnpoint_type))) {
count++;
range = PlayersRangeFromSpot( spot );
if( range2 <= range )
{
if( range1 > range )
{
range1 = range;
spot1 = spot;
}
}
else
{
range2 = range;
spot2 = spot;
}
}
range = PlayersRangeFromSpot(spot);
if (range2 <= range) {
if (range1 > range) {
range1 = range;
spot1 = spot;
}
} else {
range2 = range;
spot2 = spot;
}
}
spot = NULL;
spot = NULL;
if( !count ) {
return NULL;
}
if (!count) {
return NULL;
}
if( count > 2 )
{
count -= 2;
}
else
{
spot1 = NULL;
spot2 = NULL;
}
if (count > 2) {
count -= 2;
} else {
spot1 = NULL;
spot2 = NULL;
}
for( selection = rand() % count; selection != -1; selection-- )
{
spot = ( Entity * )G_FindClass( spot, spawnpoint_type );
if( !spot ) {
break;
}
for (selection = rand() % count; selection != -1; selection--) {
spot = (Entity *)G_FindClass(spot, spawnpoint_type);
if (!spot) {
break;
}
if( spot == spot1 || spot == spot2 ) {
selection++;
}
}
if (spot == spot1 || spot == spot2) {
selection++;
}
}
return spot;
return spot;
}
/*
@@ -556,28 +546,26 @@ SelectRandomFurthestSpawnPoint
Chooses a player start, deathmatch start, etc
============
*/
Entity *SelectRandomFurthestSpawnPoint( void )
Entity *SelectRandomFurthestSpawnPoint(void)
{
Entity *spot = NULL;
Entity *bestspot = NULL;
float bestplayerdistance = 0.0f;
Entity *spot = NULL;
Entity *bestspot = NULL;
float bestplayerdistance = 0.0f;
while( ( spot = ( Entity * )G_FindClass( spot, "info_player_deathmatch" ) ) )
{
float dist = PlayersRangeFromSpot( spot );
while ((spot = (Entity *)G_FindClass(spot, "info_player_deathmatch"))) {
float dist = PlayersRangeFromSpot(spot);
if( dist > bestplayerdistance )
{
bestplayerdistance = dist;
bestspot = spot;
}
}
if (dist > bestplayerdistance) {
bestplayerdistance = dist;
bestspot = spot;
}
}
if( !bestspot ) {
bestspot = ( Entity * )G_FindClass( NULL, "info_player_deathmatch" );
}
if (!bestspot) {
bestspot = (Entity *)G_FindClass(NULL, "info_player_deathmatch");
}
return bestspot;
return bestspot;
}
/*
@@ -587,54 +575,50 @@ SelectSpawnPoint
Chooses a player start, deathmatch start, etc
============
*/
PlayerStart *SelectSpawnPoint( Player *player )
PlayerStart *SelectSpawnPoint(Player *player)
{
PlayerStart *spot = NULL;
PlayerStart *spot = NULL;
switch( g_gametype->integer )
{
case GT_FFA:
spot = player->GetDM_Team()->GetRandomFfaSpawnpoint( player );
break;
case GT_SINGLE_PLAYER:
break;
case GT_TEAM:
case GT_TEAM_ROUNDS:
spot = player->GetDM_Team()->GetRandomTeamSpawnpoint( player );
break;
case GT_OBJECTIVE:
spot = player->GetDM_Team()->GetRandomObjectiveSpawnpoint( player );
break;
default:
Com_Printf("SelectSpawnPoint: unknown game type '%i'\n", g_gametype->integer);
spot = player->GetDM_Team()->GetRandomFfaSpawnpoint( player );
break;
}
switch (g_gametype->integer) {
case GT_SINGLE_PLAYER:
break;
case GT_FFA:
spot = player->GetDM_Team()->GetRandomFfaSpawnpoint(player);
break;
case GT_TEAM:
case GT_TEAM_ROUNDS:
case GT_LIBERATION:
spot = player->GetDM_Team()->GetRandomTeamSpawnpoint(player);
break;
case GT_OBJECTIVE:
case GT_TOW:
spot = player->GetDM_Team()->GetRandomObjectiveSpawnpoint(player);
break;
default:
Com_Printf("SelectSpawnPoint: unknown game type '%i'\n", g_gametype->integer);
spot = player->GetDM_Team()->GetRandomFfaSpawnpoint(player);
break;
}
// 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;
}
}
// 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;
}
}
if( !spot && !level.spawnpoint.length() )
{
// there wasn't a spawnpoint without a target, so use any
spot = ( PlayerStart * )G_FindArchivedClass( NULL, "info_player_start" );
}
if (!spot && !level.spawnpoint.length()) {
// there wasn't a spawnpoint without a target, so use any
spot = (PlayerStart *)G_FindArchivedClass(NULL, "info_player_start");
}
if( !spot )
{
gi.Error( ERR_DROP, "No player spawn position named '%s'. Can't spawn player.\n", level.spawnpoint.c_str() );
}
}
if (!spot) {
gi.Error(ERR_DROP, "No player spawn position named '%s'. Can't spawn player.\n", level.spawnpoint.c_str());
}
}
return spot;
return spot;
}
//======================================================================
@@ -644,89 +628,87 @@ PlayerStart *SelectSpawnPoint( Player *player )
ClientCheckName
============
*/
static void ClientCleanName( const char *in, char *out, int outSize )
static void ClientCleanName(const char *in, char *out, int outSize)
{
int len, colorlessLen;
char ch;
char *p;
int spaces;
int len, colorlessLen;
char ch;
char *p;
int spaces;
//save room for trailing null byte
outSize--;
//save room for trailing null byte
outSize--;
len = 0;
colorlessLen = 0;
p = out;
*p = 0;
spaces = 0;
len = 0;
colorlessLen = 0;
p = out;
*p = 0;
spaces = 0;
while( 1 ) {
ch = *in++;
if( !ch ) {
break;
}
while (1) {
ch = *in++;
if (!ch) {
break;
}
// don't allow leading spaces
if( colorlessLen == 0 && ch == ' ' ) {
continue;
}
// don't allow leading spaces
if (colorlessLen == 0 && ch == ' ') {
continue;
}
// check colors
if( ch == Q_COLOR_ESCAPE ) {
// solo trailing carat is not a color prefix
if( !*in ) {
break;
}
// check colors
if (ch == Q_COLOR_ESCAPE) {
// solo trailing carat is not a color prefix
if (!*in) {
break;
}
// don't allow black in a name, period
if( ColorIndex(*in) == 0 ) {
in++;
continue;
}
// don't allow black in a name, period
if (ColorIndex(*in) == 0) {
in++;
continue;
}
// make sure room in dest for both chars
if( len > outSize - 2 ) {
break;
}
// make sure room in dest for both chars
if (len > outSize - 2) {
break;
}
*out++ = ch;
*out++ = *in++;
len += 2;
continue;
}
*out++ = ch;
*out++ = *in++;
len += 2;
continue;
}
// don't allow too many consecutive spaces
// don't count spaces in colorlessLen
if( ch == ' ' ) {
spaces++;
if( spaces > 3 ) {
continue;
}
*out++ = ch;
len++;
continue;
}
else {
spaces = 0;
}
// don't allow too many consecutive spaces
// don't count spaces in colorlessLen
if (ch == ' ') {
spaces++;
if (spaces > 3) {
continue;
}
*out++ = ch;
len++;
continue;
} else {
spaces = 0;
}
if( len > outSize - 1 ) {
break;
}
if (len > outSize - 1) {
break;
}
*out++ = ch;
colorlessLen++;
len++;
}
*out = 0;
*out++ = ch;
colorlessLen++;
len++;
}
*out = 0;
// don't allow empty names
if( *p == 0 || colorlessLen == 0 ) {
Q_strncpyz( p, "UnnamedPlayer", outSize );
}
// don't allow empty names
if (*p == 0 || colorlessLen == 0) {
Q_strncpyz(p, "UnnamedPlayer", outSize);
}
}
/*
===========
ClientUserInfoChanged
@@ -738,102 +720,92 @@ The game can override any of the settings and call gi.SetUserinfo
if desired.
============
*/
void G_ClientUserinfoChanged( gentity_t *ent, const char *u ) {
char *s;
gclient_t *client;
int clientnum;
void G_ClientUserinfoChanged(gentity_t *ent, const char *u)
{
char *s;
gclient_t *client;
int clientnum;
if( !ent )
{
return;
}
if (!ent) {
return;
}
client = ent->client;
client = ent->client;
s = Info_ValueForKey( u, "name" );
s = Info_ValueForKey(u, "name");
if( !s )
{
return;
}
if (!s) {
return;
}
clientnum = ent - g_entities;
clientnum = ent - g_entities;
if( gi.SanitizeName( s, client->pers.netname ) )
{
gi.Printf( "WARNING: had to sanitize the name for client %i\n", clientnum );
}
if (gi.SanitizeName(s, client->pers.netname)) {
gi.Printf("WARNING: had to sanitize the name for client %i\n", clientnum);
}
s = Info_ValueForKey( u, "dm_playermodel" );
s = Info_ValueForKey(u, "dm_playermodel");
if( !s )
{
assert( 0 );
return;
}
if (!s) {
assert(0);
return;
}
Q_strncpyz( client->pers.playermodel, s, sizeof( client->pers.playermodel ) );
Q_strncpyz(client->pers.dm_playermodel, s, sizeof(client->pers.dm_playermodel));
s = Info_ValueForKey( u, "dm_playergermanmodel" );
s = Info_ValueForKey(u, "dm_playergermanmodel");
if( !s )
{
assert( 0 );
return;
}
if (!s) {
assert(0);
return;
}
Q_strncpyz( client->pers.playergermanmodel, s, sizeof( client->pers.playergermanmodel ) );
Q_strncpyz(client->pers.dm_playergermanmodel, s, sizeof(client->pers.dm_playergermanmodel));
gi.SetConfigstring( CS_PLAYERS + clientnum, va( "name\\%s", client->pers.netname ) );
gi.setConfigstring(CS_PLAYERS + clientnum, va("name\\%s", client->pers.netname));
if( ent->entity )
{
float fov;
if (ent->entity) {
float fov;
s = Info_ValueForKey( u, "fov" );
s = Info_ValueForKey(u, "fov");
fov = atof( s );
fov = atof(s);
if( fov < 80.0f )
{
fov = 80.0f;
}
else if( fov > 160.0f )
{
fov = 160.0f;
}
if (fov < 80.0f) {
fov = 80.0f;
} else if (fov > 160.0f) {
fov = 160.0f;
}
Event *ev = new Event( EV_Player_Fov );
ev->AddFloat( fov );
Event *ev = new Event(EV_Player_Fov);
ev->AddFloat(fov);
ent->entity->ProcessEvent( ev );
}
ent->entity->ProcessEvent(ev);
}
Q_strncpyz( client->pers.userinfo, u, sizeof( client->pers.userinfo ) );
Q_strncpyz(client->pers.userinfo, u, sizeof(client->pers.userinfo));
}
void G_BotConnect( int clientNum ) {
gclient_t *client;
gentity_t *ent;
char userinfo[ MAX_INFO_STRING ];
void G_BotConnect(int clientNum, const char* userinfo)
{
gclient_t *client;
gentity_t *ent;
ent = &g_entities[ clientNum ];
ent = &g_entities[clientNum];
ent->client = game.clients + clientNum;
ent->s.number = clientNum;
ent->client = game.clients + clientNum;
ent->s.number = clientNum;
client = ent->client;
client = ent->client;
Q_strncpyz( userinfo, client->pers.userinfo, sizeof( userinfo ) );
// read the session data
memset(client, 0, sizeof(*client));
G_InitSessionData(client, userinfo);
// read the session data
memset( client, 0, sizeof( *client ) );
G_InitSessionData( client, userinfo );
Q_strncpyz(client->pers.ip, "localhost", sizeof(client->pers.ip));
client->pers.port = 0;
Q_strncpyz( client->pers.ip, "localhost", sizeof( client->pers.ip ) );
client->pers.port = 0;
G_ClientUserinfoChanged( ent, userinfo );
G_ClientUserinfoChanged(ent, userinfo);
}
/*
@@ -856,64 +828,60 @@ to the server machine, but qfalse on map changes and tournement
restarts.
============
*/
const char *G_ClientConnect( int clientNum, qboolean firstTime ) {
char *ip, *port, *value;
gclient_t *client;
gentity_t *ent;
char userinfo[ MAX_INFO_STRING ];
const char *G_ClientConnect(int clientNum, qboolean firstTime)
{
char *ip, *port, *value;
gclient_t *client;
gentity_t *ent;
char userinfo[MAX_INFO_STRING];
gi.DPrintf("TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT\n");
if( !g_gametype->integer ) {
return NULL;
}
gi.DPrintf("TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT\n");
if (!g_gametype->integer) {
return NULL;
}
ent = &g_entities[ clientNum ];
ent = &g_entities[clientNum];
gi.GetUserinfo( clientNum, userinfo, sizeof( userinfo ) );
gi.GetUserinfo(clientNum, userinfo, sizeof(userinfo));
// IP filtering
// https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=500
// recommanding PB based IP / GUID banning, the builtin system is pretty limited
// check to see if they are on the banned IP list
ip = Info_ValueForKey( userinfo, "ip" );
port = Info_ValueForKey( userinfo, "port" );
// IP filtering
// https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=500
// recommanding PB based IP / GUID banning, the builtin system is pretty limited
// check to see if they are on the banned IP list
ip = Info_ValueForKey(userinfo, "ip");
port = Info_ValueForKey(userinfo, "port");
// FIXME: what is fucking wrong with G_FilterPacket...
//if ( G_FilterPacket( value ) ) {
// return "Banned IP";
//}
// FIXME: what is fucking wrong with G_FilterPacket...
//if ( G_FilterPacket( value ) ) {
// return "Banned IP";
//}
// we don't check password for bots and local client
// NOTE: local client <-> "ip" "localhost"
// this means this client is not running in our current process
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 ) {
return "Invalid password";
}
}
// we don't check password for bots and local client
// NOTE: local client <-> "ip" "localhost"
// this means this client is not running in our current process
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) {
return "Invalid password";
}
}
ent->client = game.clients + clientNum;
client = ent->client;
ent->client = game.clients + clientNum;
client = ent->client;
// read or initialize the session data
if ( firstTime )
{
memset( client, 0, sizeof( *client ) );
G_InitSessionData( client, userinfo );
}
else
{
G_ReadSessionData( client );
}
// read or initialize the session data
if (firstTime) {
memset(client, 0, sizeof(*client));
G_InitSessionData(client, userinfo);
} else {
G_ReadSessionData(client);
}
Q_strncpyz( client->pers.ip, ip, sizeof( client->pers.ip ) );
client->pers.port = atoi( port );
Q_strncpyz(client->pers.ip, ip, sizeof(client->pers.ip));
client->pers.port = atoi(port);
G_ClientUserinfoChanged( ent, userinfo );
G_ClientUserinfoChanged(ent, userinfo);
#if 0
if( isBot )
@@ -926,17 +894,15 @@ 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( dedicated->integer )
{
gi.Printf( "%s is preparing for deployment\n", client->pers.netname );
}
// don't do the "xxx connected" messages if they were caried over from previous level
if (firstTime && g_gametype->integer) {
if (dedicated->integer) {
gi.Printf("%s is preparing for deployment\n", client->pers.netname);
}
G_PrintToAllClients( va( "%s is preparing for deployment\n", client->pers.netname ) );
}
return NULL;
G_PrintToAllClients(va("%s is preparing for deployment\n", client->pers.netname), 2);
}
return NULL;
}
/*
@@ -948,68 +914,80 @@ to be placed into the level. This will happen every level load,
and on transition between teams, but doesn't happen on respawns
============
*/
void G_ClientBegin( gentity_t *ent, usercmd_t *cmd )
void G_ClientBegin(gentity_t *ent, usercmd_t *cmd)
{
try
{
assert( ent->s.number < game.maxclients );
assert( ent->client != NULL );
try {
assert(ent->s.number < game.maxclients);
assert(ent->client != NULL);
if( ent->inuse && ent->entity )
{
VectorClear(ent->client->cmd_angles);
// the client has cleared the client side viewangles upon
// connecting to the server, which is different than the
// state when the game is saved, so we need to compensate
// with deltaangles
ent->entity->SetDeltaAngles();
}
else
{
// a spawn point will completely reinitialize the entity
level.spawn_entnum = ent->s.number;
if (ent->inuse && ent->entity) {
VectorClear(ent->client->cmd_angles);
// the client has cleared the client side viewangles upon
// connecting to the server, which is different than the
// state when the game is saved, so we need to compensate
// with deltaangles
ent->entity->SetDeltaAngles();
} else {
// a spawn point will completely reinitialize the entity
level.spawn_entnum = ent->s.number;
if( level.m_bSpawnBot )
{
level.m_bSpawnBot = false;
PlayerBot *player = new PlayerBot;
}
else
{
Player *player = new Player;
}
}
if (level.m_bSpawnBot) {
level.m_bSpawnBot = false;
PlayerBot *player = new PlayerBot;
} else {
Player *player = new Player;
}
}
if( level.intermissiontime && ent->entity )
{
G_MoveClientToIntermission( ent->entity );
}
else
{
ent->client->pers.enterTime = level.svsFloatTime;
if (level.intermissiontime && ent->entity) {
G_MoveClientToIntermission(ent->entity);
} else {
ent->client->pers.enterTime = level.svsFloatTime;
if( g_gametype->integer )
{
// send effect if in a multiplayer game
if( dedicated->integer )
{
gi.Printf( "%s has entered the battle\n", ent->client->pers.netname );
}
if (g_gametype->integer) {
// send effect if in a multiplayer game
if (dedicated->integer) {
gi.Printf("%s has entered the battle\n", ent->client->pers.netname);
}
G_PrintToAllClients( va( "%s has entered the battle\n", ent->client->pers.netname ) );
}
}
G_PrintToAllClients(va("%s has entered the battle\n", ent->client->pers.netname), 2);
}
}
// make sure all view stuff is valid
if( ent->entity )
{
ent->entity->EndFrame();
}
}
catch( const char *error )
{
G_ExitWithError( error );
}
// make sure all view stuff is valid
if (ent->entity) {
ent->entity->EndFrame();
}
} catch (const char *error) {
G_ExitWithError(error);
}
}
/*
===========
G_SetClientConfigString
============
*/
void G_SetClientConfigString(gentity_t *ent)
{
int num;
const char *string;
if (!ent) {
return;
}
num = ent - g_entities;
if (ent->entity) {
Player *pEnt = static_cast<Player *>(ent->entity);
string = va("name\\%s\\team\\%i", ent->client->pers.netname, pEnt->GetTeam());
} else {
// No team
string = va("name\\%s\\team\\0", ent->client->pers.netname);
}
gi.setConfigstring(CS_PLAYERS + num, string);
}
/*
@@ -1024,26 +1002,24 @@ call gi.DropClient(), which will call this and do
server system housekeeping.
============
*/
void G_ClientDisconnect( gentity_t *ent ) {
try
{
if ( !ent || ( !ent->client ) || ( !ent->entity ) )
{
return;
}
void G_ClientDisconnect(gentity_t *ent)
{
try {
if (!ent || (!ent->client) || (!ent->entity)) {
return;
}
G_PrintToAllClients( va( "%s has left the battle\n", ent->client->pers.netname ) );
G_PrintToAllClients(va("%s has left the battle\n", ent->client->pers.netname), 2);
( ( Player * )ent->entity )->Disconnect();
((Player *)ent->entity)->Disconnect();
delete ent->entity;
ent->entity = NULL;
}
delete ent->entity;
ent->entity = NULL;
}
catch( const char *error )
{
G_ExitWithError( error );
}
catch (const char *error) {
G_ExitWithError(error);
}
#if 0
int i;
@@ -1071,12 +1047,12 @@ void G_ClientDisconnect( gentity_t *ent ) {
// They don't get to take powerups with them!
// Especially important for stuff like CTF flags
TossClientItems( ent );
#ifdef MISSIONPACK
# ifdef MISSIONPACK
TossClientPersistantPowerups( ent );
if( g_gametype->integer == GT_HARVESTER ) {
TossClientCubes( ent );
}
#endif
# endif
}
@@ -1100,5 +1076,3 @@ void G_ClientDisconnect( gentity_t *ent ) {
}
#endif
}
+291 -334
View File
@@ -32,44 +32,43 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//==================================================================
// the "gameversion" client command will print this plus compile date
#define GAMEVERSION BASEGAME
#define GAMEVERSION "OPENMOHAA"
#define BODY_QUEUE_SIZE 8
#define BODY_QUEUE_SIZE 8
#define INFINITE 1000000
#define INFINITE 1000000
#define FRAMETIME level.frametime // float sec
#define CARNAGE_REWARD_TIME 3000
#define REWARD_SPRITE_TIME 2000
#define FRAMETIME level.frametime // float sec
#define CARNAGE_REWARD_TIME 3000
#define REWARD_SPRITE_TIME 2000
#define INTERMISSION_DELAY_TIME 1000
#define SP_INTERMISSION_DELAY_TIME 5000
#define INTERMISSION_DELAY_TIME 1000
#define SP_INTERMISSION_DELAY_TIME 5000
// flags
#define FL_FLY (1<<0)
#define FL_SWIM (1<<1) // implied immunity to drowining
#define FL_INWATER (1<<2)
#define FL_GODMODE (1<<3)
#define FL_NOTARGET (1<<4)
#define FL_PARTIALGROUND (1<<5) // not all corners are valid
#define FL_TEAMSLAVE (1<<6) // not the first on the team
#define FL_NO_KNOCKBACK (1<<7)
#define FL_THINK (1<<8)
#define FL_BLOOD (1<<9) // when hit, it should bleed.
#define FL_DIE_GIBS (1<<10) // when it dies, it should gib
#define FL_DIE_EXPLODE (1<<11) // when it dies, it will explode
#define FL_ROTATEDBOUNDS (1<<12) // model uses rotated mins and maxs
#define FL_DONTSAVE (1<<13) // don't add to the savegame
#define FL_IMMOBILE (1<<14) // entity has been immobolized somehow
#define FL_PARTIAL_IMMOBILE (1<<15) // entity has been immobolized somehow
#define FL_ANIMATE (1<<16) // entity has been immobolized somehow
#define FL_POSTTHINK (1<<17) // call a think function after the physics have been run
#define FL_TOUCH_TRIGGERS (1<<18) // should this entity touch triggers
#define FL_AUTOAIM (1<<19) // Autoaim on this entity
#define FL_UNKNOWN (1<<20)
#define FL_UNKNOWN2 (1<<21)
#define FL_FLY (1 << 0)
#define FL_SWIM (1 << 1) // implied immunity to drowining
#define FL_INWATER (1 << 2)
#define FL_GODMODE (1 << 3)
#define FL_NOTARGET (1 << 4)
#define FL_PARTIALGROUND (1 << 5) // not all corners are valid
#define FL_TEAMSLAVE (1 << 6) // not the first on the team
#define FL_NO_KNOCKBACK (1 << 7)
#define FL_THINK (1 << 8)
#define FL_BLOOD (1 << 9) // when hit, it should bleed.
#define FL_DIE_GIBS (1 << 10) // when it dies, it should gib
#define FL_DIE_EXPLODE (1 << 11) // when it dies, it will explode
#define FL_ROTATEDBOUNDS (1 << 12) // model uses rotated mins and maxs
#define FL_DONTSAVE (1 << 13) // don't add to the savegame
#define FL_IMMOBILE (1 << 14) // entity has been immobolized somehow
#define FL_PARTIAL_IMMOBILE (1 << 15) // entity has been immobolized somehow
#define FL_POSTTHINK (1 << 17) // call a think function after the physics have been run
#define FL_TOUCH_TRIGGERS (1 << 18) // should this entity touch triggers
#define FL_AUTOAIM (1 << 19) // Autoaim on this entity
#define FL_ANIMATE (1 << 20) // entity has been immobolized somehow
#define FL_UNKNOWN2 (1 << 21)
#define SOUND_RADIUS 1500.0f // Sound travel distance for AI
#define SOUND_RADIUS 1500.0f // Sound travel distance for AI
//============================================================================
@@ -83,363 +82,322 @@ template<typename T>
class Container;
typedef enum {
SPECTATOR_NOT,
SPECTATOR_FREE,
SPECTATOR_FOLLOW,
SPECTATOR_SCOREBOARD
SPECTATOR_NOT,
SPECTATOR_FREE,
SPECTATOR_FOLLOW,
SPECTATOR_SCOREBOARD
} spectatorState_t;
typedef enum {
TEAM_BEGIN, // Beginning a team game, spawn at base
TEAM_ACTIVE // Now actively playing
TEAM_BEGIN, // Beginning a team game, spawn at base
TEAM_ACTIVE // Now actively playing
} playerTeamStateState_t;
typedef struct {
playerTeamStateState_t state;
playerTeamStateState_t state;
int location;
int location;
int captures;
int basedefense;
int carrierdefense;
int flagrecovery;
int fragcarrier;
int assists;
int captures;
int basedefense;
int carrierdefense;
int flagrecovery;
int fragcarrier;
int assists;
float lasthurtcarrier;
float lastreturnedflag;
float flagsince;
float lastfraggedcarrier;
float lasthurtcarrier;
float lastreturnedflag;
float flagsince;
float lastfraggedcarrier;
} playerTeamState_t;
// the auto following clients don't follow a specific client
// number, but instead follow the first two active players
#define FOLLOW_ACTIVE1 -1
#define FOLLOW_ACTIVE2 -2
#define FOLLOW_ACTIVE1 -1
#define FOLLOW_ACTIVE2 -2
// client data that stays across multiple levels or tournament restarts
// this is achieved by writing all the data to cvar strings at game shutdown
// time and reading them back at connection time. Anything added here
// MUST be dealt with in G_InitSessionData() / G_ReadSessionData() / G_WriteSessionData()
typedef struct {
teamtype_t sessionTeam;
int spectatorTime; // for determining next-in-line to play
spectatorState_t spectatorState;
int spectatorClient; // for chasecam and follow mode
int wins, losses; // tournament stats
qboolean teamLeader; // true when this client is a team leader
teamtype_t sessionTeam;
int spectatorTime; // for determining next-in-line to play
spectatorState_t spectatorState;
int spectatorClient; // for chasecam and follow mode
int wins, losses; // tournament stats
qboolean teamLeader; // true when this client is a team leader
} clientSession_t;
//
#define MAX_NETNAME 32
#define MAX_VOTE_COUNT 3
#define MAX_NETNAME 32
#define MAX_VOTE_COUNT 3
typedef enum
{
CS_FREE,
CS_ZOMBIE,
CS_CONNECTED,
CS_PRIMED,
CS_ACTIVE
typedef enum {
CS_FREE,
CS_ZOMBIE,
CS_CONNECTED,
CS_PRIMED,
CS_ACTIVE
} clientState_t;
typedef enum
{
WEAPON_MAIN,
WEAPON_OFFHAND,
WEAPON_ERROR
} weaponhand_t;
#define NUM_ACTIVE_WEAPONS WEAPON_ERROR
typedef enum
{
FIRE_PRIMARY,
FIRE_SECONDARY,
MAX_FIREMODES,
FIRE_ERROR
} firemode_t;
//
// g_spawn.c
//
qboolean G_SpawnString( const char *key, const char *defaultString, char **out );
qboolean G_SpawnString(const char *key, const char *defaultString, char **out);
// spawn string returns a temporary reference, you must CopyString() if you want to keep it
qboolean G_SpawnFloat( const char *key, const char *defaultString, float *out );
qboolean G_SpawnInt( const char *key, const char *defaultString, int *out );
qboolean G_SpawnVector( const char *key, const char *defaultString, float *out );
void G_SpawnEntitiesFromString( void );
char *G_NewString( const char *string );
qboolean G_SpawnFloat(const char *key, const char *defaultString, float *out);
qboolean G_SpawnInt(const char *key, const char *defaultString, int *out);
qboolean G_SpawnVector(const char *key, const char *defaultString, float *out);
void G_SpawnEntitiesFromString(void);
char *G_NewString(const char *string);
const char *G_FixTIKIPath(const char *in);
void G_GetNullEntityState( entityState_t *nullState );
void G_GetNullEntityState(entityState_t *nullState);
//
// g_cmds.c
//
void Cmd_Score_f (gentity_t *ent);
void StopFollowing( gentity_t *ent );
void BroadcastTeamChange( gclient_t *client, int oldTeam );
void SetTeam( gentity_t *ent, char *s );
void Cmd_FollowCycle_f( gentity_t *ent, int dir );
void Cmd_Score_f(gentity_t *ent);
void StopFollowing(gentity_t *ent);
void BroadcastTeamChange(gclient_t *client, int oldTeam);
void SetTeam(gentity_t *ent, char *s);
void Cmd_FollowCycle_f(gentity_t *ent, int dir);
//
// g_items.c
//
//
// g_utils.c
//
float G_Random( void );
float G_Random( float n );
float G_CRandom( void );
float G_CRandom( float n );
float G_Random(void);
float G_Random(float n);
float G_CRandom(void);
float G_CRandom(float n);
int G_ModelIndex( const char *name );
int G_SoundIndex( const char *name );
void G_TeamCommand( teamtype_t team, char *cmd );
void G_KillBox (gentity_t *ent);
qboolean M_CheckBottom( Entity *ent );
gentity_t *G_PickTarget (char *targetname);
void G_UseTargets (gentity_t *ent, gentity_t *activator);
Vector G_GetMovedir( float angle );
void G_SetMovedir ( vec3_t angles, vec3_t movedir);
int G_ModelIndex(const char *name);
int G_SoundIndex(const char *name);
void G_TeamCommand(teamtype_t team, char *cmd);
void G_KillBox(gentity_t *ent);
qboolean M_CheckBottom(Entity *ent);
gentity_t *G_PickTarget(char *targetname);
void G_UseTargets(gentity_t *ent, gentity_t *activator);
void G_SetMovedir(vec3_t angles, vec3_t movedir);
void G_InitGentity( gentity_t *e );
gentity_t *G_Spawn (void);
gentity_t *G_TempEntity( vec3_t origin, int event );
void G_Sound( gentity_t *ent, int channel, int soundIndex );
void G_FreeEntity( gentity_t *e );
qboolean G_entitiesFree( void );
void G_InitGentity(gentity_t *e);
gentity_t *G_Spawn(void);
gentity_t *G_TempEntity(vec3_t origin, int event);
void G_Sound(gentity_t *ent, int channel, int soundIndex);
void G_FreeEntity(gentity_t *e);
qboolean G_entitiesFree(void);
Entity *G_NextEntity( Entity *ent );
Entity *G_NextEntity(Entity *ent);
void G_CalcBoundsOfMove( Vector &start, Vector &end, Vector &mins, Vector &maxs, Vector *minbounds, Vector *maxbounds );
void G_CalcBoundsOfMove(Vector& start, Vector& end, Vector& mins, Vector& maxs, Vector *minbounds, Vector *maxbounds);
void G_ShowTrace( trace_t *trace, gentity_t *passent, const char *reason );
bool G_SightTrace(const Vector &start, const Vector &mins, const Vector &maxs, const Vector &end, Entity *passent, Entity *passent2, int contentmask, qboolean cylindrical, const char *reason );
bool G_SightTrace( const Vector &start, const Vector &mins, const Vector &maxs, const Vector &end, gentity_t *passent, gentity_t *passent2, int contentmask, qboolean cylindrical, const char *reason );
trace_t G_Trace(const Vector &start, const Vector &mins, const Vector &maxs, const Vector &end, Entity *passent, int contentmask, qboolean cylindrical, const char *reason, qboolean tracedeep = qfalse );
trace_t G_Trace( vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, gentity_t *passent, int contentmask, qboolean cylindrical, const char *reason, qboolean tracedeep = qfalse );
void G_TraceEntities( Vector &start, Vector &mins, Vector &maxs, Vector &end, Container<Entity *>*victimlist, int contentmask, qboolean bIncludeTriggers = qfalse );
float PlayersRangeFromSpot(Entity *ent);
float PlayersRangeFromSpot( Entity *ent );
Entity *findradius(Entity *startent, Vector org, float rad);
Entity *findclientsinradius(Entity *startent, Vector org, float rad);
Entity *findradius( Entity *startent, Vector org, float rad );
Entity *findclientsinradius( Entity *startent, Vector org, float rad );
void G_TouchTriggers(gentity_t *ent);
void G_TouchSolids(gentity_t *ent);
Vector G_CalculateImpulse( const Vector &start, const Vector &end, float speed, float gravity );
void G_CenterPrintToAllClients(const char *pszString);
void G_PrintToAllClients(const char *pszString, int iType = 1);
void G_PrintDeathMessage(
const char *s1, const char *s2, const char *attackerName, const char *victimName, Player *victim, const char *type
);
void G_PrintDeathMessage_Old(const char *pszString);
void G_WarnPlayer(class Player *player, const char *format, ...);
void G_TouchTriggers (gentity_t *ent);
void G_TouchSolids (gentity_t *ent);
int MOD_NameToNum( const str &meansOfDeath );
const char *MOD_NumToName( int meansOfDeath );
qboolean MOD_matches( int incoming_damage, int damage_type );
void G_MissionFailed( void );
void G_FadeOut( float delaytime );
void G_FadeSound( float delaytime );
void G_PlayerDied( float delaytime );
void G_AutoFadeIn( void );
void G_ClearFade( void );
void G_StartCinematic( void );
void G_StopCinematic( void );
void G_CenterPrintToAllClients( const char *pszString );
void G_PrintToAllClients( const char *pszString, qboolean bBold = qtrue );
void G_PrintDeathMessage( const char *pszString );
void G_WarnPlayer( class Player *player, const char *format, ... );
int G_WeaponIndex( const char *name );
int G_WeaponIndex(const char *name);
class SkelMat4;
orientation_t G_TIKI_Orientation( gentity_t *edict, int num );
SkelMat4 *G_TIKI_Transform( gentity_t *edict, int num );
qboolean G_TIKI_IsOnGround( gentity_t *edict, int num, float threshold );
qboolean G_Command_ProcessFile( const char * filename, qboolean quiet );
orientation_t G_TIKI_Orientation(gentity_t *edict, int num);
SkelMat4 *G_TIKI_Transform(gentity_t *edict, int num);
qboolean G_TIKI_IsOnGround(gentity_t *edict, int num, float threshold);
qboolean G_Command_ProcessFile(const char *filename, qboolean quiet);
char *G_TimeString( float fTime );
char *CanonicalTikiName( const char *szInName );
char *G_TimeString(float fTime);
char *CanonicalTikiName(const char *szInName);
float *tv (float x, float y, float z);
char *vtos( const vec3_t v );
float *tv(float x, float y, float z);
char *vtos(const vec3_t v);
float vectoyaw( const vec3_t vec );
void G_SetOrigin(gentity_t *ent, vec3_t origin);
void AddRemap(const char *oldShader, const char *newShader, float timeOffset);
const char *BuildShaderStateConfig(void);
void G_SetOrigin( gentity_t *ent, vec3_t origin );
void AddRemap(const char *oldShader, const char *newShader, float timeOffset);
const char *BuildShaderStateConfig( void );
void G_DebugTargets(Entity *e, const str& from);
void G_DebugDamage(float damage, Entity *victim, Entity *attacker, Entity *inflictor);
void G_DebugString(Vector pos, float scale, float r, float g, float b, const char *pszText, ...);
firemode_t WeaponModeNameToNum( str mode );
const char *WeaponHandNumToName( weaponhand_t hand );
weaponhand_t WeaponHandNameToNum( str side );
void G_DebugTargets( Entity *e, const str &from );
void G_DebugDamage( float damage, Entity *victim, Entity *attacker, Entity *inflictor );
void G_DebugString( Vector pos, float scale, float r, float g, float b, const char *pszText, ... );
qboolean KillBox(Entity *ent);
qboolean KillBox( Entity *ent );
void ChangeMusic(const char *current, const char *fallback, qboolean force);
void ChangeMusicVolume(float volume, float fade_time);
void RestoreMusicVolume(float fade_time);
void ChangeSoundtrack(const char *soundtrack);
void RestoreSoundtrack(void);
int G_AIEventTypeFromString(const char *pszType);
const char *G_AIEventStringFromType(int iType);
float G_AIEventRadius(int iType);
void G_BroadcastAIEvent(Entity *originator, Vector origin, char *pszType);
void G_BroadcastAIEvent(Entity *originator, Vector origin, int iType, float radius);
void ChangeMusic( const char *current, const char *fallback, qboolean force );
void ChangeMusicVolume( float volume, float fade_time );
void RestoreMusicVolume( float fade_time );
void ChangeSoundtrack( const char * soundtrack );
void RestoreSoundtrack( void );
int G_AIEventTypeFromString( const char *pszType );
const char * G_AIEventStringFromType(int iType );
float G_AIEventRadius( int iType );
void G_BroadcastAIEvent( Entity *originator, Vector origin, char *pszType );
void G_BroadcastAIEvent( Entity *originator, Vector origin, int iType, float radius );
void CloneEntity(Entity *dest, Entity *src);
void G_ArchiveEdict(Archiver& arc, gentity_t *edict);
void CloneEntity( Entity * dest, Entity * src );
void G_ArchiveEdict( Archiver &arc, gentity_t *edict );
const char *G_LocationNumToDispString(int iLocation);
str G_WeaponClassNumToName(int num);
int G_WeaponClassNameToNum(str name);
const char *G_LocationNumToDispString( int iLocation );
str G_WeaponClassNumToName( int num );
int G_WeaponClassNameToNum( str name );
//Checks for the intermission to exit.
void G_CheckIntermissionExit(void);
void G_CheckStartRules(void);
void G_CheckExitRules(void);
void G_MoveClientToIntermission( Entity *ent );
void G_DisplayScores( Entity *ent );
void G_HideScores( Entity *ent );
void G_DisplayScoresToAllClients( void );
void G_HideScoresToAllClients( void );
// Update the time limit
void G_UpdateMatchEndTime(void);
void G_MoveClientToIntermission(Entity *ent);
void G_DisplayScores(Entity *ent);
void G_HideScores(Entity *ent);
void G_DisplayScoresToAllClients(void);
void G_HideScoresToAllClients(void);
//
// caching commands
//
void G_ProcessCacheInitCommands( dtiki_t *tiki );
void CacheResource( const char * stuff );
void G_ProcessCacheInitCommands(dtiki_t *tiki);
void G_SetTrajectory( gentity_t *ent, vec3_t org );
void G_SetConstantLight (
int * constantlight,
float * red,
float * green,
float * blue,
float * radius,
int * lightstyle = NULL
);
void G_SetTrajectory(gentity_t *ent, vec3_t org);
//
// g_combat.c
//
qboolean CanDamage (gentity_t *targ, vec3_t origin);
void G_Damage (gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, vec3_t dir, vec3_t point, int damage, int dflags, int mod);
qboolean G_RadiusDamage (vec3_t origin, gentity_t *attacker, float damage, float radius, gentity_t *ignore, int mod);
int G_InvulnerabilityEffect( gentity_t *targ, vec3_t dir, vec3_t point, vec3_t impactpoint, vec3_t bouncedir );
void body_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int meansOfDeath );
void TossClientItems( gentity_t *self );
qboolean CanDamage(gentity_t *targ, vec3_t origin);
void G_Damage(
gentity_t *targ,
gentity_t *inflictor,
gentity_t *attacker,
vec3_t dir,
vec3_t point,
int damage,
int dflags,
int mod
);
qboolean G_RadiusDamage(vec3_t origin, gentity_t *attacker, float damage, float radius, gentity_t *ignore, int mod);
int G_InvulnerabilityEffect(gentity_t *targ, vec3_t dir, vec3_t point, vec3_t impactpoint, vec3_t bouncedir);
void body_die(gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int meansOfDeath);
void TossClientItems(gentity_t *self);
#ifdef MISSIONPACK
void TossClientPersistantPowerups( gentity_t *self );
void TossClientPersistantPowerups(gentity_t *self);
#endif
void TossClientCubes( gentity_t *self );
void TossClientCubes(gentity_t *self);
// damage flags
#define DAMAGE_NONE 0
#define DAMAGE_RADIUS 0x00000001 // damage was indirect
#define DAMAGE_NO_ARMOR 0x00000002 // armour does not protect from this damage
#define DAMAGE_ENERGY 0x00000004 // damage is from an energy based weapon
#define DAMAGE_NO_KNOCKBACK 0x00000008 // do not affect velocity, just view angles
#define DAMAGE_BULLET 0x00000010 // damage is from a bullet (used for ricochets)
#define DAMAGE_NO_PROTECTION 0x00000020 // armor, shields, invulnerability, and godmode have no effect
#define DAMAGE_NO_SKILL 0x00000040 // damage is not affected by skill level
#define DAMAGE_NONE 0
#define DAMAGE_RADIUS 0x00000001 // damage was indirect
#define DAMAGE_NO_ARMOR 0x00000002 // armour does not protect from this damage
#define DAMAGE_ENERGY 0x00000004 // damage is from an energy based weapon
#define DAMAGE_NO_KNOCKBACK 0x00000008 // do not affect velocity, just view angles
#define DAMAGE_BULLET 0x00000010 // damage is from a bullet (used for ricochets)
#define DAMAGE_NO_PROTECTION 0x00000020 // armor, shields, invulnerability, and godmode have no effect
#define DAMAGE_NO_SKILL 0x00000040 // damage is not affected by skill level
//
// g_missile.c
//
void G_RunMissile( gentity_t *ent );
void G_RunMissile(gentity_t *ent);
gentity_t *fire_blaster (gentity_t *self, vec3_t start, vec3_t aimdir);
gentity_t *fire_plasma (gentity_t *self, vec3_t start, vec3_t aimdir);
gentity_t *fire_grenade (gentity_t *self, vec3_t start, vec3_t aimdir);
gentity_t *fire_rocket (gentity_t *self, vec3_t start, vec3_t dir);
gentity_t *fire_bfg (gentity_t *self, vec3_t start, vec3_t dir);
gentity_t *fire_grapple (gentity_t *self, vec3_t start, vec3_t dir);
gentity_t *fire_blaster(gentity_t *self, vec3_t start, vec3_t aimdir);
gentity_t *fire_plasma(gentity_t *self, vec3_t start, vec3_t aimdir);
gentity_t *fire_grenade(gentity_t *self, vec3_t start, vec3_t aimdir);
gentity_t *fire_rocket(gentity_t *self, vec3_t start, vec3_t dir);
gentity_t *fire_bfg(gentity_t *self, vec3_t start, vec3_t dir);
gentity_t *fire_grapple(gentity_t *self, vec3_t start, vec3_t dir);
#ifdef MISSIONPACK
gentity_t *fire_nail( gentity_t *self, vec3_t start, vec3_t forward, vec3_t right, vec3_t up );
gentity_t *fire_prox( gentity_t *self, vec3_t start, vec3_t aimdir );
gentity_t *fire_nail(gentity_t *self, vec3_t start, vec3_t forward, vec3_t right, vec3_t up);
gentity_t *fire_prox(gentity_t *self, vec3_t start, vec3_t aimdir);
#endif
//
// g_mover.c
//
void G_RunMover( gentity_t *ent );
void Touch_DoorTrigger( gentity_t *ent, gentity_t *other, trace_t *trace );
void Use_BinaryMover( gentity_t *ent, gentity_t *other, gentity_t *activator );
void G_RunMover(gentity_t *ent);
void Touch_DoorTrigger(gentity_t *ent, gentity_t *other, trace_t *trace);
void Use_BinaryMover(gentity_t *ent, gentity_t *other, gentity_t *activator);
//
// g_trigger.c
//
void trigger_teleporter_touch (gentity_t *self, gentity_t *other, trace_t *trace );
void trigger_teleporter_touch(gentity_t *self, gentity_t *other, trace_t *trace);
//
// g_misc.c
//
void TeleportPlayer( gentity_t *player, vec3_t origin, vec3_t angles );
void TeleportPlayer(gentity_t *player, vec3_t origin, vec3_t angles);
#ifdef MISSIONPACK
void DropPortalSource( gentity_t *ent );
void DropPortalDestination( gentity_t *ent );
void DropPortalSource(gentity_t *ent);
void DropPortalDestination(gentity_t *ent);
#endif
//
// g_weapon.c
//
qboolean LogAccuracyHit( gentity_t *target, gentity_t *attacker );
void SnapVectorTowards( vec3_t v, vec3_t to );
qboolean CheckGauntletAttack( gentity_t *ent );
void Weapon_HookFree (gentity_t *ent);
void Weapon_HookThink (gentity_t *ent);
void CalcMuzzlePoint( gentity_t *ent, vec3_t forward, vec3_t right, vec3_t up, vec3_t muzzlePoint );
qboolean LogAccuracyHit(gentity_t *target, gentity_t *attacker);
void SnapVectorTowards(vec3_t v, vec3_t to);
qboolean CheckGauntletAttack(gentity_t *ent);
void Weapon_HookFree(gentity_t *ent);
void Weapon_HookThink(gentity_t *ent);
void CalcMuzzlePoint(gentity_t *ent, vec3_t forward, vec3_t right, vec3_t up, vec3_t muzzlePoint);
//
// g_client.c
//
gentity_t *G_Find( gentity_t *from, int fieldofs, const char *match );
teamtype_t TeamCount( int ignoreClientNum, int team );
int TeamLeader( int team );
teamtype_t PickTeam( int ignoreClientNum );
void SetClientViewAngle( gentity_t *ent, vec3_t angle );
class PlayerStart *SelectSpawnPoint( Player *player );
void CopyToBodyQue( gentity_t *ent );
void respawn (gentity_t *ent);
void BeginIntermission (void);
void InitClientPersistant (gclient_t *client);
void InitClientResp (gclient_t *client);
void InitBodyQue (void);
void ClientSpawn( gentity_t *ent );
void player_die (gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int mod);
void AddScore( gentity_t *ent, vec3_t origin, int score );
void CalculateRanks( void );
gentity_t *G_Find(gentity_t *from, int fieldofs, const char *match);
teamtype_t TeamCount(int ignoreClientNum, int team);
int TeamLeader(int team);
teamtype_t PickTeam(int ignoreClientNum);
void SetClientViewAngle(gentity_t *ent, vec3_t angle);
class PlayerStart *SelectSpawnPoint(Player *player);
void CopyToBodyQue(gentity_t *ent);
void respawn(gentity_t *ent);
void BeginIntermission(void);
void InitClientPersistant(gclient_t *client);
void InitClientResp(gclient_t *client);
void InitBodyQue(void);
void ClientSpawn(gentity_t *ent);
void player_die(gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int mod);
void AddScore(gentity_t *ent, vec3_t origin, int score);
void CalculateRanks(void);
//
// g_svcmds.c
//
qboolean G_ConsoleCommand( void );
void G_ProcessIPBans(void);
qboolean G_FilterPacket (char *from);
qboolean G_ConsoleCommand(void);
void G_ProcessIPBans(void);
qboolean G_FilterPacket(char *from);
//
// g_weapon.c
//
void FireWeapon( gentity_t *ent );
void FireWeapon(gentity_t *ent);
#ifdef MISSIONPACK
void G_StartKamikaze( gentity_t *ent );
void G_StartKamikaze(gentity_t *ent);
#endif
//
// p_hud.c
//
void MoveClientToIntermission (gentity_t *client);
void G_SetStats (gentity_t *ent);
void DeathmatchScoreboardMessage (gentity_t *client);
void MoveClientToIntermission(gentity_t *client);
void G_SetStats(gentity_t *ent);
void DeathmatchScoreboardMessage(gentity_t *client);
//
// g_cmds.c
@@ -449,129 +407,128 @@ void DeathmatchScoreboardMessage (gentity_t *client);
// g_pweapon.c
//
//
// g_main.c
//
void FindIntermissionPoint( void );
void SetLeader(int team, int client);
void CheckTeamLeader( int team );
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 FindIntermissionPoint(void);
void SetLeader(int team, int client);
void CheckTeamLeader(int team);
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, ...);
//
// g_client.c
//
void G_BotConnect( int clientNum );
const char *G_ClientConnect( int clientNum, qboolean firstTime );
void G_ClientUserinfoChanged( gentity_t *ent, const char *userinfo );
void G_ClientDisconnect( gentity_t *ent );
void G_ClientBegin( gentity_t *ent, usercmd_t *cmd );
void G_ClientCommand( gentity_t *ent );
void G_BotConnect(int clientNum, const char* userinfo);
const char *G_ClientConnect(int clientNum, qboolean firstTime);
void G_ClientUserinfoChanged(gentity_t *ent, const char *userinfo);
void G_ClientDisconnect(gentity_t *ent);
void G_ClientBegin(gentity_t *ent, usercmd_t *cmd);
void G_SetClientConfigString(gentity_t *ent);
void G_ClientCommand(gentity_t *ent);
//
// g_active.c
//
void G_ClientThink( gentity_t *ent, usercmd_t *cmd, usereyes_t *eyeinfo );
void ClientEndFrame( gentity_t *ent );
void G_ClientEndServerFrames( void );
void G_RunClient( 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_RunClient(gentity_t *ent);
//
// g_team.c
//
qboolean OnSameTeam( gentity_t *ent1, gentity_t *ent2 );
void Team_CheckDroppedItem( gentity_t *dropped );
qboolean CheckObeliskAttack( gentity_t *obelisk, gentity_t *attacker );
qboolean OnSameTeam(gentity_t *ent1, gentity_t *ent2);
void Team_CheckDroppedItem(gentity_t *dropped);
qboolean CheckObeliskAttack(gentity_t *obelisk, gentity_t *attacker);
//
// g_mem.c
//
void *G_Alloc( int size );
void G_InitMemory( void );
void Svcmd_GameMem_f( void );
void *G_Alloc(int size);
void G_InitMemory(void);
void Svcmd_GameMem_f(void);
//
// g_session.c
//
void G_ReadSessionData( gclient_t *client );
void G_InitSessionData( gclient_t *client, char *userinfo );
void G_ReadSessionData(gclient_t *client);
void G_InitSessionData(gclient_t *client, const char *userinfo);
void G_InitWorldSession( void );
void G_WriteSessionData( void );
void G_InitWorldSession(void);
void G_WriteSessionData(void);
//
// g_arenas.c
//
void UpdateTournamentInfo( void );
void SpawnModelsOnVictoryPads( void );
void Svcmd_AbortPodium_f( void );
void UpdateTournamentInfo(void);
void SpawnModelsOnVictoryPads(void);
void Svcmd_AbortPodium_f(void);
//
// g_bot.c
//
void G_BotBegin( gentity_t *ent );
void G_BotThink( gentity_t *ent, int msec );
typedef struct mmove_s {
vec3_t origin;
vec3_t velocity;
vec3_t origin;
vec3_t velocity;
qboolean walking;
qboolean groundPlane;
vec3_t groundPlaneNormal;
qboolean walking;
qboolean groundPlane;
vec3_t groundPlaneNormal;
float frametime;
float frametime;
float desired_speed;
int tracemask;
float desired_dir[ 2 ];
float desired_speed;
int tracemask;
float desired_dir[2];
int entityNum;
int entityNum;
vec3_t mins;
vec3_t maxs;
vec3_t mins;
vec3_t maxs;
int numtouch;
int touchents[ MAXTOUCH ];
int numtouch;
int touchents[MAXTOUCH];
qboolean hit_obstacle;
vec3_t hit_origin;
int hit_temp_obstacle;
qboolean hit_obstacle;
vec3_t hit_origin;
int hit_temp_obstacle;
vec3_t obstacle_normal;
vec3_t obstacle_normal;
} mmove_t;
// g_mmove.cpp
void MmoveSingle( mmove_t *mmove );
void MmoveSingle(mmove_t *mmove);
// g_vmove.cpp
void VmoveSingle( struct vmove_s *mmove );
void VmoveSingle(struct vmove_s *mmove);
// ai_main.c
#define MAX_FILEPATH 144
#define MAX_FILEPATH 144
//bot settings
typedef struct bot_settings_s
{
char characterfile[MAX_FILEPATH];
float skill;
char team[MAX_FILEPATH];
typedef struct bot_settings_s {
char characterfile[MAX_FILEPATH];
float skill;
char team[MAX_FILEPATH];
} bot_settings_t;
int BotAISetup( int restart );
int BotAIShutdown();
int BotAILoadMap( int restart );
int BotAISetupClient(int client, struct bot_settings_s *settings, qboolean restart);
int BotAIShutdownClient( int client, qboolean restart );
int BotAIStartFrame( int time );
int BotAISetup(int restart);
int BotAIShutdown();
int BotAILoadMap(int restart);
int BotAISetupClient(int client, struct bot_settings_s *settings, qboolean restart);
int BotAIShutdownClient(int client, qboolean restart);
int BotAIStartFrame(int time);
void BotTestAAS(vec3_t origin);
extern gentity_t *g_entities;
#define FOFS(x) ((size_t)&(((gentity_t *)0)->x))
#define FOFS(x) ((size_t) & (((gentity_t *)0)->x))
#include "g_utils.h"
#endif /* g_local.h */
+1390 -1132
View File
File diff suppressed because it is too large. Load diff
+16 -16
View File
@@ -30,28 +30,28 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
class Player;
extern qboolean LoadingSavegame;
extern qboolean LoadingServer;
extern game_import_t gi;
extern game_export_t globals;
extern int g_protocol;
extern qboolean LoadingSavegame;
extern qboolean LoadingServer;
extern game_import_t gi;
extern game_export_t globals;
extern int g_protocol;
extern qboolean g_iInThinks;
extern qboolean g_bBeforeThinks;
extern gentity_t active_edicts;
extern gentity_t free_edicts;
extern gentity_t active_edicts;
extern gentity_t free_edicts;
extern int sv_numtraces;
extern int sv_numpmtraces;
extern int sv_numtraces;
extern int sv_numpmtraces;
extern usercmd_t *current_ucmd;
extern usereyes_t *current_eyeinfo;
extern Player *g_pPlayer;
extern usercmd_t *current_ucmd;
extern usereyes_t *current_eyeinfo;
extern Player *g_pPlayer;
void G_ExitWithError( const char *error );
void G_AllocGameData( void );
void G_DeAllocGameData( void );
void G_ClientDrawBoundingBoxes( void );
void G_ExitWithError(const char *error);
void G_AllocGameData(void);
void G_DeAllocGameData(void);
void G_ClientDrawBoundingBoxes(void);
#endif /* g_main.h */
+5 -5
View File
@@ -172,7 +172,7 @@ qboolean MM_SlideMove
VectorMA( mm->origin, time_left, mm->velocity, end );
// see if we can make it there
gi.Trace( &trace, mm->origin, mm->mins, mm->maxs, end, mm->entityNum, mm->tracemask, qtrue, qfalse );
gi.trace( &trace, mm->origin, mm->mins, mm->maxs, end, mm->entityNum, mm->tracemask, qtrue, qfalse );
if( trace.allsolid )
break;
@@ -379,7 +379,7 @@ void MM_GroundTrace
point[ 1 ] = mm->origin[ 1 ];
point[ 2 ] = mm->origin[ 2 ] - 0.25f;
gi.Trace( &mml.groundTrace, mm->origin, mm->mins, mm->maxs, point, mm->entityNum, mm->tracemask, qtrue, qfalse );
gi.trace( &mml.groundTrace, mm->origin, mm->mins, mm->maxs, point, mm->entityNum, mm->tracemask, qtrue, qfalse );
MM_GroundTraceInternal();
}
@@ -420,7 +420,7 @@ void MM_StepSlideMove
VectorCopy( start_o, down );
down[ 2 ] -= STEPSIZE;
gi.Trace( &trace, start_o, mm->mins, mm->maxs, down, mm->entityNum, mm->tracemask, qtrue, qfalse );
gi.trace( &trace, start_o, mm->mins, mm->maxs, down, mm->entityNum, mm->tracemask, qtrue, qfalse );
VectorSet( up, 0, 0, 1 );
// never step up when you still have up velocity
@@ -460,7 +460,7 @@ void MM_StepSlideMove
down[ 2 ] -= STEPSIZE * 2;
// test the player position if they were a stepheight higher
gi.Trace( &trace, up, mm->mins, mm->maxs, up, mm->entityNum, mm->tracemask, qtrue, qfalse );
gi.trace( &trace, up, mm->mins, mm->maxs, up, mm->entityNum, mm->tracemask, qtrue, qfalse );
if( trace.entityNum > ENTITYNUM_NONE )
{
VectorCopy( nostep_o, mm->origin );
@@ -607,7 +607,7 @@ void MmoveSingle
point[ 1 ] = mmove->origin[ 1 ];
point[ 2 ] = mmove->origin[ 2 ] - 18.0f;
gi.Trace( &trace, mm->origin, mm->mins, mm->maxs, point, mm->entityNum, mm->tracemask, qtrue, qfalse );
gi.trace( &trace, mm->origin, mm->mins, mm->maxs, point, mm->entityNum, mm->tracemask, qtrue, qfalse );
if( trace.fraction < 1.0f && !trace.allsolid )
{
+4 -4
View File
@@ -588,7 +588,7 @@ retry:
mask = MASK_SOLID;
}
trace = G_Trace( start, ent->mins, ent->maxs, end, ent, mask, false, "G_PushEntity" );
trace = G_Trace( start, ent->mins, ent->maxs, end, ent, mask, true, "G_PushEntity" );
edict = ent->edict;
@@ -1216,7 +1216,7 @@ void G_Physics_Toss
onconveyor = ( basevel != vec_zero );
// if onground, return without moving
if( ent->groundentity && !onconveyor && ( ent->movetype != MOVETYPE_VEHICLE ) )
if( ent->groundentity && ent->groundentity->entity->movetype == MOVETYPE_NONE && !onconveyor && ( ent->movetype != MOVETYPE_VEHICLE ) )
{
if( ent->avelocity.length() )
{
@@ -1328,7 +1328,7 @@ void G_Physics_Toss
// check for water transition
wasinwater = ( ent->watertype & MASK_WATER );
ent->watertype = gi.PointContents( ent->origin, 0 );
ent->watertype = gi.pointcontents( ent->origin, 0 );
isinwater = ent->watertype & MASK_WATER;
if( isinwater )
@@ -1418,7 +1418,7 @@ void G_CheckWater
Entity *ent
)
{
ent->watertype = gi.PointContents( ent->origin, 0 );
ent->watertype = gi.pointcontents( ent->origin, 0 );
if( ent->watertype & MASK_WATER )
{
ent->waterlevel = 1;
+2 -1
View File
@@ -57,7 +57,8 @@ typedef enum
MOVETYPE_SLIDE,
MOVETYPE_GIB,
MOVETYPE_VEHICLE,
MOVETYPE_TURRET
MOVETYPE_TURRET,
MOVETYPE_PORTABLE_TURRET
} movetype_t;
typedef struct
+18 -15
View File
@@ -43,7 +43,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define SVF_CLIENTMASK 0x00000002
#define SVF_BROADCAST 0x00000004 // send to all connected clients
#define SVF_BOT 0x00000008 // set if the entity is a bot
#define SVF_MONSTER 0x00000008 // set if the entity is a bot
#define SVF_PORTAL 0x00000040 // merge a second pvs at origin2 into snapshots
#define SVF_USE_CURRENT_ORIGIN 0x00000080 // entity->r.currentOrigin instead of entity->s.origin
// for link position (missiles and movers)
@@ -120,18 +120,18 @@ typedef struct {
typedef struct {
char userinfo[ MAX_INFO_STRING ];
char netname[ MAX_NAME_LENGTH ];
char playermodel[ MAX_QPATH ];
char playergermanmodel[ MAX_QPATH ];
char weapon[ MAX_QPATH ];
char dm_playermodel[ MAX_QPATH ];
char dm_playergermanmodel[ MAX_QPATH ];
char dm_primary[ MAX_QPATH ];
float enterTime;
teamtype_t team;
int kills;
teamtype_t teamnum;
int round_kills;
char ip[ 17 ];
int port;
} clientPersistant_t;
} client_persistant_t;
// this structure is cleared on each ClientSpawn(),
@@ -143,7 +143,7 @@ struct gclient_s {
#ifdef GAME_DLL
// the rest of the structure is private to game
int ping;
clientPersistant_t pers;
client_persistant_t pers;
float cmd_angles[ 3 ];
int lastActiveTime;
@@ -231,10 +231,11 @@ typedef struct gameImport_s
void ( *Error )( int level, const char *format, ... );
int ( *Milliseconds )( );
const char * ( *LV_ConvertString )( const char *string );
const char * ( *CL_LV_ConvertString )( const char *string );
void * ( *Malloc )( size_t size );
void ( *Free )( void *ptr );
cvar_t * ( *Cvar_Get )( const char *varName, const char *varValue, int varFlags );
void ( *Cvar_Set )( const char *varName, const char *varValue );
void ( *cvar_set )( const char *varName, const char *varValue );
cvar_t *( *cvar_set2 )( const char *varName, const char *varValue, qboolean force );
cvar_t *( *NextCvar )( cvar_t *var );
int ( *Argc )( );
@@ -280,26 +281,27 @@ typedef struct gameImport_s
void ( *SetBroadcastVisible )( const vec3_t pos, const vec3_t posB );
void ( *SetBroadcastHearable )(const vec3_t pos, const vec3_t posB );
void ( *SetBroadcastAll )( );
void ( *SetConfigstring )( int index, const char *val );
char *( *GetConfigstring )( int index );
void ( *setConfigstring )( int index, const char *val );
char *( *getConfigstring )( int index );
void ( *SetUserinfo )( int index, const char *val );
void ( *GetUserinfo )( int index, char *buffer, int bufferSize );
void ( *SetBrushModel )( gentity_t *ent, const char *name );
void ( *ModelBoundsFromName )(const char *name, vec3_t mins, vec3_t maxs );
qboolean ( *SightTraceEntity )( gentity_t *touch, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int contentMask, qboolean cylinder );
qboolean ( *SightTrace )( const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int passEntityNum, int passEntityNum2, int contentMask, qboolean cylinder );
void ( *Trace )( trace_t *results, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int passEntityNum, int contentMask, qboolean cylinder, qboolean traceDeep );
void ( *trace )( trace_t *results, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int passEntityNum, int contentMask, qboolean cylinder, qboolean traceDeep );
baseshader_t * ( *GetShader )( int shaderNum );
int ( *PointContents )( const vec3_t p, int passEntityNum );
int ( *pointcontents )( const vec3_t p, int passEntityNum );
int ( *PointBrushnum )(const vec3_t p, clipHandle_t model );
void ( *AdjustAreaPortalState )( gentity_t *ent, qboolean open );
int ( *AreaForPoint )( vec3_t pos );
qboolean ( *AreasConnected )( int area1, int area2);
qboolean ( *InPVS )( float *p1, float *p2 );
void ( *LinkEntity )( gentity_t *gEnt );
void ( *UnlinkEntity )( gentity_t *gEnt );
void ( *linkentity )( gentity_t *gEnt );
void ( *unlinkentity )( gentity_t *gEnt );
int ( *AreaEntities )( const vec3_t mins, const vec3_t maxs, int *list, int maxcount );
void ( *ClipToEntity )( trace_t *tr, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int entityNum, int contentMask );
qboolean (*HitEntity)(gentity_t* pEnt, gentity_t* pOther);
int ( *imageindex )( const char *name );
int ( *itemindex )( const char *name );
int ( *soundindex )( const char *name, int streamed );
@@ -325,6 +327,7 @@ typedef struct gameImport_s
void ( *Anim_Delta )( dtiki_t *tiki, int animNum, float *delta );
qboolean ( *Anim_HasDelta )( dtiki_t *tiki, int animNum );
void ( *Anim_DeltaOverTime )( dtiki_t *tiki, int animNum, float time1, float time2, float *delta );
void ( *Anim_AngularDeltaOverTime )( dtiki_t *tiki, int animNum, float time1, float time2, float *delta );
int ( *Anim_Flags )( dtiki_t *tiki, int animNum );
int ( *Anim_FlagsSkel )( dtiki_t *tiki, int animNum );
qboolean ( *Anim_HasCommands )( dtiki_t *tiki, int animNum );
+9 -9
View File
@@ -45,10 +45,10 @@ Called on game shutdown
*/
void G_WriteClientSessionData( gclient_t *client )
{
gi.Cvar_Set( va( "session%i", ( int )( client - game.clients ) ),
va( "%s %i %i", client->pers.weapon[ 0 ] ? client->pers.weapon : "-",
client->pers.team,
client->pers.kills ) );
gi.cvar_set( va( "session%i", ( int )( client - game.clients ) ),
va( "%s %i %i", client->pers.dm_primary[ 0 ] ? client->pers.dm_primary : "-",
client->pers.teamnum,
client->pers.round_kills) );
}
/*
@@ -68,10 +68,10 @@ void G_ReadSessionData( gclient_t *client )
session = gi.Cvar_Get(va("session%zi", client - game.clients), "", 0);
sscanf( session->string, "%s %i %i", client->pers.weapon, &client->pers.team, &client->pers.kills );
if( client->pers.weapon[ 0 ] == '-' )
sscanf( session->string, "%s %i %i", client->pers.dm_primary, &client->pers.teamnum, &client->pers.round_kills);
if( client->pers.dm_primary[ 0 ] == '-' )
{
client->pers.weapon[ 0 ] = 0;
client->pers.dm_primary[ 0 ] = 0;
}
}
@@ -83,7 +83,7 @@ G_InitSessionData
Called on a first-time connect
================
*/
void G_InitSessionData( gclient_t *client, char *userinfo )
void G_InitSessionData( gclient_t *client, const char *userinfo )
{
G_WriteClientSessionData( client );
}
@@ -119,7 +119,7 @@ G_WriteSessionData
void G_WriteSessionData( void ) {
int i;
gi.Cvar_Set( "session", va( "%i", g_gametype->integer ) );
gi.cvar_set( "session", va( "%i", g_gametype->integer ) );
for ( i = 0 ; i < game.maxclients ; i++ )
{
+6 -6
View File
@@ -564,7 +564,7 @@ Listener *SpawnArgs::SpawnInternal( void )
}
else
{
ev = new Event( keyname, EV_SETTER );
ev = new Event(eventnum);
ev->AddString( value );
obj->PostEvent( ev, EV_SPAWNARG );
@@ -1039,7 +1039,7 @@ qboolean G_CallSpawn( gentity_t *ent ) {
}
ent->s.frameInfo[0].weight = 1.f;
G_SetOrigin( ent, ent->s.origin );
gi.LinkEntity (ent);
gi.linkentity (ent);
return qtrue;
#endif
}
@@ -1332,13 +1332,13 @@ void SP_worldspawn( void ) {
gi.SetConfigstring( CS_MOTD, g_motd.string ); // message of the day
G_SpawnString( "gravity", "800", &s );
gi.Cvar_Set( "g_gravity", s );
gi.cvar_set( "g_gravity", s );
G_SpawnString( "enableDust", "0", &s );
gi.Cvar_Set( "g_enableDust", s );
gi.cvar_set( "g_enableDust", s );
G_SpawnString( "enableBreath", "0", &s );
gi.Cvar_Set( "g_enableBreath", s );
gi.cvar_set( "g_enableBreath", s );
for( i = 0; i < level.numSpawnVars; i++ )
{
@@ -1354,7 +1354,7 @@ void SP_worldspawn( void ) {
// see if we want a warmup time
gi.SetConfigstring( CS_WARMUP, "" );
if ( g_restarted.integer ) {
gi.Cvar_Set( "g_restarted", "0" );
gi.cvar_set( "g_restarted", "0" );
level.warmupTime = 0;
} else if ( g_doWarmup.integer ) { // Turn it on
level.warmupTime = -1;
+2040 -2530
View File
File diff suppressed because it is too large. Load diff
+325
View File
@@ -0,0 +1,325 @@
/*
===========================================================================
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#pragma once
#include "../qcommon/str.h"
class Archiver;
class Entity;
class SimpleEntity;
class SimpleArchivedEntity;
class ScriptThread;
void G_ArchiveEdict(Archiver& arc, gentity_t *edict);
void G_AllocDebugLines(void);
void G_DeAllocDebugLines(void);
void G_TouchTriggers(Entity *ent);
void G_TouchSolids(Entity *ent);
Entity *G_FindClass(Entity *ent, const char *classname);
Entity *G_NextEntity(Entity *ent);
void G_CalcBoundsOfMove(Vector& start, Vector& end, Vector& mins, Vector& maxs, Vector *minbounds, Vector *maxbounds);
void G_ShowTrace(trace_t *trace, const gentity_t *passent, const char *reason);
void G_ShowSightTrace(trace_t *trace, const gentity_t *passent, const char *reason);
bool G_SightTrace(
const Vector& start,
const Vector& mins,
const Vector& maxs,
const Vector& end,
Entity *passent,
Entity *passent2,
int contentmask,
qboolean cylindrical,
const char *reason
);
bool G_SightTrace(
const Vector& start,
const Vector& mins,
const Vector& maxs,
const Vector& end,
gentity_t *passent,
gentity_t *passent2,
int contentmask,
qboolean cylindrical,
const char *reason
);
void G_PMDrawTrace(
trace_t *results,
const vec3_t start,
const vec3_t mins,
const vec3_t maxs,
const vec3_t end,
int passEntityNum,
int contentMask,
qboolean cylinder,
qboolean traceDeep
);
trace_t G_Trace(
const Vector& start,
const Vector& mins,
const Vector& maxs,
const Vector& end,
const Entity *passent,
int contentmask,
qboolean cylindrical,
const char *reason,
qboolean tracedeep = qfalse
);
trace_t G_Trace(
vec3_t start,
vec3_t mins,
vec3_t maxs,
vec3_t end,
const gentity_t *passent,
int contentmask,
qboolean cylindrical,
const char *reason,
qboolean tracedeep = qfalse
);
void G_TraceEntities(
Vector & start,
Vector & mins,
Vector & maxs,
Vector & end,
Container<Entity *> *victimlist,
int contentmask,
qboolean bIncludeTriggers = qfalse
);
void SelectSpawnPoint(Vector& org, Vector& angles, str& thread);
Entity *G_FindTarget(Entity *ent, const char *name);
Entity *G_FindRandomTarget(const char *name);
SimpleEntity *G_FindRandomSimpleTarget(const char *name);
Entity *G_NextEntity(Entity *ent);
qboolean M_CheckBottom(Entity *ent);
Vector G_GetMovedir(float angle);
qboolean KillBox(Entity *ent);
qboolean IsNumeric(const char *str);
Entity *findradius(Entity *startent, Vector org, float rad);
Entity *findclientsinradius(Entity *startent, Vector org, float rad);
Vector G_CalculateImpulse(Vector start, Vector end, float speed, float gravity);
Vector G_PredictPosition(Vector start, Vector target, Vector targetvelocity, float speed);
qboolean G_LoadAndExecScript(const char *filename, const char *label = NULL, qboolean quiet = qfalse);
ScriptThread *ExecuteThread(str thread_name, qboolean start = true);
int MOD_string_to_int(const str &immune_string);
qboolean MOD_matches(int incoming_damage, int damage_type);
void G_MissionFailed(void);
void G_FadeOut(float delaytime);
void G_FadeSound(float delaytime);
void G_RestartLevelWithDelay(float delaytime);
void G_PlayerDied(float delaytime);
void G_AutoFadeIn(void);
void G_ClearFade(void);
void G_StartCinematic(void);
void G_StopCinematic(void);
// copy the entity exactly including all its children
void CloneEntity(Entity *dest, Entity *src);
qboolean OnSameTeam(Entity *ent1, Entity *ent2);
//
// caching commands
//
void CacheResource(const char *stuff);
int modelIndex(const char *mdl);
void G_SetTrajectory(gentity_t *ent, vec3_t org);
void G_SetConstantLight(
int *constantlight, float *red, float *green, float *blue, float *radius, int *lightstyle = NULL
);
void ChangeMusic(const char *current, const char *fallback, qboolean force);
void ChangeMusicVolume(float volume, float fade_time);
void RestoreMusicVolume(float fade_time);
void ChangeSoundtrack(const char *soundtrack);
void RestoreSoundtrack(void);
void G_BroadcastSound(Entity *ent, Vector origin, float radius = SOUND_RADIUS);
SimpleArchivedEntity *G_FindArchivedClass(SimpleArchivedEntity *ent, const char *classname);
Entity *G_FindClass(Entity *ent, const char *classname);
int G_GetClientNumber(gentity_t *ent);
int G_GetClientNumber(Entity *ent);
Entity *G_GetEntityByClient(int clientNum);
int G_GetEntityIndex(int number);
int G_GetEntityIndex(gentity_t *ent);
gentity_t *G_GetGEntity(int id);
//==================================================================
//
// Inline functions
//
//==================================================================
/*
=================
G_GetEntity
Takes an index to an entity and returns pointer to it.
=================
*/
inline Entity *G_GetEntity(int entnum)
{
if ((entnum < 0) || (entnum >= globals.max_entities)) {
gi.Error(ERR_DROP, "G_GetEntity: %d out of valid range.", entnum);
}
return (Entity *)g_entities[entnum].entity;
}
/*
=================
G_Random
Returns a number from 0<= num < 1
random()
=================
*/
inline float G_Random(void)
{
return ((float)(rand() & 0x7fff)) / ((float)0x8000);
}
/*
=================
G_Random
Returns a number from 0 <= num < n
random()
=================
*/
inline float G_Random(float n)
{
return G_Random() * n;
}
/*
=================
G_CRandom
Returns a number from -1 <= num < 1
crandom()
=================
*/
inline float G_CRandom(void)
{
return G_Random(2) - 1;
}
/*
=================
G_CRandom
Returns a number from -n <= num < n
crandom()
=================
*/
inline float G_CRandom(float n)
{
return G_CRandom() * n;
}
/*
=================
G_FixSlashes
Converts all backslashes in a string to forward slashes.
Used to make filenames consistant.
=================
*/
inline str G_FixSlashes(const char *filename)
{
int i;
size_t len;
str text;
if (filename) {
// Convert all forward slashes to back slashes
text = filename;
len = text.length();
for (i = 0; i < len; i++) {
if (text[i] == '\\') {
text[i] = '/';
}
}
}
return text;
}
typedef enum {
WEAPON_MAIN,
WEAPON_OFFHAND,
WEAPON_ERROR
} weaponhand_t;
#define NUM_ACTIVE_WEAPONS WEAPON_ERROR
typedef enum {
FIRE_PRIMARY,
FIRE_SECONDARY,
MAX_FIREMODES,
FIRE_ERROR
} firemode_t;
firemode_t WeaponModeNameToNum(str mode);
const char *WeaponHandNumToName(weaponhand_t hand);
weaponhand_t WeaponHandNameToNum(str side);
void G_DebugTargets(Entity *e, str from);
void G_DebugDamage(float damage, Entity *victim, Entity *attacker, Entity *inflictor);
+5 -5
View File
@@ -157,7 +157,7 @@ qboolean VM_SlideMove
VectorMA( vm->vs->origin, time_left, vm->vs->velocity, end );
// see if we can make it there
gi.Trace( &trace, vm->vs->origin, vm->mins, vm->maxs, end, vm->vs->entityNum, vm->tracemask, qtrue, qfalse );
gi.trace( &trace, vm->vs->origin, vm->mins, vm->maxs, end, vm->vs->entityNum, vm->tracemask, qtrue, qfalse );
if( trace.allsolid )
break;
@@ -351,7 +351,7 @@ void VM_GroundTrace
point[ 1 ] = vm->vs->origin[ 1 ];
point[ 2 ] = vm->vs->origin[ 2 ] - 0.25f;
gi.Trace( &vm->vs->groundTrace, vm->vs->origin, vm->mins, vm->maxs, point, vm->vs->entityNum, vm->tracemask, qtrue, qfalse );
gi.trace( &vm->vs->groundTrace, vm->vs->origin, vm->mins, vm->maxs, point, vm->vs->entityNum, vm->tracemask, qtrue, qfalse );
VM_GroundTraceInternal();
}
@@ -392,7 +392,7 @@ void VM_StepSlideMove
VectorCopy( start_o, down );
down[ 2 ] -= STEPSIZE;
gi.Trace( &trace, start_o, vm->mins, vm->maxs, down, vm->vs->entityNum, vm->tracemask, qtrue, qfalse );
gi.trace( &trace, start_o, vm->mins, vm->maxs, down, vm->vs->entityNum, vm->tracemask, qtrue, qfalse );
VectorSet( up, 0, 0, 1 );
// never step up when you still have up velocity
@@ -432,7 +432,7 @@ void VM_StepSlideMove
down[ 2 ] -= STEPSIZE * 2;
// test the player position if they were a stepheight higher
gi.Trace( &trace, up, vm->mins, vm->maxs, up, vm->vs->entityNum, vm->tracemask, qtrue, qfalse );
gi.trace( &trace, vm->vs->origin, vm->mins, vm->maxs, down, vm->vs->entityNum, vm->tracemask, qtrue, qfalse );
if( trace.entityNum > ENTITYNUM_NONE )
{
VectorCopy( nostep_o, vm->vs->origin );
@@ -624,7 +624,7 @@ void VmoveSingle
point[ 1 ] = vm->vs->origin[ 1 ];
point[ 2 ] = vm->vs->origin[ 2 ] - 18.0f;
gi.Trace( &trace, vm->vs->origin, vm->mins, vm->maxs, point, vm->vs->entityNum, vm->tracemask, qtrue, qfalse );
gi.trace( &trace, vm->vs->origin, vm->mins, vm->maxs, point, vm->vs->entityNum, vm->tracemask, qtrue, qfalse );
if( trace.fraction < 1.0f && !trace.allsolid )
{
Loaded 100 of 263 files, more files were not shown because too many files have changed in this diff. Show more