Compare commits

...
148 Commits
Author SHA1 Message Date
taylor 00828e8410 various FS2NetD fixes:
- increase sleep time during reconnect
 - better handling of disconnects from connection errors
 - proper disconnect in case of login failure
 - log stats request calls
 - don't try to read stats from packet when there aren't any to read
 - allow proper connection resetting with standalone
 - change auto-reconnect timeout from 30 minutes to 5
 - count server traffic among activity instead of just client traffic
 - reduce uneccessary client->server traffic
2010-08-03 08:30:46 +00:00
taylor 898760e237 fix debug message 2010-08-03 08:30:43 +00:00
chief1983 b76a1e779c Remove /DEBUG in 3.6.12 builds like r6335 and r6336 2010-07-30 19:57:53 +00:00
chief1983 59553db975 Backport of r6334: Patch for issue with ai-waypoints not working correctly. The ship's goals were accidentally cleared after a single run through the waypoint path. 2010-07-30 16:30:16 +00:00
chief1983 aad8c85e51 Backport of r6329: Fix/Workaround for Mantis 2272 (Int3() in hudtarget.cpp) 2010-07-30 16:28:43 +00:00
chief1983 3a2e0f2c4e Backport of r6325: Fix for reinforcement menu bug - Mantis 2246 2010-07-30 16:27:42 +00:00
chief1983 8fc0593dca Backport of r6322: Should allow INT_MAX to be visible on POSIX-compliant systems 2010-07-21 18:53:41 +00:00
chief1983 388fe6b029 Backport of r5930: Get rid of extra hardcoded version string. 2010-07-21 17:01:44 +00:00
chief1983 e6dc61fec8 Backport of r6316: Per IssMneur, fix the root directory detection on *nix systems. 2010-07-20 22:09:35 +00:00
chief1983 1ec9395914 Backport of r6315: Fix for the 'is-ai-class' sexp. Previously, the sexp would compare the given AI class against the ship class' tbl default AI class, which produced erroneous results. 2010-07-20 22:08:48 +00:00
chief1983 fca80c1a83 Backport of r6317: IssMneur's fix for Mantis #2240, allow gaps after the hardcoded retail sound entries. 2010-07-20 22:05:57 +00:00
chief1983 7985dc1bb5 Backport of r6313:
No wonder it didn't really work. I was looking in the wrong array.
2010-07-18 02:35:12 +00:00
chief1983 d7936867c7 Backport of r6301:
Bump to MAX_SHIP_FLAGS and a subtle reminder for posterity
2010-07-17 23:12:10 +00:00
chief1983 0034a4ccee Backport of r6300:
One more autopilot fix for 3.6.12, per IssMneur
2010-07-17 23:11:14 +00:00
chief1983 22d4de689b Backport of r6299:
Fix for Mantis 2263 (Objectives list is still displayed despite disable-hud-except-messages being active)
2010-07-17 23:10:20 +00:00
chief1983 80c2b908ce Backport of r6297:
Slight cockup on my part here. Pain flashes were not supposed to be gone for everyone.
2010-07-17 23:09:29 +00:00
chief1983 63514f47b6 Backport of r6296:
Updated the credits after god knows how long
2010-07-17 23:08:26 +00:00
chief1983 aad9dd77c1 Backport of r6292:
Fix an Assertion usage issue on *nix platforms.
2010-07-17 23:06:15 +00:00
chief1983 da0e3676c1 Backport of r6291:
IssMneur's autopilot fixes (hooray!)
2010-07-17 23:04:13 +00:00
chief1983 88ed177663 Backport of r6289:
Patch for Mantis 2205 (Division by zero in do_random_sidethrust())
2010-07-17 23:02:31 +00:00
chief1983 51c6b581cb Backport of r6279:
Introducing new SIF2 flag ("no pain flash") to turn off the pain flash. I guess all the peeps who want to do capship missions can rejoice now.
2010-07-17 22:58:07 +00:00
chief1983 d4084ce89d Backport of r6278:
Update Lua interpreter to 5.1.4 (patch 2) to fix the following bugs http://www.lua.org/bugs.html#5.1.4
2010-07-17 22:56:58 +00:00
chief1983 af56b471c1 Backport of r6265:
use 2_ animations in the tech room, just as in the command brief (Mantis #2231)
2010-07-17 22:53:44 +00:00
Goober5000 3cb841101c fix a bug noticed by The_E: object types are not bitfields 2010-07-05 05:43:18 +00:00
chief1983 f25a1448be Get rid of RC1 references. 2010-07-01 15:51:52 +00:00
chief1983 00a62e93a4 Backport of r6263: Add a Directives: option to hud_gauges.tbl -- works just like Escort Ships 2010-06-28 18:20:11 +00:00
chief1983 b8fca97f43 Backport of r6262: fix for potential null vec issue when using limited base rotation turrets 2010-06-28 18:19:41 +00:00
chief1983 e7a7d75ccc Backport of r6261: fix for salvo + check hull bug found by fubar 2010-06-28 18:19:08 +00:00
chief1983 14f81c7b63 Backport of r6260: Removed unpopular circle strafe changes to make circle-strafing AI more aggressive (like in RC2) 2010-06-28 18:18:21 +00:00
chief1983 7dfc67e9be Backport of r6259: this is just a bit cleaner 2010-06-28 18:17:42 +00:00
chief1983 6ac52660b6 Backport of r6257: fix for Mantis #2056 (sexps may not want to process every ship)
also, account for the fact that Command may not be "#Command"
2010-06-28 18:16:46 +00:00
Goober5000 bf9766e1ef backport of commit 6267:
make FRED be intelligent about mission directory (Mantis #2236)
2010-06-27 08:35:24 +00:00
chief1983 ac9ad20924 Backport of r6070: fix parsing of miss factors (Mantis #2185) 2010-06-22 21:16:37 +00:00
chief1983 eb663c01d3 Backport of r6067: add beam miss factor by team, requested by Blue Planet 2010-06-22 20:47:11 +00:00
chief1983 7ced087af7 Backport of r6250:
Fix for null vec3d error mentioned in Mantis 1888 by Woolie Wool
2010-06-22 03:46:59 +00:00
chief1983 54f37f82ae Backport of r6248:
allow lua to track if ship is 'dying' during the frame (bugfix for flashy deaths script)
2010-06-22 03:46:21 +00:00
chief1983 4963b751b0 Backport of r6246:
fix for the ai profile issue (mantis 2228)
2010-06-22 03:45:47 +00:00
chief1983 a4fe0df027 Backport of r6244: Fix the Assertion to not break Macs and Linux. 2010-06-21 17:13:20 +00:00
chief1983 ec5c83a56e Backport of r6242: IssMneur's fix for #1888 (finally): Much better autopilot behavior. 2010-06-21 15:05:34 +00:00
chief1983 ce731986ae Backport of r6232:
Fix lua ray collision checks against debris pieces
2010-06-20 19:45:57 +00:00
chief1983 c061d53614 Backport of r6231:
add a null vec check - hit by fubar
2010-06-20 19:45:31 +00:00
chief1983 485d173906 Backport of r6198:
better handling of 'dying' weapons for lua scripting.cpp
added lua controls for accessing beams
2010-06-20 19:44:50 +00:00
chief1983 4b2da1591e Backport of r6223:
Stopgap fix for Mantis 2224 (Black text is unreadable in the multiplayer chat). Turned black into pink (as that colour wasn't used before).
2010-06-19 17:00:45 +00:00
chief1983 eed55a1925 Backport of r6222:
Remove the -tbp command line.
2010-06-19 17:00:13 +00:00
chief1983 a91b666702 Backport of r6221:
Commit of PNG Data fix as suggested and supplied by Armchair Commander and marvn.
(Read: http://www.hard-light.net/forums/index.php?topic=68405.0)
2010-06-19 16:59:18 +00:00
chief1983 9262e8bb0b Backport of r6214:
Fix for Mantis 2212 (Interface animations start at frame 1, not 0)
2010-06-19 16:58:45 +00:00
chief1983 787f58abfd Backport of r6213:
Fix for Mantis 2210 (Ship models in ship selection do not always show up properly)
2010-06-19 16:55:20 +00:00
chief1983 f66a232b8c Backport of r6196:
fix for target priorities and sif2 flags issue
2010-06-19 16:47:51 +00:00
chief1983 f7057f970f Backport of r6186:
mantis 1988 - error checking for the targeting priorities
2010-06-19 16:47:21 +00:00
Goober5000 e0af8bf08e backport of my commit 6180:
FUBAR's feature for LOD naming: http://www.hard-light.net/forums/index.php?topic=68901.0
2010-06-14 07:25:49 +00:00
Goober5000 8250a303ec backport of The E's commit 6207:
Don't increase the total number of loaded menu music files if a tbm with +nocreate is loaded.

This also neatly fixes the somewhat screwed up music selection list in FRED (remember all those empty lines?), albeit not completely.
2010-06-14 07:19:13 +00:00
Goober5000 cdb14a005b merge Sushi's revision 6099, plus some sync'ing with trunk 2010-06-12 21:24:30 +00:00
chief1983 040252c2ea No one will be maintaining this for 3.6.12 2010-06-08 04:36:38 +00:00
chief1983 34bc9b17d8 Backport of 6123: Fixed a parsing bug in AI.tbl that scaled Glide Attack Percent, Glide Strafe Percent, Circle Strafe Percent, and Random Sidethrust percent between 0 and 1 instead of 0 and 100 (as is the case for AI profiles.tbl) 2010-06-07 16:30:51 +00:00
chief1983 653a201993 Backport of 6122: Fix a bug where additive weapon velocity would sometimes cause primary shots to pass through a target 2010-06-07 16:28:02 +00:00
chief1983 8affc3c984 Backport of 6098: Small fix for circle strafe 2010-06-07 16:26:39 +00:00
chief1983 16a1013a0b Backport of 6083: Reverted commit 5656, due to side effect of changing AI behavior (see mantis 1982) 2010-06-07 16:21:34 +00:00
Goober5000 0c9739a2ef ignore a generated file 2010-06-07 07:01:19 +00:00
Goober5000 4cedbe3c66 backport of The E's commit 6153:
Fix for Mantis 2214 (toparc2 and toparc3 hud anis [The Enemy Missile threat and Enemy Missile lock indicators] may have a length > 2 now, instead of being fixed at 3 frames)
2010-06-07 07:00:36 +00:00
Goober5000 4fa32baf8b sync fictionviewer again 2010-06-07 06:36:19 +00:00
Goober5000 8fa09e962a sync fiction viewer with trunk 2010-06-07 02:16:28 +00:00
taylor bfd88b192e backport The_E's commit 6176:
A missing ) is bad for parsing.
2010-06-06 18:49:53 +00:00
taylor f4053eb18b make sure to stop deathroll effect too (Mantis #2215) 2010-06-06 14:50:17 +00:00
taylor 8374a8be75 add some missing safety checks for Snds[] (Mantis #2216) 2010-06-06 14:50:16 +00:00
Goober5000 8a79889583 backport of Sushi's commit 6092:
Some fixes/updates for the Circle Strafe behavior. The AI should use it a bit more effectively now.
2010-06-04 06:12:02 +00:00
Goober5000 6316b4639f backport of Sushi's commit 6118:
Added $Random Sidethrust Percent to AI Profiles and AI.tbl. Allows ships with sidethrust capability to sometimes randomly use it in dogfighting situations to make life more miserable for the player.
2010-06-04 06:06:20 +00:00
Goober5000 8bf974973e minor fix to the -wcs flag removal 2010-06-03 06:28:51 +00:00
Goober5000 749548cacb backport of karajorma's commit 6154:
Kill the -wcs flag. Should have done this years ago.
2010-06-03 06:26:37 +00:00
Goober5000 db0c0a6e6b backport of Wanderer's commit 6134:
add read access for lua to weapon and ship info index. enable to check 'weapon_armed' status
2010-06-03 06:22:03 +00:00
Goober5000 4300a67da3 backport of Wanderer's commit 6150:
Certain fixes for Bobs animation code issues. Please report if this renders any current anims invalid.
2010-06-03 05:58:26 +00:00
Goober5000 75410b1465 backport of karajorma's commit 6133:
Swap the engage enemies messages over.
2010-06-03 05:55:23 +00:00
Goober5000 eaf516756f add latest MSVC 2010 files 2010-06-03 05:54:00 +00:00
Goober5000 fc88ab03a5 backport of Sushi's commit 6057:
Added $Turret Max Aim Update Delay (same as $Max Aim Update Delay, but affecting turrets instead).
2010-06-03 05:50:27 +00:00
Goober5000 8da643a5db backport of Sushi's commit 6074:
Fix for 6057 (game sometimes crashes if $Turret Max Aim Update Delay not set)
2010-06-03 05:47:53 +00:00
Goober5000 ea3e865836 backport of Sushi's revision 6075:
Fix for Dynamic Glide Cap so that the cap ramps max speed in the same way as normal flight when turning afterburners on/off or changing the overclock (what it should have done in the first place). Also removed some old, unused glide code.
2010-06-03 05:46:13 +00:00
taylor d24e2985d2 more sane memory reserve 2010-05-29 15:52:38 +00:00
taylor eb4e65fc6e fix endless loop 2010-05-29 15:52:34 +00:00
taylor 1185261974 fix view skew math issue (Mantis #2213) 2010-05-29 14:55:31 +00:00
taylor 336fd14f8b bah! remove debug code that slipped in with safety fixes 2010-05-29 10:55:12 +00:00
taylor 042b4ce0db support for newer versions of automake (Mantis #2145) 2010-05-29 10:55:11 +00:00
Goober5000 0c513e053a remove message from queue the correct way, thus fixing the training message crash 2010-05-19 04:29:09 +00:00
Goober5000 c32b39a247 backport of my commit 6102:
better handling of missing models
2010-05-16 00:35:34 +00:00
Goober5000 e610de3516 backport of my commits 6100-6101:
fix subsystem alignment on ship class change (Mantis #1181)
fix a bug with Bobboau's external missiles feature
2010-05-16 00:34:58 +00:00
Goober5000 ef63b44a16 backport of Sushi's commit 6097:
Fix for Mantis 2099
2010-05-16 00:24:22 +00:00
Goober5000 e17526eb89 backport of karajorma's commit 6090 and chief1983's commit 6091:
Fix compilation under OSX and Linux with WarningEx
2010-05-16 00:22:58 +00:00
Goober5000 f0544cb485 backport of The_E's commit 6089:
Genghis' fix for Mantis 2162 (Thruster cones have collision detection)
2010-05-16 00:21:50 +00:00
Goober5000 b1741d2b49 backport of karajorma's commit 6087:
Genghis' fix for Mantis 2159 (Certain parsing errors are never reported)
2010-05-16 00:21:10 +00:00
Goober5000 8a1cac238f backport of karajorma's commit 6086:
Genghis' fix for Mantis 2157 (Invalid subsystems not properly detected on mission parse).
2010-05-16 00:20:33 +00:00
Goober5000 c5e346b72b backport of karajorma's commit 6085:
GencGenghis' fix for Mantis 2155 (No error checking for certain ship problems in the lab that FRED does pick up).
2010-05-16 00:20:05 +00:00
Goober5000 da999df482 backport of karajorma's commit 6084:
Genghis' fix for Mantis 2151 (No error checking for incorrect engine wash entries).
2010-05-16 00:19:41 +00:00
Goober5000 80fddda455 backport of The_E's commit 6073:
Fix for Mantis 2189 (camera FOV may get corrupted by malformed commandline argument)
2010-05-16 00:14:56 +00:00
Goober5000 d14d3b3b6c backport of my commit 6071:
make sure Fred knows its base directory before loading the command line... this will allow it to load cmdline_fso.cfg which will allow Fred to recognize mods (Mantis #2185)
2010-05-16 00:13:05 +00:00
Goober5000 cabf5068e2 backport of The_E's commits 6095-6096:
Patch for Mantis 2202 (Children of swarm weapons do not inherit parent target)
Swarm weapons should respect "$Free flight time" as well
2010-05-16 00:12:03 +00:00
Goober5000 a90b70d7f9 backport Sushi's commitbackport of Sushi's commit 6077:
Fix for bug causing AI to not fire secondaries, as well as a fix for other minor AI bugs
2010-05-16 00:10:12 +00:00
Goober5000 578aced1a5 prevent HUD formatting from destroying subsystem names - Mantis #2195
also made hud_targetbox_truncate_subsys_name return void to lessen the chance of people making the mistake in the future
2010-04-30 06:35:33 +00:00
Goober5000 876743b40e fix Mantis #2194 2010-04-30 04:06:05 +00:00
chief1983 7a796e13a4 Backport of r6068:
No 2-arg asserts on Linux.
2010-04-19 23:38:16 +00:00
Goober5000 ba52d6bbc0 backport of karajorma's commit 6053:
Iss Mneur's mission-set-subspace and hud-display-gauge SEXPs
2010-04-19 03:54:44 +00:00
Goober5000 1880beca07 merge Iss_Mneur's fix for Mantis #2173 (better error message in cmdline.cpp) 2010-04-19 03:51:12 +00:00
Goober5000 0ceb9dc04b merge Iss_Mneur's fix for Mantis #2178 (Assertion in missiontraining.cpp) 2010-04-19 03:49:17 +00:00
Goober5000 dc8e8c1270 merge The E's fix for Mantis #2182 (NaN propagation leading to rendering wonkiness) 2010-04-19 03:40:21 +00:00
Goober5000 2007614ace backport of Sushi's commit 6049:
Fixes a bug where paths generated by exit paths aren't garbage collected. This can cause the game to crash in missions where a lot of ships launch from fighterbays.
2010-04-19 03:34:16 +00:00
Goober5000 cf05b699a3 backport of karajorma's commit 6001:
Refactoring the Special Explosion and Special Hitpoints/Shield code and saving methods.
2010-04-19 03:24:36 +00:00
Goober5000 8f3144c5c4 fix Mantis #1953 (departure locations and anchors destroyed by ship editor dialog) 2010-04-13 06:53:03 +00:00
Goober5000 928858d48e prevent an endless loop if someone tries to assign a variable to itself
also, sync some formatting from trunk
2010-03-31 20:31:33 +00:00
Goober5000 9b03393fa8 The E's patch to apply capital+ to secondary weapons 2010-03-31 05:31:20 +00:00
Goober5000 b9f7c4501b backport of karajorma's commit 6028:
Fix Mantis 2000 (Skip Mission Dialog appears even when mission is successfully completed).
2010-03-31 05:28:58 +00:00
Goober5000 2c6adfd3ef backport of Echelon9's commit 6026:
Fix Mantis 2158: Increase Intelligence limit from species.tbl
2010-03-31 05:28:17 +00:00
Goober5000 dac5af56e0 backport of Echelon9's commit 6023:
Fix Mantis 2156: Crash within outwnd_printf2(char*, ...) on non-Windows platforms
2010-03-31 05:27:45 +00:00
Goober5000 9fa0cbe8c5 backport of karajorma's commit 6004:
Fix Mantis 2140 (Set-primary-ammo/weapon result in the ammo being set to 0 in some mods)
2010-03-31 05:26:45 +00:00
Goober5000 c0e3b6699c backport of Wanderer's commit 6000:
mantis 2122, fix for hud_gauge string comparison problems.
2010-03-31 05:24:31 +00:00
Goober5000 631fbc5094 backport of Wanderer's commit 5999:
mantis 2138, fix game crashing if using ships with secondaries but without primaries, allow ai ships armed only with secondaries to attack & shoot
2010-03-31 05:23:43 +00:00
Goober5000 fb02c34646 backport of Wanderer's commit 5998:
mantis 2113, make autoaim independent from lead indicator status
2010-03-31 05:23:13 +00:00
Goober5000 e136784952 backport of Wanderer's commit 5997:
feature commit - alternate lead indicator based on komet's code changes.
2010-03-31 05:22:38 +00:00
Goober5000 a6986b7598 backport of Wanderer's commit 5994:
Fix for mantis 2131:
prevent for time compression caused vector scaling errors
changed time compression related beam assert into nprintf.
2010-03-31 05:21:18 +00:00
Goober5000 5d32313599 backport of Wanderer's commit 5993:
Fubars fix for mantis 2141
2010-03-31 05:20:32 +00:00
Goober5000 12fdf1e4fa backport of Wanderer's commit 5991:
fix for mantis 2105
2010-03-31 05:18:33 +00:00
Goober5000 6c82fcce32 backport of Wanderer's commit 5990:
fix to attach muzzleflashes on ship to weapon firing points - mantis 2135.
also related fixes - fix attached particle rendering, allow all particles to exists at least 1 frame
2010-03-31 05:17:53 +00:00
Goober5000 28c573d47b patch some holes in the handling of string variables 2010-03-29 09:39:34 +00:00
Goober5000 845d8472c4 a couple of small but important fixes to the subtitle code, including (finally) the complete fix for Mantis #2152 2010-03-20 06:37:11 +00:00
Goober5000 09cca0f12b handle variables in show-subtitle 2010-03-19 07:39:55 +00:00
Goober5000 93ff4c441b Genghis's fix for too many cargo names (Mantis 2132) 2010-03-19 06:45:02 +00:00
Goober5000 6753656848 sexp help now scrolls 2010-03-19 05:48:02 +00:00
Goober5000 29eb3a8866 whitespace happiness 2010-03-19 04:04:20 +00:00
Goober5000 7b0bcfc8ae a few things here...
--add space for font argument which will be in post-3.6.12 builds
--fix round-off error in coordinate conversion, discovered by genghis
--use is_sexp_true() instead of WMC's comparison
--fix images not appearing in show-subtitle (Mantis #2152)
--fix invalid character in change-soundtrack sexp help
2010-03-19 04:01:58 +00:00
Goober5000 eb47335e1e approximate the beam whack from retail FS2 2010-03-16 06:43:01 +00:00
Goober5000 05b3645062 this is a long-overdue rewrite of WMC's show-subtitle sexps 2010-03-15 01:55:56 +00:00
Goober5000 f325afcd54 cross-patch a bug-fix 2010-03-15 01:49:20 +00:00
Goober5000 8551b19697 move the -post_process flag to the experimental section 2010-03-14 22:38:45 +00:00
taylor 1b930557cd no comment. (nothing nice to say) 2010-03-10 10:04:09 +00:00
Goober5000 586f419413 merge fiction viewer changes to 3.6.12 2010-03-06 11:43:10 +00:00
taylor f985b10eb7 properly close out mission when end-mission sexp is used (Mantis #2144) 2010-03-04 06:08:19 +00:00
taylor 5fb12eebf4 clean up launcher flags
- update easy flag settings (Mantis #2074)
 - remove -res, it requires an option
2010-03-04 06:08:16 +00:00
taylor c0ed3c79e3 handle cmdline_fso.cfg files of any size 2010-03-04 06:08:03 +00:00
taylor dc12a13ff8 updated Ogg/Vorbis/Theora libs 2010-03-04 06:07:56 +00:00
taylor b2c6a52ae4 cycle back to normal music is hostile ships leave without battle (Mantis #1632) 2010-03-04 06:07:23 +00:00
taylor fc41b260af reduce minimum sound volume value for OpenAL compatibility (Mantis #1854) 2010-03-04 06:07:21 +00:00
taylor 5c7bd6494e fix memory issues with arg parsing 2010-03-04 06:07:15 +00:00
chief1983 e8aad6f979 Backport r5969 - fix for two full packets in a frame - to 3.6.12 2010-03-03 23:40:40 +00:00
chief1983 af01576b82 Backport r5968 - upsidedown FBO rendering - to 3.6.12 2010-03-03 23:39:38 +00:00
chief1983 3c606b90ab Backport r5959 - Mantis 2137 play-sound-from-file not looping - to 3.6.12 2010-03-03 23:38:04 +00:00
chief1983 b2adf4c326 Backport r5945 - FRED dialog fix - to 3.6.12 2010-02-25 16:19:13 +00:00
chief1983 c666741e93 Backport r5931 - Mantis 2133 Monitoring text - to 3.6.12 2010-02-25 16:09:06 +00:00
chief1983 8b67b33a08 Backport r5935 - afterburner assert - to 3.6.12 2010-02-25 16:06:18 +00:00
Goober5000 d585439096 upgrade the branched VC6 and VC2005 project files to match the trunk ones 2010-02-19 06:51:27 +00:00
Goober5000 f3f6548293 delete the obsolete branched project folders 2010-02-19 06:50:16 +00:00
chief1983 7231b32c99 Update versioning and filenames for RC1 2010-02-18 01:41:26 +00:00
Goober5000 38aac6bd3a branch for 3.6.12 2010-02-17 09:08:34 +00:00
170 changed files with 17369 additions and 16552 deletions

No files matched your search

+2 -2
View File
@@ -49,7 +49,7 @@ DIE=0
DIE=1
}
for AM in automake-1.9 automake-1.8 automake-1.7 automake-1.6 automake; do
for AM in automake-1.11 automake-1.10 automake-1.9 automake-1.8 automake-1.7 automake-1.6 automake; do
(check_version "$AM" 1 6 1) && {
AUTOMAKE="$AM"
break
@@ -67,7 +67,7 @@ fi
# if no automake, don't bother testing for aclocal
test -z "$AUTOMAKE" || {
for ACL in aclocal-1.9 aclocal-1.8 aclocal-1.7 aclocal-1.6 aclocal; do
for ACL in aclocal-1.11 aclocal-1.10 aclocal-1.9 aclocal-1.8 aclocal-1.7 aclocal-1.6 aclocal; do
(check_version "$ACL" 1 6 1) && {
ACLOCAL="$ACL"
break
+8
View File
@@ -205,12 +205,16 @@ typedef struct ai_class {
float ai_glide_attack_percent[NUM_SKILL_LEVELS];
float ai_circle_strafe_percent[NUM_SKILL_LEVELS];
float ai_glide_strafe_percent[NUM_SKILL_LEVELS];
float ai_random_sidethrust_percent[NUM_SKILL_LEVELS];
float ai_stalemate_time_thresh[NUM_SKILL_LEVELS];
float ai_stalemate_dist_thresh[NUM_SKILL_LEVELS];
int ai_chance_to_use_missiles_on_plr[NUM_SKILL_LEVELS];
float ai_max_aim_update_delay[NUM_SKILL_LEVELS];
float ai_turret_max_aim_update_delay[NUM_SKILL_LEVELS];
int ai_profile_flags; //Holds the state of flags that are set
int ai_profile_flags_set; //Holds which flags are set and which are just left alone
int ai_profile_flags2;
int ai_profile_flags2_set;
//SUSHI: These are optional overrides to an AI class to prevent the automatic scaling based on AI class index
int ai_aburn_use_factor[NUM_SKILL_LEVELS];
@@ -435,11 +439,14 @@ typedef struct ai_info {
float ai_glide_attack_percent;
float ai_circle_strafe_percent;
float ai_glide_strafe_percent;
float ai_random_sidethrust_percent;
float ai_stalemate_time_thresh;
float ai_stalemate_dist_thresh;
int ai_chance_to_use_missiles_on_plr;
float ai_max_aim_update_delay;
float ai_turret_max_aim_update_delay;
int ai_profile_flags; //Holds AI_Profiles flags (possibly overriden by AI class) that actually apply to AI
int ai_profile_flags2;
union {
@@ -632,6 +639,7 @@ extern ship_subsys *set_targeted_subsys(ai_info *aip, ship_subsys *new_subsys, i
extern void ai_rearm_repair( object *objp, int docker_index, object *goal_objp, int dockee_index );
extern void ai_add_rearm_goal( object *requester_objp, object *support_objp );
extern void create_model_path(object *pl_objp, object *mobjp, int path_num, int subsys_path=0);
extern int ai_find_goal_index( ai_goal* aigp, int mode, int submode = -1, int priority = -1 );
// Goober5000
extern void ai_do_safety(object *objp);
+21 -1
View File
@@ -49,7 +49,6 @@ void set_flag(ai_profile_t *profile, char *name, int flag, int type)
void parse_ai_profiles_tbl(char *filename)
{
int i, rval;
bool no_create = false;
char profile_name[NAME_LENGTH];
ai_profile_t dummy_profile;
char *saved_Mp = NULL;
@@ -84,6 +83,7 @@ void parse_ai_profiles_tbl(char *filename)
{
ai_profile_t *profile = &dummy_profile;
ai_profile_t *previous_profile = NULL;
bool no_create = false;
// get the name
required_string("$Profile Name:");
@@ -273,6 +273,19 @@ void parse_ai_profiles_tbl(char *filename)
}
}
if (optional_string("$Random Sidethrust Percent:")) {
parse_float_list(profile->random_sidethrust_percent, NUM_SKILL_LEVELS);
//Percent is nice for modders, but here in the code we want it betwwen 0 and 1.0
//While we're at it, verify the range
for (int i = 0; i < NUM_SKILL_LEVELS; i++) {
if (profile->random_sidethrust_percent[i] < 0.0f || profile->random_sidethrust_percent[i] > 100.0f) {
profile->random_sidethrust_percent[i] = 0.0f;
Warning(LOCATION, "$Random Sidethrust Percent should be between 0 and 100.0 (read %f). Setting to 0.", profile->random_sidethrust_percent[i]);
}
profile->random_sidethrust_percent[i] /= 100.0;
}
}
if (optional_string("$Stalemate Time Threshold:"))
parse_float_list(profile->stalemate_time_thresh, NUM_SKILL_LEVELS);
@@ -309,6 +322,9 @@ void parse_ai_profiles_tbl(char *filename)
if (optional_string("$Max Aim Update Delay:"))
parse_float_list(profile->max_aim_update_delay, NUM_SKILL_LEVELS);
if (optional_string("$Turret Max Aim Update Delay:"))
parse_float_list(profile->turret_max_aim_update_delay, NUM_SKILL_LEVELS);
set_flag(profile, "$big ships can attack beam turrets on untargeted ships:", AIPF_BIG_SHIPS_CAN_ATTACK_BEAM_TURRETS_ON_UNTARGETED_SHIPS, AIP_FLAG);
set_flag(profile, "$smart primary weapon selection:", AIPF_SMART_PRIMARY_WEAPON_SELECTION, AIP_FLAG);
@@ -375,6 +391,10 @@ void parse_ai_profiles_tbl(char *filename)
set_flag(profile, "$turrets ignore targets radius in range checks:", AIPF2_TURRETS_IGNORE_TARGET_RADIUS, AIP_FLAG2);
set_flag(profile, "$no extra collision avoidance vs player:", AIPF2_NO_SPECIAL_PLAYER_AVOID, AIP_FLAG2);
set_flag(profile, "$perform less checks for death screams:", AIPF2_PERFORM_LESS_SCREAM_CHECKS, AIP_FLAG2);
// if we've been through once already and are at the same place, force a move
if ( saved_Mp && (saved_Mp == Mp) )
Mp++;
+5
View File
@@ -53,6 +53,8 @@
// flags2
#define AIPF2_TURRETS_IGNORE_TARGET_RADIUS (1 << 0)
#define AIPF2_NO_SPECIAL_PLAYER_AVOID (1 << 1)
#define AIPF2_PERFORM_LESS_SCREAM_CHECKS (1 << 2)
#define MAX_AI_PROFILES 5
@@ -94,9 +96,11 @@ typedef struct ai_profile_t {
float glide_attack_percent[NUM_SKILL_LEVELS]; // SUSHI: The likelihood (0.0-1.0) of the AI to use the "glide attack" move
float circle_strafe_percent[NUM_SKILL_LEVELS]; // SUSHI: The likelihood (0.0-1.0) of the AI to use the "circle strafe" move
float glide_strafe_percent[NUM_SKILL_LEVELS]; // SUSHI: The likelihood (0.0-1.0) of the AI to use glide when strafing capships
float random_sidethrust_percent[NUM_SKILL_LEVELS]; // SUSHI: The likelihood (0.0-1.0) of the AI to randomly use sidethrust while dogfihthing
float stalemate_time_thresh[NUM_SKILL_LEVELS]; // SUSHI: The amount of time required for the AI to detect (and try to break) dogfight stalemate
float stalemate_dist_thresh[NUM_SKILL_LEVELS]; // SUSHI: The maximum distance the AI and target must be within for a stalemate
float max_aim_update_delay[NUM_SKILL_LEVELS]; // SUSHI: The maximum delay before the AI updates their aim against small ships
float turret_max_aim_update_delay[NUM_SKILL_LEVELS]; // SUSHI: As above, but for turrets updating their aim
// Multiplicative delay factors for increasing skill levels.
float ship_fire_delay_scale_hostile[NUM_SKILL_LEVELS];
@@ -125,6 +129,7 @@ typedef struct ai_profile_t {
// the chance (x/7) that ship is allowed to fire missiles at player ship.
int chance_to_use_missiles_on_plr[NUM_SKILL_LEVELS];
} ai_profile_t;
+21 -7
View File
@@ -704,6 +704,9 @@ void ai_big_maybe_fire_weapons(float dist_to_enemy, float dot_to_enemy, vec3d *f
// ship_stop_fire_primary(Pl_objp);
}
}
}
if (tswp->num_secondary_banks > 0) {
int priority1, priority2;
@@ -787,7 +790,10 @@ void ai_big_maybe_fire_weapons(float dist_to_enemy, float dot_to_enemy, vec3d *f
}
}
} else {
aip->time_enemy_in_range *= (1.0f - flFrametime);
if (flFrametime < 1.0f)
aip->time_enemy_in_range *= (1.0f - flFrametime);
else
aip->time_enemy_in_range = 0;
}
if(has_fired == -1){ //stuff that hapens when the ship stops fireing
@@ -1094,8 +1100,12 @@ void ai_big_chase()
// a big ship
if (aip->mode != AIM_EVADE && aip->path_start == -1 ) {
ai_big_maybe_fire_weapons(dist_to_enemy, dot_to_enemy, &player_pos, &predicted_enemy_pos, &En_objp->phys_info.vel);
} else
aip->time_enemy_in_range *= (1.0f - flFrametime);
} else {
if (flFrametime < 1.0f)
aip->time_enemy_in_range *= (1.0f - flFrametime);
else
aip->time_enemy_in_range = 0;
}
}
void ai_big_ship(object *objp)
@@ -1151,9 +1161,13 @@ void ai_big_attack_get_data(vec3d *enemy_pos, float *dist_to_enemy, float *dot_t
float weapon_speed;
// Compute position of gun in absolute space and use that as fire position.
pnt = po->gun_banks[0].pnt[0];
vm_vec_unrotate(&gun_pos, &pnt, &Pl_objp->orient);
vm_vec_add2(&gun_pos, &Pl_objp->pos);
if (po->n_guns > 0) {
pnt = po->gun_banks[0].pnt[0];
vm_vec_unrotate(&gun_pos, &pnt, &Pl_objp->orient);
vm_vec_add2(&gun_pos, &Pl_objp->pos);
} else {
gun_pos = Pl_objp->pos;
}
weapon_speed = ai_get_weapon_speed(&shipp->weapons);
set_predicted_enemy_pos_turret(&predicted_enemy_pos, &gun_pos, Pl_objp, enemy_pos, &En_objp->phys_info.vel, weapon_speed, aip->time_enemy_in_range);
@@ -1417,7 +1431,7 @@ void ai_big_strafe_glide_attack()
if (aip->submode_parm1 == 1) {
accelerate_ship(aip, 1.0f);
//Use afterburners if we have them and are pointed the right way
if (dot_to_goal > 0.99f && ai_maybe_fire_afterburner(Pl_objp, aip)) {
if (dot_to_goal > 0.99f) {
afterburners_start(Pl_objp);
aip->afterburner_stop_time = Missiontime + 3*F1_0;
}
+381 -397
View File
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -990,7 +990,7 @@ void ai_add_goal_sub_sexp( int sexp, int type, ai_goal *aigp, char *actor_name )
* Pass -1 in priority to ignore priority when searching
* Returns -1 if not found, or [0, MAX_AI_GOALS)
*/
int ai_find_goal_index( ai_goal* aigp, int mode, int submode = -1, int priority = -1 )
int ai_find_goal_index( ai_goal* aigp, int mode, int submode, int priority )
{
Assert( aigp != NULL );
for ( int i = 0; i < MAX_AI_GOALS; i++ )
+24 -24
View File
@@ -26,35 +26,35 @@ struct ai_goal;
// Fred. If the goal you add doesn't have a target (such as chase_any), then you don't have
// to worry about doing this. Also add it to list in Fred\Management.cpp, and let Hoffoss know!
// WMC - Oh and add them to Ai_goal_names plz. TY! :)
#define AI_GOAL_CHASE (1<<1)
#define AI_GOAL_DOCK (1<<2) // used for undocking as well
#define AI_GOAL_WAYPOINTS (1<<3)
#define AI_GOAL_WAYPOINTS_ONCE (1<<4)
#define AI_GOAL_WARP (1<<5)
#define AI_GOAL_DESTROY_SUBSYSTEM (1<<6)
#define AI_GOAL_FORM_ON_WING (1<<7)
#define AI_GOAL_UNDOCK (1<<8)
#define AI_GOAL_CHASE_WING (1<<9)
#define AI_GOAL_GUARD (1<<10)
#define AI_GOAL_DISABLE_SHIP (1<<11)
#define AI_GOAL_DISARM_SHIP (1<<12)
#define AI_GOAL_CHASE_ANY (1<<13)
#define AI_GOAL_IGNORE (1<<14)
#define AI_GOAL_GUARD_WING (1<<15)
#define AI_GOAL_EVADE_SHIP (1<<16)
#define AI_GOAL_CHASE (1<<1) // 0x00000002
#define AI_GOAL_DOCK (1<<2) // 0x00000004 // used for undocking as well
#define AI_GOAL_WAYPOINTS (1<<3) // 0x00000008
#define AI_GOAL_WAYPOINTS_ONCE (1<<4) // 0x00000010
#define AI_GOAL_WARP (1<<5) // 0x00000020
#define AI_GOAL_DESTROY_SUBSYSTEM (1<<6) // 0x00000040
#define AI_GOAL_FORM_ON_WING (1<<7) // 0x00000080
#define AI_GOAL_UNDOCK (1<<8) // 0x00000100
#define AI_GOAL_CHASE_WING (1<<9) // 0x00000200
#define AI_GOAL_GUARD (1<<10) // 0x00000400
#define AI_GOAL_DISABLE_SHIP (1<<11) // 0x00000800
#define AI_GOAL_DISARM_SHIP (1<<12) // 0x00001000
#define AI_GOAL_CHASE_ANY (1<<13) // 0x00002000
#define AI_GOAL_IGNORE (1<<14) // 0x00004000
#define AI_GOAL_GUARD_WING (1<<15) // 0x00008000
#define AI_GOAL_EVADE_SHIP (1<<16) // 0x00010000
// the next goals are for support ships only
#define AI_GOAL_STAY_NEAR_SHIP (1<<17)
#define AI_GOAL_KEEP_SAFE_DISTANCE (1<<18)
#define AI_GOAL_REARM_REPAIR (1<<19)
#define AI_GOAL_STAY_NEAR_SHIP (1<<17) // 0x00020000
#define AI_GOAL_KEEP_SAFE_DISTANCE (1<<18) // 0x00040000
#define AI_GOAL_REARM_REPAIR (1<<19) // 0x00080000
// resume regular goals
#define AI_GOAL_STAY_STILL (1<<20)
#define AI_GOAL_PLAY_DEAD (1<<21)
#define AI_GOAL_CHASE_WEAPON (1<<22)
#define AI_GOAL_STAY_STILL (1<<20) // 0x00100000
#define AI_GOAL_PLAY_DEAD (1<<21) // 0x00200000
#define AI_GOAL_CHASE_WEAPON (1<<22) // 0x00400000
#define AI_GOAL_FLY_TO_SHIP (1<<23) // kazan
#define AI_GOAL_IGNORE_NEW (1<<24) // Goober5000
#define AI_GOAL_FLY_TO_SHIP (1<<23) // 0x00800000
#define AI_GOAL_IGNORE_NEW (1<<24) // 0x01000000
// now the masks for ship types
+35 -7
View File
@@ -1011,6 +1011,23 @@ void ship_get_global_turret_gun_info(object *objp, ship_subsys *ssp, vec3d *gpos
ship_model_stop(objp);
}
//Update turret aiming data based on max turret aim update delay
void turret_ai_update_aim(ai_info *aip, object *En_Objp, ship_subsys *ss)
{
if (Missiontime >= ss->next_aim_pos_time)
{
ss->last_aim_enemy_pos = En_Objp->pos;
ss->last_aim_enemy_vel = En_Objp->phys_info.vel;
ss->next_aim_pos_time = Missiontime + fl2f(frand_range(0.0f, aip->ai_turret_max_aim_update_delay));
}
else
{
//Update the position based on the velocity (assume no velocity vector change)
vm_vec_scale_add2(&ss->last_aim_enemy_pos, &ss->last_aim_enemy_vel, flFrametime);
}
}
// Rotate a turret towards an enemy.
// Return TRUE if caller should use angles in subsequent rotations.
// Some obscure model thing only John Slagel knows about.
@@ -1041,23 +1058,26 @@ int aifft_rotate_turret(ship *shipp, int parent_objnum, ship_subsys *ss, object
ship_get_global_turret_info(&Objects[parent_objnum], tp, &gun_pos, &gun_vec);
//Update "known" position and velocity of target. Only matters if max_aim_update_delay is set.
turret_ai_update_aim(&Ai_info[shipp->ai_index], &Objects[ss->turret_enemy_objnum], ss);
//Figure out what point on the ship we want to point the gun at, and store the global location
//in enemy_point.
vec3d enemy_point;
if ((ss->targeted_subsys != NULL) && !(ss->flags & SSF_NO_SS_TARGETING)) {
if (ss->turret_enemy_objnum != -1) {
vm_vec_unrotate(&enemy_point, &ss->targeted_subsys->system_info->pnt, &Objects[ss->turret_enemy_objnum].orient);
vm_vec_add2(&enemy_point, &Objects[ss->turret_enemy_objnum].pos);
vm_vec_add2(&enemy_point, &ss->last_aim_enemy_pos);
}
} else {
if ((lep->type == OBJ_SHIP) && (Ship_info[Ships[lep->instance].ship_info_index].flags & (SIF_BIG_SHIP | SIF_HUGE_SHIP))) {
ai_big_pick_attack_point_turret(lep, ss, &gun_pos, &gun_vec, &enemy_point, tp->turret_fov, MIN(wip->max_speed * wip->lifetime, wip->weapon_range));
} else {
enemy_point = lep->pos;
enemy_point = ss->last_aim_enemy_pos;
}
}
target_moving_direction = lep->phys_info.vel;
target_moving_direction = ss->last_aim_enemy_vel;
//Try to guess where the enemy will be, and store that spot in predicted_enemy_pos
if (The_mission.ai_profile->flags & AIPF_USE_ADDITIVE_WEAPON_VELOCITY) {
@@ -2119,6 +2139,12 @@ void ai_fire_from_turret(ship *shipp, ship_subsys *ss, int parent_objnum)
turret_fire_weapon(valid_weapons[0], ss, parent_objnum, &gpos, &tv2e, &predicted_enemy_pos);
else
turret_fire_weapon(valid_weapons[i], ss, parent_objnum, &gpos, &tv2e, &predicted_enemy_pos);
} else {
// make sure salvo fire mode does not turn into autofire
if ((tp->flags & MSS_FLAG_TURRET_SALVO) && ((i + 1) == number_of_firings)) {
ai_info *parent_aip = &Ai_info[Ships[Objects[parent_objnum].instance].ai_index];
turret_set_next_fire_timestamp(valid_weapons[0], wip, ss, parent_aip);
}
}
// moved this here so we increment the fire pos only after we have fired and not during it
ss->turret_next_fire_pos++;
@@ -2191,14 +2217,16 @@ bool turret_adv_fov_test(ship_subsys *ss, vec3d *gvec, vec3d *v2e, float size_mo
if (((dot + size_mod) > tp->turret_fov) && ((dot - size_mod) <= tp->turret_max_fov)) {
vec3d of_dst;
vm_vec_rotate( &of_dst, v2e, &ss->world_to_turret_matrix );
vm_vec_normalize(&of_dst);
if ((of_dst.xyz.x == 0) && (of_dst.xyz.y == 0)) {
return true;
} else {
of_dst.xyz.z = 0;
// now we have 2d vector with lenght of 1 that points at the targets direction after being rotated to turrets FOR
if ((-of_dst.xyz.y + size_mod) > tp->turret_y_fov)
return true;
if (!IS_VEC_NULL_SQ_SAFE(&of_dst)) {
vm_vec_normalize(&of_dst);
// now we have 2d vector with lenght of 1 that points at the targets direction after being rotated to turrets FOR
if ((-of_dst.xyz.y + size_mod) > tp->turret_y_fov)
return true;
}
}
}
return false;
+198 -141
View File
@@ -39,6 +39,7 @@ extern int Cmdline_autopilot_interruptable;
// Module variables
bool AutoPilotEngaged;
bool UseCutsceneBars;
bool LockWeaponsDuringAutopilot;
int CurrentNav;
float ramp_bias;
NavPoint Navs[MAX_NAVPOINTS];
@@ -55,6 +56,9 @@ bool CinematicStarted, CameraMoving;
vec3d cameraPos, cameraTarget;
std::map<int,int> autopilot_wings;
int AutopilotMinEnemyDistance;
int AutopilotMinAsteroidDistance;
// used for ramping time compression;
int start_dist;
@@ -149,12 +153,7 @@ char* NavPoint::GetInteralName()
}
// ********************************************************************************************
// Tell us if autopilot is allowed
// This needs:
// * Nav point selected
// * No enemies within X distance
// * Destination > 1,000 meters away
bool CanAutopilot(bool send_msg)
bool CanAutopilot(vec3d targetPos, bool send_msg)
{
if (CurrentNav == -1)
{
@@ -162,99 +161,69 @@ bool CanAutopilot(bool send_msg)
send_autopilot_msgID(NP_MSG_FAIL_NOSEL);
return false;
}
if (object_get_gliding(Player_obj))
{
if (send_msg)
send_autopilot_msgID(NP_MSG_FAIL_GLIDING);
return false;
}
// You cannot autopilot if you're within 1000 meters of your destination nav point
if (vm_vec_dist_quick(&Player_obj->pos, Navs[CurrentNav].GetPosition()) < 1000)
{
if (vm_vec_dist_quick(&targetPos, Navs[CurrentNav].GetPosition()) < 1000) {
if (send_msg)
send_autopilot_msgID(NP_MSG_FAIL_TOCLOSE);
return false;
}
// see if any hostiles are nearby
for (ship_obj *so = GET_FIRST(&Ship_obj_list); so != END_OF_LIST(&Ship_obj_list); so = GET_NEXT(so))
{
object *other_objp = &Objects[so->objnum];
// attacks player?
if (iff_x_attacks_y(obj_team(other_objp), obj_team(Player_obj))
&& !(Ship_info[Ships[other_objp->instance].ship_info_index].flags & SIF_CARGO))
if ( AutopilotMinEnemyDistance > 0 ) {
// see if any hostiles are nearby
for (ship_obj *so = GET_FIRST(&Ship_obj_list); so != END_OF_LIST(&Ship_obj_list); so = GET_NEXT(so))
{
// Cannot autopilot if enemy within 5,000 meters
if (vm_vec_dist_quick(&Player_obj->pos, &other_objp->pos) < 5000)
object *other_objp = &Objects[so->objnum];
// attacks player?
if (iff_x_attacks_y(obj_team(other_objp), obj_team(Player_obj))
&& !(Ship_info[Ships[other_objp->instance].ship_info_index].flags & SIF_CARGO)) // ignore cargo
{
if (send_msg)
send_autopilot_msgID(NP_MSG_FAIL_HOSTILES);
return false;
// Cannot autopilot if enemy within AutopilotMinEnemyDistance meters
if (vm_vec_dist_quick(&targetPos, &other_objp->pos) < AutopilotMinEnemyDistance) {
if (send_msg)
send_autopilot_msgID(NP_MSG_FAIL_HOSTILES);
return false;
}
}
}
}
//check for asteroids
for (int n=0; n<MAX_ASTEROIDS; n++)
{
// asteroid
if (Asteroids[n].flags & AF_USED)
{
// Cannot autopilot if asteroid within 1,000 meters
if (vm_vec_dist_quick(&Player_obj->pos, &Objects[Asteroids[n].objnum].pos) < 1000)
{
if (send_msg)
send_autopilot_msgID(NP_MSG_FAIL_HAZARD);
return false;
}
}
}
return true;
}
// ********************************************************************************************
// Tell us if autopilot is allowed at a certain position (only performs checks based on that position)
// This needs:
// * Nav point selected
// * No enemies within X distance
// * Destination > 1,000 meters away
bool CanAutopilotPos(vec3d targetPos)
{
// You cannot autopilot if you're within 1000 meters of your destination nav point
if (vm_vec_dist_quick(&targetPos, Navs[CurrentNav].GetPosition()) < 1000)
return false;
// see if any hostiles are nearby
for (ship_obj *so = GET_FIRST(&Ship_obj_list); so != END_OF_LIST(&Ship_obj_list); so = GET_NEXT(so))
{
object *other_objp = &Objects[so->objnum];
// attacks player?
if (iff_x_attacks_y(obj_team(other_objp), obj_team(Player_obj))
&& !(Ship_info[Ships[other_objp->instance].ship_info_index].flags & SIF_CARGO)) // ignore cargo
{
// Cannot autopilot if enemy within 5,000 meters
if (vm_vec_dist_quick(&targetPos, &other_objp->pos) < 5000)
return false;
}
}
//check for asteroids
for (int n=0; n<MAX_ASTEROIDS; n++)
{
// asteroid
if (Asteroids[n].flags & AF_USED)
if ( AutopilotMinAsteroidDistance > 0 ) {
//check for asteroids
for (int n=0; n<MAX_ASTEROIDS; n++)
{
// Cannot autopilot if asteroid within 1,000 meters
if (vm_vec_dist_quick(&targetPos, &Objects[Asteroids[n].objnum].pos) < 1000)
return false;
// asteroid
if (Asteroids[n].flags & AF_USED)
{
// Cannot autopilot if asteroid within AutopilotMinAsteroidDistance meters
if (vm_vec_dist_quick(&targetPos, &Objects[Asteroids[n].objnum].pos) < AutopilotMinAsteroidDistance) {
if (send_msg)
send_autopilot_msgID(NP_MSG_FAIL_HAZARD);
return false;
}
}
}
}
// check for support ships
// cannot autopilot if support ship present
if ( ship_find_repair_ship(Player_obj) != NULL ) {
if (send_msg)
send_autopilot_msgID(NP_MSG_FAIL_SUPPORT_PRESENT);
return false;
}
return true;
}
extern object* Autopilot_flight_leader;
// ********************************************************************************************
// Engages autopilot
// This does:
@@ -263,13 +232,54 @@ bool CanAutopilotPos(vec3d targetPos)
// * Lock time compression -WMC
// * Tell AI to fly to targetted Nav Point (for all nav-status wings/ships)
// * Sets max waypoint speed to the best-speed of the slowest ship tagged
void StartAutopilot()
bool StartAutopilot()
{
// Check for support ship and dismiss it if it is not doing anything.
// If the support ship is doing something then tell the user such.
bool done = false;
while (!done) {
object* support_ship_op = ship_find_repair_ship(Player_obj);
if ( support_ship_op == NULL ) {
// no more
done = true;
break;
}
Assert( support_ship_op->type == OBJ_SHIP );
Assert( support_ship_op->instance >= 0 );
Assert( support_ship_op->instance < MAX_SHIPS );
Assert( Ships[support_ship_op->instance].ai_index != -1 );
ai_info* support_ship_aip = &(Ai_info[Ships[support_ship_op->instance].ai_index]);
// is support ship trying to rearm-repair
if ( ai_find_goal_index( support_ship_aip->goals, AI_GOAL_REARM_REPAIR ) == -1 ) {
// no, so tell it to depart
ai_add_ship_goal_player( AIG_TYPE_PLAYER_SHIP, AI_GOAL_WARP, -1, NULL, support_ship_aip );
} else {
// yes
send_autopilot_msgID(NP_MSG_FAIL_SUPPORT_WORKING);
return false;
}
}
if (!CanAutopilot())
return;
return false;
AutoPilotEngaged = true;
// find the ship that is "leading" all of the ships when the player starts
// autopilot
// by default the ship that is leading the autopilot session the player's
// wing leader (if the player is the wing leader then it will be the
// player).
// TODO:implement a way to allow a FREDer to say a different ship is leader
Autopilot_flight_leader = get_wing_leader(Player_ship->wingnum);
if ( Autopilot_flight_leader == NULL ) {
// force player to be the leader if he doesn't have a wing
Autopilot_flight_leader = Player_obj;
}
if (The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS)
LockAPConv = timestamp(); // lock convergence instantly
else
@@ -328,10 +338,20 @@ void StartAutopilot()
}
}
// damp speed_cap to 90% of actual -- to make sure ships stay in formation
if (The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS)
speed_cap = 0.90f * speed_cap;
if ( speed_cap < 1.0f ) {
/* We need to deal with this so that incorrectly flagged ships will not
cause the engine to fail to limit all the ships speeds correctly. */
Warning(LOCATION, "Ship speed cap is way too small (%f)!\n"
"This is normally caused by a ship that has nav-carry-status set, but cannot move itself (like a Cargo container).\n"
"Speed cap has been set to 1.0 m/s.",
speed_cap);
speed_cap = 1.0f;
}
ramp_bias = speed_cap/50.0f;
// assign ship goals
@@ -397,10 +417,10 @@ void StartAutopilot()
vm_vector_2_matrix(&Objects[Ships[i].objnum].orient, &norm1, NULL, NULL);
}
// snap wings into formation them into formation
// snap wings into formation
if (The_mission.flags & MISSION_FLAG_USE_AP_CINEMATICS && // only if using cinematics
(Ships[i].wingnum != -1 && Wings[Ships[i].wingnum].flags & WF_NAV_CARRY) // only if in a wing
&& Player_obj != &Objects[Ships[i].objnum]) //only if not player object
&& Autopilot_flight_leader != &Objects[Ships[i].objnum]) //only if not flight leader's object
{
ai_info *aip = &Ai_info[Ships[i].ai_index];
int wingnum = aip->wing, wing_index = get_wing_index(&Objects[Ships[i].objnum], wingnum);
@@ -419,33 +439,34 @@ void StartAutopilot()
switch (wcount % 2)
{
case 1: // back-left
vm_vec_add(&perp, &zero, &Player_obj->orient.vec.rvec);
vm_vec_add(&perp, &zero, &Autopilot_flight_leader->orient.vec.rvec);
//vm_vec_sub(&perp, &perp, &Player_obj->orient.vec.fvec);
vm_vec_normalize(&perp);
vm_vec_scale(&perp, -166.0f*j); // 166m is supposedly the optimal range according to tolwyn
vm_vec_add(&goal_point, &Player_obj->pos, &perp);
vm_vec_add(&goal_point, &Autopilot_flight_leader->pos, &perp);
break;
default: //back-right
case 0:
vm_vec_add(&perp, &zero, &Player_obj->orient.vec.rvec);
vm_vec_add(&perp, &zero, &Autopilot_flight_leader->orient.vec.rvec);
//vm_vec_sub(&perp, &perp, &Player_obj->orient.vec.fvec);
vm_vec_normalize(&perp);
vm_vec_scale(&perp, 166.0f*j);
vm_vec_add(&goal_point, &Player_obj->pos, &perp);
vm_vec_add(&goal_point, &Autopilot_flight_leader->pos, &perp);
break;
}
autopilot_wings[wingnum] = wcount;
wcount++;
}
Objects[Ships[i].objnum].pos = goal_point;
if (vm_vec_dist_quick(&Player_obj->pos, &Objects[Ships[i].objnum].pos) > distance)
if (vm_vec_dist_quick(&Autopilot_flight_leader->pos, &Objects[Ships[i].objnum].pos) > distance)
{
distance = vm_vec_dist_quick(&Player_obj->pos, &Objects[Ships[i].objnum].pos);
distance = vm_vec_dist_quick(&Autopilot_flight_leader->pos, &Objects[Ships[i].objnum].pos);
}
}
// lock primary and secondary weapons
//Ships[i].flags2 |= (SF2_PRIMARIES_LOCKED | SF2_SECONDARIES_LOCKED);
if ( LockWeaponsDuringAutopilot )
Ships[i].flags2 |= (SF2_PRIMARIES_LOCKED | SF2_SECONDARIES_LOCKED);
// clear the ship goals and cap the waypoint speed
ai_clear_ship_goals(&Ai_info[Ships[i].ai_index]);
@@ -540,9 +561,9 @@ void StartAutopilot()
vec3d right, front, up, offset;
for (i = 0; i < (int)capIndexes.size(); i++)
{
vm_vec_add(&right, &Player_obj->orient.vec.rvec, &zero);
vm_vec_add(&front, &Player_obj->orient.vec.fvec, &zero);
vm_vec_add(&up, &Player_obj->orient.vec.uvec, &zero);
vm_vec_add(&right, &Autopilot_flight_leader->orient.vec.rvec, &zero);
vm_vec_add(&front, &Autopilot_flight_leader->orient.vec.fvec, &zero);
vm_vec_add(&up, &Autopilot_flight_leader->orient.vec.uvec, &zero);
vm_vec_add(&offset, &zero, &zero);
if (Ship_info[Ships[capIndexes[i]].ship_info_index].flags & (SIF_CAPITAL | SIF_SUPERCAP))
{
@@ -610,7 +631,7 @@ void StartAutopilot()
vm_vec_scale(&up, (1+((float)floor((float)capship_placed[1]/3))));
// move ourselves up and out of the way of the smaller ships
vm_vec_add(&perp, &Player_obj->orient.vec.uvec, &zero);
vm_vec_add(&perp, &Autopilot_flight_leader->orient.vec.uvec, &zero);
vm_vec_scale(&perp, capship_spreads[2]);
vm_vec_add(&up, &up, &perp);
@@ -665,7 +686,7 @@ void StartAutopilot()
vm_vec_scale(&front, 2*(1+((float)floor((float)capship_placed[2]/3))));
// move "out" by 166*(wcount-1) so we don't bump into fighters
vm_vec_add(&perp, &Player_obj->orient.vec.rvec, &zero);
vm_vec_add(&perp, &Autopilot_flight_leader->orient.vec.rvec, &zero);
vm_vec_scale(&perp, 166.0f*float(wcount-1));
if ( (capship_placed[2] % 2) == 0)
vm_vec_add(&right, &right, &perp);
@@ -687,16 +708,16 @@ void StartAutopilot()
// global scale the position by 50%
//vm_vec_scale(&offset, 1.5);
vm_vec_add(&Objects[Ships[capIndexes[i]].objnum].pos, &Player_obj->pos, &offset);
vm_vec_add(&Objects[Ships[capIndexes[i]].objnum].pos, &Autopilot_flight_leader->pos, &offset);
if (vm_vec_dist_quick(&Player_obj->pos, &Objects[Ships[i].objnum].pos) > distance)
if (vm_vec_dist_quick(&Autopilot_flight_leader->pos, &Objects[Ships[i].objnum].pos) > distance)
{
distance = vm_vec_dist_quick(&Player_obj->pos, &Objects[Ships[i].objnum].pos);
distance = vm_vec_dist_quick(&Autopilot_flight_leader->pos, &Objects[Ships[i].objnum].pos);
}
}
}
ftemp = floor(Player_obj->phys_info.max_vel.xyz.z/speed_cap);
ftemp = floor(Autopilot_flight_leader->phys_info.max_vel.xyz.z/speed_cap);
if (ftemp >= 2.0f && ftemp < 4.0f)
tc_factor = 2;
else if (ftemp >= 4.0f && ftemp < 8.0f)
@@ -708,11 +729,11 @@ void StartAutopilot()
tpos = *Navs[CurrentNav].GetPosition();
// determine distance toward nav at which camera will be
vm_vec_sub(&pos, &tpos, &Player_obj->pos);
vm_vec_sub(&pos, &tpos, &Autopilot_flight_leader->pos);
vm_vec_normalize(&pos); // pos is now a unit vector in the direction we will be moving the camera
//norm1 = pos;
vm_vec_scale(&pos, 5*speed_cap*tc_factor); // pos is now scaled by 5 times the speed (5 seconds ahead)
vm_vec_add(&pos, &pos, &Player_obj->pos); // pos is now 5*speed cap in front of player ship
vm_vec_add(&pos, &pos, &Autopilot_flight_leader->pos); // pos is now 5*speed cap in front of player ship
switch (myrand()%24)
// 8 different ways of getting perp points
@@ -723,74 +744,74 @@ void StartAutopilot()
case 9:
case 16:
if (capship_placed[0] == 0)
vm_vec_sub(&perp, &zero, &Player_obj->orient.vec.uvec);
vm_vec_sub(&perp, &zero, &Autopilot_flight_leader->orient.vec.uvec);
else
{ // become up-left
vm_vec_add(&perp, &zero, &Player_obj->orient.vec.uvec);
vm_vec_sub(&perp, &perp, &Player_obj->orient.vec.rvec);
vm_vec_add(&perp, &zero, &Autopilot_flight_leader->orient.vec.uvec);
vm_vec_sub(&perp, &perp, &Autopilot_flight_leader->orient.vec.rvec);
}
break;
case 2: // up
case 10:
case 23:
vm_vec_add(&perp, &perp, &Player_obj->orient.vec.uvec);
vm_vec_add(&perp, &perp, &Autopilot_flight_leader->orient.vec.uvec);
if (capshipPresent) // become up-right
vm_vec_add(&perp, &perp, &Player_obj->orient.vec.rvec);
vm_vec_add(&perp, &perp, &Autopilot_flight_leader->orient.vec.rvec);
break;
case 3: // left
case 11:
case 22:
vm_vec_sub(&perp, &zero, &Player_obj->orient.vec.rvec);
vm_vec_sub(&perp, &zero, &Autopilot_flight_leader->orient.vec.rvec);
break;
case 4: // up-left
case 12:
case 21:
vm_vec_sub(&perp, &zero, &Player_obj->orient.vec.rvec);
vm_vec_add(&perp, &perp, &Player_obj->orient.vec.uvec);
vm_vec_sub(&perp, &zero, &Autopilot_flight_leader->orient.vec.rvec);
vm_vec_add(&perp, &perp, &Autopilot_flight_leader->orient.vec.uvec);
break;
case 5: // up-right
case 13:
case 20:
vm_vec_add(&perp, &zero, &Player_obj->orient.vec.rvec);
vm_vec_add(&perp, &perp, &Player_obj->orient.vec.uvec);
vm_vec_add(&perp, &zero, &Autopilot_flight_leader->orient.vec.rvec);
vm_vec_add(&perp, &perp, &Autopilot_flight_leader->orient.vec.uvec);
break;
case 6: // down-left
case 14:
case 19:
vm_vec_sub(&perp, &zero, &Player_obj->orient.vec.rvec);
vm_vec_sub(&perp, &zero, &Autopilot_flight_leader->orient.vec.rvec);
if (capship_placed[0] < 2)
vm_vec_sub(&perp, &perp, &Player_obj->orient.vec.uvec);
vm_vec_sub(&perp, &perp, &Autopilot_flight_leader->orient.vec.uvec);
else
vm_vec_add(&perp, &perp, &Player_obj->orient.vec.uvec);
vm_vec_add(&perp, &perp, &Autopilot_flight_leader->orient.vec.uvec);
break;
case 7: // down-right
case 15:
case 18:
vm_vec_add(&perp, &zero, &Player_obj->orient.vec.rvec);
vm_vec_add(&perp, &zero, &Autopilot_flight_leader->orient.vec.rvec);
if (capship_placed[0] < 1)
vm_vec_sub(&perp, &perp, &Player_obj->orient.vec.uvec);
vm_vec_sub(&perp, &perp, &Autopilot_flight_leader->orient.vec.uvec);
else
vm_vec_add(&perp, &perp, &Player_obj->orient.vec.uvec);
vm_vec_add(&perp, &perp, &Autopilot_flight_leader->orient.vec.uvec);
break;
default:
case 0: // right
case 8:
case 17:
perp = Player_obj->orient.vec.rvec;
perp = Autopilot_flight_leader->orient.vec.rvec;
break;
}
vm_vec_normalize(&perp);
//vm_vec_scale(&perp, 2*radius+distance);
vm_vec_scale(&perp, Player_obj->radius+radius);
vm_vec_scale(&perp, Autopilot_flight_leader->radius+radius);
// randomly scale up/down by up to 20%
j = 20-myrand()%40; // [-20,20]
@@ -830,16 +851,8 @@ void StartAutopilot()
camMovingTime = int(4.5*float(tc_factor));
set_time_compression((float)tc_factor);
}
}
// ********************************************************************************************
// Checks if autopilot should automatically die
// Returns true if:
// * Targetted waypoint < 10,000 meters away
// * Enemy < 10,000 meters
bool Autopilot_AutoDiable()
{
return !CanAutopilot();
return true;
}
// ********************************************************************************************
@@ -852,6 +865,8 @@ void EndAutoPilot()
{
AutoPilotEngaged = false;
Autopilot_flight_leader = NULL;
set_time_compression(1);
lock_time_compression(false);
Player_use_ai = 0;
@@ -899,8 +914,10 @@ void EndAutoPilot()
)
{
//unlock their weaponry
//Ships[i].flags2 &= ~(SF2_PRIMARIES_LOCKED | SF2_SECONDARIES_LOCKED);
if ( LockWeaponsDuringAutopilot )
Ships[i].flags2 &= ~(SF2_PRIMARIES_LOCKED | SF2_SECONDARIES_LOCKED);
Ai_info[Ships[i].ai_index].waypoint_speed_cap = -1; // uncap their speed
Ai_info[Ships[i].ai_index].mode = AIM_NONE; // make AI re-evaluate current ship mode
for (j = 0; j < MAX_AI_GOALS; j++)
{
@@ -975,34 +992,54 @@ camera* nav_get_set_camera()
void nav_warp(bool prewarp=false)
{
// ok... find our end distance - norm1 is still a unit vector in the direction from the player to the navpoint
vec3d targetPos, tpos=Player_obj->pos, pos;
vm_vec_sub(&pos, Navs[CurrentNav].GetPosition(), &Player_obj->pos);
/* ok... find our end distance - norm1 is still a unit vector in the
direction from the flight leader to the navpoint */
vec3d targetPos, tpos=Autopilot_flight_leader->pos, pos, velocity;
/* calculate a vector that we can use to make a path from the flight
leader's location to the nav point */
vm_vec_sub(&pos, Navs[CurrentNav].GetPosition(), &Autopilot_flight_leader->pos);
vm_vec_normalize(&pos);
velocity = pos; // make a copy for later when we do setup veleocity vector
vm_vec_scale(&pos, 250.0f); // we move by increments of 250
while (CanAutopilotPos(tpos))
/* using the vector of the flight leaders's path, simulate moving the
flight along this path by checking the autopilot conditions as specific
intervals along the path*/
while (CanAutopilot(tpos))
{
vm_vec_add(&tpos, &tpos, &pos);
}
vm_vec_sub(&targetPos, &tpos, &Player_obj->pos); //targetPos is actually a projection in a the direction toward the nav
vm_vec_sub(&targetPos, &tpos, &Autopilot_flight_leader->pos);
/* targetPos is actually a vector that describes the exact 3D movement that
the flgith leader needs to execute to reach the location that the auto
pilot is to shut off */
// Check if we are actually just setting up for the cinimatic shot of the
// flight flying on autopilot. Only jump halfway. Also we also need to
// put the camera in the correct position to show the player this cinimatic
if (prewarp)
{
vm_vec_scale(&targetPos, 0.5);
vm_vec_add(&cameraPos, &cameraPos, &targetPos);
}
/* calcuate the speed that everyone is supposed to be going so that there
is no need for anyone to accelerate or decelerate (most obvious with
the player's fighter slowing down as it changes the camera pan speed). */
Assert( Ai_info[Ships[Autopilot_flight_leader->instance].ai_index].waypoint_speed_cap > 0 );
vm_vec_scale(&velocity, (float)Ai_info[Ships[Autopilot_flight_leader->instance].ai_index].waypoint_speed_cap);
// Find all ships that are supposed to autopilot with the player and move them
// to the cinimatic location or the final destination
for (int i = 0; i < MAX_SHIPS; i++)
{
if (Ships[i].objnum != -1 &&
(Ships[i].flags2 & SF2_NAVPOINT_CARRY ||
(Ships[i].wingnum != -1 && Wings[Ships[i].wingnum].flags & WF_NAV_CARRY)
)
)
if (Ships[i].objnum != -1
&& (Ships[i].flags2 & SF2_NAVPOINT_CARRY
|| (Ships[i].wingnum != -1 && Wings[Ships[i].wingnum].flags & WF_NAV_CARRY)))
{
vm_vec_add(&Objects[Ships[i].objnum].pos, &Objects[Ships[i].objnum].pos, &targetPos);
Objects[Ships[i].objnum].phys_info.vel = velocity;
}
}
@@ -1041,7 +1078,7 @@ void NavSystem_Do()
}
if (timestamp() >= EndAPCinematic || Autopilot_AutoDiable())
if (timestamp() >= EndAPCinematic || !CanAutopilot())
{
nav_warp();
EndAutoPilot();
@@ -1060,7 +1097,7 @@ void NavSystem_Do()
if(cam != NULL)
{
cam->set_position(&cameraPos);
cam->set_rotation_facing(&Player_obj->pos);
cam->set_rotation_facing(&Autopilot_flight_leader->pos);
}
CinematicStarted = true;
@@ -1068,7 +1105,7 @@ void NavSystem_Do()
}
else
{
if (Autopilot_AutoDiable())
if (!CanAutopilot())
EndAutoPilot();
}
@@ -1141,7 +1178,10 @@ void NavSystem_Do()
}
}
// autopilot linking
/* Link in any ships that need to be linked in when the player gets close
enough. Always done by the player because: "making sure the AI fighters
are where they're supposed to be at all times is like herding cats" -Woolie Wool
*/
for (int i = 0; i < MAX_SHIPS; i++)
{
if (Ships[i].objnum != -1 && Ships[i].flags2 & SF2_NAVPOINT_NEEDSLINK)
@@ -1247,6 +1287,21 @@ void parse_autopilot_table(char *filename)
required_string("$Link Distance:");
stuff_int(&NavLinkDistance);
if (optional_string("$Interrupt autopilot if enemy within distance:"))
stuff_int(&AutopilotMinEnemyDistance);
else
AutopilotMinEnemyDistance = 5000;
if (optional_string("$Interrupt autopilot if asteroid within distance:"))
stuff_int(&AutopilotMinAsteroidDistance);
else
AutopilotMinAsteroidDistance = 1000;
if (optional_string("$Lock Weapons During Autopilot:"))
stuff_boolean(&LockWeaponsDuringAutopilot);
else
LockWeaponsDuringAutopilot = false;
// optional no cutscene bars
if (optional_string("+No_Cutscene_Bars"))
UseCutsceneBars = false;
@@ -1255,7 +1310,9 @@ void parse_autopilot_table(char *filename)
Cmdline_autopilot_interruptable = 0;
// No Nav selected message
char *msg_tags[] = { "$No Nav Selected:", "$Gliding:", "$Too Close:", "$Hostiles:", "$Linked:", "$Hazard:" };
char *msg_tags[] = { "$No Nav Selected:", "$Gliding:",
"$Too Close:", "$Hostiles:", "$Linked:", "$Hazard:",
"$Support Present:", "$Support Working:" };
for (int i = 0; i < NP_NUM_MESSAGES; i++)
{
required_string(msg_tags[i]);
+17 -13
View File
@@ -8,6 +8,7 @@
#define _AUTOPILOT_H_
#include "globalincs/pstypes.h"
#include "object/object.h"
#include <map>
// milliseconds between updates
@@ -37,13 +38,15 @@ struct NavPoint
};
#define NP_NUM_MESSAGES 6
#define NP_MSG_FAIL_NOSEL 0
#define NP_MSG_FAIL_GLIDING 1
#define NP_MSG_FAIL_TOCLOSE 2
#define NP_MSG_FAIL_HOSTILES 3
#define NP_MSG_MISC_LINKED 4
#define NP_MSG_FAIL_HAZARD 5
#define NP_MSG_FAIL_SUPPORT_PRESENT 6
#define NP_MSG_FAIL_SUPPORT_WORKING 7
#define NP_NUM_MESSAGES 8
struct NavMessage
{
@@ -62,27 +65,28 @@ extern std::map<int,int> autopilot_wings;
bool Sel_NextNav();
// Tell us is autopilot is allow
// Tell us if autopilot is allowed
// This needs:
// * Nav point selected
// * No enemies within 5,000 meters
// * No enemies within AutopilotMinEnemyDistance meters
// * No asteroids within AutopilotMinAsteroidDistance meters
// * Destination > 1,000 meters away
bool CanAutopilot(bool send_msg=false);
bool CanAutopilotPos(vec3d targetPos);
// * Support ship not present or is actively leaving
bool CanAutopilot(vec3d targetPos, bool send_msg=false);
// Check if autopilot is allowed at player's current position
// See CanAutopilot(vec3d, bool) for more information
inline bool CanAutopilot(bool send_msg=false) { return CanAutopilot(Player_obj->pos, send_msg); }
// Engages autopilot
// This does:
// * Checks if Autopilot is allowed. See CanAutopilot() for conditions.
// * Control switched from player to AI
// * Time compression to 32x
// * Tell AI to fly to targetted Nav Point (for all nav-status wings/ships)
// * Sets max waypoint speed to the best-speed of the slowest ship tagged
void StartAutopilot();
// Checks if autopilot should automatically die
// Returns true if:
// * Targetted waypoint < 1,000 meters away
// * Enemy < 5,000 meters
bool Autopilot_AutoDiable();
// * Sets max waypoint speed to the best-speed of the slowest ship tagged
// Returns false if autopilot cannot be started. True otherwise.
bool StartAutopilot();
// Disengages autopilot
// this does:
+61 -42
View File
@@ -471,6 +471,8 @@ void camera::get_info(vec3d *position, matrix *orientation)
mtxB.a1d[i] = pos;
}
vm_matrix_x_matrix(&c_ori, &mtxA, &mtxB);
vm_orthogonalize_matrix(&c_ori);
/*
angles a;
ori_p.get(&a.p, NULL);
@@ -613,15 +615,25 @@ void warp_camera::get_info(vec3d *position, matrix *orientation)
//*************************subtitle*************************
#define MAX_SUBTITLE_LINES 64
subtitle::subtitle(int in_x_pos, int in_y_pos, char* in_text, float in_display_time, char* in_imageanim, float in_fade_time, color *in_text_color, bool center_x, bool center_y, int in_width, bool in_post_shaded)
subtitle::subtitle(int in_x_pos, int in_y_pos, char* in_text, char* in_imageanim, float in_display_time, float in_fade_time, color *in_text_color, bool center_x, bool center_y, int in_width, int in_height, bool in_post_shaded)
{
// basic init, this always has to be done
memset( imageanim, 0, sizeof(imageanim) );
memset( &text_pos, 0, 2*sizeof(int) );
memset( &image_pos, 0, 4*sizeof(int) );
image_id = -1;
if ( ((in_text != NULL) && (strlen(in_text) <= 0)) && ((in_imageanim != NULL) && (strlen(in_imageanim) <= 0)) )
return;
char text_buf[256];
if (in_text != NULL && strlen(in_text) > 0)
{
strcpy(text_buf, in_text);
sexp_replace_variable_names_with_values(text_buf, 256);
in_text = text_buf;
}
int num_text_lines = 0;
char *text_line_ptrs[MAX_SUBTITLE_LINES];
@@ -629,7 +641,9 @@ subtitle::subtitle(int in_x_pos, int in_y_pos, char* in_text, float in_display_t
//Setup text
if ( (in_text != NULL) && (strlen(in_text) > 0) ) {
num_text_lines = split_str(in_text, in_width, text_line_lens, text_line_ptrs, MAX_SUBTITLE_LINES);
int split_width = (in_width > 0) ? in_width : 200;
num_text_lines = split_str(in_text, split_width, text_line_lens, text_line_ptrs, MAX_SUBTITLE_LINES);
std::string temp_str;
for(int i = 0; i < num_text_lines; i++)
{
@@ -639,7 +653,7 @@ subtitle::subtitle(int in_x_pos, int in_y_pos, char* in_text, float in_display_t
}
//Setup text color
if(in_text_color)
if(in_text_color != NULL)
text_color = *in_text_color;
else
gr_init_alphacolor(&text_color, 255, 255, 255, 255);
@@ -659,9 +673,6 @@ subtitle::subtitle(int in_x_pos, int in_y_pos, char* in_text, float in_display_t
//Setup pos
int w=0, h=0, tw=0, th=0;
float deltax, deltay;
image_pos[0] = 0;
image_pos[1] = 0;
if(center_x || center_y)
{
//Get text size
@@ -679,6 +690,11 @@ subtitle::subtitle(int in_x_pos, int in_y_pos, char* in_text, float in_display_t
if(image_id != -1)
{
bm_get_info(image_id, &w, &h);
if (in_width > 0)
w = in_width;
if (in_height > 0)
h = in_height;
tw += w;
if(h > th)
th = h;
@@ -686,44 +702,29 @@ subtitle::subtitle(int in_x_pos, int in_y_pos, char* in_text, float in_display_t
//Center it?
if(center_x)
image_pos[0] = (gr_screen.max_w - tw)/2;
image_pos.x = (gr_screen.max_w - tw)/2;
if(center_y)
image_pos[1] = (gr_screen.max_h - th)/2;
image_pos.y = (gr_screen.max_h - th)/2;
}
if(in_x_pos < 0 && !center_x)
image_pos[0] += gr_screen.max_w + in_x_pos;
image_pos.x += gr_screen.max_w + in_x_pos;
else if(!center_x)
image_pos[0] += in_x_pos;
image_pos.x += in_x_pos;
if(in_y_pos < 0 && !center_y)
image_pos[1] += gr_screen.max_h + in_y_pos;
image_pos.y += gr_screen.max_h + in_y_pos;
else if(!center_y)
image_pos[1] += in_y_pos;
image_pos.y += in_y_pos;
image_pos.w = in_width;
image_pos.h = in_height;
if(image_id != -1)
{
text_pos[0] = (float) (image_pos[0] + w); //Still set from bm_get_info call
if (!center_x)
{
deltax = text_pos[0] / 1024.0f; //MikeStar;
text_pos[0] = gr_screen.max_w * deltax; //MikeStar;
}
}
text_pos.x = image_pos.x + w; //Still set from bm_get_info call
else
{
text_pos[0] = (float) image_pos[0];
if (!center_x)
{
deltax = text_pos[0] / 1024.0f; //MikeStar;
text_pos[0] = gr_screen.max_w * deltax; //MikeStar;
}
}
text_pos[1] = (float) image_pos[1];
if (!center_y)
{
deltay = text_pos[1] / 768.0f; //MikeStar;
text_pos[1] = gr_screen.max_h * deltay; //MikeStar;
}
text_pos.x = image_pos.x;
text_pos.y = image_pos.y;
time_displayed = 0.0f;
time_displayed_end = 2.0f*fade_time + display_time;
@@ -755,8 +756,8 @@ void subtitle::do_frame(float frametime)
gr_set_color_fast(&text_color);
int font_height = gr_get_font_height();
int x = fl2i(text_pos[0]);
int y = fl2i(text_pos[1]);
int x = text_pos.x;
int y = text_pos.y;
for(unsigned int i = 0; i < text_lines.size(); i++)
{
@@ -767,7 +768,27 @@ void subtitle::do_frame(float frametime)
if(image_id != -1)
{
gr_set_bitmap(image_id, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, text_color.alpha/255.0f);
gr_bitmap(image_pos[0], image_pos[1], false);
// scaling?
if (image_pos.w > 0 || image_pos.h > 0)
{
int orig_w, orig_h;
vec3d scale;
bm_get_info(image_id, &orig_w, &orig_h);
scale.xyz.x = image_pos.w / (float) orig_w;
scale.xyz.y = image_pos.h / (float) orig_h;
scale.xyz.z = 1.0f;
gr_push_scale_matrix(&scale);
gr_bitmap(image_pos.x, image_pos.y, false);
gr_pop_scale_matrix();
}
// no scaling
else
{
gr_bitmap(image_pos.x, image_pos.y, false);
}
}
time_displayed += frametime;
@@ -790,8 +811,9 @@ void subtitle::clone(const subtitle &sub)
text_lines.push_back(sub.text_lines[i]);
}
text_pos[0] = sub.text_pos[0];
text_pos[1] = sub.text_pos[1];
// copy the structs
text_pos = sub.text_pos;
image_pos = sub.image_pos;
display_time = sub.display_time;
fade_time = sub.fade_time;
@@ -806,9 +828,6 @@ void subtitle::clone(const subtitle &sub)
image_id = -1;
}
image_pos[0] = sub.image_pos[0];
image_pos[1] = sub.image_pos[1];
time_displayed = sub.time_displayed;
time_displayed_end = sub.time_displayed_end;
+5 -5
View File
@@ -125,7 +125,7 @@ private:
void clone(const subtitle &sub);
SCP_vector<std::string> text_lines;
float text_pos[2];
struct { int x; int y; } text_pos;
float display_time;
float fade_time;
@@ -134,7 +134,7 @@ private:
//Done with set
char imageanim[MAX_FILENAME_LEN];
int image_id;
int image_pos[2];
struct { int x; int y; int w; int h; } image_pos;
//Time this has been displayed
float time_displayed;
@@ -144,9 +144,9 @@ private:
bool post_shaded;
public:
subtitle(int in_x_pos, int in_y_pos, char* in_text, float in_display_time,
char* in_imageanim = NULL, float in_fade_time = 0.0f, color *in_text_color = NULL,
bool center_x = false, bool center_y = false, int in_width = 200, bool post_shaded=false);
subtitle(int in_x_pos, int in_y_pos, char* in_text = NULL, char* in_imageanim = NULL,
float in_display_time = 0, float in_fade_time = 0.0f, color *in_text_color = NULL,
bool center_x = false, bool center_y = false, int in_width = 0, int in_height = 0, bool post_shaded=false);
~subtitle();
subtitle(const subtitle &sub) { clone(sub); }
+7 -2
View File
@@ -147,9 +147,14 @@ int cfile_in_root_dir(char *exe_path)
token_count++;
tok = strtok(NULL, DIR_SEPARATOR_STR);
} while(tok != NULL);
// root directory if we have <= 1 slash
#ifdef SCP_UNIX
// /freespace works, / does not
if(token_count <= 1) {
#else
// C:/freespace works, C:/ does not
if(token_count <= 2){
#endif
return 1;
}
+1 -1
View File
@@ -1168,7 +1168,7 @@ int cf_find_file_location_ext( char *filename, const int ext_num, const char **e
int last_root_index = -1;
int last_path_index = -1;
file_list_index.reserve(Num_files);
file_list_index.reserve( MIN(ext_num * 4, Num_files) );
// next, run though and pick out base matches
for (i = 0; i < Num_files; i++) {
+78 -56
View File
@@ -21,6 +21,7 @@
#include "globalincs/pstypes.h"
#ifdef _WIN32
#include <io.h>
#include <direct.h>
#elif defined(APPLE_APP)
#include <CoreFoundation/CoreFoundation.h>
@@ -49,6 +50,7 @@ public:
int get_int();
float get_float();
char *str();
bool check_if_args_is_valid();
};
static cmdline_parm Parm_list(NULL, NULL);
@@ -108,16 +110,15 @@ typedef struct
// Please group them by type, ie graphics, gameplay etc, maximum 20 different types
Flag exe_params[] =
{
{ "-spec", "Enable specular", true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-spec", },
{ "-spec", "Enable specular", true, EASY_MEM_ALL_ON, EASY_DEFAULT_MEM, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-spec", },
{ "-glow", "Enable glowmaps", true, EASY_MEM_ALL_ON, EASY_DEFAULT_MEM, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-glow", },
{ "-env", "Enable environment maps", true, EASY_MEM_ALL_ON, EASY_DEFAULT_MEM, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-env", },
{ "-mipmap", "Enable mipmapping", true, EASY_MEM_ALL_ON, EASY_DEFAULT_MEM, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-mipmap", },
{ "-mipmap", "Enable mipmapping", true, 0, EASY_DEFAULT_MEM, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-mipmap", },
{ "-nomotiondebris", "Disable motion debris", true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nomotiondebris",},
{ "-noscalevid", "Disable scale-to-window for movies", true, 0, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noscalevid", },
{ "-missile_lighting", "Apply Lighting to Missiles" , true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-missile_lighting", },
{ "-normal", "Enable normal maps", true, EASY_MEM_ALL_ON, EASY_DEFAULT_MEM, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-normal" },
{ "-3dshockwave", "Enable 3D shockwaves", true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-3dshockwave" },
{ "-post_process", "Enable post processing", true, EASY_MEM_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-post_process" },
{ "-3dshockwave", "Enable 3D shockwaves", true, EASY_MEM_ALL_ON, EASY_DEFAULT_MEM, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-3dshockwave" },
{ "-img2dds", "Compress non-compressed images", true, 0, EASY_DEFAULT, "Game Speed", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-img2dds", },
{ "-no_vsync", "Disable vertical sync", true, 0, EASY_DEFAULT, "Game Speed", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_vsync", },
@@ -126,18 +127,16 @@ Flag exe_params[] =
{ "-dualscanlines", "Another pair of scanning lines", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-dualscanlines", },
{ "-targetinfo", "Enable info next to target", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-targetinfo", },
{ "-orbradar", "Enables 3d radar", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-orbradar", },
{ "-rearm_timer", "Enable Rearm/Repair Completion Timer", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-rearm_timer", },
{ "-rearm_timer", "Enable Rearm/Repair Completion Timer", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-rearm_timer", },
{ "-ballistic_gauge", "Enable the analog ballistic ammo gauge", true, 0, EASY_DEFAULT, "HUD", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-ballistic_gauge", },
{ "-ship_choice_3d", "Use models for ship selection", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-ship_choice_3d", },
{ "-weapon_choice_3d", "Use models for weapon selection", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-weapon_choice_3d", },
{ "-weapon_choice_3d", "Use models for weapon selection", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-weapon_choice_3d", },
{ "-3dwarp", "Enable 3d warp", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-3dwarp", },
{ "-warp_flash", "Enable flash upon warp", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-warp_flash", },
{ "-no_ap_interrupt", "Disable interrupting autopilot", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_ap_interrupt", },
{ "-tbp", "Toggle features for The Babylon Project", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-tbp", }, // TBP warp effects -Et1
{ "-wcsaga", "Toggle features for Wing Commander Saga", true, 0, EASY_DEFAULT, "Gameplay", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-wcsaga", },
{ "-snd_preload", "Preload mission game sounds", true, EASY_MEM_ALL_ON, EASY_DEFAULT_MEM, "Audio", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-snd_preload", },
{ "-snd_preload", "Preload mission game sounds", true, EASY_MEM_ALL_ON, EASY_DEFAULT_MEM, "Audio", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-snd_preload", },
{ "-nosound", "Disable sound and music", false, 0, EASY_DEFAULT, "Audio", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nosound", },
{ "-nomusic", "Disable music", false, 0, EASY_DEFAULT, "Audio", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nomusic", },
@@ -151,40 +150,40 @@ Flag exe_params[] =
{ "-oldfire", "", false, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-oldfire", },
{ "-nohtl", "Software mode (very slow)", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nohtl", },
{ "-no_set_gamma", "Disable setting of gamma", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_set_gamma", },
{ "-no_set_gamma", "Disable setting of gamma", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_set_gamma", },
{ "-nomovies", "Disable video playback", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nomovies", },
{ "-noparseerrors", "Disable parsing errors", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noparseerrors", },
{ "-safeloading", "", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-safeloading", },
{ "-query_speech", "Does this build have speech?", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-query_speech", },
{ "-query_speech", "Does this build have speech?", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-query_speech", },
{ "-d3d_bad_tsys", "Enable inefficient textures", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-d3d_bad_tsys", },
{ "-novbo", "Disable OpenGL VBO", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-novbo", },
{ "-noibx", "Don't use cached index buffers (IBX)", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noibx", },
{ "-noibx", "Don't use cached index buffers (IBX)", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-noibx", },
{ "-loadallweps", "Load all weapons, even those not used", true, 0, EASY_DEFAULT, "Troubleshoot", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-loadallweps", },
{ "-disable_fbo", "Disable OpenGL RenderTargets", true, 0, EASY_DEFAULT, "Troubleshoot", "", },
{ "-disable_fbo", "Disable OpenGL RenderTargets", true, 0, EASY_DEFAULT, "Troubleshoot", "", },
{ "-no_glsl", "Disable GLSL (shader) support", true, 0, EASY_DEFAULT, "Troubleshoot", "", },
{ "-ati_swap", "Fix Color issues on some ATI cards", true, 0, EASY_DEFAULT, "Troubleshoot", "http://scp.indiegames.us/mantis/view.php?id=1669", },
{ "-ati_swap", "Fix Color issues on some ATI cards", true, 0, EASY_DEFAULT, "Troubleshoot", "http://scp.indiegames.us/mantis/view.php?id=1669", },
{ "-ingame_join", "Allows ingame joining", true, 0, EASY_DEFAULT, "Experimental", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-ingame_join", },
{ "-voicer", "Voice recognition", true, 0, EASY_DEFAULT, "Experimental", "", },
{ "-post_process", "Enable post processing", true, 0, EASY_DEFAULT, "Experimental", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-post_process" },
{ "-fps", "Show frames per second on HUD", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fps", },
{ "-pos", "Show position of camera", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-pos", },
{ "-window", "Run in window", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-window", },
{ "-fullscreen_window", "Run in fullscreen window", false, 0, 0, "Dev Tool", "", },
{ "-res", "Run at specified resolution", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-res", },
{ "-fullscreen_window", "Run in fullscreen window", false, 0, EASY_DEFAULT, "Dev Tool", "", },
{ "-timerbar", "", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-timerbar", },
{ "-stats", "Show statistics", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-stats", },
{ "-coords", "Show coordinates", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-coords", },
{ "-coords", "Show coordinates", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-coords", },
{ "-show_mem_usage", "Show memory usage", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-show_mem_usage", },
{ "-pofspew", "", false, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-pofspew", },
{ "-tablecrcs", "", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-tablecrcs", },
{ "-missioncrcs", "", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-missioncrcs", },
{ "-dis_collisions", "Disable collisions", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-dis_collisions", },
{ "-dis_weapons", "Disable weapon rendering", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-dis_weapons", },
{ "-dis_weapons", "Disable weapon rendering", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-dis_weapons", },
{ "-output_sexps", "Outputs SEXPs to sexps.html", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-output_sexps", },
{ "-output_scripting", "Outputs scripting to scripting.html", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-output_scripting", },
{ "-save_render_target", "Save render targets to file", true, 0, EASY_DEFAULT, "Dev Tool", "", },
{ "-debug_window", "Display debug window", true, 0, EASY_DEFAULT, "Dev Tool", "", },
{ "-debug_window", "Display debug window", true, 0, EASY_DEFAULT, "Dev Tool", "", },
{ "-verify_vps", "Spew VP crcs to vp_crcs.txt", true, 0, EASY_DEFAULT, "Dev Tool", "", },
#ifdef SCP_UNIX
{ "-nograb", "Don't grab mouse/keyboard in a window", true, 0, EASY_DEFAULT, "Dev Tool", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-nograb", },
@@ -332,12 +331,8 @@ int Cmdline_voice_recognition = 0;
// MOD related
cmdline_parm mod_arg("-mod", NULL, true); // Cmdline_mod -- DTP modsupport
cmdline_parm tbp("-tbp", NULL); // Cmdline_tbp -- TBP warp effects -Et1
cmdline_parm wcsaga("-wcsaga", NULL); // Cmdline_wcsaga
char *Cmdline_mod = NULL; //DTP for mod arguement
int Cmdline_tbp = 0;
int Cmdline_wcsaga = 0;
// Multiplayer/Network related
cmdline_parm almission_arg("-almission", NULL); // Cmdline_almission -- DTP for autoload Multi mission
@@ -385,6 +380,7 @@ cmdline_parm dis_collisions("-dis_collisions", NULL); // Cmdline_dis_collisions
cmdline_parm dis_weapons("-dis_weapons", NULL); // Cmdline_dis_weapons
cmdline_parm noparseerrors_arg("-noparseerrors", NULL); // Cmdline_noparseerrors -- turns off parsing errors -C
cmdline_parm nowarn_arg("-no_warn", NULL); // Cmdline_nowarn
cmdline_parm extra_warn_arg("-extra_warn", NULL); // Cmdline_extra_warn
cmdline_parm fps_arg("-fps", NULL); // Cmdline_show_fps
cmdline_parm show_mem_usage_arg("-show_mem_usage", NULL); // Cmdline_show_mem_usage
cmdline_parm pos_arg("-pos", NULL); // Cmdline_show_pos
@@ -405,6 +401,7 @@ int Cmdline_dis_collisions = 0;
int Cmdline_dis_weapons = 0;
int Cmdline_noparseerrors = 0;
int Cmdline_nowarn = 0; // turn warnings off in FRED
int Cmdline_extra_warn = 0;
int Cmdline_show_mem_usage = 0;
int Cmdline_show_pos = 0;
int Cmdline_show_stats = 0;
@@ -502,7 +499,7 @@ void parm_stuff_args(cmdline_parm *parm, char *cmdline)
cmdline += strlen(parm->name);
while ((*cmdline != '\0') && strncmp(cmdline, " -", 2)) {
while ((*cmdline != '\0') && strncmp(cmdline, " -", 2) && ((size_t)(dest-buffer) < sizeof(buffer))) {
*dest++ = *cmdline++;
}
@@ -521,12 +518,15 @@ void parm_stuff_args(cmdline_parm *parm, char *cmdline)
parm->args = NULL;
}
int size = strlen(buffer) + 1;
if (saved_args != NULL)
size += (strlen(saved_args) + 1); // an ',' is used as a separator when combining, so be sure to account for it
int size = strlen(buffer);
if (size > 0) {
size++; // nul char
if (saved_args != NULL) {
size += (strlen(saved_args) + 1); // an ',' is used as a separator when combining, so be sure to account for it
}
parm->args = new char[size];
memset(parm->args, 0, size);
@@ -537,13 +537,14 @@ void parm_stuff_args(cmdline_parm *parm, char *cmdline)
strcat_s(parm->args, size, ",");
// now the new arg
strcat_s(parm->args, size, buffer);
delete [] saved_args;
} else {
strcpy_s(parm->args, size, buffer);
}
} else {
parm->args = saved_args;
}
if (saved_args != NULL)
delete[] saved_args;
}
@@ -698,9 +699,12 @@ void os_init_cmdline(char *cmdline)
// if the file exists, get a single line, and deal with it
if ( fp ) {
char buf[1024], *p;
char *buf, *p;
fgets(buf, 1024, fp);
size_t len = filelength( fileno(fp) ) + 2;
buf = new char [len];
fgets(buf, len-1, fp);
// replace the newline character with a NULL
if ( (p = strrchr(buf, '\n')) != NULL ) {
@@ -709,11 +713,12 @@ void os_init_cmdline(char *cmdline)
#ifdef SCP_UNIX
// append a space for the os_parse_parms() check
strcat_s(buf, " ");
strcat_s(buf, len, " ");
#endif
os_parse_parms(buf);
os_validate_parms(buf);
delete [] buf;
fclose(fp);
}
@@ -732,9 +737,12 @@ void os_init_cmdline(char *cmdline)
// if the file exists, get a single line, and deal with it
if ( fp ) {
char buf[1024], *p;
char *buf, *p;
fgets(buf, 1024, fp);
size_t len = filelength( fileno(fp) ) + 2;
buf = new char [len];
fgets(buf, len-1, fp);
// replace the newline character with a NULL
if ( (p = strrchr(buf, '\n')) != NULL ) {
@@ -742,10 +750,11 @@ void os_init_cmdline(char *cmdline)
}
// append a space for the os_parse_parms() check
strcat_s(buf, " ");
strcat_s(buf, len, " ");
os_parse_parms(buf);
os_validate_parms(buf);
delete [] buf;
fclose(fp);
}
#endif
@@ -788,6 +797,21 @@ cmdline_parm::~cmdline_parm()
#endif
}
// checks if the objects args variable is valid
// returns true if it is, shows an error box and returns false if not valid.
bool cmdline_parm::check_if_args_is_valid() {
if ( args == NULL ) {
Error(__FILE__, __LINE__,
"Command line flag passed that requires an argument, but the argument is missing!\r\n"
"The flag is '%s', make sure that you have an argument that follows it.\r\n"
"You may need to close your launcher and remove the flag manually from %s/data/cmdline_fso.cfg\r\n",
name, "<Freespace directory>");
return false;
} else {
return true;
}
}
// returns - true if the parameter exists on the command line, otherwise false
int cmdline_parm::found()
@@ -798,7 +822,8 @@ int cmdline_parm::found()
// returns - the interger representation for the parameter arguement
int cmdline_parm::get_int()
{
Assert(args);
check_if_args_is_valid();
int offset = 0;
if (stacks) {
@@ -821,7 +846,8 @@ int cmdline_parm::get_int()
// returns - the float representation for the parameter arguement
float cmdline_parm::get_float()
{
Assert(args!=NULL);
check_if_args_is_valid();
int offset = 0;
if (stacks) {
@@ -844,7 +870,8 @@ float cmdline_parm::get_float()
// returns - the string value for the parameter arguement
char *cmdline_parm::str()
{
Assert(args);
check_if_args_is_valid();
return args;
}
@@ -879,6 +906,11 @@ bool SetCmdlineParams()
Cmdline_FRED2_htl = 1;
}*/
if (extra_warn_arg.found())
{
Cmdline_extra_warn = 1;
}
if (timerbar_arg.found()) {
Cmdline_timerbar = 1;
}
@@ -1125,7 +1157,12 @@ bool SetCmdlineParams()
}
if ( fov_arg.found() ) {
VIEWER_ZOOM_DEFAULT = Cmdline_fov = fov_arg.get_float();
Cmdline_fov = fov_arg.get_float();
if (Cmdline_fov > 0.1) {
VIEWER_ZOOM_DEFAULT = Cmdline_fov;
} else {
VIEWER_ZOOM_DEFAULT = Cmdline_fov = 0.75f;
}
}
if( clip_dist_arg.found() ) {
@@ -1137,16 +1174,6 @@ bool SetCmdlineParams()
Cmdline_orb_radar = 1;
}
// TBP warp effects -Et1
// Chief1983 - Add 3d shockwave, ship choice 3d and weapon choice 3d if TBP is checked
if( tbp.found() )
{
Cmdline_tbp = 1;
Cmdline_enable_3d_shockwave = 1;
Cmdline_ship_choice_3d = 1;
Cmdline_weapon_choice_3d = 1;
}
if ( use_3dwarp.found() ) {
Cmdline_3dwarp = 1;
}
@@ -1326,11 +1353,6 @@ bool SetCmdlineParams()
Cmdline_ballistic_gauge = 1;
}
if (wcsaga.found())
{
Cmdline_wcsaga = 1;
}
if ( cache_bitmaps_arg.found() ) {
Cmdline_cache_bitmaps = 1;
}
+1 -3
View File
@@ -104,9 +104,6 @@ extern int Cmdline_voice_recognition;
// MOD related
extern char *Cmdline_mod; // DTP for mod support
extern int Cmdline_tbp;
extern int Cmdline_wcsaga;
// Multiplayer/Network related
extern char *Cmdline_almission; // DTP for autoload mission (for multi only)
extern int Cmdline_ingamejoin;
@@ -134,6 +131,7 @@ extern int Cmdline_dis_collisions;
extern int Cmdline_dis_weapons;
extern int Cmdline_noparseerrors;
extern int Cmdline_nowarn;
extern int Cmdline_extra_warn;
extern int Cmdline_show_mem_usage;
extern int Cmdline_show_pos;
extern int Cmdline_show_stats;
+3 -2
View File
@@ -87,7 +87,6 @@ BOOL AltShipClassDlg::OnInitDialog()
while (objp != END_OF_LIST(&obj_used_list)) {
if ((objp->type == OBJ_START) || (objp->type == OBJ_SHIP)) {
if (objp->flags & OF_MARKED) {
m_selected_ships[num_selected_ships++] = objp->instance;
}
}
@@ -95,6 +94,8 @@ BOOL AltShipClassDlg::OnInitDialog()
}
Assert (num_selected_ships > 0);
Assert (Objects[cur_object_index].flags & OF_MARKED);
if (num_selected_ships > 1)
{
multi_edit = true;
@@ -137,7 +138,7 @@ BOOL AltShipClassDlg::OnInitDialog()
// Set up the actual list of alt classes
alt_class_pool.clear();
alt_class_pool = Ships[m_selected_ships[0]].s_alt_classes;
alt_class_pool = Ships[Objects[cur_object_index].instance].s_alt_classes;
alt_class_list_rebuild();
return TRUE; // return TRUE unless you set the focus to a control
+41 -2
View File
@@ -28,6 +28,8 @@
#include "debugconsole/dbugfile.h"
#include "globalincs/mspdb_callstack.h"
#include "AFXADV.H"
#ifdef NDEBUG
#ifndef FRED
#error macro FRED is not defined when trying to build release Fred. Please define FRED macro in build settings in all Fred projects
@@ -80,12 +82,12 @@ window_data Mission_notes_wnd_data;
BEGIN_MESSAGE_MAP(CFREDApp, CWinApp)
//{{AFX_MSG_MAP(CFREDApp)
ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
// Standard file based document commands
ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
// Standard print setup command
ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup)
END_MESSAGE_MAP()
@@ -236,9 +238,23 @@ BOOL CFREDApp::InitInstance()
*str_end = '\0';
// Goober5000 - figure out where the FRED file dialog should go
if ((m_pRecentFileList != NULL) && (m_pRecentFileList->GetSize() > 0))
{
// use the most recently opened file to supply the default folder
m_sInitialDir = m_pRecentFileList->operator[](0); // lol syntax
}
else
{
// use FRED's own directory to search for missions
m_sInitialDir = Fred_base_dir;
m_sInitialDir += "\\data\\missions";
}
// Parse command line for standard shell commands, DDE, file open
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
ParseCommandLine(cmdInfo);
m_nCmdShow = Main_wnd_data.p.showCmd;
@@ -309,6 +325,25 @@ void CFREDApp::OnAppAbout()
aboutDlg.DoModal();
}
// G5K - from http://www.experts-exchange.com/Programming/System/Windows__Programming/MFC/Q_20155824.html
void CFREDApp::OnFileOpen()
{
// use the initial dir the first time we prompt for a file
// name. after a successful open, the file name will be
// changed to be the empty string and the default dir
// will be supplied by the CFileDialog internal memory
if(!DoPromptFileName(m_sInitialDir, AFX_IDS_OPENFILE, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST, TRUE, NULL))
{
// open cancelled
return;
}
AfxGetApp()->OpenDocumentFile(m_sInitialDir);
// if returns NULL, the user has already been alerted
// now erase the initial dir since we only want to use it once
m_sInitialDir.Empty();
}
/////////////////////////////////////////////////////////////////////////////
// CFREDApp commands
@@ -668,3 +703,7 @@ int CFREDApp::ExitInstance()
return CWinApp::ExitInstance();
}
// Empty functions to make fred link with the sexp_mission_set_subspace
void game_start_subspace_ambient_sound() {}
void game_stop_subspace_ambient_sound() {}
+2
View File
@@ -52,6 +52,7 @@ typedef struct window_data {
class CFREDApp : public CWinApp
{
int app_init;
CString m_sInitialDir;
public:
void record_window_data(window_data *wndd, CWnd *wnd);
@@ -75,6 +76,7 @@ public:
//{{AFX_MSG(CFREDApp)
afx_msg void OnAppAbout();
afx_msg void OnFileOpen();
// NOTE - the ClassWizard will add and remove member functions here.
// DO NOT EDIT what you see in these blocks of generated code !
//}}AFX_MSG
+18 -16
View File
@@ -634,7 +634,7 @@ CAPTION "About FRED2"
FONT 8, "MS Sans Serif"
BEGIN
ICON IDR_MAINFRAME,IDC_STATIC,10,17,20,20,SS_REALSIZEIMAGE
LTEXT "FRED2_OPEN - FreeSpace Editor, Version 3.6.11 OpenGL",
LTEXT "FRED2_OPEN - FreeSpace Editor, Version 3.6.12 OpenGL",
IDC_STATIC,39,8,184,10,SS_NOPREFIX
LTEXT "Copyright © 1999 Volition, Inc. All Rights Reserved",
IDC_STATIC,39,17,164,8
@@ -1527,7 +1527,7 @@ END
IDD_EVENT_EDITOR DIALOGEX 0, 0, 437, 431
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Mission Event Edit"
FONT 8, "MS Sans Serif", 0, 0, 0x1
FONT 8, "MS Sans Serif"
BEGIN
CONTROL "Tree1",IDC_EVENT_TREE,"SysTreeView32",TVS_HASBUTTONS |
TVS_HASLINES | TVS_LINESATROOT | TVS_EDITLABELS |
@@ -1552,8 +1552,8 @@ BEGIN
EDITTEXT IDC_CHAIN_DELAY,210,255,45,14,ES_AUTOHSCROLL | ES_NUMBER
EDITTEXT IDC_OBJ_TEXT,86,246,117,14,ES_AUTOHSCROLL
EDITTEXT IDC_OBJ_KEY_TEXT,86,262,117,14,ES_AUTOHSCROLL
EDITTEXT IDC_HELP_BOX,7,298,423,126,ES_MULTILINE | ES_READONLY,
WS_EX_TRANSPARENT
EDITTEXT IDC_HELP_BOX,7,298,423,126,ES_MULTILINE | ES_AUTOVSCROLL |
ES_READONLY | WS_VSCROLL,WS_EX_TRANSPARENT
PUSHBUTTON "New Msg",IDC_NEW_MSG,229,59,50,14,0,WS_EX_STATICEDGE
PUSHBUTTON "Delete Msg",IDC_DELETE_MSG,229,77,50,14,0,
WS_EX_STATICEDGE
@@ -2270,8 +2270,8 @@ BEGIN
BS_3STATE | WS_TABSTOP,165,17,85,10
CONTROL "Affected By Gravity",IDC_AFFECTED_BY_GRAVITY,"Button",
BS_3STATE | WS_TABSTOP,165,27,77,10
CONTROL "Special Warpin",IDC_SPECIAL_WARPIN,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,165,37,59,10
CONTROL "Special Warpin",IDC_SPECIAL_WARPIN,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,165,37,59,10
CONTROL "Targetable as Bomb",IDC_TARGETABLE_AS_BOMB,"Button",
BS_3STATE | WS_TABSTOP,165,47,79,10
CONTROL "Disable Built-in Messages",IDC_DISABLE_BUILTIN_SHIP,
@@ -2398,19 +2398,21 @@ BEGIN
CBS_SORT | WS_VSCROLL | WS_TABSTOP
END
IDD_SPECIAL_HITPOINTS DIALOG DISCARDABLE 0, 0, 234, 57
IDD_SPECIAL_HITPOINTS DIALOG DISCARDABLE 0, 0, 234, 85
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Special Hitpoints"
FONT 8, "MS Sans Serif"
BEGIN
CONTROL "Enable Special Hitpoints",IDC_ENABLE_SPECIAL_HITPOINTS,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,7,93,10
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,37,93,10
EDITTEXT IDC_SPECIAL_SHIELDS,91,19,62,12,ES_AUTOHSCROLL
LTEXT "Shields:",-1,61,23,26,8
EDITTEXT IDC_SPECIAL_HULL,91,33,62,12,ES_AUTOHSCROLL
LTEXT "Hull:",-1,72,36,15,8
LTEXT "Shields:",-1,62,23,26,8
EDITTEXT IDC_SPECIAL_HULL,91,52,62,12,ES_AUTOHSCROLL
LTEXT "Hull:",-1,73,55,15,8
DEFPUSHBUTTON "OK",ID_OK,177,7,50,14
PUSHBUTTON "Cancel",ID_CANCEL,177,24,50,14
CONTROL "Enable Special Shield Points",IDC_ENABLE_SPECIAL_SHIELD,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,7,106,10
END
IDD_SET_GLOBAL_SHIP_FLAGS DIALOG DISCARDABLE 0, 0, 114, 79
@@ -2560,8 +2562,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 3,6,11,0
PRODUCTVERSION 3,6,11,0
FILEVERSION 3,6,12,0
PRODUCTVERSION 3,6,12,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -2578,12 +2580,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "Volition Inc.\0"
VALUE "FileDescription", "Fred 2 Open\0"
VALUE "FileVersion", "3.6.11.0000\0"
VALUE "FileVersion", "3.6.12.0\0"
VALUE "InternalName", "Fred 2 Open\0"
VALUE "LegalCopyright", "Copyright © 1998\0"
VALUE "OriginalFilename", "fred2.exe\0"
VALUE "ProductName", "Fred 2 Open\0"
VALUE "ProductVersion", "3.6.11\0"
VALUE "ProductVersion", "3.6.12.0\0"
END
END
BLOCK "VarFileInfo"
@@ -3145,7 +3147,7 @@ IDC_CURSOR2 CURSOR DISCARDABLE "res\\cursor2.cur"
STRINGTABLE DISCARDABLE
BEGIN
IDR_MAINFRAME "FRED2_OPEN 3.6.11 - FreeSpace2 Mission Editor\nUntitled\nFRED2\nFreeSpace2 Missions (*.fs2)\n.fs2\nFreeSpace2Mission\nFreeSpace2 Mission"
IDR_MAINFRAME "FRED2_OPEN 3.6.12 - FreeSpace2 Mission Editor\nUntitled\nFRED2\nFreeSpace2 Missions (*.fs2)\n.fs2\nFreeSpace2Mission\nFreeSpace2 Mission"
END
STRINGTABLE DISCARDABLE
+7 -4
View File
@@ -324,8 +324,10 @@ bool fred_init()
timer_init();
Assert(strlen(Fred_exe_dir) > 0);
Assert(strlen(Fred_base_dir) > 0);
// sigh... this should enable proper reading of cmdline_fso.cfg - Goober5000
cfile_chdir(Fred_base_dir);
// this should enable mods - Kazan
fred2_parse_cmdline(__argc, __argv);
@@ -563,6 +565,7 @@ int create_ship(matrix *orient, vec3d *pos, int ship_type)
resolve_parse_flags(&Objects[obj], Iff_info[shipp->team].default_parse_flags, Iff_info[shipp->team].default_parse_flags2);
// default shield setting
shipp->special_shield = -1;
z1 = Shield_sys_teams[shipp->team];
z2 = Shield_sys_types[ship_type];
if (((z1 == 1) && z2) || (z2 == 1))
@@ -601,9 +604,9 @@ int create_ship(matrix *orient, vec3d *pos, int ship_type)
}
// calc kamikaze stuff
if (shipp->special_hitpoint_index != -1)
if (shipp->use_special_explosion)
{
temp_max_hull_strength = (float) atoi(Sexp_variables[shipp->special_hitpoint_index+HULL_STRENGTH].text);
temp_max_hull_strength = (float)shipp->special_exp_blast;
}
else
{
@@ -2518,7 +2521,7 @@ void generate_weaponry_usage_list(int *arr, int wing)
j = swp->num_secondary_banks;
while (j--) {
if (swp->secondary_bank_weapons[j] >=0 && swp->secondary_bank_weapons[j] < MAX_WEAPON_TYPES) {
arr[swp->secondary_bank_weapons[j]] += int(ceil(swp->secondary_bank_ammo[j] * swp->secondary_bank_capacity[j] / 100 / (Weapon_info[swp->secondary_bank_weapons[j]].cargo_size + 0.5f)));
arr[swp->secondary_bank_weapons[j]] += (int) floor((swp->secondary_bank_ammo[j] * swp->secondary_bank_capacity[j] / 100.0f / Weapon_info[swp->secondary_bank_weapons[j]].cargo_size) + 0.5f);
}
}
}
+110 -15
View File
@@ -1035,13 +1035,18 @@ int CFred_mission_save::save_variables()
char string[] = "string";
char block[] = "block";
int i;
int num_block_vars = 0;
// sort sexp_variables
sexp_variable_sort();
// get count
int num_variables = sexp_variable_count();
int num_block_vars = sexp_variable_block_count();
if (Format_fs2_open == FSO_FORMAT_RETAIL) {
generate_special_explosion_block_variables();
num_block_vars = num_block_variables();
}
int total_variables = num_variables + num_block_vars;
if (total_variables > 0) {
@@ -1087,7 +1092,7 @@ int CFred_mission_save::save_variables()
for (i=MAX_SEXP_VARIABLES-num_block_vars; i<MAX_SEXP_VARIABLES; i++) {
type = block;
fout("\n\t\t%d\t\t\"%s\"\t\t\"%s\"\t\t\"%s\"", i, Sexp_variables[i].variable_name, Sexp_variables[i].text, type);
fout("\n\t\t%d\t\t\"%s\"\t\t\"%s\"\t\t\"%s\"", i, Block_variables[i].variable_name, Block_variables[i].text, type);
}
fout("\n)");
@@ -1626,27 +1631,117 @@ int CFred_mission_save::save_objects()
fout(" %d", Ships[i].escort_priority);
}
if (Ships[i].special_exp_index != -1) {
if (optional_string_fred("+Special Exp index:", "$Name:")) {
parse_comments();
} else {
fout("\n+Special Exp index:");
}
// special explosions
if (Format_fs2_open != FSO_FORMAT_RETAIL) {
if (Ships[i].use_special_explosion) {
if (optional_string_fred("$Special Explosion:", "$Name:")) {
parse_comments();
fout(" %d", Ships[i].special_exp_index);
required_string_fred("+Special Exp Damage:");
parse_comments();
fout(" %d", Ships[i].special_exp_damage);
required_string_fred("+Special Exp Blast:");
parse_comments();
fout(" %d", Ships[i].special_exp_blast);
required_string_fred("+Special Exp Inner Radius:");
parse_comments();
fout(" %d", Ships[i].special_exp_inner);
required_string_fred("+Special Exp Outer Radius:");
parse_comments();
fout(" %d", Ships[i].special_exp_outer);
if (Ships[i].use_shockwave && (Ships[i].special_exp_shockwave_speed > 0)) {
optional_string_fred("+Special Exp Shockwave Speed:");
parse_comments();
fout(" %d", Ships[i].special_exp_shockwave_speed);
}
else {
bypass_comment(";;FSO 3.6.13;; +Special Exp Shockwave Speed:");
}
}
else {
fso_comment_push(";;FSO 3.6.13;;");
fout_version("\n$Special Explosion:");
fout_version("\n+Special Exp Damage:");
fout(" %d", Ships[i].special_exp_damage);
fout_version("\n+Special Exp Blast:");
fout(" %d", Ships[i].special_exp_blast);
fout_version("\n+Special Exp Inner Radius:");
fout(" %d", Ships[i].special_exp_inner);
fout_version("\n+Special Exp Outer Radius:");
fout(" %d", Ships[i].special_exp_outer);
if (Ships[i].use_shockwave && (Ships[i].special_exp_shockwave_speed > 0)) {
fout_version("\n+Special Exp Shockwave Speed:");
fout(" %d", Ships[i].special_exp_shockwave_speed);
}
fso_comment_pop();
}
}
else {
bypass_comment(";;FSO 3.6.13;; +Special Exp Shockwave Speed:");
}
}
// retail format special explosions
else {
if (Ships[i].use_special_explosion) {
int special_exp_index;
if (has_special_explosion_block_index(&Ships[i], &special_exp_index)) {
fout("\n+Special Exp index:");
fout(" %d", special_exp_index);
}
else {
CString text = "You are saving in the retail mission format, but ";
text += "the mission has too many special explosions defined. \"";
text += Ships[i].ship_name;
text += "\" has therefore lost any special explosion data that was defined for it. ";
text += "\" Either remove special explosions or SEXP variables if you need it to have one ";
MessageBox(NULL, text, "Too many variables!", MB_OK);
}
}
}
// Goober5000 ------------------------------------------------
if (Format_fs2_open != FSO_FORMAT_RETAIL)
{
if (Ships[i].special_hitpoint_index != -1) {
if (optional_string_fred("+Special Hitpoint index:", "$Name:")) {
if (Ships[i].special_hitpoints) {
if (optional_string_fred("+Special Hitpoints:", "$Name:")) {
parse_comments();
} else {
fout("\n+Special Hitpoint index:");
fso_comment_push(";;FSO 3.6.13;;");
fout_version("\n+Special Hitpoints:");
fso_comment_pop();
}
fout(" %d", Ships[i].special_hitpoint_index);
fout(" %d", Ships[i].special_hitpoints);
}
else {
bypass_comment(";;FSO 3.6.13;; +Special Hitpoints:");
}
if (Ships[i].special_shield >= 0) {
if (optional_string_fred("+Special Shield Points:", "$Name:")) {
parse_comments();
} else {
fso_comment_push(";;FSO 3.6.13;;");
fout_version("\n+Special Shield Points:");
fso_comment_pop();
}
fout(" %d", Ships[i].special_shield);
}
else {
bypass_comment(";;FSO 3.6.13;; +Special Shield Points:");
}
}
// -----------------------------------------------------------
@@ -1864,9 +1959,9 @@ int CFred_mission_save::save_common_object_data(object *objp, ship *shipp)
}
// Goober5000
if (Format_fs2_open != FSO_FORMAT_RETAIL && (shipp->special_hitpoint_index != -1))
if (Format_fs2_open != FSO_FORMAT_RETAIL && (shipp->special_hitpoints))
{
temp_max_hull_strength = (float) atoi(Sexp_variables[shipp->special_hitpoint_index+HULL_STRENGTH].text);
temp_max_hull_strength = (float)shipp->special_hitpoints;
}
else
{
+3 -2
View File
@@ -1,6 +1,6 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by FRED.rc
// Microsoft Visual C++ generated include file.
// Used by fred.rc
//
#define IDC_SAVE_DEFAULT_PREFS 3
#define ID_DELETE_VARIABLE 3
@@ -1048,6 +1048,7 @@
#define IDC_SPECIAL_SHIELDS 1555
#define IDC_SPECIAL_HULL 1556
#define IDC_LOADING_SCREEN_BUTTON1024 1557
#define IDC_ENABLE_SPECIAL_SHIELD 1557
#define IDC_LOADING_SCREEN640 1558
#define IDC_TYPE_CAMPAIGN_PERSISTENT 1559
#define IDC_MAX_HULL_REPAIR_VAL 1559
+50 -10
View File
@@ -867,8 +867,9 @@ void sexp_tree::right_clicked(int mode)
case OP_TECH_ADD_INTEL:
case OP_TECH_RESET_TO_DEFAULT:
#endif*/
// unlike the above operators, this one is deprecated
// unlike the above operators, these are deprecated
case OP_HITS_LEFT_SUBSYSTEM:
case OP_CUTSCENES_SHOW_SUBTITLE:
j = Num_op_menus; // don't allow these operators to be visible
break;
}
@@ -904,8 +905,9 @@ void sexp_tree::right_clicked(int mode)
case OP_TECH_ADD_INTEL:
case OP_TECH_RESET_TO_DEFAULT:
#endif*/
// unlike the above operators, this one is deprecated
// unlike the above operators, these are deprecated
case OP_HITS_LEFT_SUBSYSTEM:
case OP_CUTSCENES_SHOW_SUBTITLE:
j = Num_submenus; // don't allow these operators to be visible
break;
}
@@ -1145,7 +1147,7 @@ void sexp_tree::right_clicked(int mode)
}
// modify string or number if (modify_variable)
if ( Operators[op].value == OP_MODIFY_VARIABLE || Operators[op].value == OP_SET_VARIABLE_BY_INDEX ) {
if ( Operators[op].value == OP_MODIFY_VARIABLE ) {
int modify_type = get_modify_variable_type(parent);
if (modify_type == OPF_NUMBER) {
@@ -1154,6 +1156,24 @@ void sexp_tree::right_clicked(int mode)
}
// no change for string type
}
else if ( Operators[op].value == OP_SET_VARIABLE_BY_INDEX ) {
// it depends on which argument we are modifying
// first argument is always a number
if (Replace_count == 0) {
menu.EnableMenuItem(ID_REPLACE_NUMBER, MF_ENABLED);
menu.EnableMenuItem(ID_REPLACE_STRING, MF_GRAYED);
}
// second argument could be anything
else {
int modify_type = get_modify_variable_type(parent);
if (modify_type == OPF_NUMBER) {
menu.EnableMenuItem(ID_REPLACE_NUMBER, MF_ENABLED);
menu.EnableMenuItem(ID_REPLACE_STRING, MF_GRAYED);
}
// no change for string type
}
}
list->destroy();
@@ -2632,6 +2652,7 @@ int sexp_tree::query_default_argument_available(int op, int i)
case OPF_POST_EFFECT:
case OPF_TARGET_PRIORITIES:
case OPF_ARMOR_TYPES:
case OPF_HUD_ELEMENT:
return 1;
case OPF_SHIP:
@@ -3136,20 +3157,27 @@ void get_variable_name_from_sexp_tree_node_text(const char *text, char *var_name
int sexp_tree::get_modify_variable_type(int parent)
{
Assert(parent >= 0);
int sexp_var_index = -1;
Assert(parent >= 0);
int op_const = get_operator_const(tree_nodes[parent].text);
Assert(tree_nodes[parent].child >= 0);
char *node_text = tree_nodes[tree_nodes[parent].child].text;
if ( op_const == OP_MODIFY_VARIABLE ) {
Assert(tree_nodes[parent].child >= 0);
sexp_var_index = get_tree_name_to_sexp_variable_index(tree_nodes[tree_nodes[parent].child].text);
sexp_var_index = get_tree_name_to_sexp_variable_index(node_text);
Assert(sexp_var_index >= 0);
} else if ( op_const == OP_SET_VARIABLE_BY_INDEX ) {
Assert(tree_nodes[parent].child != -1);
if (can_construe_as_integer(tree_nodes[tree_nodes[parent].child].text)) {
sexp_var_index = atoi(tree_nodes[tree_nodes[parent].child].text);
}
else if ( op_const == OP_SET_VARIABLE_BY_INDEX ) {
if (can_construe_as_integer(node_text)) {
sexp_var_index = atoi(node_text);
Assert(sexp_var_index >= 0);
}
else if (strchr(node_text, '(') && strchr(node_text, ')')) {
// the variable index is itself a variable!
return OPF_AMBIGUOUS;
}
} else {
Int3(); // should not be called otherwise
}
@@ -4316,6 +4344,10 @@ sexp_list_item *sexp_tree::get_listing_opf(int opf, int parent_node, int arg_ind
case OPF_POST_EFFECT:
list = get_listing_opf_post_effect();
break;
case OPF_HUD_ELEMENT:
list = get_listing_opf_hud_elements();
break;
default:
@@ -5636,6 +5668,14 @@ sexp_list_item *sexp_tree::get_listing_opf_armor_types()
return head.next;
}
sexp_list_item *sexp_tree::get_listing_opf_hud_elements()
{
sexp_list_item head;
head.add_data("warpout");
return head.next;
}
// Deletes sexp_variable from sexp_tree.
// resets tree to not include given variable, and resets text and type
void sexp_tree::delete_sexp_tree_variable(const char *var_name)
+1
View File
@@ -258,6 +258,7 @@ public:
sexp_list_item *get_listing_opf_persona();
// ---------------------------------------------------------
sexp_list_item *get_listing_opf_post_effect();
sexp_list_item *get_listing_opf_hud_elements();
int m_mode;
int item_index;
+16 -7
View File
@@ -1253,9 +1253,16 @@ int CShipEditorDlg::update_ship(int ship)
if (strlen(m_cargo1)) {
z = string_lookup(m_cargo1, Cargo_names, Num_cargo);
if (z == -1) {
Assert(Num_cargo < MAX_CARGO);
z = Num_cargo++;
strcpy(Cargo_names[z], m_cargo1);
if (Num_cargo < MAX_CARGO) {
z = Num_cargo++;
strcpy(Cargo_names[z], m_cargo1);
}
else {
str.Format("Maximum number of cargo names (%d) reached.\nIgnoring new name.\n", MAX_CARGO);
MessageBox(str, "Error", MB_ICONEXCLAMATION);
z = 0;
m_cargo1 = Cargo_names[z];
}
}
MODIFY(Ships[ship].cargo1, (char)z);
@@ -1314,7 +1321,7 @@ int CShipEditorDlg::update_ship(int ship)
m_arrival_delay.save(&Ships[ship].arrival_delay);
m_departure_delay.save(&Ships[ship].departure_delay);
if (m_arrival_target >= 0) {
z = ((CComboBox *) GetDlgItem(IDC_ARRIVAL_TARGET)) -> GetItemData(m_arrival_target);
z = ((CComboBox *) GetDlgItem(IDC_ARRIVAL_TARGET))->GetItemData(m_arrival_target);
MODIFY(Ships[ship].arrival_anchor, z);
// if the arrival is not hyperspace or docking bay -- force arrival distance to be
@@ -1324,7 +1331,7 @@ int CShipEditorDlg::update_ship(int ship)
if ((Ships[ship].arrival_distance < d) && (Ships[ship].arrival_distance > -d)) {
str.Format("Ship must arrive at least %d meters away from target.\n"
"Value has been reset to this. Use with caution!\r\n"
"Reccomended distance is %d meters.\r\n", d, (int)(2.0f * Objects[Ships[ship].objnum].radius) );
"Recommended distance is %d meters.\r\n", d, (int)(2.0f * Objects[Ships[ship].objnum].radius) );
MessageBox(str);
if (Ships[ship].arrival_distance < 0)
@@ -1336,8 +1343,10 @@ int CShipEditorDlg::update_ship(int ship)
}
}
}
z = ((CComboBox *)GetDlgItem(IDC_DEPARTURE_TARGET))->GetItemData(m_departure_target);
MODIFY(Ships[ship].departure_anchor, z );
if (m_departure_target >= 0) {
z = ((CComboBox *) GetDlgItem(IDC_DEPARTURE_TARGET))->GetItemData(m_departure_target);
MODIFY(Ships[ship].departure_anchor, z );
}
}
if (m_hotkey != -1)
+61 -73
View File
@@ -42,15 +42,15 @@ void ShipSpecialDamage::DoDataExchange(CDataExchange* pDX)
DDX_Check(pDX, IDC_ENABLE_SHOCKWAVE, m_shock_enabled);
DDX_Check(pDX, IDC_ENABLE_SPECIAL_EXP, m_special_exp_enabled);
DDX_Text(pDX, IDC_SPECIAL_INNER_RAD, m_inner_rad);
DDV_MinMaxInt(pDX, m_inner_rad, 10, 10000);
DDV_MinMaxInt(pDX, m_inner_rad, 1, INT_MAX);
DDX_Text(pDX, IDC_SPECIAL_OUTER_RAD, m_outer_rad);
DDV_MinMaxInt(pDX, m_outer_rad, 11, 10000);
DDV_MinMaxInt(pDX, m_outer_rad, 2, INT_MAX);
DDX_Text(pDX, IDC_SPECIAL_DAMAGE, m_damage);
DDV_MinMaxInt(pDX, m_damage, 0, 100000);
DDV_MinMaxInt(pDX, m_damage, 0, INT_MAX);
DDX_Text(pDX, IDC_SPECIAL_SHOCK_SPEED, m_shock_speed);
DDV_MinMaxInt(pDX, m_shock_speed, 10, 10000);
DDV_MinMaxInt(pDX, m_shock_speed, 0, INT_MAX);
DDX_Text(pDX, IDC_SPECIAL_BLAST, m_blast);
DDV_MinMaxInt(pDX, m_blast, 0, 100000);
DDV_MinMaxInt(pDX, m_blast, 0, INT_MAX);
//}}AFX_DATA_MAP
}
@@ -71,7 +71,8 @@ void ShipSpecialDamage::OnEnableShockwave()
UpdateData(TRUE);
// enable/disable shock speed
DoGray();}
DoGray();
}
void ShipSpecialDamage::OnEnableSpecialExp()
{
@@ -89,21 +90,23 @@ BOOL ShipSpecialDamage::OnInitDialog()
// get ship num
object *objp;
m_ship_num = -1;
num_selected_ships = 0;
objp = GET_FIRST(&obj_used_list);
while (objp != END_OF_LIST(&obj_used_list)) {
if ((objp->type == OBJ_START) || (objp->type == OBJ_SHIP)) {
if (objp->flags & OF_MARKED) {
m_ship_num = objp->instance;
break;
m_selected_ships[num_selected_ships] = objp->instance;
num_selected_ships++;
}
}
objp = GET_NEXT(objp);
}
if (Ships[m_ship_num].special_exp_index == -1) {
Assert (Objects[cur_object_index].flags & OF_MARKED);
m_ship_num = Objects[cur_object_index].instance;
if (!(Ships[m_ship_num].use_special_explosion)) {
// get default_table_values
ship_info *sip;
sip = &Ship_info[Ships[m_ship_num].ship_info_index];
@@ -116,19 +119,23 @@ BOOL ShipSpecialDamage::OnInitDialog()
m_shock_speed = (int) sip->shockwave.speed;
m_special_exp_enabled = FALSE;
if (m_inner_rad < 10) m_inner_rad = 10;
if (m_outer_rad < 11) m_outer_rad = 11;
if (m_shock_speed < 10) m_shock_speed = 10;
} else {
int index = Ships[m_ship_num].special_exp_index;
Assert( (index > 0) && (index < MAX_SEXP_VARIABLES-(BLOCK_EXP_SIZE-1)) );
m_inner_rad = atoi(Sexp_variables[index++].text);
m_outer_rad = atoi(Sexp_variables[index++].text);
m_damage = atoi(Sexp_variables[index++].text);
m_blast = atoi(Sexp_variables[index++].text);
m_shock_enabled = atoi(Sexp_variables[index++].text);
m_shock_speed = atoi(Sexp_variables[index++].text);
if (m_inner_rad < 1) {
m_inner_rad = 1;
}
if (m_outer_rad < 2) {
m_outer_rad = 2;
}
if (m_shock_speed < 1) {
m_shock_speed = 1;
}
}
else {
m_inner_rad = Ships[m_ship_num].special_exp_inner;
m_outer_rad = Ships[m_ship_num].special_exp_outer;
m_damage = Ships[m_ship_num].special_exp_damage;
m_blast = Ships[m_ship_num].special_exp_blast;
m_shock_enabled = Ships[m_ship_num].use_shockwave;
m_shock_speed = Ships[m_ship_num].special_exp_shockwave_speed;
m_special_exp_enabled = TRUE;
}
@@ -164,16 +171,15 @@ void ShipSpecialDamage::OnOK()
{
UpdateData(TRUE);
object *objp;
int i;
objp = GET_FIRST(&obj_used_list);
while (objp != END_OF_LIST(&obj_used_list)) {
if ((objp->type == OBJ_START) || (objp->type == OBJ_SHIP)) {
if (objp->flags & OF_MARKED)
update_ship(objp->instance);
}
if (m_inner_rad > m_outer_rad) {
MessageBox("Inner radius must be less than outer radius");
return;
}
objp = GET_NEXT(objp);
for ( i = 0; i < num_selected_ships; i++ ) {
update_ship(m_selected_ships[i]);
}
CDialog::OnOK();
@@ -182,51 +188,33 @@ void ShipSpecialDamage::OnOK()
void ShipSpecialDamage::update_ship(int shipnum)
{
ship *shipp = &Ships[shipnum];
// set to update
set_modified();
// TODO: Add extra validation here
if (m_special_exp_enabled) {
int start;
if (m_inner_rad > m_outer_rad) {
MessageBox("Inner radius must be less than outer radius");
return;
}
if (shipp->special_exp_index == -1) {
// get free sexp_variables
start = sexp_variable_allocate_block(shipp->ship_name, SEXP_VARIABLE_BLOCK | SEXP_VARIABLE_BLOCK_EXP);
if (start == -1) {
MessageBox("Unable to allocate storage, try deleting Sexp variables");
return;
} else {
shipp->special_exp_index = start;
}
} else {
start = shipp->special_exp_index;
}
// set to update
set_modified();
// set em
sprintf(Sexp_variables[start+INNER_RAD].text, "%d", m_inner_rad);
sprintf(Sexp_variables[start+OUTER_RAD].text, "%d", m_outer_rad);
sprintf(Sexp_variables[start+DAMAGE].text, "%d", m_damage);
sprintf(Sexp_variables[start+BLAST].text, "%d", m_blast);
sprintf(Sexp_variables[start+PROPAGATE].text, "%d", m_shock_enabled);
sprintf(Sexp_variables[start+SHOCK_SPEED].text, "%d", m_shock_speed);
} else {
if (shipp->special_exp_index != -1) {
// set to update
set_modified();
// free block
sexp_variable_block_free(shipp->ship_name, Ships[m_ship_num].special_exp_index, SEXP_VARIABLE_BLOCK | SEXP_VARIABLE_BLOCK_EXP);
// set index to no exp block
shipp->special_exp_index = -1;
shipp->use_special_explosion = true;
shipp->special_exp_inner = m_inner_rad;
shipp->special_exp_outer = m_outer_rad;
shipp->special_exp_damage = m_damage;
shipp->special_exp_blast = m_blast;
shipp->use_shockwave = (m_shock_enabled ? 1:0) ;
if (m_shock_speed) {
if (m_shock_speed < 1) {
m_shock_speed = 1;
MessageBox("Shockwave speed must be defined! Setting this to 1 now");
}
shipp->special_exp_shockwave_speed = m_shock_speed;
}
} else {
shipp->use_special_explosion = false;
shipp->special_exp_inner = -1;
shipp->special_exp_outer = -1;
shipp->special_exp_damage = -1;
shipp->special_exp_blast = -1;
shipp->use_shockwave = false;
shipp->special_exp_shockwave_speed = -1;
}
}
+7 -1
View File
@@ -30,13 +30,19 @@ public:
//{{AFX_DATA(ShipSpecialDamage)
enum { IDD = IDD_SPECIAL_DAMAGE };
int m_shock_enabled;
BOOL m_special_exp_enabled;
BOOL m_special_exp_enabled;
int m_inner_rad;
int m_outer_rad;
int m_damage;
int m_shock_speed;
int m_blast;
int m_ship_num;
private:
// variables to handle selection of multiple ships
int m_selected_ships[MAX_SHIPS];
int num_selected_ships;
//}}AFX_DATA
+96 -61
View File
@@ -31,10 +31,11 @@ void ShipSpecialHitpoints::DoDataExchange(CDataExchange* pDX)
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(ShipSpecialHitpoints)
DDX_Check(pDX, IDC_ENABLE_SPECIAL_HITPOINTS, m_special_hitpoints_enabled);
DDX_Check(pDX, IDC_ENABLE_SPECIAL_SHIELD, m_special_shield_enabled);
DDX_Text(pDX, IDC_SPECIAL_SHIELDS, m_shields);
DDV_MinMaxInt(pDX, m_shields, 0, INT_MAX);
DDV_MinMaxInt(pDX, m_shields, -1, INT_MAX);
DDX_Text(pDX, IDC_SPECIAL_HULL, m_hull);
DDV_MinMaxInt(pDX, m_hull, 10, INT_MAX);
DDV_MinMaxInt(pDX, m_hull, 1, INT_MAX);
//}}AFX_DATA_MAP
}
@@ -42,6 +43,7 @@ void ShipSpecialHitpoints::DoDataExchange(CDataExchange* pDX)
BEGIN_MESSAGE_MAP(ShipSpecialHitpoints, CDialog)
//{{AFX_MSG_MAP(ShipSpecialHitpoints)
ON_BN_CLICKED(IDC_ENABLE_SPECIAL_HITPOINTS, OnEnableSpecialHitpoints)
ON_BN_CLICKED(IDC_ENABLE_SPECIAL_SHIELD, OnEnableSpecialShieldpoints)
ON_BN_CLICKED(ID_OK, OnOk)
ON_BN_CLICKED(ID_CANCEL, OnCancel)
//}}AFX_MSG_MAP
@@ -58,46 +60,70 @@ void ShipSpecialHitpoints::OnEnableSpecialHitpoints()
DoGray();
}
void ShipSpecialHitpoints::OnEnableSpecialShieldpoints()
{
// TODO: Add your control notification handler code here
UpdateData(TRUE);
DoGray();
}
BOOL ShipSpecialHitpoints::OnInitDialog()
{
// get ship num
object *objp;
m_ship_num = -1;
num_selected_ships = 0;
objp = GET_FIRST(&obj_used_list);
while (objp != END_OF_LIST(&obj_used_list)) {
if ((objp->type == OBJ_START) || (objp->type == OBJ_SHIP)) {
if (objp->flags & OF_MARKED) {
m_ship_num = objp->instance;
break;
m_selected_ships[num_selected_ships] = objp->instance;
num_selected_ships++;
}
}
objp = GET_NEXT(objp);
}
if (Ships[m_ship_num].special_hitpoint_index == -1)
{
Assert(num_selected_ships);
Assert (Objects[cur_object_index].flags & OF_MARKED);
m_ship_num = Objects[cur_object_index].instance;
// get the details from the first ship
//hull
if (Ships[m_ship_num].special_hitpoints) {
m_hull = Ships[m_ship_num].special_hitpoints;
m_special_hitpoints_enabled = TRUE;
}
else {
// get default_table_values
ship_info *sip;
sip = &Ship_info[Ships[m_ship_num].ship_info_index];
m_hull = (int)sip->max_hull_strength;
m_special_hitpoints_enabled = FALSE;
if (m_hull < 1) m_hull = 10;
}
//shields
if (Ships[m_ship_num].special_shield > 0){
m_shields = Ships[m_ship_num].special_shield;
m_special_shield_enabled = TRUE;
}
else {
// get default_table_values
ship_info *sip;
sip = &Ship_info[Ships[m_ship_num].ship_info_index];
m_shields = (int)sip->max_shield_strength;
m_hull = (int)sip->max_hull_strength;
m_special_hitpoints_enabled = FALSE;
m_special_shield_enabled = FALSE;
if (m_shields < 0) m_shields = 0;
if (m_hull < 10) m_hull = 10;
} else {
int index = Ships[m_ship_num].special_hitpoint_index;
// Assert( (index > 0) && (index < MAX_SEXP_VARIABLES-(BLOCK_HITPOINT_SIZE-1)) );
m_shields = atoi(Sexp_variables[index++].text);
m_hull = atoi(Sexp_variables[index++].text);
m_special_hitpoints_enabled = TRUE;
}
if (m_shields < 0) {
m_shields = 0;
}
}
CDialog::OnInitDialog();
@@ -110,7 +136,7 @@ BOOL ShipSpecialHitpoints::OnInitDialog()
void ShipSpecialHitpoints::DoGray()
{
GetDlgItem(IDC_SPECIAL_SHIELDS)->EnableWindow(m_special_hitpoints_enabled);
GetDlgItem(IDC_SPECIAL_SHIELDS)->EnableWindow(m_special_shield_enabled);
GetDlgItem(IDC_SPECIAL_HULL)->EnableWindow(m_special_hitpoints_enabled);
}
@@ -124,6 +150,8 @@ void ShipSpecialHitpoints::OnCancel()
void ShipSpecialHitpoints::OnOk()
{
float temp_max_hull_strength;
int new_shield_strength, new_hull_strength;
int i;
UpdateData(TRUE);
@@ -131,58 +159,65 @@ void ShipSpecialHitpoints::OnOk()
if (m_special_hitpoints_enabled) {
// Don't update anything if the hull strength is invalid
if (m_hull < 10)
{
if (m_hull < 1) {
return;
}
int start;
if (Ships[m_ship_num].special_hitpoint_index == -1) {
// get free sexp_variables
start = sexp_variable_allocate_block(Ships[m_ship_num].ship_name, SEXP_VARIABLE_BLOCK | SEXP_VARIABLE_BLOCK_HIT);
if (start == -1) {
MessageBox("Unable to allocate storage, try deleting Sexp variables");
return;
} else {
Ships[m_ship_num].special_hitpoint_index = start;
}
} else {
start = Ships[m_ship_num].special_hitpoint_index;
}
// set to update
set_modified();
// set em
sprintf(Sexp_variables[start+SHIELD_STRENGTH].text, "%d", m_shields);
sprintf(Sexp_variables[start+HULL_STRENGTH].text, "%d", m_hull);
new_hull_strength = m_hull;
//Ships[m_ship_num].special_hitpoints = m_hull;
} else {
if (Ships[m_ship_num].special_hitpoint_index != -1) {
// set to update
set_modified();
}
else {
// set to update
set_modified();
// free block
sexp_variable_block_free(Ships[m_ship_num].ship_name, Ships[m_ship_num].special_hitpoint_index, SEXP_VARIABLE_BLOCK | SEXP_VARIABLE_BLOCK_HIT);
new_hull_strength = 0;
}
// set index to no hit block
Ships[m_ship_num].special_hitpoint_index = -1;
if (m_special_shield_enabled) {
// Don't update anything if the hull strength is invalid
if (m_shields < 0) {
return;
}
// set to update
set_modified();
new_shield_strength = m_shields;
//Ships[m_ship_num].special_shield = m_shields;
}
else {
// set to update
set_modified();
new_shield_strength = -1;
}
// calc kamikaze stuff
if (Ships[m_ship_num].special_hitpoint_index != -1)
{
temp_max_hull_strength = (float) atoi(Sexp_variables[Ships[m_ship_num].special_hitpoint_index+HULL_STRENGTH].text);
}
else
{
temp_max_hull_strength = Ship_info[Ships[m_ship_num].ship_info_index].max_hull_strength;
for ( i=0; i<num_selected_ships; i++) {
// set the special hitpoints/shield
Ships[m_selected_ships[i]].special_hitpoints = new_hull_strength;
Ships[m_selected_ships[i]].special_shield = new_shield_strength;
// calc kamikaze stuff
if (Ships[m_selected_ships[i]].special_hitpoints)
{
temp_max_hull_strength = (float)Ships[m_selected_ships[i]].special_hitpoints;
}
else
{
temp_max_hull_strength = Ship_info[Ships[m_selected_ships[i]].ship_info_index].max_hull_strength;
}
Ai_info[Ships[m_selected_ships[i]].ai_index].kamikaze_damage = min(1000.0f, 200.0f + (temp_max_hull_strength / 4.0f));
}
Ai_info[Ships[m_ship_num].ai_index].kamikaze_damage = min(1000.0f, 200.0f + (temp_max_hull_strength / 4.0f));
CDialog::OnOK();
}
+7 -1
View File
@@ -23,11 +23,16 @@ public:
//{{AFX_DATA(ShipSpecialHitpoints)
enum { IDD = IDD_SPECIAL_HITPOINTS };
BOOL m_special_hitpoints_enabled;
BOOL m_special_shield_enabled;
int m_shields;
int m_hull;
int m_ship_num;
//}}AFX_DATA
private:
// variables to handle selection of multiple ships
int m_selected_ships[MAX_SHIPS];
int num_selected_ships;
int m_ship_num;
// Overrides
// ClassWizard generated virtual function overrides
@@ -42,6 +47,7 @@ protected:
// Generated message map functions
//{{AFX_MSG(ShipSpecialHitpoints)
afx_msg void OnEnableSpecialHitpoints();
afx_msg void OnEnableSpecialShieldpoints();
virtual BOOL OnInitDialog();
afx_msg void DoGray();
virtual void OnCancel();
+6 -5
View File
@@ -778,7 +778,7 @@ void wing_editor::update_data_safe()
MODIFY(Wings[cur_wing].wave_delay_max, m_arrival_delay_max);
MODIFY(Wings[cur_wing].arrival_distance, m_arrival_dist);
if (m_arrival_target >= 0) {
i = ((CComboBox *) GetDlgItem(IDC_ARRIVAL_TARGET)) -> GetItemData(m_arrival_target);
i = ((CComboBox *) GetDlgItem(IDC_ARRIVAL_TARGET))->GetItemData(m_arrival_target);
MODIFY(Wings[cur_wing].arrival_anchor, i);
// when arriving near or in front of a ship, be sure that we are far enough away from it!!!
@@ -788,7 +788,7 @@ void wing_editor::update_data_safe()
if (!bypass_errors) {
sprintf(buf, "Ship must arrive at least %d meters away from target.\n"
"Value has been reset to this. Use with caution!\r\n"
"Reccomended distance is %d meters.\r\n", d, (int)(2.0f * Objects[Ships[i].objnum].radius) );
"Recommended distance is %d meters.\r\n", d, (int)(2.0f * Objects[Ships[i].objnum].radius) );
MessageBox(buf);
}
@@ -802,9 +802,10 @@ void wing_editor::update_data_safe()
}
}
}
i = ((CComboBox*)GetDlgItem(IDC_DEPARTURE_TARGET))->GetItemData(m_departure_target);
MODIFY(Wings[cur_wing].departure_anchor, i);
if (m_departure_target >= 0) {
i = ((CComboBox *) GetDlgItem(IDC_DEPARTURE_TARGET))->GetItemData(m_departure_target);
MODIFY(Wings[cur_wing].departure_anchor, i);
}
MODIFY(Wings[cur_wing].departure_delay, m_departure_delay);
hotkey = m_hotkey - 1;
+38 -9
View File
@@ -823,6 +823,7 @@ void game_sunspot_process(float frametime)
Sun_drew = 0;
} else {
Sun_spot_goal = 0.0f;
if ( Sun_drew ) {
// check sunspots for all suns
n_lights = light_get_global_count();
@@ -845,14 +846,10 @@ void game_sunspot_process(float frametime)
// draw the glow for this sun
stars_draw_sun_glow(idx);
} else {
Sun_spot_goal = 0.0f;
}
}
Sun_drew = 0;
} else {
Sun_spot_goal = 0.0f;
}
}
@@ -6211,11 +6208,17 @@ void game_leave_state( int old_state, int new_state )
case GS_STATE_DEATH_DIED:
Game_mode &= ~GM_DEAD_DIED;
// early end while respawning or blowing up in a multiplayer game
if((Game_mode & GM_MULTIPLAYER) && ((new_state == GS_STATE_DEBRIEF) || (new_state == GS_STATE_MULTI_DOGFIGHT_DEBRIEF)) ){
game_stop_time();
freespace_stop_mission();
if ( !(Game_mode & GM_MULTIPLAYER) ) {
if ( end_mission && (new_state == GS_STATE_DEBRIEF) ) {
freespace_stop_mission();
}
} else {
// early end while respawning or blowing up in a multiplayer game
if ( (new_state == GS_STATE_DEBRIEF) || (new_state == GS_STATE_MULTI_DOGFIGHT_DEBRIEF) ) {
game_stop_time();
freespace_stop_mission();
}
}
break;
@@ -6536,6 +6539,32 @@ void game_enter_state( int old_state, int new_state )
//Game_time_compression = F1_0;
}
/* game could be comming from a restart (rather than first start)
so make sure that we zero the hud gauge overrides (Sexp_hud_*)
\sa sexp_hud_display_gauge*/
if ( (old_state == GS_STATE_GAME_PLAY)
|| (old_state == GS_STATE_BRIEFING)
|| (old_state == GS_STATE_DEBRIEF)
|| (old_state == GS_STATE_SHIP_SELECT)
|| (old_state == GS_STATE_WEAPON_SELECT)
|| (old_state == GS_STATE_RED_ALERT) )
{
Sexp_hud_display_warpout = 0;
}
/* game could be comming from a restart (rather than first start)
so make sure that we zero the hud gauge overrides (Sexp_hud_*)
\sa sexp_hud_display_gauge*/
if ( (old_state == GS_STATE_GAME_PLAY)
|| (old_state == GS_STATE_BRIEFING)
|| (old_state == GS_STATE_DEBRIEF)
|| (old_state == GS_STATE_SHIP_SELECT)
|| (old_state == GS_STATE_WEAPON_SELECT)
|| (old_state == GS_STATE_RED_ALERT) )
{
Sexp_hud_display_warpout = 0;
}
// coming from the gameplay state or the main menu, we might need to load the mission
if ( (Game_mode & GM_NORMAL) && ((old_state == GS_STATE_MAIN_MENU) || (old_state == GS_STATE_GAME_PLAY) || (old_state == GS_STATE_DEATH_BLEW_UP)) ) {
if ( !game_start_mission() ) // this should put us into a new state.
+4 -4
View File
@@ -336,8 +336,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 3,6,11,0000
PRODUCTVERSION 3,6,11,0000
FILEVERSION 3,6,12,0
PRODUCTVERSION 3,6,12,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -354,12 +354,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "Volition Inc."
VALUE "FileDescription", "FreeSpace 2 Open"
VALUE "FileVersion", "3.6.11.0000"
VALUE "FileVersion", "3.6.12.0"
VALUE "InternalName", "FreeSpace 2 Open"
VALUE "LegalCopyright", "Copyright © 1998"
VALUE "OriginalFilename", "fs2.exe"
VALUE "ProductName", "FreeSpace 2 Open"
VALUE "ProductVersion", "3.6.11"
VALUE "ProductVersion", "3.6.12.0"
END
END
BLOCK "VarFileInfo"
+75 -38
View File
@@ -66,7 +66,8 @@ static bool do_full_packet = true;
static int Local_timeout = -1;
static int Next_gameserver_update = -1;
static int Last_pong = -1;
static int Ping_timestamp = -1;
static int Last_activity = -1;
static int Login_retry_time = -1;
static SCP_vector<file_record> FS2NetD_file_list;
@@ -92,7 +93,8 @@ static void fs2netd_reset_state()
do_full_packet = true;
Local_timeout = -1;
Next_gameserver_update = -1;
Last_pong = -1;
Last_activity = -1;
Ping_timestamp = -1;
Duplicate_login_detected = false;
Login_retry_time = -1;
}
@@ -167,19 +169,38 @@ void fs2netd_reset_connection()
FS2NetD_Disconnect();
// wait a little to allow for the port to clear
Sleep(250);
fs2netd_reset_state();
// wait a little to allow for the port to clear
Sleep(500);
// try to reinit the server connection
fs2netd_login();
if (reset_gameserver) {
Sleep(250);
if ( reset_gameserver && fs2netd_is_online() ) {
fs2netd_gameserver_start();
}
}
void fs2netd_disconnect()
{
if ( !Is_connected ) {
return;
}
if (Net_player->flags & NETINFO_FLAG_MT_CONNECTED) {
fs2netd_gameserver_disconnect();
}
FS2NetD_Disconnect();
fs2netd_reset_state();
Sleep(500);
}
static int fs2netd_connect_do()
{
int retval = FS2NetD_ConnectToServer(Multi_options_g.game_tracker_ip, Multi_options_g.tracker_port);
@@ -307,6 +328,10 @@ int fs2netd_login_do()
return 2;
}
if (do_full_packet) {
ml_printf("FS2NetD MSG: Requesting login pilot stats for '%s' ...", Players[Player_num].callsign);
}
int rescode = FS2NetD_GetPlayerData(Players[Player_num].callsign, &Players[Player_num], true, do_full_packet);
do_full_packet = false;
@@ -469,6 +494,9 @@ bool fs2netd_login()
if (retval) {
Logged_in = true;
sprintf(Multi_tracker_id_string, "%d", Multi_tracker_id);
} else {
// clear and reset connection, for the next time we try...
fs2netd_disconnect();
}
if (Is_standalone) {
@@ -480,11 +508,13 @@ bool fs2netd_login()
static void fs2netd_handle_ping()
{
static int Next_ping = -1;
bool reset = false;
static int CONN_check = -1;
// if we didn't get a pong within 30 seconds of a ping then assume that the
// server connection must of have dropped or is otherwise unresponsive
if ( (Ping_timestamp != -1) && ((timer_get_seconds() - Ping_timestamp) > 30) ) {
Ping_timestamp = -1;
// if we didn't get a PONG within 4 minutes the server connection must have dropped
if ( (Last_pong != -1) && ((Next_ping - Last_pong) > 240) ) {
ml_string("FS2NetD WARNING: Lost connection to server!");
fs2netd_reset_connection();
@@ -496,11 +526,11 @@ static void fs2netd_handle_ping()
}
ml_string("FS2NetD ERROR: Lost connection to the FS2NetD server!");
FS2NetD_Disconnect();
fs2netd_reset_state();
ml_string("FS2NetD MSG: Will attempt an automatic reconnect to server in 30 minutes...");
Login_retry_time = timer_get_seconds() + 1800;
fs2netd_disconnect();
ml_string("FS2NetD MSG: Will attempt an automatic reconnect to server in 5 minutes...");
Login_retry_time = timer_get_seconds() + 300;
return;
} else {
@@ -508,24 +538,24 @@ static void fs2netd_handle_ping()
}
}
// send out ping every 90 seconds
if ( (Next_ping == -1) || (timer_get_seconds() >= Next_ping) ) {
// if we have seen a long period of time between pings then reset the pong time too
if ( (timer_get_seconds() - Next_ping) > 120 ) {
reset = true;
}
Next_ping = timer_get_seconds() + 90;
// we go ahead and set the initial Last_pong here, even though we haven't gotten a pong yet
if ( (Last_pong == -1) || reset ) {
Last_pong = Next_ping;
reset = false;
}
// send out a ping after 5 minutes of no other activity to make sure the server
// is still responding (probably not though)
if ( (Ping_timestamp == -1) && (timer_get_seconds() >= (Last_activity + 300)) ) {
Ping_timestamp = timer_get_seconds();
FS2NetD_Ping();
ml_string("FS2NetD sent PING");
// also send out a ID check to keep our login verified
if (Last_activity < 0) {
Last_activity = timer_get_seconds();
}
}
// check for a valid connection (SID, duplicate login, etc.)
if ( (CONN_check == -1) || (timer_get_seconds() >= CONN_check) ) {
// every 3 minutes
CONN_check = timer_get_seconds() + 180;
// session ID check
if ( FS2NetD_CheckValidID() < 0 ) {
ml_string("FS2NetD WARNING: Unable to validate login!");
fs2netd_reset_connection();
@@ -538,11 +568,11 @@ static void fs2netd_handle_ping()
}
ml_string("FS2NetD ERROR: Lost connection to the FS2NetD server!");
FS2NetD_Disconnect();
fs2netd_reset_state();
ml_string("FS2NetD MSG: Will attempt an automatic reconnect to server in 30 minutes...");
Login_retry_time = timer_get_seconds() + 1800;
fs2netd_disconnect();
ml_string("FS2NetD MSG: Will attempt an automatic reconnect to server in 5 minutes...");
Login_retry_time = timer_get_seconds() + 300;
return;
} else {
@@ -555,7 +585,7 @@ static void fs2netd_handle_ping()
FS2NetD_CheckDuplicateLogin();
}
ml_string("FS2NetD sent PING/IDENT");
ml_string("FS2NetD sent IDENT check");
}
}
@@ -584,6 +614,8 @@ static void fs2netd_handle_messages()
return;
}
Last_activity = timer_get_seconds();
buffer_offset = 0;
while (buffer_offset+BASE_PACKET_SIZE <= bytes_read) {
@@ -612,7 +644,8 @@ static void fs2netd_handle_messages()
ml_printf("FS2NetD PONG: %d ms", timer_get_milliseconds() - itemp);
Last_pong = timer_get_seconds();
// reset timestamp, since the ping was successful
Ping_timestamp = -1;
break;
}
@@ -739,8 +772,8 @@ void fs2netd_do_frame()
fs2netd_login();
if ( !Logged_in ) {
// bah! try again in another 30 minutes
Login_retry_time = timer_get_seconds() + 1800;
// bah! try again in another 5 minutes
Login_retry_time = timer_get_seconds() + 300;
} else {
Login_retry_time = -1;
}
@@ -1550,6 +1583,10 @@ int fs2netd_get_pilot_info(const char *callsign, player *out_plr, bool first_cal
In_process = true;
}
if (first_call) {
ml_printf("FS2NetD MSG: Requesting pilot stats for '%s' ...", callsign);
}
int rc = FS2NetD_GetPlayerData(callsign, &new_plr, false, first_call);
// some sort of failure
+1
View File
@@ -47,6 +47,7 @@ extern tracker_game_data Multi_tracker_game_data;
bool fs2netd_is_online();
void fs2netd_reset_connection();
void fs2netd_disconnect();
void fs2netd_close();
+2 -2
View File
@@ -265,8 +265,8 @@ int FS2NetD_GetPlayerData(const char *player_name, player *pl, bool can_create,
PXO_GET_DATA( reply_type );
// if we weren't retrieved or created then bail out now
if (reply_type > 1) {
// if we weren't retrieved then bail out now
if (reply_type != 0) {
return (int)reply_type;
}
+35 -24
View File
@@ -480,29 +480,6 @@ void event_music_do_frame()
}
}
// We want to go back to NRML track music if all the hostiles have been
// destroyed, and we are still playing the battle music
if (Current_pattern == SONG_BTTL_1 || Current_pattern == SONG_BTTL_2 || Current_pattern == SONG_BTTL_3)
{
if (timestamp_elapsed(Battle_over_timestamp) && Event_Music_battle_started == 1)
{
if (hostile_ships_present() == FALSE)
{
if (Patterns[Current_pattern].next_pattern != SONG_VICT_2)
{
// Goober5000
if (Soundtracks[Current_soundtrack_num].flags & EMF_CYCLE_FS1)
Patterns[Current_pattern].next_pattern = SONG_NRML_3;
else
Patterns[Current_pattern].next_pattern = SONG_NRML_1;
Patterns[Current_pattern].force_pattern = TRUE;
Event_Music_battle_started = 0;
}
}
}
}
if (Event_Music_battle_started == 0) {
if (Current_pattern == SONG_NRML_1 || Current_pattern == SONG_NRML_2 || Current_pattern == SONG_NRML_3 ) {
if (timestamp_elapsed(Check_for_battle_music)) {
@@ -512,6 +489,39 @@ void event_music_do_frame()
Patterns[Current_pattern].force_pattern = TRUE;
}
}
} else if (Current_pattern == SONG_BTTL_1 || Current_pattern == SONG_BTTL_2 || Current_pattern == SONG_BTTL_3) {
if (timestamp_elapsed(Battle_over_timestamp)) {
Battle_over_timestamp = timestamp(BATTLE_CHECK_INTERVAL);
if (hostile_ships_present() == FALSE) {
Patterns[Current_pattern].force_pattern = TRUE;
if (Soundtracks[Current_soundtrack_num].flags & EMF_CYCLE_FS1) {
Patterns[Current_pattern].next_pattern = SONG_NRML_3;
} else {
Patterns[Current_pattern].next_pattern = SONG_NRML_1;
}
}
}
}
} else {
// We want to go back to NRML track music if all the hostiles have been
// destroyed, and we are still playing the battle music
if (Current_pattern == SONG_BTTL_1 || Current_pattern == SONG_BTTL_2 || Current_pattern == SONG_BTTL_3) {
if (timestamp_elapsed(Battle_over_timestamp)) {
if (hostile_ships_present() == FALSE) {
if (Patterns[Current_pattern].next_pattern != SONG_VICT_2) {
// Goober5000
if (Soundtracks[Current_soundtrack_num].flags & EMF_CYCLE_FS1) {
Patterns[Current_pattern].next_pattern = SONG_NRML_3;
} else {
Patterns[Current_pattern].next_pattern = SONG_NRML_1;
}
Patterns[Current_pattern].force_pattern = TRUE;
Event_Music_battle_started = 0;
}
}
}
}
}
@@ -1361,7 +1371,8 @@ void parse_menumusic()
if ( cf_exists_full_ext(Spooled_music[idx].filename, CF_TYPE_MUSIC, NUM_EXT, exts) )
Spooled_music[idx].flags |= SMF_VALID;
Num_music_files++;
if (!nocreate)
Num_music_files++;
}
// -------------------------------------------------------------------------------------------------
+84 -68
View File
@@ -13,14 +13,13 @@
#include "localization/localize.h"
#include "species_defs/species_defs.h"
#include "parse/parselo.h"
#include <limits.h>
int Num_game_sounds = 0;
game_snd *Snds = NULL;
SCP_vector<game_snd> Snds;
int Num_iface_sounds = 0;
game_snd *Snds_iface = NULL;
int *Snds_iface_handle = NULL;
SCP_vector<game_snd> Snds_iface;
SCP_vector<int> Snds_iface_handle;
#define GAME_SND 0
#define IFACE_SND 1
@@ -38,7 +37,8 @@ void gamesnd_play_iface(int n)
//WMC - now ignores file extension.
int gamesnd_get_by_name(char* name)
{
for(int i = 0; i < Num_game_sounds; i++)
Assert( Snds.size() <= INT_MAX );
for(int i = 0; i < (int)Snds.size(); i++)
{
char *p = strrchr( Snds[i].filename, '.' );
if(p == NULL)
@@ -56,6 +56,31 @@ int gamesnd_get_by_name(char* name)
return -1;
}
int gamesnd_get_by_tbl_index(int index)
{
Assert( Snds.size() <= INT_MAX );
for(int i = 0; i < (int)Snds.size(); i++) {
if ( Snds[i].sig == index )
{
return i;
}
}
return -1;
}
int gamesnd_get_by_iface_tbl_index(int index)
{
Assert( Snds_iface.size() <= INT_MAX );
Assert( Snds_iface.size() == Snds_iface_handle.size() );
for(int i = 0; i < (int)Snds_iface.size(); i++) {
if ( Snds_iface[i].sig == index )
{
return i;
}
}
return -1;
}
//Takes a tag, a sound index destination, and the object name being parsed
//tag and object_name are mostly so that we can debug stuff
//This also means you shouldn't use optional_string or required_string,
@@ -73,12 +98,18 @@ void parse_sound(char* tag, int *idx_dest, char* object_name)
if(idx != -1)
(*idx_dest) = idx;
else
(*idx_dest) = atoi(buf);
//Ensure sound is in range
if((*idx_dest) < -1 || (*idx_dest) >= Num_game_sounds)
{
Warning(LOCATION, "%s sound index out of range on '%s'. Must be between 0 and %d. Forcing to -1 (Nonexistant sound).\n", tag, object_name, Num_game_sounds);
idx = gamesnd_get_by_tbl_index(atoi(buf));
if (idx != -1)
(*idx_dest) = idx;
}
Assert( Snds.size() <= INT_MAX );
//Ensure sound is in range
if((*idx_dest) < -1 || (*idx_dest) >= (int)Snds.size())
{
(*idx_dest) = -1;
Warning(LOCATION, "%s sound index out of range on '%s'. Must be between 0 and %d. Forcing to -1 (Nonexistant sound).\n", tag, object_name, Snds.size());
}
}
}
@@ -96,7 +127,8 @@ void gamesnd_preload_common_sounds()
if ( !Sound_enabled )
return;
for ( i = 0; i < Num_game_sounds; i++ ) {
Assert( Snds.size() <= INT_MAX );
for ( i = 0; i < (int)Snds.size(); i++ ) {
gs = &Snds[i];
if ( gs->filename[0] != 0 && strnicmp(gs->filename, NOX("none.wav"), 4) ) {
if ( gs->preload ) {
@@ -120,7 +152,8 @@ void gamesnd_load_gameplay_sounds()
if ( !Sound_enabled )
return;
for ( i = 0; i < Num_game_sounds; i++ ) {
Assert( Snds.size() <= INT_MAX );
for ( i = 0; i < (int)Snds.size(); i++ ) {
gs = &Snds[i];
if ( gs->filename[0] != 0 && strnicmp(gs->filename, NOX("none.wav"), 4) ) {
if ( !gs->preload ) { // don't try to load anything that's already preloaded
@@ -141,7 +174,8 @@ void gamesnd_unload_gameplay_sounds()
int i;
game_snd *gs;
for ( i = 0; i < Num_game_sounds; i++ ) {
Assert( Snds.size() <= INT_MAX );
for ( i = 0; i < (int)Snds.size(); i++ ) {
gs = &Snds[i];
if ( gs->id != -1 ) {
snd_unload( gs->id );
@@ -163,7 +197,8 @@ void gamesnd_load_interface_sounds()
if ( !Sound_enabled )
return;
for ( i = 0; i < Num_iface_sounds; i++ ) {
Assert( Snds_iface.size() < INT_MAX );
for ( i = 0; i < (int)Snds_iface.size(); i++ ) {
gs = &Snds_iface[i];
if ( gs->filename[0] != 0 && strnicmp(gs->filename, NOX("none.wav"), 4) ) {
gs->id = snd_load(gs);
@@ -181,7 +216,8 @@ void gamesnd_unload_interface_sounds()
int i;
game_snd *gs;
for ( i = 0; i < Num_iface_sounds; i++ ) {
Assert( Snds_iface.size() < INT_MAX );
for ( i = 0; i < (int)Snds_iface.size(); i++ ) {
gs = &Snds_iface[i];
if ( gs->id != -1 ) {
snd_unload( gs->id );
@@ -255,7 +291,8 @@ void gamesnd_parse_soundstbl()
// Parse the gameplay sounds section
required_string("#Game Sounds Start");
while (required_string_either("#Game Sounds End","$Name:")) {
Assert( num_game_sounds < Num_game_sounds);
Assert( Snds.size() < INT_MAX );
Assert( num_game_sounds < (int)Snds.size() );
gamesnd_parse_line( &Snds[num_game_sounds], "$Name:" );
num_game_sounds++;
gamesnd_add_sound_slot( GAME_SND, num_game_sounds );
@@ -265,7 +302,8 @@ void gamesnd_parse_soundstbl()
// Parse the interface sounds section
required_string("#Interface Sounds Start");
while (required_string_either("#Interface Sounds End","$Name:")) {
Assert( num_iface_sounds < Num_iface_sounds);
Assert( Snds_iface_handle.size() < INT_MAX );
Assert( num_iface_sounds < (int)Snds_iface.size() );
gamesnd_parse_line(&Snds_iface[num_iface_sounds], "$Name:");
num_iface_sounds++;
gamesnd_add_sound_slot( IFACE_SND, num_iface_sounds );
@@ -326,6 +364,7 @@ void gamesnd_parse_soundstbl()
//
void gamesnd_init_struct(game_snd *gs)
{
gs->sig = -1;
gs->filename[0] = 0;
gs->id = -1;
gs->id_sig = -1;
@@ -341,33 +380,26 @@ void gamesnd_init_sounds()
{
int i;
if (Snds == NULL) {
Snds = (game_snd *) vm_malloc (sizeof(game_snd) * MIN_GAME_SOUNDS);
Verify( Snds != NULL );
Num_game_sounds = MIN_GAME_SOUNDS;
}
Snds.clear();
Snds.resize(MIN_GAME_SOUNDS);
Assert( Num_game_sounds > 0 );
Assert( Snds.size() > 0 );
Assert( Snds.size() <= INT_MAX );
// init the gameplay sounds
for ( i = 0; i < Num_game_sounds; i++ ) {
for ( i = 0; i < (int)Snds.size(); i++ ) {
gamesnd_init_struct(&Snds[i]);
}
if (Snds_iface == NULL) {
Snds_iface = (game_snd *) vm_malloc (sizeof(game_snd) * MIN_INTERFACE_SOUNDS);
Verify( Snds_iface != NULL );
Num_iface_sounds = MIN_INTERFACE_SOUNDS;
Assert( Snds_iface_handle == NULL );
Snds_iface_handle = (int *) vm_malloc (sizeof(int) * Num_iface_sounds);
Verify( Snds_iface_handle != NULL );
}
Assert( Num_iface_sounds > 0 );
Snds_iface.clear();
Snds_iface.resize(MIN_INTERFACE_SOUNDS);
Snds_iface_handle.resize(MIN_INTERFACE_SOUNDS);
Assert( Snds_iface.size() > 0 );
Assert( Snds_iface.size() < INT_MAX );
// init the interface sounds
for ( i = 0; i < Num_iface_sounds; i++ ) {
for ( i = 0; i < (int)Snds_iface.size(); i++ ) {
gamesnd_init_struct(&Snds_iface[i]);
Snds_iface_handle[i] = -1;
}
@@ -376,20 +408,9 @@ void gamesnd_init_sounds()
// close out gamesnd, ONLY CALL FROM game_shutdown()!!!!
void gamesnd_close()
{
if (Snds != NULL) {
vm_free(Snds);
Snds = NULL;
}
if (Snds_iface != NULL) {
vm_free(Snds_iface);
Snds_iface = NULL;
}
if (Snds_iface_handle != NULL) {
vm_free(Snds_iface_handle);
Snds_iface_handle = NULL;
}
Snds.clear();
Snds_iface.clear();
Snds_iface_handle.clear();
}
// callback function for the UI code to call when the mouse first goes over a button.
@@ -411,16 +432,14 @@ void gamesnd_add_sound_slot(int type, int num)
switch (type) {
case GAME_SND:
{
Assert( Snds != NULL );
Assert( num < (Num_game_sounds + increase_by) );
Assert( Snds.size() <= INT_MAX );
Assert( num < ((int)Snds.size() + increase_by) );
if (num >= Num_game_sounds) {
Snds = (game_snd *) vm_realloc (Snds, sizeof(game_snd) * (Num_game_sounds + increase_by));
Verify( Snds != NULL );
Num_game_sounds += increase_by;
if (num >= (int)Snds.size()) {
Snds.resize(Snds.size() + increase_by);
// default all new entries
for (i = (Num_game_sounds - increase_by); i < Num_game_sounds; i++) {
for (i = ((int)Snds.size() - increase_by); i < (int)Snds.size(); i++) {
gamesnd_init_struct(&Snds[i]);
}
}
@@ -429,20 +448,17 @@ void gamesnd_add_sound_slot(int type, int num)
case IFACE_SND:
{
Assert( Snds_iface != NULL );
Assert( num < (Num_game_sounds + increase_by) );
Assert( Snds_iface.size() < INT_MAX );
Assert( num < ((int)Snds_iface.size() + increase_by) );
if (num >= Num_iface_sounds) {
Snds_iface = (game_snd *) vm_realloc (Snds_iface, sizeof(game_snd) * (Num_iface_sounds + increase_by));
Verify( Snds_iface != NULL );
Num_iface_sounds += increase_by;
if (num >= (int)Snds_iface.size()) {
Snds_iface.resize(Snds_iface.size() + increase_by);
Assert( Snds_iface_handle != NULL );
Snds_iface_handle = (int *) vm_realloc (Snds_iface_handle, sizeof(int) * Num_iface_sounds);
Verify( Snds_iface_handle != NULL );
Snds_iface_handle.resize(Snds_iface.size());
Assert( Snds_iface.size() < INT_MAX );
// default all new entries
for (i = (Num_iface_sounds - increase_by); i < Num_iface_sounds; i++) {
for (i = ((int)Snds_iface_handle.size() - increase_by); i < (int)Snds_iface_handle.size(); i++) {
gamesnd_init_struct(&Snds_iface[i]);
Snds_iface_handle[i] = -1;
}
+4 -5
View File
@@ -27,6 +27,8 @@ void gamesnd_preload_common_sounds();
void gamesnd_play_iface(int n);
void gamesnd_play_error_beep();
int gamesnd_get_by_name(char* name);
int gamesnd_get_by_tbl_index(int index);
int gamesnd_get_by_iface_tbl_index(int index);
//This should handle NO_SOUND just fine since it doesn't directly access lowlevel code
//Does all parsing for a sound
@@ -40,11 +42,8 @@ void common_play_highlight_sound();
#define MIN_GAME_SOUNDS 202
#define MIN_INTERFACE_SOUNDS 70
extern int Num_game_sounds;
extern int Num_iface_sounds;
extern game_snd *Snds;
extern game_snd *Snds_iface;
extern SCP_vector<game_snd> Snds;
extern SCP_vector<game_snd> Snds_iface;
// symbolic names for misc. game sounds. The order here must match the order in
+1 -1
View File
@@ -30,7 +30,7 @@ color *Color_netplayer[20] = {
&Color_bright_blue,
&Color_green,
&Color_bright_green,
&Color_black,
&Color_pink,
&Color_grey,
&Color_silver,
&Color_white,
+23 -1
View File
@@ -762,6 +762,10 @@ $Circle Strafe Percent: 0, 0, 0, 0, 0 \n\
;; capital ships when it is an option. \n""\
$Glide Strafe Percent: 0, 0, 0, 0, 0 \n\
\n\
;; Percentage of the time where AI ships will randomly sidethrust in a \n\
;; dogfight. \n\
$Random Sidethrust Percent: 0, 0, 0, 0, 0 \n\
\n\
;; The amount of time required for the AI to detect \n\
;; (and try to break) dogfight stalemate. \n\
$Stalemate Time Threshold: 0, 0, 0, 0, 0 \n\
@@ -812,6 +816,10 @@ $Chance AI Has to Fire Missiles at Player: 0, 1, 2, 3, 4 \n\
;; aim. Applies for small ships vs small ships \n\
$Max Aim Update Delay: 0, 0, 0, 0, 0 \n\
\n\
;; The maximum amount of delay allowed before turret AI will update its \n\
;; aim. Applies for turrets vs small ships \n\
$Turret Max Aim Update Delay: 0, 0, 0, 0, 0 \n\
\n\
;; General AI-related flags. These were previously all lumped together \n\
;; under the New AI mission flag. \n\
\n\
@@ -928,7 +936,7 @@ $use only single fov for turrets: NO \n\
\n\
;; allow AI ships to dodge weapons vertically as well as horizontally \n\
$allow vertical dodge: NO \n\
\n\
\n""\
;; a disam or disable goal will protect a ship globally and purge \n\
;; standing attack orders globally. If set to NO, only the ship/wing \n\
;; given the order to disarm or disable will be affected. \n\
@@ -938,6 +946,14 @@ $disarm or disable cause global ai goal effects: YES \n\
;; This should be YES if you want anything in AI.tbl to mean anything \n\
$fix AI class bug: NO \n\
\n\
;; If set, the AI will NOT make extra effort to avoid ramming the player\n\
;; during dogfights. This results in more aggressive AI. \n\
$no extra collision avoidance vs player: NO \n\
\n\
;; If set, the game will check if the dying ship is a player's wingman, \n\
;; before making it give a death scream \n\
$perform less checks for death screams: NO \n\
\n\
#End \n\
";
@@ -969,6 +985,12 @@ $Linked: \n\
+Snd File: none \n\
$Hazard: \n\
+Msg: Cannot engage autopilot: Hazard Near \n\
+Snd File: none \n\
$Support Present: \n\
+Msg: Cannot engage autopilot: Support Ship Present \n\
+Snd File: none \n\
$Support Working: \n\
+Msg: Cannot engage autopilot: Support Ship is rearming or repairing a ship \n\
+Snd File: none \n\
\n\
#END \n\
+2
View File
@@ -123,5 +123,7 @@ extern int Num_medals;
// from lighting.cpp
#define MAX_LIGHTS 256
// from weapon.h (and beam.h)
#define MAX_BEAM_SECTIONS 5
#endif // _GLOBALS_H
+1
View File
@@ -180,6 +180,7 @@ void _cdecl WinAssert(char * text, char * filename, int linenum, const char * fo
extern void LuaError(struct lua_State *L, char *format=NULL, ...);
extern void _cdecl Error( const char * filename, int line, const char * format, ... );
extern void _cdecl Warning( char * filename, int line, const char * format, ... );
extern void _cdecl WarningEx( char *filename, int line, const char *format, ... );
extern int Global_warning_count;
extern int Global_error_count;
+2 -2
View File
@@ -39,8 +39,8 @@
#define FS_VERSION_MAJOR 3 // major version
#define FS_VERSION_MINOR 6 // increase by 1 for minor revs
#define FS_VERSION_BUILD 11 // bugfix release
#define FS_VERSION_REVIS 1111 // SVN revision
#define FS_VERSION_BUILD 12 // bugfix release
#define FS_VERSION_REVIS 0 // SVN revision
#define VERSION_LOC_FNAME "version.nfo"
#define MOTD_LOC_FNAME "motd.txt"
+14
View File
@@ -1164,6 +1164,20 @@ void _cdecl Error( const char * filename, int line, const char * format, ... )
Messagebox_active = false;
}
void _cdecl WarningEx( char *filename, int line, const char *format, ... )
{
#ifndef NDEBUG
if (Cmdline_extra_warn) {
char msg[sizeof(AssertText1)];
va_list args;
va_start(args, format);
vsprintf(msg, format, args);
va_end(args);
Warning(filename, line, msg);
}
#endif
}
void _cdecl Warning( char *filename, int line, const char *format, ... )
{
Global_warning_count++;
+52 -3
View File
@@ -1,4 +1,5 @@
#include "globalincs/pstypes.h"
#include "globalincs/globals.h"
#include "bmpman/bmpman.h"
#include "graphics/generic.h"
#include "graphics/2d.h"
@@ -19,6 +20,54 @@
//we check background type to avoid messed up colours for ANI
#define ANI_BPP_CHECK (ga->ani.bg_type == BM_TYPE_PCX) ? 16 : 32
// Goober5000
int generic_anim_init_and_stream(generic_anim *anim, char *anim_filename, ubyte bg_type, bool attempt_hi_res)
{
int stream_result = -1;
char filename[NAME_LENGTH];
char *p;
Assert(anim != NULL);
Assert(anim_filename != NULL);
// hi-res support
if (attempt_hi_res && (gr_screen.res == GR_1024)) {
// attempt to load a hi-res animation
memset(filename, 0, NAME_LENGTH);
strcpy_s(filename, "2_");
strncat(filename, anim_filename, NAME_LENGTH - 3);
// remove extension
p = strchr(filename, '.');
if(p) {
*p = '\0';
}
// attempt to stream the hi-res ani
generic_anim_init(anim, filename);
anim->ani.bg_type = bg_type;
stream_result = generic_anim_stream(anim);
}
// we failed to stream hi-res, or we aren't running in hi-res, so try low-res
if (stream_result < 0) {
strcpy_s(filename, anim_filename);
// remove extension
p = strchr(filename, '.');
if(p) {
*p = '\0';
}
// attempt to stream the low-res ani
generic_anim_init(anim, filename);
anim->ani.bg_type = bg_type;
stream_result = generic_anim_stream(anim);
}
return stream_result;
}
// Goober5000
void generic_anim_init(generic_anim *ga, char *filename)
{
@@ -317,7 +366,7 @@ void generic_anim_render(generic_anim *ga, float frametime, int x, int y)
if((ga->direction & GENERIC_ANIM_DIRECTION_PAUSED) == 0) {
if(ga->direction & GENERIC_ANIM_DIRECTION_BACKWARDS) {
//keep going forwards if we're in a keyframe loop
if(ga->keyframe && (ga->anim_time > keytime)) {
if(ga->keyframe && (ga->anim_time >= keytime)) {
ga->anim_time += frametime;
if(ga->anim_time >= ga->total_time) {
ga->anim_time = keytime - 0.001f;
@@ -327,11 +376,11 @@ void generic_anim_render(generic_anim *ga, float frametime, int x, int y)
else {
//playing backwards
ga->anim_time -= frametime;
if((ga->direction & GENERIC_ANIM_DIRECTION_NOLOOP) && ga->anim_time < 0.0) {
if((ga->direction & GENERIC_ANIM_DIRECTION_NOLOOP) && ga->anim_time <= 0.0) {
ga->anim_time = 0; //stop on first frame when playing in reverse
}
else {
while(ga->anim_time < 0.0)
while(ga->anim_time <= 0.0)
ga->anim_time += ga->total_time; //make sure we're always positive, so we can go back to the end
}
}
+1 -1
View File
@@ -52,7 +52,7 @@ typedef struct generic_bitmap {
int bitmap_id;
} generic_bitmap;
int generic_anim_init_and_stream(generic_anim *anim, char *anim_filename, ubyte bg_type, bool attempt_hi_res);
void generic_anim_init(generic_anim *ga, char *filename = NULL);
void generic_bitmap_init(generic_bitmap *gb, char *filename = NULL);
int generic_anim_load(generic_anim *ga);
+5 -1
View File
@@ -453,7 +453,11 @@ void gr_opengl_set_clip(int x, int y, int w, int h, bool resize)
}
GL_state.ScissorTest(GL_TRUE);
glScissor(x, gr_screen.max_h-y-h, w, h);
if(GL_rendering_to_framebuffer) {
glScissor(x, y, w, h);
} else {
glScissor(x, gr_screen.max_h-y-h, w, h);
}
}
void gr_opengl_reset_clip()
+80 -20
View File
@@ -10,9 +10,19 @@ using namespace opengl;
bool post_effect::changed = true;
texture *bloom::high_pass(texture *image, int size) {
Assert(image);
Assert(size != 0);
if ( !image ) {
return NULL;
}
// Get bright pass filter
special_shader *bright_sdr = shader_manager::get()->get_special_shader(special_shader::bright_pass);
if ( !bright_sdr ) {
return NULL;
}
// Acquire render target
opengl::render_target *target;
@@ -28,11 +38,13 @@ texture *bloom::high_pass(texture *image, int size) {
target->apply();
target->attach_texture(tex);
target->clear(render_target::clr_color);
// Apply bright pass filter
special_shader *bright_sdr = shader_manager::get()->apply_special_shader(special_shader::bright_pass);
if (!bright_sdr)
// Apply bright pass filter
if ( !bright_sdr->start_pass(0) ) {
render_target::release(target);
texture_pool::release(tex);
return NULL;
}
bright_sdr->set_texture(b_texture, image);
@@ -43,9 +55,19 @@ texture *bloom::high_pass(texture *image, int size) {
}
texture *bloom::blur(texture *image, int size) {
Assert(image);
Assert(size != 0);
if ( !image ) {
return NULL;
}
// Blur
special_shader *blur_sdr = shader_manager::get()->get_special_shader(special_shader::blur);
if ( !blur_sdr ) {
return NULL;
}
// Acquire render target
opengl::render_target *target;
@@ -63,9 +85,12 @@ texture *bloom::blur(texture *image, int size) {
target->apply();
// Blur
special_shader *blur_sdr = shader_manager::get()->apply_special_shader(special_shader::blur);
if (!blur_sdr)
if ( !blur_sdr->start_pass(0) ) {
render_target::release(target);
texture_pool::release(texture0);
texture_pool::release(texture1);
return NULL;
}
for (int pass = 0; pass < 2; pass++) {
target->attach_texture(!pass ? texture0 : texture1);
@@ -101,7 +126,6 @@ bool bloom::begin(texture *pp_img) {
void bloom::end() {
if (config::get_integer(config::bloom_int)) {
Assert(blurred);
texture_pool::release(blurred);
}
}
@@ -126,6 +150,12 @@ void bloom::set_uniforms(post_shader *sdr) {
bool depth_of_field::begin(texture *pp_img) {
Assert(pp_img);
special_shader *blur_sdr = shader_manager::get()->apply_special_shader(special_shader::blur);
if ( !blur_sdr ) {
return false;
}
render_target *target;
target = render_target::acquire(gr_screen.max_w / 4, gr_screen.max_h / 4);
@@ -140,10 +170,12 @@ bool depth_of_field::begin(texture *pp_img) {
Assert(texture0);
Assert(texture1);
special_shader *blur_sdr = shader_manager::get()->apply_special_shader(special_shader::blur);
if (!blur_sdr)
if ( !blur_sdr->start_pass(0) ) {
render_target::release(target);
texture_pool::release(texture0);
texture_pool::release(texture1);
return false;
}
for (int pass = 0; pass < 2; pass++) {
target->attach_texture(!pass ? texture0 : texture1);
@@ -201,19 +233,19 @@ void simple_effects::read_list() {
required_string("#Effects");
while (required_string_either("#End", "$Name:")) {
post_effect eff;
char buf[NAME_LENGTH];
char buf[NAME_LENGTH+1] = { 0 };
required_string("$Name:");
stuff_string(buf, F_NAME, NAME_LENGTH);
eff.name = vm_strdup(buf);
eff.name = buf;
required_string("$Uniform:");
stuff_string(buf, F_NAME, NAME_LENGTH);
eff.uniform_name = vm_strdup(buf);
eff.uniform_name = buf;
required_string("$Define:");
stuff_string(buf, F_NAME, NAME_LENGTH);
eff.define_name = vm_strdup(buf);
eff.define_name = buf;
required_string("$AlwaysOn:");
stuff_boolean(&eff.always_on);
@@ -272,8 +304,18 @@ post_processing *post_processing::instance = NULL;
void post_processing::create() {
Assert(instance == NULL);
if (config::is_enabled(config::post_process))
instance = new post_processing;
if (config::is_enabled(config::post_process)) {
instance = new(std::nothrow) post_processing;
if ( instance && !config::is_enabled(config::post_process) ) {
delete instance;
instance = NULL;
}
}
if ( !instance ) {
config::disable(config::post_process);
}
}
void post_processing::remove() {
@@ -295,14 +337,26 @@ post_processing::post_processing() {
image = texture_pool::acquire(target->get_width(), target->get_height());
target->attach_texture(image);
bloom_eff = NULL;
simple_eff = NULL;
#ifdef DEPTH_OF_FIELD
dof_eff = NULL;
#endif
if (!target->check_status()) {
mprintf(("FBO error. Could not initialize post-processing.\n"));
config::disable(config::post_process);
} else {
bloom_eff = new bloom;
simple_eff = new simple_effects;
bloom_eff = new(std::nothrow) bloom;
simple_eff = new(std::nothrow) simple_effects;
if ( !(bloom_eff && simple_eff) ) {
mprintf(("Memory error. Could not initialize post-processing.\n"));
config::disable(config::post_process);
}
#ifdef DEPTH_OF_FIELD
dof_eff = new depth_of_field;
dof_eff = new(std::nothrow) depth_of_field;
depth = texture::create(target->get_width(), target->get_height(), texture::fmt_depth);
#endif
@@ -473,6 +527,12 @@ void gr_opengl_post_process_init() {
return;
}
if (!resources::text_file::file_exist("post_processing.tbl", resources::text_file::table_file)) {
mprintf(("Post-processing table not found. Disabling...\n"));
Cmdline_postprocess = 0;
return;
}
opengl::post_processing::create();
opengl::simple_effects::restore_defaults();
+58 -55
View File
@@ -204,13 +204,13 @@ static const int Num_shader_files = sizeof(GL_shader_file) / sizeof(opengl_shade
// Resources system - move it to more appropiate file as soon as we get working resource manager
using namespace resources;
text_file::text_file(const char *filename, txt_file_type ftype) {
bool text_file::open(const char *filename, txt_file_type ftype) {
// open file
CFILE *fp = cfopen(const_cast<char*>(filename), "rt", CFILE_NORMAL, get_cfile_type(ftype));
if (!fp) {
mprintf(("Could not open text file \'%s\'.\n", filename));
return;
// nprintf(("SHADER_DEBUG", "Could not open text file \'%s\'.\n", filename));
return false;
}
// load file
@@ -225,6 +225,8 @@ text_file::text_file(const char *filename, txt_file_type ftype) {
// clean
vm_free(bytes);
return true;
}
const SCP_string &text_file::read() const {
@@ -273,13 +275,13 @@ bool opengl::shader::compile_link() {
do {
vert = compile_object((const GLcharARB*)vert_src, GL_VERTEX_SHADER_ARB);
if (!vert) {
mprintf(("ERROR! Unable to create vertex shader!\n"));
mprintf((" ERROR! Unable to create vertex shader!\n"));
break;
}
frag = compile_object((const GLcharARB*)frag_src, GL_FRAGMENT_SHADER_ARB);
if (!frag) {
mprintf(("ERROR! Unable to create fragment shader!\n"));
mprintf((" ERROR! Unable to create fragment shader!\n"));
break;
}
} while (false);
@@ -288,7 +290,7 @@ bool opengl::shader::compile_link() {
if (vert && frag) {
shader_program = link_objects(vert, frag);
if (!shader_program)
mprintf(("ERROR! Unable to create shader program!\n"));
mprintf((" ERROR! Unable to create shader program!\n"));
}
// clean
@@ -331,7 +333,7 @@ GLhandleARB opengl::shader::compile_object(const GLcharARB *shader_source, GLenu
// we failed, bail out now...
if (status == 0) {
// basic error check
mprintf(("%s shader failed to compile:\n%s\n", (shader_type == GL_VERTEX_SHADER_ARB) ? "Vertex" : "Fragment", info_log.c_str()));
mprintf((" %s shader failed to compile:\n%s\n", (shader_type == GL_VERTEX_SHADER_ARB) ? "Vertex" : "Fragment", info_log.c_str()));
if (shader_object) {
vglDeleteObjectARB(shader_object);
shader_object = 0;
@@ -367,7 +369,7 @@ GLhandleARB opengl::shader::link_objects(GLhandleARB vertex_object, GLhandleARB
// we failed, bail out now...
if (status == 0) {
mprintf(("Shader failed to link:\n%s\n", info_log.c_str()));
mprintf((" Shader failed to link:\n%s\n", info_log.c_str()));
if (shader_object) {
vglDeleteObjectARB(shader_object);
shader_object = 0;
@@ -686,7 +688,7 @@ void shader_manager::apply_main_shader(int flags) {
current_main->apply();
} else {
current_main = NULL;
mprintf(("Requested main shader not found: 0x%x.\n", flags));
mprintf((" Requested main shader not found: 0x%x.\n", flags));
}
}
}
@@ -713,26 +715,28 @@ opengl::post_shader *shader_manager::apply_post_shader(int flags) {
return current_post;
}
opengl::special_shader *shader_manager::apply_special_shader(int flags) {
opengl::special_shader *shader_manager::get_special_shader(int flags) {
special_shader *sshader;
SCP_map<int, special_shader*>::iterator itr = special_shaders.find(flags);
if (itr == special_shaders.end()) {
mprintf((" Compiling special shader -> %s / %s ... \n", special_shader::get_vert_name(flags).c_str(), special_shader::get_frag_name(flags).c_str()));
resources::text_file *vert = new resources::text_file(special_shader::get_vert_name(flags).c_str(), resources::text_file::shader_source);
resources::text_file *frag = new resources::text_file(special_shader::get_frag_name(flags).c_str(), resources::text_file::shader_source);
sshader = new opengl::special_shader(flags, vert, frag);
special_shaders[flags] = sshader;
resources::text_file vert;
resources::text_file frag;
delete vert;
delete frag;
bool r_vert = vert.open(special_shader::get_vert_name(flags).c_str(), resources::text_file::shader_source);
bool r_frag = frag.open(special_shader::get_frag_name(flags).c_str(), resources::text_file::shader_source);
if ( !(r_vert && r_frag) ) {
return NULL;
}
sshader = new opengl::special_shader(flags, &vert, &frag);
special_shaders[flags] = sshader;
} else
sshader = (*itr).second;
if (!sshader->start_pass(0))
return NULL;
return sshader;
}
@@ -741,10 +745,10 @@ void shader_manager::apply_fixed_pipeline() {
}
shader_manager::shader_manager() : current_main(NULL), current_post(NULL) {
mprintf(("\nInitializing Shaders Manager...\n"));
mprintf((" Initializing Shaders Manager...\n"));
load_main_shaders();
// load_post_shaders(); //we load post-processing shaders on demand
mprintf(("Shaders Manager initialized.\n\n"));
mprintf((" Shaders Manager initialized.\n\n"));
}
shader_manager::~shader_manager() {
@@ -766,7 +770,7 @@ shader_manager::~shader_manager() {
opengl::shader_manager *opengl::shader_manager::instance = NULL;
void shader_manager::load_main_shaders() {
mprintf(("Loading and compiling main shaders...\n"));
mprintf((" Loading and compiling main shaders...\n"));
// check if we can use new main shaders
bool main_vert = resources::text_file::file_exist("main-v.sdr", resources::text_file::shader_source) != 0;
@@ -805,55 +809,54 @@ void shader_manager::load_main_shaders() {
else
frag_name = shader_file->frag;
mprintf((" Compiling main shader -> %s (%s) / %s (%s) ... \n", vert_name, shader_file->vert, frag_name, shader_file->frag));
mprintf((" Compiling main shader -> %s (%s) / %s (%s) ... \n", vert_name, shader_file->vert, frag_name, shader_file->frag));
// create new shader program
resources::text_file *vert = new resources::text_file(vert_name, resources::text_file::shader_source);
resources::text_file *frag = new resources::text_file(frag_name, resources::text_file::shader_source);
opengl::main_shader *sdr = new opengl::main_shader(vert, frag);
resources::text_file vert, frag;
opengl::main_shader *sdr = NULL;
// configure shader
sdr->configure(shader_file->flags);
bool r_vert = vert.open(vert_name, resources::text_file::shader_source);
bool r_frag = frag.open(frag_name, resources::text_file::shader_source);
if (r_vert && r_frag) {
sdr = new(std::nothrow) opengl::main_shader(&vert, &frag);
Verify( sdr );
// configure shader
sdr->configure(shader_file->flags);
} else {
mprintf((" Shader file(s) (%s / %s) not found!\n", vert_name, frag_name));
}
// compile shader and add it to shaders list
if (sdr->compile_link())
if (sdr && sdr->compile_link())
main_shaders[shader_file->flags] = sdr;
else {
// if problem caused by height map - disable
if (shader_file->flags & main_shader::flag_height_map) {
mprintf((" Shader in_error! Disabling height maps!\n"));
mprintf((" Shader in_error! Disabling height maps!\n"));
config::disable(config::height_map);
}
// if problem caused by normal map - disable
if (shader_file->flags & main_shader::flag_normal_map) {
mprintf((" Shader in_error! Disabling normal maps and height maps!\n"));
mprintf((" Shader in_error! Disabling normal maps and height maps!\n"));
config::disable(config::height_map);
config::disable(config::normal_map);
}
// there is no way to use glsl
if (i == 0) {
mprintf((" Shader in_error! Disabling GLSL!\n"));
mprintf((" Shader in_error! Disabling GLSL!\n"));
config::disable(config::glsl);
config::disable(config::height_map);
config::disable(config::normal_map);
delete sdr;
delete vert;
delete frag;
destroy();
return;
}
delete sdr;
}
// clean
delete vert;
delete frag;
}
}
@@ -863,27 +866,27 @@ opengl::post_shader *shader_manager::load_post_shader(int flags) {
mprintf((" Compiling post shader (0x%x) -> %s / %s ... \n", flags, vert_name, frag_name));
// create new shader program
resources::text_file *vert = new resources::text_file(vert_name, resources::text_file::shader_source);
resources::text_file *frag = new resources::text_file(frag_name, resources::text_file::shader_source);
opengl::post_shader *sdr = new opengl::post_shader(vert, frag);
resources::text_file vert, frag;
opengl::post_shader *sdr = NULL;
// configure shader
sdr->configure(flags);
bool r_vert = vert.open(vert_name, resources::text_file::shader_source);
bool r_frag = frag.open(frag_name, resources::text_file::shader_source);
if (r_vert && r_frag) {
sdr = new(std::nothrow) opengl::post_shader(&vert, &frag);
Verify( sdr );
// configure shader
sdr->configure(flags);
}
// compile shader and add it to shaders list
if (sdr->compile_link())
if (sdr && sdr->compile_link())
post_shaders[flags] = sdr;
else {
mprintf((" Post-processing shader in_error!\n"));
delete sdr;
sdr = NULL;
}
// clean
delete vert;
delete frag;
return sdr;
}
+5 -3
View File
@@ -41,7 +41,9 @@ namespace resources {
table_file
};
text_file(const char *, txt_file_type ftype);
text_file() { }
bool open(const char *, txt_file_type ftype);
const SCP_string &read() const;
@@ -470,10 +472,10 @@ namespace opengl {
*/
post_shader *apply_post_shader(int flags);
/** Applies specific special %shader.
/** Get specific special %shader.
* @param flags special %shader index
*/
special_shader *apply_special_shader(int flags);
special_shader *get_special_shader(int flags);
/** Turns main %shader off. */
void apply_fixed_pipeline();
+2 -2
View File
@@ -914,7 +914,7 @@ int opengl_create_texture(int bitmap_handle, int bitmap_type, tcache_slot_opengl
}
if ( (Detail.hardware_textures < 4) && (bitmap_type != TCACHE_TYPE_AABITMAP) && (bitmap_type != TCACHE_TYPE_INTERFACE)
&& ((bitmap_type != TCACHE_TYPE_COMPRESSED) || (bitmap_type == TCACHE_TYPE_COMPRESSED) && (max_levels > 1)) )
&& ((bitmap_type != TCACHE_TYPE_COMPRESSED) || ((bitmap_type == TCACHE_TYPE_COMPRESSED) && (max_levels > 1))) )
{
if (max_levels == 1) {
// if we are going to cull the size then we need to force a resize
@@ -1923,7 +1923,7 @@ namespace opengl {
SCP_multimap <std::pair<int, int>, render_target*> render_target::pool;
render_target::render_target(int w, int h) : width(w), height(h), depth_t(NULL), depth_rb(NULL), use_rb(false) {
render_target::render_target(int w, int h) : depth_rb(NULL), depth_t(NULL), use_rb(false), target(0), width(w), height(h) {
Assert(w > 0 && h > 0);
// Create frame buffer
+3 -2
View File
@@ -167,8 +167,9 @@ namespace opengl {
* @param tex released texture
*/
static void release(texture *tex) {
Assert(tex);
pool.insert(std::pair<std::pair<int, int>, texture*>(std::pair<int, int>(tex->get_width(), tex->get_height()), tex));
if (tex) {
pool.insert(std::pair<std::pair<int, int>, texture*>(std::pair<int, int>(tex->get_width(), tex->get_height()), tex));
}
}
};
+12 -3
View File
@@ -953,8 +953,13 @@ void gr_opengl_set_projection_matrix(float fov, float aspect, float z_near, floa
}
GL_CHECK_FOR_ERRORS("start of set_projection_matrix()()");
glViewport(gr_screen.offset_x, (gr_screen.max_h - gr_screen.offset_y - gr_screen.clip_height), gr_screen.clip_width, gr_screen.clip_height);
if (GL_rendering_to_framebuffer) {
glViewport(gr_screen.offset_x, gr_screen.offset_y, gr_screen.clip_width, gr_screen.clip_height);
} else {
glViewport(gr_screen.offset_x, (gr_screen.max_h - gr_screen.offset_y - gr_screen.clip_height), gr_screen.clip_width, gr_screen.clip_height);
}
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
@@ -964,7 +969,11 @@ void gr_opengl_set_projection_matrix(float fov, float aspect, float z_near, floa
clip_height = tan( (double)fov * 0.5 ) * z_near;
clip_width = clip_height * (GLdouble)aspect;
glFrustum( -clip_width, clip_width, -clip_height, clip_height, z_near, z_far );
if (GL_rendering_to_framebuffer) {
glFrustum( -clip_width, clip_width, clip_height, -clip_height, z_near, z_far );
} else {
glFrustum( -clip_width, clip_width, -clip_height, clip_height, z_near, z_far );
}
glMatrixMode(GL_MODELVIEW);
+17 -2
View File
@@ -1788,7 +1788,10 @@ void hud_show_damage_popup()
n_firstline++;
gr_string(sx, sy, n_firstline);
} else {
gr_string(sx, sy, hud_targetbox_truncate_subsys_name(hud_subsys_list[best_index].name));
char temp_name[NAME_LENGTH];
strcpy(temp_name, hud_subsys_list[best_index].name);
hud_targetbox_truncate_subsys_name(temp_name);
gr_string(sx, sy, temp_name);
}
sprintf(buf, XSTR( "%d%%", 219), best_str);
@@ -2700,7 +2703,12 @@ void hud_maybe_display_subspace_notify()
{
int warp_aborted = 0;
// maybe make gauge active
if ( (Player->control_mode == PCM_WARPOUT_STAGE1) || (Player->control_mode == PCM_WARPOUT_STAGE2) || (Player->control_mode == PCM_WARPOUT_STAGE3) ) {
if ( (Player->control_mode == PCM_WARPOUT_STAGE1)
|| (Player->control_mode == PCM_WARPOUT_STAGE2)
|| (Player->control_mode == PCM_WARPOUT_STAGE3)
|| (Sexp_hud_display_warpout > 0)
)
{
if (!hud_subspace_notify_active()) {
// keep sound from being played 1e06 times
hud_start_subspace_notify();
@@ -2717,6 +2725,13 @@ void hud_maybe_display_subspace_notify()
return;
}
if ( Sexp_hud_display_warpout > 1 ) {
if ( Sexp_hud_display_warpout < timestamp()) {
Sexp_hud_display_warpout = 0;
return;
}
}
if ( Objective_display_gauge.first_frame < 0 ) {
return;
}
+43 -26
View File
@@ -12,6 +12,7 @@
#include "graphics/2d.h"
#include "localization/localize.h"
#include "hud/hud.h"
#include "mission/missiontraining.h" //for Max_directives
#include "hud/hudescort.h"
//#include "weapon/emp.h"
#include "hud/hudparse.h" //Duh.
@@ -29,6 +30,7 @@ extern int ships_inited; //Need this
extern char Hud_Gauge_Names[NUM_HUD_GAUGES][NAME_LENGTH];
float Hud_unit_multiplier = 1.0f; //Backslash
bool Hud_lead_alternate = false;
// Goober5000
int Hud_reticle_style = HUD_RETICLE_STYLE_FS2;
@@ -44,26 +46,26 @@ int Hud_reticle_style = HUD_RETICLE_STYLE_FS2;
#define HUD_VAR(a) offsetof(hud_info, a)
gauge_info gauges[MAX_HUD_GAUGE_TYPES] = {
{ NULL, HUD_VAR(Player_shield_coords), "$Player Shield:", 396, 379, 634, 670, 0, 0, 0, 0, 0, 0, 0, -1, -1 },
{ NULL, HUD_VAR(Target_shield_coords), "$Target Shield:", 142, 379, 292, 670, 0, 0, 0, 0, 0, 0, 0, -1, -1 },
{ NULL, HUD_VAR(Shield_mini_coords), "$Shield Mini:", 305, 291, 497, 470, 0, HUD_VAR(Shield_mini_fname), 0, 0, 0, 0, 0, -1, -1 },
{ NULL, HUD_VAR(Aburn_coords), "$Afterburner Energy:", 171, 265, 274, 424, HUD_VAR(Aburn_size), HUD_VAR(Aburn_fname), 0, 0, 0, 0, HUD_VAR(Aburn_move_flag), -1, -1 },
{ NULL, HUD_VAR(Wenergy_coords), "$Weapons Energy:", 416, 265, 666, 424, HUD_VAR(Wenergy_size), HUD_VAR(Wenergy_fname), 0, 0, 0, 0, HUD_VAR(Wenergy_move_flag), -1, -1 },
{ NULL, HUD_VAR(Wenergy_text_coords), "$Weapons Energy Text:", 439, 318, 708, 509, 0, 0, 0, 0, 0, 0, 0, -1, -1 },
{ NULL, HUD_VAR(Escort_coords), "$Escort List:", 486, 206, 865, 330, 0, HUD_VAR(Escort_filename[0]), 0, HUD_VAR(Escort_htext), 0, 0, 0, -1, -1 },
{ NULL, HUD_VAR(Player_shield_coords), "Player Shield", 396, 379, 634, 670, 0, 0, 0, 0, 0, 0, 0, -1, -1 },
{ NULL, HUD_VAR(Target_shield_coords), "Target Shield", 142, 379, 292, 670, 0, 0, 0, 0, 0, 0, 0, -1, -1 },
{ NULL, HUD_VAR(Shield_mini_coords), "Shield Mini", 305, 291, 497, 470, 0, HUD_VAR(Shield_mini_fname), 0, 0, 0, 0, 0, -1, -1 },
{ NULL, HUD_VAR(Aburn_coords), "Afterburner Energy", 171, 265, 274, 424, HUD_VAR(Aburn_size), HUD_VAR(Aburn_fname), 0, 0, 0, 0, HUD_VAR(Aburn_move_flag), -1, -1 },
{ NULL, HUD_VAR(Wenergy_coords), "Weapons Energy", 416, 265, 666, 424, HUD_VAR(Wenergy_size), HUD_VAR(Wenergy_fname), 0, 0, 0, 0, HUD_VAR(Wenergy_move_flag), -1, -1 },
{ NULL, HUD_VAR(Wenergy_text_coords), "Weapons Energy Text", 439, 318, 708, 509, 0, 0, 0, 0, 0, 0, 0, -1, -1 },
{ NULL, HUD_VAR(Escort_coords), "Escort List", 486, 206, 865, 330, 0, HUD_VAR(Escort_filename[0]), 0, HUD_VAR(Escort_htext), 0, 0, 0, -1, -1 },
//Mini-gauges
{ &gauges[2], HUD_VAR(Hud_mini_3digit), "$Text Base:", 310, 298, 502, 477, 0, 0, 0, 0, 0, 0, 0, HG_NOADD, -1 },
{ &gauges[2], HUD_VAR(Hud_mini_1digit), "$Text 1 digit:", 316, 298, 511, 477, 0, 0, 0, 0, 0, 0, 0, HG_NOADD, -1 },
// { &gauges[2], HUD_VAR(Hud_mini_2digit), "$Text 2 digit:", 213, 298, 346, 477, 0, 0, 0, 0, 0, 0, 0, HG_NOADD, -1 },
{ &gauges[2], HUD_VAR(Hud_mini_2digit), "$Text 2 digit:", 313, 298, 506, 477, 0, 0, 0, 0, 0, 0, 0, HG_NOADD, -1 },
{ &gauges[6], HUD_VAR(Escort_htext_coords), "$Header Text:", 3, 2, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, -1 },
{ &gauges[6], HUD_VAR(Escort_list), "$List:", 0, 12, 0, 13, 0, 0, 0, 0, 0, 0, 0, HG_NOADD, -1 },
{ &gauges[6], HUD_VAR(Escort_entry), "$Ship:", 0, 11, 0, 11, 0, HUD_VAR(Escort_filename[1]), 0, 0, 0, 0, 0, HG_NOADD, -1 },
{ &gauges[6], HUD_VAR(Escort_entry_last), "$Last Ship:", 0, 11, 0, 11, 0, HUD_VAR(Escort_filename[2]), 0, 0, 0, 0, 0, HG_NOADD, -1 },
{ &gauges[6], HUD_VAR(Escort_name), "$Ship Name:", 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, HG_NOADD, -1 },
{ &gauges[6], HUD_VAR(Escort_integrity), "$Ship Hull:", 128, 0, 116, 0, 0, 0, 0, 0, 0, 0, 0, HG_NOADD, -1 },
{ &gauges[6], HUD_VAR(Escort_status), "$Ship Status:", -12, 0, -11, 0, 0, 0, 0, 0, 0, 0, 0, HG_NOADD, -1 }
{ &gauges[2], HUD_VAR(Hud_mini_3digit), "Text Base", 310, 298, 502, 477, 0, 0, 0, 0, 0, 0, 0, HG_NOADD, -1 },
{ &gauges[2], HUD_VAR(Hud_mini_1digit), "Text 1 digit", 316, 298, 511, 477, 0, 0, 0, 0, 0, 0, 0, HG_NOADD, -1 },
// { &gauges[2], HUD_VAR(Hud_mini_2digit), "Text 2 digit", 213, 298, 346, 477, 0, 0, 0, 0, 0, 0, 0, HG_NOADD, -1 },
{ &gauges[2], HUD_VAR(Hud_mini_2digit), "Text 2 digit", 313, 298, 506, 477, 0, 0, 0, 0, 0, 0, 0, HG_NOADD, -1 },
{ &gauges[6], HUD_VAR(Escort_htext_coords), "Header Text", 489, 208, 869, 331, 0, 0, 0, 0, 0, 0, 0, -1, -1 },
{ &gauges[6], HUD_VAR(Escort_list), "List", 0, 12, 0, 13, 0, 0, 0, 0, 0, 0, 0, HG_NOADD, -1 },
{ &gauges[6], HUD_VAR(Escort_entry), "Ship", 0, 11, 0, 11, 0, HUD_VAR(Escort_filename[1]), 0, 0, 0, 0, 0, HG_NOADD, -1 },
{ &gauges[6], HUD_VAR(Escort_entry_last), "Last Ship", 0, 11, 0, 11, 0, HUD_VAR(Escort_filename[2]), 0, 0, 0, 0, 0, HG_NOADD, -1 },
{ &gauges[6], HUD_VAR(Escort_name), "Ship Name", 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, HG_NOADD, -1 },
{ &gauges[6], HUD_VAR(Escort_integrity), "Ship Hull", 128, 0, 116, 0, 0, 0, 0, 0, 0, 0, 0, HG_NOADD, -1 },
{ &gauges[6], HUD_VAR(Escort_status), "Ship Status", -12, 0, -11, 0, 0, 0, 0, 0, 0, 0, 0, HG_NOADD, -1 }
};
//Number of gauges
@@ -181,12 +183,16 @@ int stuff_coords(hud_info* dest_hud, gauge_info* cg, bool required = false)
float percentage_temp[2];
int size_temp[2];
bool size_defined = false;
char token_name[NAME_LENGTH + 2] = "$";
strcat_s(token_name, cg->fieldname);
strcat_s(token_name, ":");
if(required)
{
required_string(cg->fieldname);
required_string(token_name);
}
if(!required && !optional_string(cg->fieldname))
if(!required && !optional_string(token_name))
{
return 0;
}
@@ -332,7 +338,7 @@ static void parse_resolution_gauges(hud_info* dest_hud)
{
cg = &gauges[i];
if(!parent && !strnicmp(cg->fieldname + sizeof(char), gaugename, strlen(cg->fieldname) - 2))
if(!parent && !stricmp(cg->fieldname, gaugename))
{
parent = cg;
break;
@@ -386,6 +392,7 @@ hud_info* parse_ship_start()
if(ship_index == -1)
{
WarningEx(LOCATION, "\"$Ship:\" name \"%s\" not found.", shipname);
return NULL;
}
@@ -464,10 +471,7 @@ void parse_custom_gauge()
cg->moveflag_dest = HUD_VAR(custom_gauge_moveflags[0]) + (Num_custom_gauges * sizeof(bool));
required_string("$Name:");
//Gotta make this a token
cg->fieldname[0] = '$';
stuff_string(cg->fieldname + 1, F_NAME, sizeof(cg->fieldname) - 1);
strcat_s(cg->fieldname, ":");
stuff_string(cg->fieldname, F_NAME, NAME_LENGTH);
if(optional_string("+Default640X:"))
{
@@ -489,6 +493,9 @@ void parse_custom_gauge()
{
stuff_string(buffer, F_NAME, NAME_LENGTH);
cg->parent = hud_get_gauge(buffer);
if (cg->parent == NULL) {
WarningEx(LOCATION, "\"+Parent:\" HUD gauge \"%s\" not found!", buffer);
}
}
Num_gauge_types++;
@@ -517,6 +524,11 @@ void parse_hud_gauges_tbl(char *filename)
read_file_text(filename, CF_TYPE_TABLES);
reset_parse();
if(optional_string("$Max Directives:"))
{
stuff_int(&Max_directives);
}
if(optional_string("$Max Escort Ships:"))
{
stuff_int(&Max_escort_ships);
@@ -554,6 +566,11 @@ void parse_hud_gauges_tbl(char *filename)
Hud_reticle_style = temp;
}
if(optional_string("$Alternate Lead Indicator:"))
{
stuff_boolean(&Hud_lead_alternate);
}
if(optional_string("#Custom Gauges"))
{
while(required_string_either("#End", "$Name:"))
@@ -737,7 +754,7 @@ int hud_get_gauge_index(char* name)
{
for(int i = 0; i < Num_gauge_types; i++)
{
if(!strnicmp(gauges[i].fieldname + sizeof(char), name, strlen(gauges[i].fieldname) - 2))
if(!stricmp(gauges[i].fieldname, name))
{
return i;
}
+1
View File
@@ -145,6 +145,7 @@ typedef struct gauge_info
//Variables
extern int Num_custom_gauges;
extern float Hud_unit_multiplier;
extern bool Hud_lead_alternate;
#define NUM_HUD_RETICLE_STYLES 2
+14 -4
View File
@@ -585,7 +585,12 @@ void hud_show_reticle_weapons()
// threat exists, and draw flashing frames.
void hud_show_lock_threat()
{
int frame_offset;
int frame_offset, num_frames;
//Let's find out how many frames our ani has, and adjust accordingly
num_frames = Reticle_gauges[RETICLE_LOCK_WARN].num_frames;
//We need at least two frames here
Assert( num_frames >= 2 );
if ( Player->threat_flags & (THREAT_LOCK | THREAT_ATTEMPT_LOCK) ) {
if ( timestamp_elapsed(Threat_lock_timer) ) {
@@ -595,7 +600,7 @@ void hud_show_lock_threat()
Threat_lock_timer = timestamp(THREAT_LOCK_FLASH);
}
Threat_lock_frame++;
if ( Threat_lock_frame > 2 ) {
if ( Threat_lock_frame > (num_frames - 1) ) { //The first frame being the default "off" setting, we need to cycle through all the other frames
Threat_lock_frame = 1;
}
if ( (Threat_lock_frame == 2) && (Player->threat_flags & THREAT_ATTEMPT_LOCK ) ) {
@@ -633,13 +638,18 @@ void hud_show_lock_threat()
// threat exists, and draw flashing frames.
void hud_show_dumbfire_threat()
{
int frame_offset;
int frame_offset, num_frames;
//Check how many frames the ani actually has
num_frames = Reticle_gauges[RETICLE_LASER_WARN].num_frames;
//We need at least two frames here
Assert( num_frames >= 2 );
if ( Player->threat_flags & THREAT_DUMBFIRE ) {
if ( timestamp_elapsed(Threat_dumbfire_timer) ) {
Threat_dumbfire_timer = timestamp(THREAT_DUMBFIRE_FLASH);
Threat_dumbfire_frame++;
if ( Threat_dumbfire_frame > 2 ) {
if ( Threat_dumbfire_frame > (num_frames - 1) ) { //The first frame being the default "off" setting, we need to cycle through all the other frames
Threat_dumbfire_frame = 1;
}
}
+32 -6
View File
@@ -1391,9 +1391,9 @@ int hud_squadmsg_send_ship_command( int shipnum, int command, int send_message,
ai_submode = SM_ATTACK;
// if no enemies present, use the affirmative, instead of engaging enemies message
if ( hud_squadmsg_enemies_present() )
message = MESSAGE_YESSIR;
else
message = MESSAGE_ENGAGE;
else
message = MESSAGE_YESSIR;
target_shipname = NULL;
break;
@@ -1642,10 +1642,11 @@ int hud_squadmsg_send_wing_command( int wingnum, int command, int send_message,
case ENGAGE_ENEMY_ITEM:
ai_mode = AI_GOAL_CHASE_ANY;
ai_submode = SM_ATTACK;
// if no enemies present, use the affirmative, instead of engaging enemies message
if ( hud_squadmsg_enemies_present() )
message = MESSAGE_YESSIR;
else
message = MESSAGE_ENGAGE;
else
message = MESSAGE_YESSIR;
target_shipname = NULL;
break;
@@ -2025,7 +2026,7 @@ void hud_squadmsg_call_reinforcement(int reinforcement_num, int player_num)
// function to display a list of reinforcements available to the player
void hud_squadmsg_reinforcement_select()
{
int i, k;
int i, k, wingnum;
reinforcements *rp;
if ( Num_menu_items == -1 ) {
@@ -2041,7 +2042,32 @@ void hud_squadmsg_reinforcement_select()
// don't put items which are not on my team
if((Player_ship != NULL) && (ship_get_reinforcement_team(i) != Player_ship->team)){
continue;
}
}
// check the arrival cue sexpression of the ship/wing of this reinforcement.
// Goober5000 - if it can't arrive, it doesn't count. This should check
// for SEXP_FALSE as well as SEXP_KNOWN_FALSE, otherwise you end up with
// a reinforcement menu containing no valid selections.
if ( (wingnum = wing_name_lookup(rp->name, 1)) != -1 ) {
Assert ( Wings[wingnum].arrival_cue >= 0 );
if ( Sexp_nodes[Wings[wingnum].arrival_cue].value == SEXP_FALSE
|| Sexp_nodes[Wings[wingnum].arrival_cue].value == SEXP_KNOWN_FALSE ){
continue;
}
} else {
p_object *p_objp;
p_objp = mission_parse_get_arrival_ship( rp->name );
if ( p_objp != NULL ) {
if ( Sexp_nodes[p_objp->arrival_cue].value == SEXP_FALSE
|| Sexp_nodes[p_objp->arrival_cue].value == SEXP_KNOWN_FALSE ){
continue;
}
} else {
Int3(); // allender says bogus! reinforcement should be here since it wasn't a wing!
continue;
}
}
Assert ( Num_menu_items < MAX_MENU_ITEMS );
strcpy_s( MsgItems[Num_menu_items].text, rp->name );
+95 -23
View File
@@ -1809,8 +1809,8 @@ void hud_target_live_turret(int next_flag, int auto_advance, int only_player_tar
} else if (turret_weapon_has_subtype(&A->weapons, WP_LASER)) {
ent[num_live_turrets].type = TYPE_FACING_LASER;
} else {
Int3();
ent[num_live_turrets].type = TYPE_FACING_LASER;
//Turret not live, bail
continue;
}
}
@@ -4137,13 +4137,37 @@ void hud_show_lead_indicator(vec3d *target_world_pos)
hud_set_iff_color(targetp, 1);
}
if ( indicator_frame >= 0 ) {
sx = lead_target_vertex.sx;
sy = lead_target_vertex.sy;
if (Hud_lead_alternate) {
vertex target_vertex;
g3_rotate_vertex(&target_vertex, target_world_pos);
if (target_vertex.codes == 0) { // on screen
gr_unsize_screen_posf(&sx, &sy);
g3_project_vertex(&target_vertex);
if (!(target_vertex.flags & PF_OVERFLOW)) {
//indicator_frame = Reticle2_indicator_gauge.first_frame + frame_offset;
if ( indicator_frame >= 0 ) {
//hud_set_gauge_color(HUD_CENTER_RETICLE, HUD_C_BRIGHT);
float reticle2_target_sx = target_vertex.sx - Lead_indicator_half[Hud_reticle_style][gr_screen.res][0] - lead_target_vertex.sx;
float reticle2_target_sy = target_vertex.sy - Lead_indicator_half[Hud_reticle_style][gr_screen.res][1] - lead_target_vertex.sy;
reticle2_target_sx += HUD_offset_x + Hud_reticle_center[gr_screen.res][0] + 0.5f;
reticle2_target_sy += HUD_offset_y + Hud_reticle_center[gr_screen.res][1] + 0.5f;
GR_AABITMAP(indicator_frame, fl2i(reticle2_target_sx)+HUD_nose_x, fl2i(reticle2_target_sy)+HUD_nose_y);
}
}
}
} else {
if ( indicator_frame >= 0 ) {
sx = lead_target_vertex.sx;
sy = lead_target_vertex.sy;
GR_AABITMAP(indicator_frame, fl2i(sx - Lead_indicator_half[Hud_reticle_style][gr_screen.res][0]), fl2i(sy - Lead_indicator_half[Hud_reticle_style][gr_screen.res][1]));
gr_unsize_screen_posf(&sx, &sy);
GR_AABITMAP(indicator_frame, fl2i(sx - Lead_indicator_half[Hud_reticle_style][gr_screen.res][0]), fl2i(sy - Lead_indicator_half[Hud_reticle_style][gr_screen.res][1]));
}
}
}
}
@@ -4210,17 +4234,41 @@ void hud_show_lead_indicator(vec3d *target_world_pos)
hud_set_iff_color(targetp, 1);
}
if ( indicator_frame >= 0 ) {
sx = lead_target_vertex.sx;
sy = lead_target_vertex.sy;
if (Hud_lead_alternate) {
vertex target_vertex;
g3_rotate_vertex(&target_vertex, target_world_pos);
if (target_vertex.codes == 0) { // on screen
gr_unsize_screen_posf(&sx, &sy);
g3_project_vertex(&target_vertex);
if (!(target_vertex.flags & PF_OVERFLOW)) {
//indicator_frame = Reticle2_indicator_gauge.first_frame + frame_offset;
if ( indicator_frame >= 0 ) {
//hud_set_gauge_color(HUD_CENTER_RETICLE, HUD_C_BRIGHT);
float reticle2_target_sx = target_vertex.sx - Lead_indicator_half[Hud_reticle_style][gr_screen.res][0] - lead_target_vertex.sx;
float reticle2_target_sy = target_vertex.sy - Lead_indicator_half[Hud_reticle_style][gr_screen.res][1] - lead_target_vertex.sy;
reticle2_target_sx += HUD_offset_x + Hud_reticle_center[gr_screen.res][0] + 0.5f;
reticle2_target_sy += HUD_offset_y + Hud_reticle_center[gr_screen.res][1] + 0.5f;
GR_AABITMAP(indicator_frame, fl2i(reticle2_target_sx)+HUD_nose_x, fl2i(reticle2_target_sy)+HUD_nose_y);
}
}
}
} else {
if ( indicator_frame >= 0 ) {
sx = lead_target_vertex.sx;
sy = lead_target_vertex.sy;
//WMC - shake them
sx += HUD_nose_x;
sy += HUD_nose_y;
gr_unsize_screen_posf(&sx, &sy);
GR_AABITMAP(indicator_frame, fl2i(sx - Lead_indicator_half[Hud_reticle_style][gr_screen.res][0]), fl2i(sy - Lead_indicator_half[Hud_reticle_style][gr_screen.res][1]));
//WMC - shake them
sx += HUD_nose_x;
sy += HUD_nose_y;
GR_AABITMAP(indicator_frame, fl2i(sx - Lead_indicator_half[Hud_reticle_style][gr_screen.res][0]), fl2i(sy - Lead_indicator_half[Hud_reticle_style][gr_screen.res][1]));
}
}
}
}
@@ -4345,17 +4393,41 @@ void hud_show_lead_indicator_quick(vec3d *target_world_pos, object *targetp)
g3_project_vertex(&lead_target_vertex);
if (!(lead_target_vertex.flags & PF_OVERFLOW)) {
if ( indicator_frame >= 0 ) {
sx = lead_target_vertex.sx;
sy = lead_target_vertex.sy;
if (Hud_lead_alternate) {
vertex target_vertex;
g3_rotate_vertex(&target_vertex, target_world_pos);
if (target_vertex.codes == 0) { // on screen
gr_unsize_screen_posf(&sx, &sy);
g3_project_vertex(&target_vertex);
if (!(target_vertex.flags & PF_OVERFLOW)) {
//indicator_frame = Reticle2_indicator_gauge.first_frame + frame_offset;
if ( indicator_frame >= 0 ) {
//hud_set_gauge_color(HUD_CENTER_RETICLE, HUD_C_BRIGHT);
float reticle2_target_sx = target_vertex.sx - Lead_indicator_half[Hud_reticle_style][gr_screen.res][0] - lead_target_vertex.sx;
float reticle2_target_sy = target_vertex.sy - Lead_indicator_half[Hud_reticle_style][gr_screen.res][1] - lead_target_vertex.sy;
reticle2_target_sx += HUD_offset_x + Hud_reticle_center[gr_screen.res][0] + 0.5f;
reticle2_target_sy += HUD_offset_y + Hud_reticle_center[gr_screen.res][1] + 0.5f;
GR_AABITMAP(indicator_frame, fl2i(reticle2_target_sx)+HUD_nose_x, fl2i(reticle2_target_sy)+HUD_nose_y);
}
}
}
} else {
if ( indicator_frame >= 0 ) {
sx = lead_target_vertex.sx;
sy = lead_target_vertex.sy;
//WMC - shake them
sx += HUD_nose_x;
sy += HUD_nose_y;
gr_unsize_screen_posf(&sx, &sy);
GR_AABITMAP(indicator_frame, fl2i(sx - Lead_indicator_half[Hud_reticle_style][gr_screen.res][0]), fl2i(sy - Lead_indicator_half[Hud_reticle_style][gr_screen.res][1]));
//WMC - shake them
sx += HUD_nose_x;
sy += HUD_nose_y;
GR_AABITMAP(indicator_frame, fl2i(sx - Lead_indicator_half[Hud_reticle_style][gr_screen.res][0]), fl2i(sy - Lead_indicator_half[Hud_reticle_style][gr_screen.res][1]));
}
}
}
}
+7 -9
View File
@@ -196,7 +196,7 @@ static int Last_ts; // holds last target status.
void hud_blit_target_integrity(int disabled,int force_obj_num = -1);
// cut down long subsystem names to a more manageable length
char *hud_targetbox_truncate_subsys_name(char *outstr)
void hud_targetbox_truncate_subsys_name(char *outstr)
{
if(Lcl_gr){
if ( strstr(outstr, "communication") ) {
@@ -244,17 +244,15 @@ char *hud_targetbox_truncate_subsys_name(char *outstr)
} else if ( strstr(outstr, "laser") || strstr(outstr, "turret") || strstr(outstr, "missile") ) {
strcpy(outstr, "tourelle");
}
} else {
if ( strstr(outstr, XSTR( "communication", 333))) {
strcpy( outstr, XSTR( "comm", 334) );
} else if ( strstr(outstr, XSTR( "navigation", 335))) {
strcpy( outstr, XSTR( "nav", 336) );
} else if (!stricmp(outstr, "Gas Collector")) {
} else {
if (strstr(outstr, XSTR("communication", 333))) {
strcpy(outstr, XSTR("comm", 334));
} else if (strstr(outstr, XSTR("navigation", 335))) {
strcpy(outstr, XSTR("nav", 336));
} else if (strstr(outstr, "gas collector")) {
strcpy(outstr, "collector");
}
}
return outstr;
}
//swich through the valid targetbox modes
+1 -1
View File
@@ -72,7 +72,7 @@ void hud_render_target_weapon(object *target_objp);
void hud_update_cargo_scan_sound();
void hud_cargo_scan_update(object *targetp, float frametime);
char *hud_targetbox_truncate_subsys_name(char *outstr);
void hud_targetbox_truncate_subsys_name(char *outstr);
//swich through the valid targetbox modes
void hud_targetbox_switch_wireframe_mode();
+6
View File
@@ -331,6 +331,12 @@ int joy_ff_create_effects()
void joy_ff_stop_effects()
{
joy_ff_afterburn_off();
if (pDeathroll1)
pDeathroll1->Stop();
if (pDeathroll2)
pDeathroll2->Stop();
}
void joy_ff_mission_init(vec3d v)
+1 -5
View File
@@ -2846,11 +2846,7 @@ int button_function(int n)
}
else
{
if (CanAutopilot(true))
{
StartAutopilot();
}
else
if (!StartAutopilot())
gamesnd_play_iface(SND_GENERAL_FAIL);
}
}
+12
View File
@@ -33,6 +33,7 @@
#define LAB_FLAG_SHOW_DEBRIS (1<<2) // render debris instead of normal LOD
#define LAB_FLAG_SUBMODEL_ROTATE (1<<3) // do rotation for any rotating ship subobjects
#define LAB_FLAG_LIGHTNING_ARCS (1<<4) // show damage lightning
#define LAB_FLAG_FULLY_LOAD (1<<5) // use create_ship() to test the ships
// modes
#define LAB_MODE_NONE 0 // not showing anything
@@ -1607,6 +1608,7 @@ void labviewer_make_render_options_window(Button *caller)
// add all of the flags that we want/need...
// viewer flags
ADD_RENDER_FLAG("Test Load Ships", Lab_viewer_flags, LAB_FLAG_FULLY_LOAD);
ADD_RENDER_FLAG("Disable Model Rotation", Lab_viewer_flags, LAB_FLAG_NO_ROTATION);
ADD_RENDER_FLAG("Show Insignia", Lab_viewer_flags, LAB_FLAG_SHOW_INSIGNIA);
ADD_RENDER_FLAG("Show Damage Lightning", Lab_viewer_flags, LAB_FLAG_LIGHTNING_ARCS);
@@ -1838,6 +1840,16 @@ void labviewer_change_ship_lod(Tree* caller)
int ship_index = (int)(caller->GetSelectedItem()->GetParentItem()->GetData());
Assert( ship_index >= 0 );
// Genghis - Attempt to create and then immediately delete the selected ship type.
// This causes the full error-handling to kick-in, making the Lab viewer a more
// useful tool for checking model errors.
if (Lab_viewer_flags & LAB_FLAG_FULLY_LOAD)
{
The_mission.ai_profile = &Ai_profiles[Default_ai_profile];
int test_idx = ship_create(&vmd_identity_matrix, &vmd_zero_vector, ship_index);
obj_delete(test_idx);
}
Lab_last_selected_ship = Lab_selected_index;
labviewer_change_model(Ship_info[ship_index].pof_file, caller->GetSelectedItem()->GetData(), ship_index);
+3
View File
@@ -35,6 +35,9 @@ int static_rand(int num)
{
int a, b, c;
if (num < 0)
num *= -1;
if (!Semirand_inited)
init_semirand();
+5 -1
View File
@@ -1630,7 +1630,11 @@ void vm_matrix_to_rot_axis_and_angle(matrix *m, float *theta, vec3d *rot_axis)
rot_axis->xyz.x = (m->vec.uvec.xyz.z - m->vec.fvec.xyz.y);
rot_axis->xyz.y = (m->vec.fvec.xyz.x - m->vec.rvec.xyz.z);
rot_axis->xyz.z = (m->vec.rvec.xyz.y - m->vec.uvec.xyz.x);
vm_vec_normalize(rot_axis);
if (IS_VEC_NULL_SQ_SAFE(rot_axis)) {
vm_vec_make(rot_axis, 1.0f, 0.0f, 0.0f);
} else {
vm_vec_normalize(rot_axis);
}
} else { // angle is PI within limits
*theta = PI;
+33 -30
View File
@@ -33,41 +33,42 @@
// This is the fs2_open credit list, please only add yourself if you have actually contributed code
// Rules!
char *fs2_open_credit_text =
"SOURCE CODE PROJECT STAFF:\n"
"SOURCE CODE PROJECT STAFF:\n"
"\n"
"Project Leaders:\n"
"\n"
"Ian \"Goober5000\" Warfield\n"
"Cliff \"chief1983\" Gordon"
"\n"
"Senior Advisors:\n"
"\n"
"Taylor Richards\n"
"\n"
"Senior Advisor\n"
"\n"
"Ian \"Goober5000\" Warfield\n"
"Edward \"Inquisitor\" Gardner\n"
"\n"
"Programmers:\n"
"\n"
"Mike \"Bobboau\" Abegg\n"
"Dennis \"DTP\" Pedersen\n"
"\"EdrickV\"\n"
"Derek \"Kazan\" Meek\n"
"Ian \"Goober5000\" Warfield\n"
"\"Mysterial\"\n"
"Joe \"Righteous1\" Dowd\n"
"Jon \"Sesquipedalian\" Stovell\n"
"Matt \"Sticks\" Nischan\n"
"Mike \"penguin\" Harris\n"
"Nick \"phreak\" Iannetta\n"
"Thomas \"RandomTiger\" Whittaker\n"
"Taylor Richards\n"
"Will \"##Unknown Player##\" Rousnel\n"
"\"WMCoolmon\"\n"
"Hassan \"Karajorma\" Kazmi\n"
"Derek \"Kazan\" Meek\n"
"Nick \"phreak\" Iannetta\n"
"Mike \"Bobboau\" Abegg\n"
"Backslash\n"
"Echelon9\n"
"Flaming_Sword\n"
"FUBAR\n"
"Iss Mneur\n"
"kkmic\n"
"Michael \"Zacam\" LaFleur\n"
"Shade\n"
"Soulstorm\n"
"Sushi\n"
"Swifty\n"
"Wanderer\n"
"Fabian \"The E\" Woltermann\n"
"\n"
"\n"
"Readme Staff:\n"
"\n"
"\"Bottomfan\"\n"
"Peter \"Flipside\" Dibble\n"
"Jonathan \"Redmenace\" Willsher\n"
"\n"
"Web Support:\n"
"\n"
@@ -77,12 +78,10 @@ char *fs2_open_credit_text =
"\n"
"Special thanks to:\n"
"\n"
"\"Maeglamor\"\n"
"for donating a graphics card!\n"
"\n"
"\"Lightspeed\"\n"
"\"DaBrain\"\n"
"for helping out with the graphics enhancements\n"
"portej05\n"
"Hery\n"
"QuantumDelta\n"
"Fury\n"
"\n"
"Linux and OSX version with the support of\n"
"the icculus.org FreeSpace2 project:\n"
@@ -102,8 +101,12 @@ char *fs2_open_credit_text =
"\n"
"Ogg Vorbis - (C) 2005, Xiph.Org Foundation\n"
"JPEG - Independent JPEG Group, (C) 1991-1998, Thomas G. Lane\n"
"\n\n"
"\n\n";
"libpng - Copyright (C) 1998-2010 Glenn Randers-Pehrson\n"
"liblua - Copyright (C) 1994–2008 Lua.org, PUC-Rio\n"
"zlib - Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler\n"
"\n"
"\n"
"\n";
char *unmodified_credits = "ORIGINAL VOLITION STAFF:\n\n\n";
char *mod_check = "Design:";
+7 -6
View File
@@ -244,7 +244,6 @@ static int Techroom_ship_modelnum;
static float Techroom_ship_rot;
static UI_BUTTON List_buttons[LIST_BUTTONS_MAX]; // buttons for each line of text in list
//static int Anim_playing_id = -1;
//static int anim_done = 0;
static int Palette_bmp;
//static int ShipWin01;
//static int ShipWin02;
@@ -395,12 +394,14 @@ void techroom_select_new_entry()
Techroom_ship_modelnum = -1;
Trackball_mode = 0;
//load animation here, we now only have one loaded
generic_anim_init(&Current_list[Cur_entry].animation, Current_list[Cur_entry].tech_anim_filename);
Current_list[Cur_entry].animation.ani.bg_type = bm_get_type(Tech_background_bitmap);
if(generic_anim_stream(&Current_list[Cur_entry].animation) != -1){
// load animation here, we now only have one loaded
int stream_result = generic_anim_init_and_stream(&Current_list[Cur_entry].animation, Current_list[Cur_entry].tech_anim_filename, bm_get_type(Tech_background_bitmap), true);
if (stream_result >= 0) {
Current_list[Cur_entry].has_anim = 1;
} else {
// we've failed to load any animation
// load an image and treat it like a 1 frame animation
Current_list[Cur_entry].bitmap = bm_load(Current_list[Cur_entry].tech_anim_filename);
}
}
@@ -730,7 +731,7 @@ void tech_ship_scroll_capture()
techroom_unload_animation();
techroom_select_new_entry();
}
}
void techroom_anim_render(float frametime)
{
+1 -1
View File
@@ -14,7 +14,7 @@
#include "globalincs/globals.h"
#define MAX_INTEL_ENTRIES 30
#define MAX_INTEL_ENTRIES 75
#define TECH_INTEL_DESC_LEN 5120
typedef struct {
+11 -5
View File
@@ -264,12 +264,16 @@ void persona_parse()
}
}
if ( i == MAX_PERSONA_TYPES )
WarningEx(LOCATION, "Unknown persona type in messages.tbl -- %s\n", type );
char cstrtemp[NAME_LENGTH];
if ( optional_string("+") )
{
int j;
stuff_string(cstrtemp, F_NAME, NAME_LENGTH);
for (int j = 0; j < (int)Species_info.size(); j++)
for (j = 0; j < (int)Species_info.size(); j++)
{
if (!strcmp(cstrtemp, Species_info[j].species_name))
{
@@ -277,12 +281,11 @@ void persona_parse()
break;
}
}
if ( j == (int)Species_info.size() )
WarningEx(LOCATION, "Unknown species in messages.tbl -- %s\n", cstrtemp );
}
if ( i == MAX_PERSONA_TYPES )
Error(LOCATION, "Unknown persona type in messages.tbl -- %s\n", type );
Num_personas++;
}
@@ -367,6 +370,9 @@ void message_parse(bool importing_from_fsm)
if ( optional_string("+Persona:") ) {
stuff_string(persona_name, F_NAME, NAME_LENGTH);
msg.persona_index = message_persona_name_lookup( persona_name );
if ( msg.persona_index == -1 )
WarningEx(LOCATION, "Unknown persona in message %s in messages.tbl -- %s\n", msg.name, persona_name );
}
if ( !Fred_running)
+154 -47
View File
@@ -711,6 +711,8 @@ void parse_mission_info(mission *pm, bool basic = false)
if (index >= 0)
The_mission.ai_profile = &Ai_profiles[index];
else
WarningEx(LOCATION, "Mission: %s\nUnknown AI profile %s!", pm->name, temp );
}
Assert( The_mission.ai_profile != NULL );
@@ -806,6 +808,9 @@ void parse_player_info2(mission *pm)
if (optional_string("+Default_ship:")) {
stuff_string(str, F_NAME, NAME_LENGTH);
ptr->default_ship = ship_info_lookup(str);
if (-1 == ptr->default_ship) {
WarningEx(LOCATION, "Mission: %s\nUnknown default ship %s! Defaulting to %s.", pm->name, str, Ship_info[ptr->ship_list[0]].name );
}
// see if the player's default ship is an allowable ship (campaign only). If not, then what
// do we do? choose the first allowable one?
if (Game_mode & GM_CAMPAIGN_MODE || ((Game_mode & GM_MULTIPLAYER) && !(Net_player->flags & NETINFO_FLAG_AM_MASTER))) {
@@ -1731,7 +1736,18 @@ int parse_create_object_sub(p_object *p_objp)
shipp->team = p_objp->team;
strcpy_s(shipp->ship_name, p_objp->name);
shipp->escort_priority = p_objp->escort_priority;
shipp->special_exp_index = p_objp->special_exp_index;
shipp->use_special_explosion = p_objp->use_special_explosion;
shipp->special_exp_damage = p_objp->special_exp_damage;
shipp->special_exp_blast = p_objp->special_exp_blast ;
shipp->special_exp_inner = p_objp->special_exp_inner ;
shipp->special_exp_outer = p_objp->special_exp_outer ;
shipp->use_shockwave = p_objp->use_shockwave ;
shipp->special_exp_shockwave_speed = p_objp->special_exp_shockwave_speed ;
shipp->special_hitpoints = p_objp->special_hitpoints ;
shipp->special_shield = p_objp->special_shield ;
for (i=0;i<MAX_IFFS;i++)
{
@@ -1742,13 +1758,12 @@ int parse_create_object_sub(p_object *p_objp)
}
// Goober5000
shipp->special_hitpoint_index = p_objp->special_hitpoint_index;
shipp->ship_max_shield_strength = p_objp->ship_max_shield_strength;
shipp->ship_max_hull_strength = p_objp->ship_max_hull_strength;
// Goober5000 - ugh, this is really stupid having to do this here; if the
// ship creation code was better organized this wouldn't be necessary
if (shipp->special_hitpoint_index >= 0)
if (shipp->special_hitpoints > 0)
{
float hull_factor = shipp->ship_max_hull_strength / sip->max_hull_strength;
ship_subsys *ss;
@@ -2363,6 +2378,48 @@ void resolve_parse_flags(object *objp, int parse_flags, int parse_flags2)
shipp->flags2 |= SF2_FORCE_SHIELDS_ON;
}
void fix_old_special_explosions(p_object *p_objp, int variable_index)
{
int i;
Assertion(!(p_objp->use_special_explosion), "Mission appears to be using both the new and old method of special explosions for %s. Old method values used", p_objp->name);
// check all the variables are valid
for ( i = variable_index; i < (variable_index + BLOCK_EXP_SIZE); i++ ) {
if (!( Block_variables[i].type & SEXP_VARIABLE_BLOCK )) {
Warning (LOCATION, "%s is using the old special explosions method but does not appear to have variables for all the values", p_objp->name);
return;
}
}
p_objp->use_special_explosion = true;
p_objp->special_exp_damage = atoi(Block_variables[variable_index+DAMAGE].text);
p_objp->special_exp_blast = atoi(Block_variables[variable_index+BLAST].text);
p_objp->special_exp_inner = atoi(Block_variables[variable_index+INNER_RAD].text);
p_objp->special_exp_outer = atoi(Block_variables[variable_index+OUTER_RAD].text);
p_objp->use_shockwave = (atoi(Block_variables[variable_index+PROPAGATE].text) ? 1:0);
p_objp->special_exp_shockwave_speed = atoi(Block_variables[variable_index+SHOCK_SPEED].text);
}
void fix_old_special_hits(p_object *p_objp, int variable_index)
{
int i;
Assertion( ((p_objp->special_hitpoints == 0) && (p_objp->special_shield == -1)),"Mission appears to be using both the new and old method of special hitpoints for %s", p_objp->name);
// check all the variables are valid
for ( i = variable_index; i < (variable_index + BLOCK_HIT_SIZE); i++ ) {
if (!( Block_variables[i].type & SEXP_VARIABLE_BLOCK )) {
Warning (LOCATION, "%s is using the old special hitpoints method but does not appear to have variables for all the values", p_objp->name);
return;
}
}
p_objp->special_hitpoints = atoi(Block_variables[variable_index+HULL_STRENGTH].text);
p_objp->special_shield = atoi(Block_variables[variable_index+SHIELD_STRENGTH].text);
}
// Mp points at the text of an object, which begins with the "$Name:" field.
// Snags all object information. Creating the ship now only happens after everything has been parsed.
//
@@ -2457,9 +2514,8 @@ int parse_object(mission *pm, int flag, p_object *p_objp)
// try and find the alternate name
p_objp->alt_type_index = (char)mission_parse_lookup_alt(name);
Assert(p_objp->alt_type_index >= 0);
if(p_objp->alt_type_index < 0)
mprintf(("Error looking up alternate ship type name!\n"));
WarningEx(LOCATION, "Mission %s\nError looking up alternate ship type name %s!\n", pm->name, name);
else
mprintf(("Using alternate ship type name: %s\n", name));
}
@@ -2473,9 +2529,8 @@ int parse_object(mission *pm, int flag, p_object *p_objp)
// try and find the callsign
p_objp->callsign_index = (char)mission_parse_lookup_callsign(name);
Assert(p_objp->callsign_index >= 0);
if(p_objp->callsign_index < 0)
mprintf(("Error looking up callsign!\n"));
WarningEx(LOCATION, "Mission %s\nError looking up callsign %s!\n", pm->name, name);
else
mprintf(("Using callsign: %s\n", name));
}
@@ -2712,44 +2767,74 @@ int parse_object(mission *pm, int flag, p_object *p_objp)
Player_starts++;
}
p_objp->special_exp_index = -1;
if (optional_string("+Special Exp index:"))
stuff_int(&p_objp->special_exp_index);
p_objp->use_special_explosion = false;
p_objp->special_exp_damage = -1;
p_objp->special_exp_blast = -1;
p_objp->special_exp_inner = -1;
p_objp->special_exp_outer = -1;
p_objp->use_shockwave = false;
p_objp->special_exp_shockwave_speed = 0;
p_objp->special_hitpoints = 0;
p_objp->special_shield = -1;
p_objp->special_hitpoint_index = -1;
if (optional_string("+Special Hitpoint index:"))
stuff_int(&p_objp->special_hitpoint_index);
if (optional_string("$Special Explosion:")) {
p_objp->use_special_explosion = true;
// set max hitpoint values
p_objp->ship_max_shield_strength = Ship_info[p_objp->ship_class].max_shield_strength;
p_objp->ship_max_hull_strength = Ship_info[p_objp->ship_class].max_hull_strength;
// swap to the special hitpoint ones if they were set
if (p_objp->special_hitpoint_index != -1)
{
bool reset_index = false;
if ((Sexp_variables[p_objp->special_hitpoint_index+SHIELD_STRENGTH].type & SEXP_VARIABLE_SET) &&
(Sexp_variables[p_objp->special_hitpoint_index+SHIELD_STRENGTH].type & SEXP_VARIABLE_BLOCK) ) {
p_objp->ship_max_shield_strength = (float) atoi(Sexp_variables[p_objp->special_hitpoint_index+SHIELD_STRENGTH].text);
}
else {
Warning(LOCATION, "Special shield hitpoints used for variable number %d. But no variable with this number exists!", p_objp->special_hitpoint_index+SHIELD_STRENGTH);
reset_index = true;
if (required_string("+Special Exp Damage:")) {
stuff_int(&p_objp->special_exp_damage);
}
if ((Sexp_variables[p_objp->special_hitpoint_index+HULL_STRENGTH].type & SEXP_VARIABLE_SET) &&
(Sexp_variables[p_objp->special_hitpoint_index+HULL_STRENGTH].type & SEXP_VARIABLE_BLOCK) ) {
p_objp->ship_max_hull_strength = (float) atoi(Sexp_variables[p_objp->special_hitpoint_index+HULL_STRENGTH].text);
}
else {
Warning(LOCATION, "Special hitpoints used for variable number %d. But no variable with this number exists!", p_objp->special_hitpoint_index+HULL_STRENGTH);
reset_index = true;
if (required_string("+Special Exp Blast:")) {
stuff_int(&p_objp->special_exp_blast);
}
if (reset_index) {
p_objp->special_hitpoint_index = -1;
if (required_string("+Special Exp Inner Radius:")) {
stuff_int(&p_objp->special_exp_inner);
}
if (required_string("+Special Exp Outer Radius:")) {
stuff_int(&p_objp->special_exp_outer);
}
if (optional_string("+Special Exp Shockwave Speed:")) {
stuff_int(&p_objp->special_exp_shockwave_speed);
p_objp->use_shockwave = true;
}
}
if (optional_string("+Special Hitpoints:")) {
stuff_int(&p_objp->special_hitpoints);
}
if (optional_string("+Special Shield Points:")) {
stuff_int(&p_objp->special_shield);
}
if (optional_string("+Special Exp index:")) {
int variable_index;
stuff_int(&variable_index);
fix_old_special_explosions(p_objp, variable_index);
}
if (optional_string("+Special Hitpoint index:")) {
int variable_index;
stuff_int(&variable_index);
fix_old_special_hits(p_objp, variable_index);
}
// set max hitpoint and shield values
if (p_objp->special_shield != -1) {
p_objp->ship_max_shield_strength = (float) p_objp->special_shield;
}
else {
p_objp->ship_max_shield_strength = Ship_info[p_objp->ship_class].max_shield_strength;
}
if (p_objp->special_hitpoints > 0) {
p_objp->ship_max_hull_strength = (float) p_objp->special_hitpoints;
}
else {
p_objp->ship_max_hull_strength = Ship_info[p_objp->ship_class].max_hull_strength;
}
Assert(p_objp->ship_max_hull_strength > 0.0f); // Goober5000: div-0 check (not shield because we might not have one)
@@ -3080,6 +3165,9 @@ void parse_common_object_data(p_object *objp)
{
int i;
// Genghis: used later for subsystem checking
ship_info* sip = &Ship_info[objp->ship_class];
// set some defaults..
objp->initial_velocity = 0;
objp->initial_hull = 100;
@@ -3103,6 +3191,17 @@ void parse_common_object_data(p_object *objp)
objp->subsys_count++;
stuff_string(Subsys_status[i].name, F_NAME, NAME_LENGTH);
// Genghis: check that the subsystem name makes sense for this ship type
if (stricmp("Pilot", Subsys_status[i].name))
{
int j;
for (j=0; j < sip->n_subsystems; ++j)
if (!stricmp(sip->subsystems[j].subobj_name, Subsys_status[i].name))
break;
if (j == sip->n_subsystems)
Warning(LOCATION, "Ship \"%s\", class \"%s\"\nUnknown subsystem \"%s\" found in mission!", objp->name, sip->name, Subsys_status[i].name);
}
if (optional_string("$Damage:"))
stuff_float(&Subsys_status[i].percent);
@@ -3111,9 +3210,15 @@ void parse_common_object_data(p_object *objp)
char cargo_name[NAME_LENGTH];
stuff_string(cargo_name, F_NAME, NAME_LENGTH);
int index = string_lookup(cargo_name, Cargo_names, Num_cargo, "cargo", 0);
if (index == -1 && (Num_cargo < MAX_CARGO)) {
index = Num_cargo;
strcpy(Cargo_names[Num_cargo++], cargo_name);
if (index == -1) {
if (Num_cargo < MAX_CARGO) {
index = Num_cargo;
strcpy(Cargo_names[Num_cargo++], cargo_name);
}
else {
WarningEx(LOCATION, "Maximum number of cargo names (%d) exceeded, defaulting to Nothing!", MAX_CARGO);
index = 0;
}
}
Subsys_status[i].subsys_cargo_name = index;
}
@@ -4805,6 +4910,9 @@ void parse_bitmaps(mission *pm)
}
}
if (z == NUM_NEBULAS)
WarningEx(LOCATION, "Mission %s\nUnknown nebula %s!", pm->name, str);
if (optional_string("+Color:")) {
stuff_string(str, F_NAME, MAX_FILENAME_LEN);
for (z=0; z<NUM_NEBULA_COLORS; z++){
@@ -4815,6 +4923,9 @@ void parse_bitmaps(mission *pm)
}
}
if (z == NUM_NEBULA_COLORS)
WarningEx(LOCATION, "Mission %s\nUnknown nebula color %s!", pm->name, str);
if (optional_string("+Pitch:")){
stuff_int(&Nebula_pitch);
} else {
@@ -5001,9 +5112,7 @@ void parse_variables()
// if the active mission has a variable with the same name as a campaign
// variable AND it is not a block variable, override its initial value
// with the previous mission's value
if (!(stricmp(Sexp_variables[k].variable_name, Campaign.missions[i].saved_variables[j].variable_name))
&& !(Campaign.missions[i].saved_variables[j].type & SEXP_VARIABLE_BLOCK))
{
if (!(stricmp(Sexp_variables[k].variable_name, Campaign.missions[i].saved_variables[j].variable_name)) ) {
Sexp_variables[k].type = Campaign.missions[i].saved_variables[j].type;
strcpy_s(Sexp_variables[k].text, Campaign.missions[i].saved_variables[j].text);
}
@@ -5020,9 +5129,7 @@ void parse_variables()
// if the active mission has a variable with the same name as a player
// variable AND it is not a block variable, override its initial value
// with the previous mission's value
if (!(stricmp(Sexp_variables[j].variable_name, Player->player_variables[i].variable_name))
&& !(Player->player_variables[i].type & SEXP_VARIABLE_BLOCK))
{
if (!(stricmp(Sexp_variables[j].variable_name, Player->player_variables[i].variable_name)) ) {
Sexp_variables[j].type = Player->player_variables[i].type;
strcpy_s(Sexp_variables[j].text, Player->player_variables[i].text);
}
+20 -4
View File
@@ -400,8 +400,17 @@ typedef struct p_object {
int group; // group object is within or -1 if none.
int persona_index;
float kamikaze_damage; // base damage for a kamikaze attack
int special_exp_index;
int special_hitpoint_index;
bool use_special_explosion; // new special explosion/hitpoints system
int special_exp_damage;
int special_exp_blast;
int special_exp_inner;
int special_exp_outer;
bool use_shockwave;
int special_exp_shockwave_speed;
int special_hitpoints;
int special_shield;
ushort net_signature; // network signature this object can have
int destroy_before_mission_time;
@@ -485,8 +494,15 @@ typedef struct p_object {
group = 0;
persona_index = 0;
kamikaze_damage = 0.;
special_exp_index = 0;
special_hitpoint_index = 0;
use_special_explosion = false;
special_exp_damage = -1;
special_exp_blast = -1;
special_exp_inner = -1;
special_exp_outer = -1;
use_shockwave = false;
special_exp_shockwave_speed = -1;
special_hitpoints = 0;
special_shield = -1;
net_signature = 0;
destroy_before_mission_time = 0;
+32 -19
View File
@@ -74,6 +74,7 @@ typedef struct {
char Training_buf[TRAINING_MESSAGE_LENGTH];
char *Training_lines[MAX_TRAINING_MESSAGE_LINES]; // Training message split into lines
char Training_voice_filename[NAME_LENGTH];
int Max_directives = TRAINING_OBJ_DISPLAY_LINES;
int Training_message_timestamp;
int Training_line_sizes[MAX_TRAINING_MESSAGE_LINES];
int Training_message_method = 1;
@@ -173,8 +174,8 @@ void training_obj_display()
offset = 0;
end = Training_obj_num_lines;
if (end > TRAINING_OBJ_DISPLAY_LINES) {
end = TRAINING_OBJ_DISPLAY_LINES;
if (end > Max_directives) {
end = Max_directives;
offset = Training_obj_num_lines - end;
}
@@ -302,6 +303,9 @@ void training_mission_init()
Training_obj_num_lines = 0;
Training_message_queue_count = 0;
Training_failure = 0;
if (Max_directives > TRAINING_OBJ_LINES) {
Max_directives = TRAINING_OBJ_LINES;
}
for (i=0; i<TRAINING_OBJ_LINES; i++)
Training_obj_lines[i] = -1;
@@ -361,7 +365,7 @@ void sort_training_objectives()
// get the index of the first directive that will be displayed
// if less than 0, display all lines
offset = Training_obj_num_lines - TRAINING_OBJ_DISPLAY_LINES;
offset = Training_obj_num_lines - Max_directives;
if (offset <= 0) {
return;
@@ -447,7 +451,7 @@ void sort_training_objectives()
// find first slot that can be bumped
// look at the last (N-4 to N) positions
for (slot_idx=0; slot_idx<TRAINING_OBJ_DISPLAY_LINES; slot_idx++) {
for (slot_idx=0; slot_idx<Max_directives; slot_idx++) {
if ( Training_obj_lines[i+offset] & TRAINING_OBJ_STATUS_KNOWN ) {
break;
}
@@ -785,6 +789,8 @@ void message_training_setup(int m, int length, char *special_message)
training_process_message(Training_buf);
Training_num_lines = split_str(Training_buf, TRAINING_LINE_WIDTH, Training_line_sizes, Training_lines, MAX_TRAINING_MESSAGE_LINES);
Assert( Training_num_lines >= 0 );
if (message_play_training_voice(Messages[m].wave_info.index) < 0) {
if (length > 0)
Training_message_timestamp = timestamp(length * 1000);
@@ -853,20 +859,25 @@ void message_training_queue(char *text, int timestamp, int length)
// Goober5000 - removes current message from the queue
void message_training_remove_from_queue(int idx)
{
Training_message_queue[idx].length = -1;
Training_message_queue[idx].num = -1;
Training_message_queue[idx].timestamp = -1;
{
// we're overwriting all messages with the next message, but to
// avoid memory leaks, we should free the special message entry
if (Training_message_queue[idx].special_message != NULL)
{
vm_free(Training_message_queue[idx].special_message);
Training_message_queue[idx].special_message = NULL;
}
// replace current message with the one above it, etc.
for (int j=idx+1; j<Training_message_queue_count; j++)
Training_message_queue[j - 1] = Training_message_queue[j];
// delete the topmost message
Training_message_queue_count--;
Training_message_queue[Training_message_queue_count].length = -1;
Training_message_queue[Training_message_queue_count].num = -1;
Training_message_queue[Training_message_queue_count].timestamp = -1;
Training_message_queue[Training_message_queue_count].special_message = NULL; // not a memory leak because we copied the pointer
}
// check the training message queue to see if we should play a new message yet or not.
@@ -907,7 +918,11 @@ void message_training_display()
Training_message_visible = 0;
message_training_queue_check();
training_obj_display();
if ( !hud_disabled_except_messages() ) {
training_obj_display();
}
if (Training_failure){
return;
@@ -917,20 +932,18 @@ void message_training_display()
return;
}
// next two lines moved to message_training_setup() - taylor
// training_process_message(Training_buf);
// Training_num_lines = split_str(Training_buf, TRAINING_LINE_WIDTH, Training_line_sizes, Training_lines, MAX_TRAINING_MESSAGE_LINES);
Assert(Training_num_lines > 0);
for (i=0; i<Training_num_lines; i++) {
Training_lines[i][Training_line_sizes[i]] = 0;
drop_leading_white_space(Training_lines[i]);
}
// the code that preps the training message and counts the number of lines
// has been moved to message_training_setup()
if (Training_num_lines <= 0){
return;
}
for (i=0; i<Training_num_lines; i++) {
Training_lines[i][Training_line_sizes[i]] = 0;
drop_leading_white_space(Training_lines[i]);
}
height = gr_get_font_height();
gr_set_shader(&Training_msg_glass);
gr_shade(Training_message_window_coords[gr_screen.res][0], Training_message_window_coords[gr_screen.res][1], TRAINING_MESSAGE_WINDOW_WIDTH, Training_num_lines * height + height);
+1
View File
@@ -9,6 +9,7 @@
extern int Max_directives;
extern int Training_message_method;
extern int Training_num_lines;
extern int Training_message_visible;
+124 -52
View File
@@ -24,17 +24,52 @@
// ---------------------------------------------------------------------------------------------------------------------------------------
// MISSION FICTION VIEWER DEFINES/VARS
//
#define NUM_FVW_SETTINGS 2
char *Fiction_viewer_screen_filename[GR_NUM_RESOLUTIONS] =
char *Fiction_viewer_screen_filename[NUM_FVW_SETTINGS][GR_NUM_RESOLUTIONS] =
{
"fvw", // GR_640
"2_fvw", // GR_1024
{
"FictionViewer", // GR_640
"2_FictionViewer" // GR_1024
},
{
"FictionViewerb", // GR_640
"2_FictionViewerb" // GR_1024
}
};
char *Fiction_viewer_screen_mask[GR_NUM_RESOLUTIONS] =
char *Fiction_viewer_screen_mask[NUM_FVW_SETTINGS][GR_NUM_RESOLUTIONS] =
{
"fvw-m", // GR_640
"2_fvw-m", // GR_1024
{
"FictionViewer-m", // GR_640
"2_FictionViewer-m" // GR_1024
},
{
"FictionViewer-mb", // GR_640
"2_FictionViewer-mb" // GR_1024
}
};
int Fiction_viewer_text_coordinates[NUM_FVW_SETTINGS][GR_NUM_RESOLUTIONS][4] =
{
// standard FS2-style interface
{
{ // GR_640
17, 37, 588, 344
},
{ // GR_1024
25, 48, 944, 576
}
},
// WCS-style interface
{
{ // GR_640
44, 50, 522, 348
},
{ // GR_1024
71, 80, 835, 556
}
}
};
#define NUM_FVW_BUTTONS 3
@@ -45,43 +80,70 @@ char *Fiction_viewer_screen_mask[GR_NUM_RESOLUTIONS] =
// the xt and yt fields aren't normally used for width and height,
// but the fields would go unused here and this is more
// convenient for initialization
ui_button_info Fiction_viewer_buttons[GR_NUM_RESOLUTIONS][NUM_FVW_BUTTONS] =
ui_button_info Fiction_viewer_buttons[NUM_FVW_SETTINGS][GR_NUM_RESOLUTIONS][NUM_FVW_BUTTONS] =
{
{ // GR_640
ui_button_info("fvw_accept_", 105, 444, 37, 26, 0),
ui_button_info("fvw_up_", 576, 51, 37, 33, 1),
ui_button_info("fvw_down_", 576, 364, 37, 33, 2),
// standard FS2-style interface
{
{ // GR_640
ui_button_info("fvw_accept_", 571, 425, 69, 55, FVW_BUTTON_ACCEPT),
ui_button_info("fvw_up_", 614, 14, 25, 31, FVW_BUTTON_SCROLL_UP),
ui_button_info("fvw_down_", 614, 370, 25, 31, FVW_BUTTON_SCROLL_DOWN),
// Filename x y width height
},
{ // GR_1024
ui_button_info("2_fvw_accept_", 918, 688, 99, 77, FVW_BUTTON_ACCEPT),
ui_button_info("2_fvw_up_", 981, 16, 40, 50, FVW_BUTTON_SCROLL_UP),
ui_button_info("2_fvw_down_", 981, 606, 40, 50, FVW_BUTTON_SCROLL_DOWN),
}
},
{ // GR_1024
ui_button_info("2_fvw_accept_", 168, 710, 59, 41, 0),
ui_button_info("2_fvw_up_", 922, 81, 59, 53, 1),
ui_button_info("2_fvw_down_", 922, 582, 59, 53, 2),
// WCS-style interface
{
{ // GR_640
ui_button_info("fvw_accept_", 105, 444, 37, 26, FVW_BUTTON_ACCEPT),
ui_button_info("fvw_up_", 576, 51, 37, 33, FVW_BUTTON_SCROLL_UP),
ui_button_info("fvw_down_", 576, 364, 37, 33, FVW_BUTTON_SCROLL_DOWN),
},
{ // GR_1024
ui_button_info("2_fvw_accept_", 168, 710, 59, 41, FVW_BUTTON_ACCEPT),
ui_button_info("2_fvw_up_", 922, 81, 59, 53, FVW_BUTTON_SCROLL_UP),
ui_button_info("2_fvw_down_", 922, 582, 59, 53, FVW_BUTTON_SCROLL_DOWN),
}
}
};
char *Fiction_viewer_slider_filename[GR_NUM_RESOLUTIONS] =
char *Fiction_viewer_slider_filename[NUM_FVW_SETTINGS][GR_NUM_RESOLUTIONS] =
{
"fvw_slider_",
"2_fvw_slider_"
};
int Fiction_viewer_slider_coordinates[GR_NUM_RESOLUTIONS][4] =
{
{ // GR_640
589, 83, 16, 280
// standard FS2-style interface
{
"slider",
"2_slider"
},
{ // GR_1024
944, 132, 25, 451
// WCS-style interface
{
"fvw_slider_",
"2_fvw_slider_"
}
};
int Fiction_viewer_text_coordinates[GR_NUM_RESOLUTIONS][4] =
int Fiction_viewer_slider_coordinates[NUM_FVW_SETTINGS][GR_NUM_RESOLUTIONS][4] =
{
{ // GR_640
44, 50, 522, 348
// standard FS2-style interface
{
{ // GR_640
618, 48, 18, 320 //Initial position x, initial position y, width, height of the slider column
},
{ // GR_1024
988, 70, 28, 532
}
},
{ // GR_1024
71, 80, 835, 556
// WCS-style interface
{
{ // GR_640
589, 83, 16, 280
},
{ // GR_1024
944, 132, 25, 451
}
}
};
@@ -100,6 +162,8 @@ static char Fiction_viewer_filename[MAX_FILENAME_LEN];
static char Fiction_viewer_font_filename[MAX_FILENAME_LEN];
static char *Fiction_viewer_text = NULL;
static int Fiction_viewer_ui = -1;
// ---------------------------------------------------------------------------------------------------------------------------------------
// FICTION VIEWER FUNCTIONS
//
@@ -186,11 +250,19 @@ void fiction_viewer_init()
// music
common_music_init(SCORE_FICTION_VIEWER);
// load the background bitmap
Fiction_viewer_bitmap = bm_load(Fiction_viewer_screen_filename[gr_screen.res]);
// no graphics?
if (Fiction_viewer_bitmap < 0)
// see if we have a background bitmap, and if so, which one
// currently, we prioritize the UI that comes latest in the array;
// in the future we might specify this in the mission or in a tbl
for (Fiction_viewer_ui = NUM_FVW_SETTINGS - 1; Fiction_viewer_ui >= 0; Fiction_viewer_ui--)
{
// load the first available background bitmap
Fiction_viewer_bitmap = bm_load(Fiction_viewer_screen_filename[Fiction_viewer_ui][gr_screen.res]);
if (Fiction_viewer_bitmap >= 0)
break;
}
// no ui is valid?
if (Fiction_viewer_ui < 0)
{
Warning(LOCATION, "No fiction viewer graphics -- cannot display fiction viewer!");
return;
@@ -208,17 +280,17 @@ void fiction_viewer_init()
}
// calculate text area lines from font
Fiction_viewer_text_max_lines = Fiction_viewer_text_coordinates[gr_screen.res][3] / gr_get_font_height();
Fiction_viewer_text_max_lines = Fiction_viewer_text_coordinates[Fiction_viewer_ui][gr_screen.res][3] / gr_get_font_height();
// window
Fiction_viewer_window.create(0, 0, gr_screen.max_w_unscaled, gr_screen.max_h_unscaled, 0, Fiction_viewer_fontnum);
Fiction_viewer_window.set_mask_bmap(Fiction_viewer_screen_mask[gr_screen.res]);
Fiction_viewer_window.set_mask_bmap(Fiction_viewer_screen_mask[Fiction_viewer_ui][gr_screen.res]);
// add the buttons
for (int i = 0; i < NUM_FVW_BUTTONS; i++)
{
int repeat = (i == FVW_BUTTON_SCROLL_UP || i == FVW_BUTTON_SCROLL_DOWN);
ui_button_info *b = &Fiction_viewer_buttons[gr_screen.res][i];
ui_button_info *b = &Fiction_viewer_buttons[Fiction_viewer_ui][gr_screen.res][i];
b->button.create(&Fiction_viewer_window, "", b->x, b->y, b->xt, b->yt, repeat, 1);
b->button.set_highlight_action(common_play_highlight_sound);
@@ -227,23 +299,23 @@ void fiction_viewer_init()
}
// set up hotkeys for buttons
Fiction_viewer_buttons[gr_screen.res][FVW_BUTTON_ACCEPT].button.set_hotkey(KEY_CTRLED | KEY_ENTER);
Fiction_viewer_buttons[gr_screen.res][FVW_BUTTON_SCROLL_UP].button.set_hotkey(KEY_UP);
Fiction_viewer_buttons[gr_screen.res][FVW_BUTTON_SCROLL_DOWN].button.set_hotkey(KEY_DOWN);
Fiction_viewer_buttons[Fiction_viewer_ui][gr_screen.res][FVW_BUTTON_ACCEPT].button.set_hotkey(KEY_CTRLED | KEY_ENTER);
Fiction_viewer_buttons[Fiction_viewer_ui][gr_screen.res][FVW_BUTTON_SCROLL_UP].button.set_hotkey(KEY_UP);
Fiction_viewer_buttons[Fiction_viewer_ui][gr_screen.res][FVW_BUTTON_SCROLL_DOWN].button.set_hotkey(KEY_DOWN);
// init brief text
brief_color_text_init(Fiction_viewer_text, Fiction_viewer_text_coordinates[gr_screen.res][2], 0, 0);
brief_color_text_init(Fiction_viewer_text, Fiction_viewer_text_coordinates[Fiction_viewer_ui][gr_screen.res][2], 0, 0);
// if the story is going to overflow the screen, add a slider
if (Num_brief_text_lines[0] > Fiction_viewer_text_max_lines)
{
Fiction_viewer_slider.create(&Fiction_viewer_window,
Fiction_viewer_slider_coordinates[gr_screen.res][0],
Fiction_viewer_slider_coordinates[gr_screen.res][1],
Fiction_viewer_slider_coordinates[gr_screen.res][2],
Fiction_viewer_slider_coordinates[gr_screen.res][3],
Fiction_viewer_slider_coordinates[Fiction_viewer_ui][gr_screen.res][0],
Fiction_viewer_slider_coordinates[Fiction_viewer_ui][gr_screen.res][1],
Fiction_viewer_slider_coordinates[Fiction_viewer_ui][gr_screen.res][2],
Fiction_viewer_slider_coordinates[Fiction_viewer_ui][gr_screen.res][3],
Num_brief_text_lines[0] - Fiction_viewer_text_max_lines,
Fiction_viewer_slider_filename[gr_screen.res],
Fiction_viewer_slider_filename[Fiction_viewer_ui][gr_screen.res],
&fiction_viewer_scroll_up,
&fiction_viewer_scroll_down,
&fiction_viewer_scroll_capture);
@@ -307,7 +379,7 @@ void fiction_viewer_do_frame(float frametime)
// process button presses
for (i = 0; i < NUM_FVW_BUTTONS; i++)
if (Fiction_viewer_buttons[gr_screen.res][i].button.pressed())
if (Fiction_viewer_buttons[Fiction_viewer_ui][gr_screen.res][i].button.pressed())
fiction_viewer_button_pressed(i);
common_music_do();
@@ -324,14 +396,14 @@ void fiction_viewer_do_frame(float frametime)
Fiction_viewer_window.draw();
// render the briefing text
brief_render_text(Top_fiction_viewer_text_line, Fiction_viewer_text_coordinates[gr_screen.res][0], Fiction_viewer_text_coordinates[gr_screen.res][1], Fiction_viewer_text_coordinates[gr_screen.res][3], frametime);
brief_render_text(Top_fiction_viewer_text_line, Fiction_viewer_text_coordinates[Fiction_viewer_ui][gr_screen.res][0], Fiction_viewer_text_coordinates[Fiction_viewer_ui][gr_screen.res][1], Fiction_viewer_text_coordinates[Fiction_viewer_ui][gr_screen.res][3], frametime);
// maybe output the "more" indicator
if ((Fiction_viewer_text_max_lines + Top_fiction_viewer_text_line) < Num_brief_text_lines[0])
{
// can be scrolled down
int more_txt_x = Fiction_viewer_text_coordinates[gr_screen.res][0] + (Fiction_viewer_text_coordinates[gr_screen.res][2]/2) - 10;
int more_txt_y = Fiction_viewer_text_coordinates[gr_screen.res][1] + Fiction_viewer_text_coordinates[gr_screen.res][3] - 2; // located below text, centered
int more_txt_x = Fiction_viewer_text_coordinates[Fiction_viewer_ui][gr_screen.res][0] + (Fiction_viewer_text_coordinates[Fiction_viewer_ui][gr_screen.res][2]/2) - 10;
int more_txt_y = Fiction_viewer_text_coordinates[Fiction_viewer_ui][gr_screen.res][1] + Fiction_viewer_text_coordinates[Fiction_viewer_ui][gr_screen.res][3]; // located below text, centered
gr_get_string_size(&w, &h, XSTR("more", 1469), strlen(XSTR("more", 1469)));
gr_set_color_fast(&Color_black);
+1 -2
View File
@@ -1302,8 +1302,7 @@ int brief_setup_closeup(brief_icon *bi)
end_string_at_first_hash_symbol(Closeup_icon->closeup_label);
// Goober5000 - wcsaga doesn't want this
if (!Cmdline_wcsaga && sip->flags & (SIF_SMALL_SHIP|SIF_BIG_SHIP|SIF_HUGE_SHIP|SIF_SENTRYGUN))
{
if (Ship_types[sip->class_type].hud_bools & STI_HUD_NO_CLASS_DISPLAY ) {
strcat_s(Closeup_icon->closeup_label, XSTR( " class", 434));
}
+2 -40
View File
@@ -193,7 +193,6 @@ static int Voice_ended_time;
//static anim_instance *Cur_anim_instance = NULL;
static generic_anim Cur_Anim;
static char *Cur_anim_filename = "~~~~";
static int anim_done = 0;
static int Last_anim_frame_num;
@@ -342,11 +341,6 @@ void cmd_brief_new_stage(int stage)
// load a new animation if it's different to what's already playing
if (strcmp(Cur_anim_filename, Cur_cmd_brief->stage[stage].ani_filename) != 0) {
// set stuff up
int stream_result = -1;
ubyte bg_type = bm_get_type(Cmd_brief_background_bitmap);
anim_done = 0;
// unload the previous anim
if(Cur_Anim.num_frames > 0) {
generic_anim_unload(&Cur_Anim);
@@ -355,40 +349,8 @@ void cmd_brief_new_stage(int stage)
// save new filename
Cur_anim_filename = Cur_cmd_brief->stage[stage].ani_filename;
// hi-res support
if (gr_screen.res == GR_1024) {
// attempt to load a hi-res animation
memset(filename, 0, NAME_LENGTH);
strcpy_s(filename, "2_");
strncat(filename, Cur_anim_filename, NAME_LENGTH - 3);
// remove extension
p = strchr(filename, '.');
if(p) {
*p = '\0';
}
// attempt to stream the hi-res ani
generic_anim_init(&Cur_Anim, filename);
Cur_Anim.ani.bg_type = bg_type;
stream_result = generic_anim_stream(&Cur_Anim);
}
// we failed to stream hi-res, or we aren't running in hi-res, so try low-res
if (stream_result < 0) {
strcpy_s(filename, Cur_anim_filename);
// remove extension
p = strchr(filename, '.');
if(p) {
*p = '\0';
}
// attempt to stream the low-res ani
generic_anim_init(&Cur_Anim, filename);
Cur_Anim.ani.bg_type = bg_type;
stream_result = generic_anim_stream(&Cur_Anim);
}
// try to load the new anim in either high or low res
int stream_result = generic_anim_init_and_stream(&Cur_Anim, Cur_anim_filename, bm_get_type(Cmd_brief_background_bitmap), true);
// we've failed to load any animation
if (stream_result < 0) {
+1 -1
View File
@@ -2644,7 +2644,7 @@ void debrief_do_frame(float frametime)
}
// maybe show skip mission popup
if ((!Debrief_skip_popup_already_shown) && (Player->show_skip_popup) && (Game_mode & GM_NORMAL) && (Game_mode & GM_CAMPAIGN_MODE) && (Player->failures_this_session >= PLAYER_MISSION_FAILURE_LIMIT) && !(Game_mode & GM_MULTIPLAYER)) {
if ( Must_replay_mission && (!Debrief_skip_popup_already_shown) && (Player->show_skip_popup) && (Game_mode & GM_NORMAL) && (Game_mode & GM_CAMPAIGN_MODE) && (Player->failures_this_session >= PLAYER_MISSION_FAILURE_LIMIT) && !(Game_mode & GM_MULTIPLAYER)) {
int popup_choice = popup(0, 3, XSTR("Do Not Skip This Mission", 1473),
XSTR("Advance To The Next Mission", 1474),
XSTR("Don't Show Me This Again", 1475),
+13 -2
View File
@@ -1481,7 +1481,7 @@ void ship_select_do(float frametime)
//////////////////////////////////
// Render and draw the 3D model //
//////////////////////////////////
if( Cmdline_ship_choice_3d || ((Ss_icons != NULL) && (Selected_ss_class >= 0) && (Ss_icons[Selected_ss_class].ss_anim.num_frames > 0)) )
if( Cmdline_ship_choice_3d || ( (Selected_ss_class >= 0) && (Ss_icons[Selected_ss_class].ss_anim.num_frames == 0)) )
{
// check we have a valid ship class selected
if ( (Selected_ss_class >= 0) && (ShipSelectModelNum >= 0) )
@@ -1713,6 +1713,12 @@ void start_ship_animation(int ship_class, int play_sound)
return;
}
//Unload Anim if one was playing
if(Ship_anim_class > 0 && Ss_icons[Ship_anim_class].ss_anim.num_frames > 0) {
generic_anim_unload(&Ss_icons[Ship_anim_class].ss_anim);
Ship_anim_class = -1;
}
// Load the necessary model file
ShipSelectModelNum = model_load(sip->pof_file, sip->n_subsystems, &sip->subsystems[0]);
@@ -1733,6 +1739,12 @@ void start_ship_animation(int ship_class, int play_sound)
ss_icon = &Ss_icons[ship_class];
//If there was a model loaded for the previous ship, unload it
if (ShipSelectModelNum >= 0 ) {
model_unload(ShipSelectModelNum);
ShipSelectModelNum = -1;
}
//unload the previous anim
if(Ship_anim_class > 0 && Ss_icons[Ship_anim_class].ss_anim.num_frames > 0)
generic_anim_unload(&Ss_icons[Ship_anim_class].ss_anim);
@@ -1764,7 +1776,6 @@ void start_ship_animation(int ship_class, int play_sound)
// if ( play_sound ) {
gamesnd_play_iface(SND_SHIP_ICON_CHANGE);
// }
}
void ss_unload_all_anims()
+2
View File
@@ -315,6 +315,7 @@ typedef struct bsp_info {
bool nocollide_this_only; //SUSHI: Like no_collisions, but not recursive. For the "replacement" collision model scheme.
bool collide_invisible; //SUSHI: If set, this submodel should allow collisions for invisible textures. For the "replacement" collision model scheme.
bool force_turret_normal; //Wanderer: Sets the turret uvec to override any input of for turret normal.
char lod_name[MAX_NAME_LEN]; //FUBAR: Name to be used for LOD naming comparison to preserve compatibility with older tables. Only used on LOD0
float dumb_turn_rate;
@@ -350,6 +351,7 @@ typedef struct bsp_info {
dumb_turn_rate = 0.f;
bsp_data = NULL;
rad = 0.f;
lod_name[ 0 ] = '\0';
/* Compound types */
memset( live_debris, 0, sizeof( live_debris ) );
+24 -2
View File
@@ -100,7 +100,7 @@ void triggered_rotation::start(queued_animation *q)
if (q->accel.a1d[axis] == 0.0f)
slow_angle.a1d[axis] = end_angle.a1d[axis];
else
slow_angle.a1d[axis] = end_angle.a1d[axis] - (((q->vel.a1d[axis] * q->vel.a1d[axis]) / (2.0f * q->accel.a1d[axis])) * direction.a1d[axis]);
slow_angle.a1d[axis] = end_angle.a1d[axis] + (((q->vel.a1d[axis] * q->vel.a1d[axis]) / (2.0f * q->accel.a1d[axis])) * direction.a1d[axis]);
}
nprintf(("ModelAnim", "Dir=[%f, %f, %f], End=[%f, %f, %f], Vel=[%f, %f, %f], Accel=[%f, %f, %f], Slow=[%f, %f, %f]\n", direction.a1d[0], direction.a1d[1], direction.a1d[2],
@@ -421,7 +421,7 @@ void model_anim_submodel_trigger_rotate(model_subsystem *psub, ship_subsys *ss)
}
// if we've over shot the angle, this shouldn't happen but it might if odd values are given
if ( (trigger->current_ang.a1d[i] * trigger->direction.a1d[i]) > (trigger->end_angle.a1d[i] * trigger->direction.a1d[i]) ) {
if ( (trigger->current_ang.a1d[i] * trigger->direction.a1d[i]) >= (trigger->end_angle.a1d[i] * trigger->direction.a1d[i]) ) {
trigger->current_ang.a1d[i] = trigger->end_angle.a1d[i];
trigger->current_vel.a1d[i] = 0.0f;
not_moving_count++;
@@ -654,6 +654,7 @@ int model_anim_get_time_type(ship_subsys *pss, int animation_type, int subtype)
int pad = real_time - psub->triggers[i].end;
for (int a = 0; a < 3; a++) {
/*
float direction = pss->trigger.direction.a1d[a];
// if it's in the final slowdown phase then it really isn't _that_ bad
@@ -687,8 +688,29 @@ int model_anim_get_time_type(ship_subsys *pss, int animation_type, int subtype)
ani_time = a_time;
}
}
*/
// Wanderer Way -- START
// end_angle = S(2)
triggered_rotation tr = pss->trigger;
float end_angle = (tr.current_ang.a1d[a] + (((tr.rot_vel.a1d[a]*tr.rot_vel.a1d[a]) - (tr.current_vel.a1d[a]*tr.current_vel.a1d[a])) / (2*tr.rot_accel.a1d[a])));
if (end_angle > tr.slow_angle.a1d[a]) {
//T(total) = (2V(maximum) - V(initial))/a + (S(turnpoint) - S(initial) + (V(initial)^2 - V(maximum)^2)/2a) / V(maximum)
a_time = fl2i(((((2*tr.rot_vel.a1d[a]) - tr.current_ang.a1d[a])/tr.rot_accel.a1d[a]) + tr.slow_angle.a1d[a] - tr.current_ang.a1d[a] + (((tr.current_vel.a1d[a]*tr.current_vel.a1d[a]) - (tr.rot_vel.a1d[a]*tr.rot_vel.a1d[a])) / (2*tr.rot_accel.a1d[a])))*1000.0f);
if (ani_time < a_time)
ani_time = a_time;
} else {
//T(total) = 2 * sqrt((S(final) - S(initial))/a - ( (V(initial)/a)^2 ) / 2 ) - V(initial)/a
a_time = fl2i((2 * fl_sqrt(((tr.end_angle.a1d[a] - tr.current_ang.a1d[a])/tr.rot_accel.a1d[a]) - ((tr.current_vel.a1d[a] * tr.current_vel.a1d[a]) / (tr.rot_accel.a1d[a] * tr.rot_accel.a1d[a])) / 2) - (tr.current_vel.a1d[a] / tr.rot_accel.a1d[a]))*1000.0f);
if (ani_time < a_time)
ani_time = a_time;
}
// Wanderer Way -- END
}
if (ani_time)
ani_time += pad;
} else {
+45 -9
View File
@@ -1335,6 +1335,9 @@ int read_model_file(polymodel * pm, char *filename, int n_subsystems, model_subs
else
pm->submodel[n].gun_rotation = false;
if ( (p = strstr(props, "$lod0_name")) != NULL)
get_user_prop_value(p+10, pm->submodel[n].lod_name);
if ( (p = strstr(props, "$detail_box:")) != NULL ) {
p += 12;
while (*p == ' ') p++;
@@ -1502,6 +1505,13 @@ int read_model_file(polymodel * pm, char *filename, int n_subsystems, model_subs
else
pm->submodel[n].is_thruster=0;
// Genghis: if we have a thruster and none of the collision
// properties were provided, then set "nocollide_this_only".
if (pm->submodel[n].is_thruster && !(pm->submodel[n].no_collisions) && !(pm->submodel[n].nocollide_this_only) && !(pm->submodel[n].collide_invisible) )
{
pm->submodel[n].nocollide_this_only = true;
}
if ( strstr( pm->submodel[n].name, "-destroyed") )
pm->submodel[n].is_damaged=1;
else
@@ -2483,7 +2493,14 @@ int model_load(char *filename, int n_subsystems, model_subsystem *subsystems, in
}
sm1->num_details = 0;
l1 = strlen(sm1->name);
// If a backward compatibility LOD name is declared use it
if (strlen(sm1->lod_name) != 0) {
l1=strlen(sm1->lod_name);
}
// otherwise use the name for LOD comparision
else {
l1 = strlen(sm1->name);
}
for (j=0; j<pm->num_debris_objects;j++ ) {
if ( i == pm->debris_objects[j] ) {
@@ -2508,19 +2525,36 @@ int model_load(char *filename, int n_subsystems, model_subsystem *subsystems, in
}
// if sm2 is a detail of sm1 and sm1 is a high detail, then add it to sm1's list
if ((int)strlen(sm2->name)!=l1) continue;
if ((int)strlen(sm2->name)!=l1) continue;
int ndiff = 0;
int first_diff = 0;
for ( k=0; k<l1; k++) {
if (sm1->name[k] != sm2->name[k] ) {
if (ndiff==0) first_diff = k;
ndiff++;
// If a backward compatibility LOD name is declared use it
if (strlen(sm1->lod_name) != 0) {
if (sm1->lod_name[k] != sm2->name[k] ) {
if (ndiff==0) first_diff = k;
ndiff++;
}
}
// otherwise do the standard LOD comparision
else {
if (sm1->name[k] != sm2->name[k] ) {
if (ndiff==0) first_diff = k;
ndiff++;
}
}
}
if (ndiff==1) { // They only differ by one character!
int dl1, dl2;
dl1 = tolower(sm1->name[first_diff]) - 'a';
// If a backward compatibility LOD name is declared use it
if (strlen(sm1->lod_name) != 0) {
dl1 = tolower(sm1->lod_name[first_diff]) - 'a';
}
// otherwise do the standard LOD comparision
else {
dl1 = tolower(sm1->name[first_diff]) - 'a';
}
dl2 = tolower(sm2->name[first_diff]) - 'a';
if ( (dl1<0) || (dl2<0) || (dl1>=MAX_MODEL_DETAIL_LEVELS) || (dl2>=MAX_MODEL_DETAIL_LEVELS) ) continue; // invalid detail levels
@@ -2529,7 +2563,7 @@ int model_load(char *filename, int n_subsystems, model_subsystem *subsystems, in
dl2--; // Start from 1 up...
if (dl2 >= sm1->num_details ) sm1->num_details = dl2+1;
sm1->details[dl2] = j;
//mprintf(( "Submodel '%s' is detail level %d of '%s'\n", sm2->name, dl2, sm1->name ));
mprintf(( "Submodel '%s' is detail level %d of '%s'\n", sm2->name, dl2 + 1, sm1->name ));
}
}
}
@@ -2784,11 +2818,13 @@ float submodel_get_radius( int modelnum, int submodelnum )
polymodel * model_get(int model_num)
{
Assert( model_num > -1 );
Assert( model_num >= 0 );
if ( model_num < 0 )
return NULL;
int num = model_num % MAX_POLYGON_MODELS;
Assert( num > -1 );
Assert( num >= 0 );
Assert( num < MAX_POLYGON_MODELS );
Assert( Polygon_models[num] );
Assert( Polygon_models[num]->id == model_num );
+6
View File
@@ -279,6 +279,9 @@ void neb2_init()
if(Neb2_bitmap_count < MAX_NEB2_BITMAPS){
strcpy_s(Neb2_bitmap_filenames[Neb2_bitmap_count++], name);
}
else {
WarningEx(LOCATION, "nebula.tbl\nExceeded maximum number of nebulas (%d)!\nSkipping %s.", MAX_NEB2_BITMAPS, name);
}
}
// poofs
@@ -291,6 +294,9 @@ void neb2_init()
if(Neb2_poof_count < MAX_NEB2_POOFS){
strcpy_s(Neb2_poof_filenames[Neb2_poof_count++], name);
}
else {
WarningEx(LOCATION, "nebula.tbl\nExceeded maximum number of nebula poofs (%d)!\nSkipping %s.", MAX_NEB2_POOFS, name);
}
}
//Distance
+4 -1
View File
@@ -1593,6 +1593,9 @@ void standalone_main_init()
// if this is a tracker game then we have some extra tasks to perform
if (MULTI_IS_TRACKER_GAME) {
// disconnect and prepare for reset if we are already connected
fs2netd_disconnect();
// login (duh!)
if ( fs2netd_login() ) {
// validate missions
@@ -1659,7 +1662,7 @@ void multi_standalone_reset_all()
delete_player( idx );
}
}
// make sure we go to the proper state.
if(gameseq_get_state() == GS_STATE_STANDALONE_MAIN){
standalone_main_init();
+16 -5
View File
@@ -133,7 +133,7 @@ void multi_sexp_maybe_send_packet()
return;
}
send_sexp_packet(data, packet_end + 1);
send_sexp_packet(data, sub_packet_size);
j = 0;
//Slide down any entries after the stored index to the start of the array.
@@ -143,12 +143,21 @@ void multi_sexp_maybe_send_packet()
j++;
}
// if we have an existing argument count we need to update where to put it too
if (current_argument_count) {
argument_count_index -= sub_packet_size;
packet_size = j;
// flush the remaining type buffer
for (i = j ; i < MAX_PACKET_SIZE ; i++) {
type[i] = -1;
}
packet_size = j;
// if we have an existing argument count we need to update where to put it too
if (current_argument_count) {
argument_count_index = argument_count_index - sub_packet_size;
}
Assert(argument_count_index >=0);
}
// flushes out the packet and sends any data still in there
@@ -197,6 +206,8 @@ void multi_send_ship(int shipnum)
}
multi_send_ship(&Ships[shipnum]);
multi_sexp_maybe_send_packet();
}
void multi_send_ship(ship *shipp)
+1 -1
View File
@@ -1901,7 +1901,7 @@ void multi_join_send_join_request(int as_observer)
return;
}
nprintf(("Password : %s\n",Multi_join_request.passwd));
nprintf(("Network", "Password : %s\n", Multi_join_request.passwd));
}
// fill out the join request struct
+7 -5
View File
@@ -753,12 +753,14 @@ int weapon_will_never_hit( object *obj_weapon, object *other, obj_pair * current
float max_vel_weapon, max_vel_other;
max_vel_weapon = wp->weapon_max_vel;
if ((wp->lssm_stage==5))
{
//SUSHI: Fix bug where additive weapon velocity screws up collisions
//Assumes that weapons which don't home don't change speed, which is currently the case.
if (!(wip->wi_flags & WIF_TURNS))
max_vel_weapon = obj_weapon->phys_info.speed;
else if ((wp->lssm_stage==5))
max_vel_weapon = wip->lssm_stage5_vel;
}
else
max_vel_weapon = wp->weapon_max_vel;
max_vel_other = other->phys_info.max_vel.xyz.z;
if (max_vel_other < 10.0f) {
+4 -3
View File
@@ -790,6 +790,8 @@ void obj_move_call_physics(object *objp, float frametime)
int points = pm->missile_banks[i].num_slots;
int missles_left = shipp->weapons.secondary_bank_ammo[i];
int next_point = shipp->weapons.secondary_next_slot[i];
float fire_wait = Weapon_info[shipp->weapons.secondary_bank_weapons[i]].fire_wait;
float reload_time = (fire_wait == 0.0f) ? 1.0f : 1.0f / fire_wait;
//ok so...we want to move up missles but only if there is a missle there to be moved up
//there is a missle behind next_point, and how ever many missles there are left after that
@@ -799,7 +801,7 @@ void obj_move_call_physics(object *objp, float frametime)
for (int k = next_point; k < next_point+missles_left; k ++) {
float &s_pct = shipp->secondary_point_reload_pct[i][k % points];
if (s_pct < 1.0)
s_pct += shipp->reload_time[i] * frametime;
s_pct += reload_time * frametime;
if (s_pct > 1.0)
s_pct = 1.0f;
}
@@ -808,7 +810,7 @@ void obj_move_call_physics(object *objp, float frametime)
for (int k = 0; k < points; k++) {
float &s_pct = shipp->secondary_point_reload_pct[i][k];
if (s_pct < 1.0)
s_pct += shipp->reload_time[i] * frametime;
s_pct += reload_time * frametime;
if (s_pct > 1.0)
s_pct = 1.0f;
}
@@ -1927,7 +1929,6 @@ void object_set_gliding(object *objp, bool enable)
if(enable) {
objp->phys_info.flags |= PF_GLIDING;
objp->phys_info.glide_saved_vel = Player_obj->phys_info.vel;
} else {
objp->phys_info.flags &= ~PF_GLIDING;
vm_vec_rotate(&objp->phys_info.prev_ramp_vel, &objp->phys_info.vel, &objp->orient); //Backslash
+3 -1
View File
@@ -49,7 +49,9 @@ void shield_add_strength(object *objp, float delta)
if (delta == 0.0f)
return;
if (!(Ai_info[Ships[objp->instance].ai_index].ai_profile_flags & AIPF_SMART_SHIELD_MANAGEMENT))
if (!(Ai_info[Ships[objp->instance].ai_index].ai_profile_flags & AIPF_SMART_SHIELD_MANAGEMENT)
|| delta <= 0.0f) //SUSHI: We don't want smart shield management for negative delta
{
for (int i = 0; i < MAX_SHIELD_SECTIONS; i++)
shield_add_quad(objp, i, delta / MAX_SHIELD_SECTIONS);
+5 -5
View File
@@ -156,14 +156,14 @@ void save_filter_info(void)
void outwnd_printf2(char *format, ...)
{
char tmp[MAX_LINE_WIDTH*4];
char tmp[MAX_LINE_WIDTH*4] = {'\0'};
va_list args;
if (format == NULL)
return;
va_start(args, format);
vsprintf(tmp, format, args);
vsnprintf(tmp, sizeof(tmp)-1,format, args);
va_end(args);
outwnd_print("General", tmp);
@@ -171,14 +171,14 @@ void outwnd_printf2(char *format, ...)
void outwnd_printf(char *id, char *format, ...)
{
char tmp[MAX_LINE_WIDTH*4];
char tmp[MAX_LINE_WIDTH*4] = {'\0'};
va_list args;
if ( (id == NULL) || (format == NULL) )
return;
va_start(args, format);
vsprintf(tmp, format, args);
vsnprintf(tmp, sizeof(tmp)-1,format, args);
va_end(args);
outwnd_print(id, tmp);
@@ -297,7 +297,7 @@ void safe_point_print(char *format, ...)
va_list args;
va_start(args, format);
vsprintf(tmp, format, args);
vsnprintf(tmp, sizeof(tmp)-1,format, args);
va_end(args);
strcpy(safe_string, tmp);
}
+374 -3
View File
@@ -43,6 +43,7 @@
#include "sound/audiostr.h"
#include "sound/ds.h"
#include "weapon/weapon.h"
#include "weapon/beam.h"
//*************************Lua globals*************************
SCP_vector<ade_table_entry> Ade_table_entries;
@@ -3725,6 +3726,18 @@ ADE_FUNC(isValid, l_Weaponclass, NULL, "Detects whether handle is valid", "boole
return ADE_RETURN_TRUE;
}
ADE_FUNC(getWeaponClassIndex, l_Weaponclass, NULL, "Gets the index valus of the weapon class", "number", "index value of the weapon class")
{
int idx;
if(!ade_get_args(L, "o", l_Weaponclass.Get(&idx)))
return ade_set_args(L, "i", -1);
if(idx < 0 || idx >= Num_weapon_types)
return ade_set_args(L, "i", -1);
return ade_set_args(L, "i", idx);
}
//**********HANDLE: Eyepoint
struct eye_h
{
@@ -4092,20 +4105,27 @@ ADE_FUNC(checkRayCollision, l_Object, "vector Start Point, vector End Point, [bo
return ADE_RETURN_NIL;
obj = objh->objp;
int flags = 0;
int submodel = -1;
switch(obj->type) {
case OBJ_SHIP:
model_num = Ship_info[Ships[obj->instance].ship_info_index].model_num;
flags = (MC_CHECK_MODEL | MC_CHECK_RAY);
break;
case OBJ_WEAPON:
model_num = Weapon_info[Weapons[obj->instance].weapon_info_index].model_num;
flags = (MC_CHECK_MODEL | MC_CHECK_RAY);
break;
case OBJ_DEBRIS:
model_num = Debris[obj->instance].model_num;
flags = (MC_CHECK_MODEL | MC_CHECK_RAY | MC_SUBMODEL);
submodel = Debris[obj->instance].submodel_num;
break;
case OBJ_ASTEROID:
temp = Asteroids[obj->instance].asteroid_subtype;
model_num = Asteroid_info[Asteroids[obj->instance].asteroid_type].model_num[temp];
flags = (MC_CHECK_MODEL | MC_CHECK_RAY);
break;
default:
return ADE_RETURN_NIL;
@@ -4117,11 +4137,12 @@ ADE_FUNC(checkRayCollision, l_Object, "vector Start Point, vector End Point, [bo
mc_info hull_check;
hull_check.model_num = model_num;
hull_check.submodel_num = submodel;
hull_check.orient = &obj->orient;
hull_check.pos = &obj->pos;
hull_check.p0 = v3a;
hull_check.p1 = v3b;
hull_check.flags = MC_CHECK_MODEL | MC_CHECK_RAY;
hull_check.flags = flags;
if ( !model_collide(&hull_check) ) {
return ADE_RETURN_NIL;
@@ -4734,6 +4755,18 @@ ADE_FUNC(isModelLoaded, l_Shipclass, "[boolean Load = false]", "Checks if the mo
return ADE_RETURN_FALSE;
}
ADE_FUNC(getShipClassIndex, l_Shipclass, NULL, "Gets the index valus of the ship class", "number", "index value of the ship class")
{
int idx;
if(!ade_get_args(L, "o", l_Shipclass.Get(&idx)))
return ade_set_args(L, "i", -1);
if(idx < 0 || idx >= Num_ship_classes)
return ade_set_args(L, "i", -1);
return ade_set_args(L, "i", idx);
}
//**********HANDLE: Waypoint
ade_obj<object_h> l_Waypoint("waypoint", "waypoint handle", &l_Object);
@@ -6222,6 +6255,7 @@ ADE_FUNC(hasShipExploded, l_Ship, NULL, "Checks if the ship explosion event has
if (shipp->pre_death_explosion_happened == 1) {
return ade_set_args(L, "i", 1);
}
return ade_set_args(L, "i", 3);
}
return ade_set_args(L, "i", 0);
@@ -6935,6 +6969,312 @@ ADE_VIRTVAR(Team, l_Weapon, "team", "Weapon's team", "team", "Weapon team, or in
return ade_set_args(L, "o", l_Team.Set(wp->team));
}
ADE_FUNC(isArmed, l_Weapon, "[boolean Hit target]", "Checks if the weapon is armed.", "boolean", "boolean value of the weapon arming status")
{
object_h *oh = NULL;
bool hit_target = false;
if(!ade_get_args(L, "o|b", l_Weapon.GetPtr(&oh), &hit_target))
return ADE_RETURN_FALSE;
if(!oh->IsValid())
return ADE_RETURN_FALSE;
weapon *wp = &Weapons[oh->objp->instance];
if(weapon_armed(wp, hit_target))
return ADE_RETURN_TRUE;
return ADE_RETURN_FALSE;
}
//**********HANDLE: Beam
ade_obj<object_h> l_Beam("beam", "Beam handle", &l_Object);
ADE_VIRTVAR(Class, l_Beam, "weaponclass", "Weapon's class", "weaponclass", "Weapon class, or invalid weaponclass handle if beam handle is invalid")
{
object_h *oh=NULL;
int nc=-1;
if(!ade_get_args(L, "o|o", l_Beam.GetPtr(&oh), l_Weaponclass.Get(&nc)))
return ade_set_error(L, "o", l_Weaponclass.Set(-1));
if(!oh->IsValid())
return ade_set_error(L, "o", l_Weaponclass.Set(-1));
beam *bp = &Beams[oh->objp->instance];
if(ADE_SETTING_VAR && nc > -1) {
bp->weapon_info_index = nc;
}
return ade_set_args(L, "o", l_Weaponclass.Set(bp->weapon_info_index));
}
ADE_VIRTVAR(LastShot, l_Beam, "vector", "End point of the beam", "vector", "vector or null vector if beam handle is not valid")
{
object_h *oh=NULL;
vec3d *vec3;
if(!ade_get_args(L, "o|o", l_Beam.GetPtr(&oh), l_Vector.GetPtr(&vec3)))
return ade_set_error(L, "o", l_Vector.Set(vmd_zero_vector));
if(!oh->IsValid())
return ade_set_error(L, "o", l_Vector.Set(vmd_zero_vector));
beam *bp = &Beams[oh->objp->instance];
if(ADE_SETTING_VAR) {
bp->last_shot = *vec3;
}
return ade_set_args(L, "o", l_Vector.Set(bp->last_shot));
}
ADE_VIRTVAR(LastStart, l_Beam, "vector", "Start point of the beam", "vector", "vector or null vector if beam handle is not valid")
{
object_h *oh=NULL;
vec3d *v3;
if(!ade_get_args(L, "o|o", l_Beam.GetPtr(&oh), l_Vector.GetPtr(&v3)))
return ade_set_error(L, "o", l_Vector.Set(vmd_zero_vector));
if(!oh->IsValid())
return ade_set_error(L, "o", l_Vector.Set(vmd_zero_vector));
beam *bp = &Beams[oh->objp->instance];
if(ADE_SETTING_VAR) {
bp->last_start = *v3;
}
return ade_set_args(L, "o", l_Vector.Set(bp->last_start));
}
ADE_VIRTVAR(Target, l_Beam, "object", "Target of beam. Value may also be a deriviative of the 'object' class, such as 'ship'.", "object", "Beam target, or invalid object handle if beam handle is invalid")
{
object_h *objh;
object_h *newh;
if(!ade_get_args(L, "o|o", l_Beam.GetPtr(&objh), l_Object.GetPtr(&newh)))
return ade_set_error(L, "o", l_Object.Set(object_h()));
if(!objh->IsValid())
return ade_set_error(L, "o", l_Object.Set(object_h()));
beam *bp = NULL;
if(objh->objp->instance > -1)
bp = &Beams[objh->objp->instance];
else
return ade_set_error(L, "o", l_Object.Set(object_h()));
if(ADE_SETTING_VAR)
{
if(newh != NULL && newh->IsValid())
{
if(bp->target_sig != newh->sig)
{
bp->target = newh->objp;
bp->target_sig = newh->sig;
}
}
else
{
bp->target = NULL;
bp->target_sig = 0;
}
}
return ade_set_object_with_breed(L, OBJ_INDEX(bp->target));
}
ADE_VIRTVAR(TargetSubsystem, l_Beam, "subsystem", "Subsystem that beam is targeting.", "subsystem", "Target subsystem, or invalid subsystem handle if beam handle is invalid")
{
object_h *objh;
ship_subsys_h *newh;
if(!ade_get_args(L, "o|o", l_Beam.GetPtr(&objh), l_Subsystem.GetPtr(&newh)))
return ade_set_error(L, "o", l_Subsystem.Set(ship_subsys_h()));
if(!objh->IsValid())
return ade_set_error(L, "o", l_Subsystem.Set(ship_subsys_h()));
beam *bp = NULL;
if(objh->objp->instance > -1)
bp = &Beams[objh->objp->instance];
else
return ade_set_error(L, "o", l_Subsystem.Set(ship_subsys_h()));
if(ADE_SETTING_VAR)
{
if(newh != NULL && newh->IsValid())
{
if(bp->target_sig != newh->sig)
{
bp->target = newh->objp;
bp->target_subsys = newh->ss;
bp->target_sig = newh->sig;
}
}
else
{
bp->target = NULL;
bp->target_subsys = NULL;
}
}
return ade_set_args(L, "o", l_Subsystem.Set(ship_subsys_h(bp->target, bp->target_subsys)));
}
ADE_VIRTVAR(ParentShip, l_Beam, "object", "Parent of the beam.", "object", "Beam parent, or invalid object handle if beam handle is invalid")
{
object_h *objh;
object_h *newh;
if(!ade_get_args(L, "o|o", l_Beam.GetPtr(&objh), l_Object.GetPtr(&newh)))
return ade_set_error(L, "o", l_Object.Set(object_h()));
if(!objh->IsValid())
return ade_set_error(L, "o", l_Object.Set(object_h()));
beam *bp = NULL;
if(objh->objp->instance > -1)
bp = &Beams[objh->objp->instance];
else
return ade_set_error(L, "o", l_Object.Set(object_h()));
if(ADE_SETTING_VAR)
{
if(newh != NULL && newh->IsValid())
{
if(bp->sig != newh->sig)
{
bp->objp = newh->objp;
bp->sig = newh->sig;
}
}
else
{
bp->objp = NULL;
bp->sig = 0;
}
}
return ade_set_object_with_breed(L, OBJ_INDEX(bp->objp));
}
ADE_VIRTVAR(ParentSubsystem, l_Beam, "subsystem", "Subsystem that beam is fired from.", "subsystem", "Parent subsystem, or invalid subsystem handle if beam handle is invalid")
{
object_h *objh;
ship_subsys_h *newh;
if(!ade_get_args(L, "o|o", l_Beam.GetPtr(&objh), l_Subsystem.GetPtr(&newh)))
return ade_set_error(L, "o", l_Subsystem.Set(ship_subsys_h()));
if(!objh->IsValid())
return ade_set_error(L, "o", l_Subsystem.Set(ship_subsys_h()));
beam *bp = NULL;
if(objh->objp->instance > -1)
bp = &Beams[objh->objp->instance];
else
return ade_set_error(L, "o", l_Subsystem.Set(ship_subsys_h()));
if(ADE_SETTING_VAR)
{
if(newh != NULL && newh->IsValid())
{
if(bp->sig != newh->sig)
{
bp->objp = newh->objp;
bp->subsys = newh->ss;
}
}
else
{
bp->objp = NULL;
bp->subsys = NULL;
}
}
return ade_set_args(L, "o", l_Subsystem.Set(ship_subsys_h(bp->objp, bp->subsys)));
}
ADE_FUNC(getCollisionCount, l_Beam, NULL, "Get the number of collisions in frame.", "number", "Number of beam collisions")
{
object_h *objh;
if(!ade_get_args(L, "o", l_Beam.GetPtr(&objh)))
return ADE_RETURN_NIL;
beam *bp = NULL;
if(objh->objp->instance > -1)
bp = &Beams[objh->objp->instance];
else
return ADE_RETURN_NIL;
return ade_set_args(L, "i", bp->f_collision_count);
}
ADE_FUNC(getCollisionPosition, l_Beam, "number", "Get the position of the defined collision.", "vector", "World vector")
{
object_h *objh;
int idx;
if(!ade_get_args(L, "oi", l_Beam.GetPtr(&objh), &idx))
return ade_set_error(L, "o", l_Vector.Set(vmd_zero_vector));
// convert from Lua to C
idx--;
if ((idx >= 10) || (idx < 0))
return ade_set_error(L, "o", l_Vector.Set(vmd_zero_vector));
beam *bp = NULL;
if(objh->objp->instance > -1)
bp = &Beams[objh->objp->instance];
else
return ade_set_error(L, "o", l_Vector.Set(vmd_zero_vector));
// so we have valid beam and valid indexer
return ade_set_args(L, "o", l_Vector.Set(bp->f_collisions[idx].cinfo.hit_point_world));
}
ADE_FUNC(getCollisionObject, l_Beam, "number", "Get the target of the defined collision.", "object", "Object the beam collided with")
{
object_h *objh;
int idx;
if(!ade_get_args(L, "oi", l_Beam.GetPtr(&objh), &idx))
return ade_set_error(L, "o", l_Vector.Set(vmd_zero_vector));
// convert from Lua to C
idx--;
if ((idx >= 10) || (idx < 0))
return ade_set_error(L, "o", l_Vector.Set(vmd_zero_vector));
beam *bp = NULL;
if(objh->objp->instance > -1)
bp = &Beams[objh->objp->instance];
else
return ade_set_error(L, "o", l_Vector.Set(vmd_zero_vector));
// so we have valid beam and valid indexer
return ade_set_object_with_breed(L, bp->f_collisions[idx].c_objnum);
}
ADE_FUNC(isExitCollision, l_Beam, "number", "Checks if the defined collision was exit collision.", "boolean", "True if the collision was exit collision, false if entry, nil otherwise")
{
object_h *objh;
int idx;
if(!ade_get_args(L, "oi", l_Beam.GetPtr(&objh), &idx))
return ADE_RETURN_NIL;
// convert from Lua to C
idx--;
if ((idx >= 10) || (idx < 0))
return ADE_RETURN_NIL;
beam *bp = NULL;
if(objh->objp->instance > -1)
bp = &Beams[objh->objp->instance];
else
return ADE_RETURN_NIL;
// so we have valid beam and valid indexer
if (bp->f_collisions[idx].is_exit_collision)
return ADE_RETURN_TRUE;
return ADE_RETURN_FALSE;
}
//**********HANDLE: Wing
ade_obj<int> l_Wing("wing", "Wing handle");
@@ -7809,7 +8149,7 @@ ADE_FUNC(playGameSound, l_Audio, "Sound index, [Panning (-1.0 left to 1.0 right)
if(vol > 100.0f)
vol = 100.0f;
idx = snd_play(&Snds[idx], pan, vol*0.01f, pri, voice_msg);
idx = snd_play(&Snds[gamesnd_get_by_tbl_index(idx)], pan, vol*0.01f, pri, voice_msg);
return ade_set_args(L, "b", idx > -1);
}
@@ -7820,7 +8160,7 @@ ADE_FUNC(playInterfaceSound, l_Audio, "Sound index", "Plays a sound from #Interf
if(!ade_get_args(L, "i", &idx))
return ade_set_error(L, "b", false);
gamesnd_play_iface(idx);
gamesnd_play_iface(gamesnd_get_by_iface_tbl_index(idx));
return ade_set_args(L, "b", idx > -1);
}
@@ -10252,6 +10592,37 @@ ADE_FUNC(__len, l_Mission_Weapons, NULL, "Number of weapon objects in mission. N
return ade_set_args(L, "i", Num_weapons);
}
//****SUBLIBRARY: Mission/Beams
ade_lib l_Mission_Beams("Beams", &l_Mission, NULL, NULL);
ADE_INDEXER(l_Mission_Beams, "number Index", "Gets handle to a beam object in the mission.", "beam", "Beam handle, or invalid beam handle if index is invalid")
{
int idx;
if(!ade_get_args(L, "*i", &idx))
return ade_set_error(L, "o", l_Beam.Set(object_h()));
//Remember, Lua indices start at 0.
int count=1;
for(int i = 0; i < MAX_BEAMS; i++)
{
if (Beams[i].weapon_info_index < 0 || Beams[i].objnum < 0 || Objects[Beams[i].objnum].type != OBJ_BEAM)
continue;
if(count == idx) {
return ade_set_args(L, "o", l_Beam.Set(object_h(&Objects[Beams[i].objnum])));
}
count++;
}
return ade_set_error(L, "o", l_Beam.Set(object_h()));
}
ADE_FUNC(__len, l_Mission_Beams, NULL, "Number of beam objects in mission. Note that this is only accurate for one frame.", "number", "Number of beam objects in mission")
{
return ade_set_args(L, "i", Beam_count);
}
//****SUBLIBRARY: Mission/Wings
ade_lib l_Mission_Wings("Wings", &l_Mission, NULL, NULL);
+1
View File
@@ -65,6 +65,7 @@ flag_def_list Script_actions[] =
{"On Warp Out", CHA_WARPOUT, 0},
{"On Death", CHA_DEATH, 0},
{"On Mission End", CHA_MISSIONEND, 0},
{"On Weapon Delete", CHA_ONWEAPONDELETE, 0},
};
int Num_script_actions = sizeof(Script_actions)/sizeof(flag_def_list);
+1
View File
@@ -60,6 +60,7 @@ struct image_desc
#define CHA_KEYRELEASED 18
#define CHA_ONSTATESTART 19
#define CHA_ONSTATEEND 20
#define CHA_ONWEAPONDELETE 21
struct script_condition
+581 -242
View File
File diff suppressed because it is too large. Load diff
+27 -6
View File
@@ -13,6 +13,7 @@
#define _SEXP_H
struct ship_subsys;
struct ship;
// bumped to 30 by Goober5000
#define OPERATOR_LENGTH 30 // if this ever exceeds TOKEN_LENGTH, let JasonH know!
@@ -112,6 +113,7 @@ struct ship_subsys;
#define OPF_POST_EFFECT 67 // Hery - type of post-processing effect
#define OPF_TARGET_PRIORITIES 68 // FUBAR - Target priority groups
#define OPF_ARMOR_TYPES 69 // FUBAR - Armor type or <none>
#define OPF_HUD_ELEMENT 71 // A magic name of a specific HUD element
// Operand return types
#define OPR_NUMBER 1 // returns number
@@ -267,7 +269,7 @@ struct ship_subsys;
#define OP_SHIELDS_LEFT (0x0000 | OP_CATEGORY_STATUS | OP_NONCAMPAIGN_FLAG)
#define OP_HITS_LEFT (0x0001 | OP_CATEGORY_STATUS | OP_NONCAMPAIGN_FLAG)
#define OP_HITS_LEFT_SUBSYSTEM (0x0002 | OP_CATEGORY_STATUS | OP_NONCAMPAIGN_FLAG)
#define OP_HITS_LEFT_SUBSYSTEM (0x0002 | OP_CATEGORY_STATUS | OP_NONCAMPAIGN_FLAG) // deprecated
#define OP_SIM_HITS_LEFT (0x0003 | OP_CATEGORY_STATUS | OP_NONCAMPAIGN_FLAG)
#define OP_DISTANCE (0x0004 | OP_CATEGORY_STATUS | OP_NONCAMPAIGN_FLAG)
#define OP_DISTANCE_SUBSYSTEM (0x0005 | OP_CATEGORY_STATUS | OP_NONCAMPAIGN_FLAG) // Goober5000
@@ -492,7 +494,7 @@ struct ship_subsys;
#define OP_CUTSCENES_SET_FOV (0x0085 | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) // WMC
#define OP_CUTSCENES_RESET_FOV (0x0086 | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) // WMC
#define OP_CUTSCENES_RESET_CAMERA (0x0087 | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) // WMC
#define OP_CUTSCENES_SHOW_SUBTITLE (0x0088 | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) // WMC
#define OP_CUTSCENES_SHOW_SUBTITLE (0x0088 | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) // WMC / deprecated
#define OP_CUTSCENES_SET_TIME_COMPRESSION (0x0089 | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) // WMC
#define OP_CUTSCENES_RESET_TIME_COMPRESSION (0x008a | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) // WMC
#define OP_CUTSCENES_FORCE_PERSPECTIVE (0x008b | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) // WMC
@@ -567,9 +569,14 @@ struct ship_subsys;
#define OP_SET_VARIABLE_BY_INDEX (0x00cd | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) // Goober5000
#define OP_SET_POST_EFFECT (0x00ce | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) // Hery
#define OP_TURRET_SET_OPTIMUM_RANGE (0x00cf | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) // FUBAR
#define OP_TURRET_SET_DIRECTION_PREFERENCE (0x00d0 | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) // FUBAR
#define OP_TURRET_SET_TARGET_PRIORITIES (0x00d1 | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) // FUBAR
#define OP_SET_ARMOR_TYPE (0x00d2 | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) // FUBAR
#define OP_CUTSCENES_SHOW_SUBTITLE_TEXT (0x00d3 | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) // Goober5000
#define OP_CUTSCENES_SHOW_SUBTITLE_IMAGE (0x00d4 | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG) // Goober5000
#define OP_MISSION_SET_SUBSPACE (0x00d5 | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG)
#define OP_HUD_DISPLAY_GAUGE (0x00d6 | OP_CATEGORY_CHANGE | OP_NONCAMPAIGN_FLAG)
/* made obsolete by Goober5000
// debugging sexpressions
@@ -735,8 +742,10 @@ char *CTEXT(int n);
#define SEXP_VARIABLE_NOT_USED (1<<7) // (0x0080)
#define SEXP_VARIABLE_BLOCK (1<<0) // (0x0001)
/*
#define SEXP_VARIABLE_BLOCK_EXP (1<<1) // (0x0002)
#define SEXP_VARIABLE_BLOCK_HIT (1<<2) // (0x0004)
*/
#define SEXP_VARIABLE_PLAYER_PERSISTENT (1<<3) // (0x0008)
// Goober5000 - hopefully this should work and not conflict with anything
@@ -832,6 +841,7 @@ char *CTEXT(int n);
#define SEXP_CHECK_INVALID_PERSONA_NAME -139
#define SEXP_CHECK_INVALID_VARIABLE_TYPE -140
#define SEXP_CHECK_INVALID_SUBSYS_TYPE -141
#define SEXP_CHECK_INVALID_HUD_ELEMENT -143
#define TRAINING_CONTEXT_SPEED (1<<0)
#define TRAINING_CONTEXT_FLY_PATH (1<<1)
@@ -900,6 +910,7 @@ extern int Num_sexp_nodes;
extern sexp_node *Sexp_nodes;
extern sexp_variable Sexp_variables[MAX_SEXP_VARIABLES];
extern sexp_variable Block_variables[MAX_SEXP_VARIABLES];
extern sexp_oper Operators[];
extern int Num_operators;
@@ -988,10 +999,9 @@ void sexp_variable_delete(int index);
void sexp_variable_sort();
void sexp_fred_modify_variable(const char *text, const char *var_name, int index, int type);
int sexp_add_variable(const char *text, const char *var_name, int type, int index=-1);
int sexp_variable_allocate_block(const char* block_name, int block_type);
void sexp_variable_condense_block();
void sexp_variable_block_free(const char *ship_name, int start_index, int block_type);
bool generate_special_explosion_block_variables();
int num_block_variables();
bool has_special_explosion_block_index(ship *shipp, int *index);
// Karajorma
void set_primary_ammo (int ship_index, int requested_bank, int requested_ammo, int rearm_limit=-1, bool update=true);
@@ -1034,4 +1044,15 @@ bool output_sexps(char *filepath);
void multi_sexp_eval();
/** Global state variables for the hud-display-gauge sexp.
They all should be named Sexp_hud_display_*;
They all should follow the following symantics for the value of the
variable:
=0 don't show
=1 show until canceled
>1 timestamp when gauge should stop showing (set zero when expired)
\sa sexp_hud_display_warpout
*/
extern int Sexp_hud_display_warpout;
#endif
+20 -27
View File
@@ -263,7 +263,11 @@ void particle_move_all(float frametime)
return;
for (SCP_vector<particle>::iterator p = Particles.begin(); p != Particles.end(); ) {
p->age += frametime;
if (p->age == 0.0f) {
p->age = 0.00001f;
} else {
p->age += frametime;
}
// if it's time expired, remove it
if (p->age > p->max_life) {
@@ -356,12 +360,21 @@ void particle_render_all()
for (SCP_vector<particle>::iterator p = Particles.begin(); p != Particles.end(); ++p) {
// skip back-facing particles (ripped from fullneb code)
if ( vm_vec_dot_to_point(&Eye_matrix.vec.fvec, &Eye_position, &p->pos) <= 0.0f ) {
// Wanderer - add support for attached particles
vec3d p_pos;
if (p->attached_objnum >= 0) {
vm_vec_unrotate(&p_pos, &p->pos, &Objects[p->attached_objnum].orient);
vm_vec_add2(&p_pos, &Objects[p->attached_objnum].pos);
} else {
p_pos = p->pos;
}
if ( vm_vec_dot_to_point(&Eye_matrix.vec.fvec, &Eye_position, &p_pos) <= 0.0f ) {
continue;
}
// calculate the alpha to draw at
alpha = get_current_alpha(&p->pos);
alpha = get_current_alpha(&p_pos);
// if it's transparent then just skip it
if (alpha <= 0.0f) {
@@ -373,7 +386,7 @@ void particle_render_all()
// if this is a tracer style particle, calculate tracer vectors
if (p->tracer_length > 0.0f) {
ts = p->pos;
ts = p_pos;
temp = p->velocity;
vm_vec_normalize_quick(&temp);
vm_vec_scale_add(&te, &ts, &temp, p->tracer_length);
@@ -381,37 +394,17 @@ void particle_render_all()
// don't bother rotating
rotate = 0;
}
// if this is an "attached" particle. move it
else if (p->attached_objnum >= 0) {
// offset the vector, and transform to view coords
// vm_vec_add(&te, &Objects[p->attached_objnum].pos, &p->pos);
vm_vec_unrotate(&temp, &p->pos, &Objects[p->attached_objnum].orient);
vm_vec_add2(&temp, &Objects[p->attached_objnum].pos);
flags = g3_rotate_vertex(&pos, &temp);
if (flags) {
continue;
}
if (!Cmdline_nohtl)
g3_transfer_vertex(&pos, &temp);
// don't bother rotating again
rotate = 0;
}
// rotate the vertex
if (rotate) {
flags = g3_rotate_vertex( &pos, &p->pos );
flags = g3_rotate_vertex( &pos, &p_pos );
if ( flags ) {
continue;
}
if (!Cmdline_nohtl)
g3_transfer_vertex(&pos, &p->pos);
g3_transfer_vertex(&pos, &p_pos);
}
// pct complete for the particle
@@ -429,7 +422,7 @@ void particle_render_all()
if (p->type == PARTICLE_DEBUG) {
gr_set_color( 255, 0, 0 );
g3_draw_sphere_ez( &p->pos, p->radius );
g3_draw_sphere_ez( &p_pos, p->radius );
} else {
framenum = p->optional_data;
+17 -13
View File
@@ -687,7 +687,20 @@ void physics_read_flying_controls( matrix * orient, physics_info * pi, control_i
if ( pi->flags & PF_REDUCED_DAMP ) {
ramp_time_const *= reduced_damp_ramp_time_expansion;
}
pi->prev_ramp_vel.xyz.z = velocity_ramp( pi->prev_ramp_vel.xyz.z, goal_vel.xyz.z, ramp_time_const, sim_time);
pi->prev_ramp_vel.xyz.z = velocity_ramp(pi->prev_ramp_vel.xyz.z, goal_vel.xyz.z, ramp_time_const, sim_time);
//Deternine the current dynamic glide cap, and ramp to it
//This is outside the normal "glide" block since we want the cap to adjust whether or not the ship is in glide mode
float dynamic_glide_cap_goal = 0.0;
if (pi->flags & PF_AFTERBURNER_ON) {
dynamic_glide_cap_goal = ( goal_vel.xyz.z >= 0.0f ) ? pi->afterburner_max_vel.xyz.z : pi->afterburner_max_reverse_vel;
}
else {
//Use the maximum value in X, Y, and Z (including overclocking)
dynamic_glide_cap_goal = MAX(MAX(pi->max_vel.xyz.x,pi->max_vel.xyz.y), pi->max_vel.xyz.z);
}
pi->cur_glide_cap = velocity_ramp(pi->cur_glide_cap, dynamic_glide_cap_goal, ramp_time_const, sim_time);
if ( pi->flags & PF_GLIDING ) {
pi->desired_vel = pi->vel;
@@ -699,19 +712,10 @@ void physics_read_flying_controls( matrix * orient, physics_info * pi, control_i
//Having pi->glide_cap == 0 means we're using a dynamic glide cap
float curGlideCap = 0.0f;
if (pi->glide_cap == 0.0f) {
//For dynamic glide capping, normal flight and afterburner have separate glide caps
if (pi->flags & PF_AFTERBURNER_ON) {
curGlideCap = pi->afterburner_max_vel.xyz.z;
}
else {
//Take the maximum value in X, Y, and Z (including overclocking)
curGlideCap = MAX(MAX(pi->max_vel.xyz.x,pi->max_vel.xyz.y), pi->max_vel.xyz.z);
}
}
else {
if (pi->glide_cap == 0.0f)
curGlideCap = pi->cur_glide_cap;
else
curGlideCap = pi->glide_cap;
}
//If we're near the (positive) glide cap, decay velocity where we aren't thrusting
//This is a hack, but makes the flight feel a lot smoother
+1 -1
View File
@@ -85,8 +85,8 @@ typedef struct physics_info {
int shockwave_decay; // timestamp used to control how long ship affected after hit by shockwave
int reduced_damp_decay; // timestamp used to control how long ship ship has reduced damp physics
vec3d glide_saved_vel; //WMC - the key variable for gliding. Saves the orientation that velocity will be applied on.
float glide_cap; //Backslash - for 'newtonian'-style gliding, the cap on velocity (so that something can't accelerate to ridiculous speeds... unless allowed to)
float cur_glide_cap; //SUSHI: Used for dynamic glide cap, so we can use the ramping function on the glide cap
float glide_accel_mult; //SUSHI: The acceleration multiplier for glide mode. A value < 0 means use glide ramping instead
bool use_newtonian_damp; //SUSHI: Whether or not to use newtonian dampening
float afterburner_max_reverse_vel; //SparK: This is the reverse afterburners top speed vector
Loaded 100 of 170 files, more files were not shown because too many files have changed in this diff. Show more