I think this should be good, but I can't test it right now because
I don't have a Windows compiler handy at the moment. Will make sure
to do so before making a release.
The modern version sells for rockets (i.e. you get rockets back when
you sell your secondary), but the original instead left you with
no secondary at all in this case. This behavior has now been restored.
At some point I replaced the "Target" text with "Sid", "Phoebe", and
"Kline" for those respective characters. Classic difficulty now always
uses the word "Target" once again.
The main problem with this bug was simply that it caused a constant
cycle of resurrection and death, which generated tons and tons of
powerups. It was only realistically achievable with cheats enabled,
but still, this seems undesirable.
It's not exactly the same technically, but in function it is. The
only functional difference is that the original would sometimes show
an unexpected health bar for a small(ish) enemy, whereas the new
implementation never does that.
Also different is that exact location is still shown. Will fix that
next.
So, that segfault? Turns out there's a place where I forgot to check
if something was NULL before accessing it, which turned out to be
important because for some reason, gfx_textSprites[TS_RADIO] got
set to 32 at some point while gfx_messageBox remained NULL.
This may be indicative of a memory leak somewhere, but it's
also possible that maybe it was left-over from a previous mission
or something, which may have been what made it so hard to spot (that
would make the bug time-sensitive as well as context-sensitive). In
any case, at least the segfault is fixed now.
This is something I forgot about before: the executive transport
A.I. was changed by me at some point from "Normal" to "Evasive".
This change re-introduces "Normal" A.I. for this ship in Classic
difficulty.
There are only a couple changes that I've left in:
1. On normal missions, the edge of the screen still doesn't slow you down.
2. The shop still does not have the old bug where selling was based on the price of the next item.
3. Not sure about this, but some powerups don't spawn if they're of no use to you; I believe this was not in the original, but it's been left in anyway.
4. Not sure about this either, but I believe the original had the 3-way spread much wider. This has not been adjusted for Classic difficulty.
Other than those three, Classic difficulty is now exactly the same,
including a re-implementation of the whole "score" system where destroying
a ship nets you money instantly and the absurd system where you buy only
10 plasma capacity at a time. I might adjust 1, 3, and/or 4 above later
on.
Limited damage prevention to only at the "low" and "critical" levels,
plus added a delay for when damage is first inflicted by rays.
This prevents ships with multiple concentrated shots from having
a disadvantage, and it helps make rays easier to avoid at the same
time (just get out of the ray in time and you don't take damage).
Of course, neither of these apply to Classic difficulty, although
the ray damage delay does apply to Nightmare difficulty (which,
given how unpredictable rays are, I think is quite reasonable).
Limits the damage you take somewhat. Basically, this is intended
to prevent sudden deaths; if it doesn't look like you're dying,
you probably won't suddenly get axed. Of course, this is disabled
in Classic difficulty.
The mistake caused the Classic game to deviate from the original
by not allowing Kline to drop mines in the Elamale mission. For
some reason I accidentally put that check in for Moebo instead.
Whoops!
At first I was going to just not bother with the resizing thing, but
then I found out that SDL actually has a scaling function built-in.
So rather than depending on SDL_gfx for this one purpose that never
sees the light of day in practice, I have handed that job over to
that function.
The fake "windowed fullscreen" is less invasive, but it sometimes
causes ugly artifacts and as a general rule isn't really all that
useful.
However, I also defined it in defs.h, so that it can be more easily
changed in the future.
In particular, sizes larger than the background work properly now
(in general; there are of course some things positioned badly still,
but everything updates correctly at any rate).
Ultimately, the following were removed:
* The portrait of Chris on top, which was superfluous.
* The text telling you who you were communicating with. Both superfluous and prone to inconsistencies.
* The button allowing you to return to the list of missions. Instead, you can click anywhere to do so, or just click on the "Missions" button again.
So now, the only thing left preventing 640x480 from being a usable
resolution is the shop. That's going to be a tough one...
It's not perfect, but I honestly just can't be arsed to figure out
how to use the Windows API to do the same thing that pwd.h does.
At the very least, Starfighter can now be successfully compiled for
Windows with MinGW simply by defining the "SF_WINDOWS" environment
variable to 1 (or any other non-empty value). The only downside is
that it uses the current working directory to decide where
.config/starfighter should go, meaning it can't be installed into
restricted directories like Program Files.
gfx_drawLine only supported drawing straight horizontal and vertical
lines anyway, so the method it used was completely pointless. It also
wasn't used anywhere other than gfx_drawRect.
I've made a couple of improvements here:
1. There is now a limit to how much value can be in a single
collectable. This means, most importantly, that there will be
no more 1000 plasma collectables or anything else ridiculous
like that. It also means that bosses now tend to drop a ton of
different collectable objects.
2. Collectables dropped by ships now live longer if a lot of
collectables were dropped. In practice, this only affects bosses;
no normal enemy drops enough to trigger this.
The combined results of these changes are that you're less likely
to get stuck with a useless item when you kill a boss (such as
plasma you don't need) rather than money, and you are more capable
of collecting the huge wads of cash left behind by the bosses that
drop more.
Classic difficulty penalizes you for selling items, so it's best not
to automatically sell anything that doesn't need to be. It could be,
for example, that you want to switch to a laser and then back to
rockets, in which case the auto-selling could make this much more
costly or cripple your missiles when you come back to them.
It looks like I'm finally almost done with this! The only thing left
is gradually replacing "Starfighter.h" imports with imports of what
actually is needed.
I did one structural change to the way ship_fireBullet works. It
previously had two separate places for reducing ammo from the player.
I changed this so that it removes ammo in the same place regardless
of which weapon it is, but then performs the plasma "out of ammo"
action afterwards. It seems to work properly.
Also fixed a flaw in the saving which would in some cases cause
the stationed planet to not get saved properly.
This was done with "replace all" actions, but I have checked and
the only collatoral damage has been to capitalize some instances
of "objective" in comments.
At first I was doing the same thing to them I did to the bragging
messages, but when it came to actually thinking of things these
characters should say, nothing I liked came up. The main problem
is nothing fits the characters' expressions. Add to that the
complexity of making this really work right, and it's just not
worth it.
The Sid death message has also been removed, both for consistency
and because of the mismatch of Chris's face with what he said there.
I considered rewriting it, but I don't think the intro text really
adds anything. Starfighter is an action game, not an adventure game,
so it's just out of place to show a paragraph of backstory before
the game starts.
The explosions of mines off in the distance are extremely annoying in
the Mars mission, in particular. There's no real point in them
doing a timed off-screen explosion, anyway; if they just disappear,
the player won't notice.
SDL_GetTicks() returns Uint32, but I was using the long int type,
which could mean signed or unsigned, not to mention any size. Changed
missionCompleteTimer and timeTaken to Uint32 for consistency.
This prevents the weird effect where you hear a bunch of sounds of
majorly different volumes starting and stopping. If, for example, you
have several mines exploding nearby as well as several mines exploding
far away at the same time, you will hear the near ones and not the far
ones.
Several pointless lines have been removed, and I've added a workaround
to fix a segfault that was happening when Phoebe or Ursula were not
wingmates yet.
This format is actually portable, and there isn't a risk of it just
breaking any time the format is changed, since the version number
can be read independently of everything else.
I understand where this came from; obviously, this was how travel
originally worked, and then the version that made interceptions
possible was added later. But the thing is, making Spirit a special
case causes the interface to suddenly change on you, and that breaks
the flow of the game for no particular reason other than saving a
bit of time. So this special code which causes you to instantly
teleport in Spirit has now been removed. There is still no danger
of encountering interceptions, but I'll be changing that for all
non-Classic difficulties as well in another commit.
This oddity was caused by exactly what I thought it was caused by:
the code assumed that all bullets are created equal, and each bullet
had a 1 in 50 chance of causing the ship to run away. Well, the
charger inflicts so much damage that 50 shots would be a ridiculous
amount of damage for even the experimental fighter.
So now, except in Classic difficulty, whether or not it runs away
is determined partly by how much damage a weapon inflicts.
Specifically, the chance is now the damage of the bullet out of 150.
High-damage weapons are still a useful idea; after all, a 100 damage
weapon is 100 guaranteed damage, even if the fighter is likely to flee.
However, it gets rid of the skewed nature of the fleeing behavior and
prevents the charger from subverting the purpose of the behavior.
This is the last of the data files I wanted to remove.
This commit also includes some dialog changes.
I copied some of this code into a comment elsewhere, because I want
to use it as a reference when creating a new save format.
It's a modified version of the weapon switching: if Kline's health
is less than 1500, the spread shot replaces the concentrated triple
shot.
This also keeps Kline with bullet weapons during the third phase.
The main purpose of this change is to make Kline consistent. He now
switches his secondary weapon, and that's about it. The way it was
in the original, it started out much easier than previous encounters,
then it went to slightly easier than previous encounters, then
something completely unlike previous encounters, and finally
something noticeably harder than previous encounters. Now, it starts
out exactly the same as previous encounters, and then gets
progressively harder.
I don't understand why there is code to prevent Kline from dropping
mines after his first appearance. So except in Classic difficulty,
this limitation has been removed. He now drops mines in all of his
appearances.
This was just really weird-looking and had no particular benefit.
I guess theoretically you can use the couple of seconds to grab stuff
you missed, but in practice, there usually isn't much stuff there.
Sure, the escort is what you're supposedly after, but it's
invincible, and your real priority is to protect Sid. It helps that
it now says "Sid" when Sid is the target; that should prevent
any possible confusion. :)
There were two problems:
1. Some areas did not have any code to protect against this.
2. In one area that did have such code, it was malformed, and actually
caused the "no damage" cheat to be negated after the mission was
completed.
Both have been fixed.
There are two adjustments here:
First, Classic difficulty now gives these items the same price as
the original (50), which is important because the original made it
very easy to grind by filling up on plasma at interceptions and then
selling it. $25 is a lot more than $5.
Second, for every other difficulty, the price has been dropped down
from 10 to 1. The reason I'm doing this is unlike in the original,
you now pretty much have to routinely fill up on rockets and/or
plasma ammo to use these weapons, and it puts the weapons which
don't need ammo (laser and charger) at an unfair advantage, basically
turning use of rockets into a mistake. By making the prices very low,
you still want to conserve plasma and rockets, but the effect is more
to deprive you of their use later on in the mission than to drain
your money.
I think this might partly be because of my dialog changes, but this
causes a minor continuity error, since the mission clearly states
that you're rescuing "Phoebe Lexx", and there's also the fact that
the indicator now says "Phoebe" instead of "Target". I figure just
make her name known from the start; the explanation can be that the
ship automatically transmits the name.
The previous one positioned the arrows based on the difference between
their X distance and Y distance; objects that were further away
would be closer to the center. However, the code was confusing, and
a major practical effect of this was it was impossible to really know
exactly where an object was.
This new, simpler method makes aiming at targets that are off-screen
feasible, and it also utilizes the diagonal arrows.
It was triggered whenever there was a message being displayed.
Thing is, there's no legitimate reason to do this. It doesn't ever
obscure the radio message, and there wasn't some technical limitation
in place. It just did it... just because.
This was a strange cause, and I wonder why it happened. Quite simply,
there was an assumption in the code that any alien's primary weapon
was a bullet, despite the fact that the secondary weapon code could
handle any weapon, including bullets. I've fixed this by getting rid
of the special primary weapon mechanism; the one for the secondary
weapons is used on primary weapons as well.
There are two aspects to this:
1. They now simply make sure your plasma ammo is at a minimum of
50, rather than adding to your plasma ammo as in the other
difficulties.
2. Added a simulation of a bug in Starfighter 1.1 which caused
each aspect of the Supercharge to be lost when you picked up
a different associated powerup. Even though this was a bug,
without it, the Supercharge becomes extraordinarily more
game-breaking, since it's the only thing that sort of limits
its longevity.
This should add some much-needed depth to the tacticality of the
weapon. It's not much: it takes 5 plasma cells to fully charge the
cannon. But it does eliminate the previous effect where the charger
was always preferable over plasma bullets; it's still preferable in
a lot of circumstances, but for smaller ships, it's now typically
better to use plain old plasma ammo. It also limits the amount of
times the charger can be used.
The only magic numbers left now are related to positioning, image
sizing, and the remaining "data" files (the "planets" and "brief" ones).
At least, I'm pretty sure that's the case.
God, this one was definitely the biggest headache of all of the
magic number erasing. Never did I expect such cryptic problems.
The first problem was that the entirety of the player's weapon
struct was a part of the save file, *including the weapon's "image
indexes"*. Since the indexes have been changed, and the originally
used one is now unavailable when it's requested, this was causing
a segfault later on. Had to fix this by setting the image index
when the game is loaded.
The second problem was related to another bug I've been confused
about for years: the one that causes mobile rays to fire 5 green
shots. The entire reason those shots were green was because
the weapon's image indexes were undefined, and *that was causing
them to default to 0*. 0 was simply the index of green plasma.
Of course, though, now attempting to use that image causes a
segfault, so for now, I've fixed this by changing the image index
of the mobile rays to the red plasma bolts.
There are still some magic numbers left, related to the intermission
screen. But the hardest part is now done, thank God.
I found myself confused by the interception chances, because it looked
like the chance of interceptions was decreasing slowly over time.
Turns out, it was the denominator in a fraction; a "chance" of 300
meant that there was a 1 / 300 chance.
These are just there so that you can define these at compile time
without modifying the source code. In the future, I would like this
to only be the *default* screen width and height, because I'll want
to add an option in the menu to change the resolution from 640x480
up to whatever your monitor's resolution is.
This is capable of handling any resolution which is at least 640x360.
Actually, resolutions a bit smaller than that can be handled. No
manual adjustment is necessary. :)
Now, the intermission screen needs to be fixed...
This places the logo at 1/3 of the way down the screen, rather than
half of the way down, and the menu ends up about in the middle of
the screen now. This doesn't really matter as it is, but it should
help some with lower resolutions.
Also, now that the magic numbers are gone, I was able to get rid of
all the hardsetting of numbers for the special ship indexes (which
was only in place to avoid breaking the magic numbers).
This name is better since the difficulty isn't actually *exactly*
like the original; it's just trying to be as similar to the classic
experience as possible.
Like "scripts", these definitions in text files make absolutely no
sense. They are completely unreadable, and Starfighter's engine is
inflexible anyway.