Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Health gets reset on level change. #17

Closed
CKWarner opened this issue Jun 15, 2019 · 3 comments
Closed

Health gets reset on level change. #17

CKWarner opened this issue Jun 15, 2019 · 3 comments

Comments

@CKWarner
Copy link
Contributor

CKWarner commented Jun 15, 2019

If you leave a level with greater than your normal maximum health - because you've picked up some of the single-unit health packs, for example - your health gets reset down to the maximum health (100 + n adrenalines) instead. This is obviously incorrect behaviour.

@DU-jdto
Copy link

DU-jdto commented Jun 16, 2019

This is obviously incorrect behaviour.

Is it? This has been in every version of Quake 2 I've tried, and I always assumed it was intended.

@CKWarner
Copy link
Contributor Author

CKWarner commented Jun 16, 2019

Is it? This has been in every version of Quake 2 I've tried, and I always assumed it was intended.

Hmm; you're right that the GOG version does it too. I'd not played through Quake 2 before this version.

It still seems like a mistake that's just never been corrected: you keep all your armour and items intact over level changes, after all.

As far as I can tell, the health is supposed to be preserved across level changes, it just isn't. From the original Quake 2 source code's g_local.c:

// client data that stays across multiple level loads
typedef struct
{
	char		userinfo[MAX_INFO_STRING];
	char		netname[16];
	int			hand;

	qboolean	connected;			// a loadgame will leave valid entities that
									// just don't have a connection yet

	// values saved and restored from edicts when changing levels
	int			health;
	int			max_health;
	int			savedFlags;

	int			selected_item;
	int			inventory[MAX_ITEMS];

	// ammo capacities
	int			max_bullets;
	int			max_shells;
	int			max_rockets;
	int			max_grenades;
	int			max_cells;
	int			max_slugs;

	gitem_t		*weapon;
	gitem_t		*lastweapon;

	int			power_cubes;	// used for tracking the cubes in coop games
	int			score;			// for calculating total unit score in coop games

	int			game_helpchanged;
	int			helpchanged;

	qboolean	spectator;			// client is a spectator
} client_persistant_t;

Ah, nope, it was deliberate. From g_main.c:

/*
=============
ExitLevel
=============
*/
void ExitLevel (void)
{
	int		i;
	edict_t	*ent;
	char	command [256];

	Com_sprintf (command, sizeof(command), "gamemap \"%s\"\n", level.changemap);
	gi.AddCommandString (command);
	level.changemap = NULL;
	level.exitintermission = 0;
	level.intermissiontime = 0;
	ClientEndServerFrames ();

	// clear some things before going to next level
	for (i=0 ; i<maxclients->value ; i++)
	{
		ent = g_edicts + 1 + i;
		if (!ent->inuse)
			continue;
		if (ent->health > ent->client->pers.max_health)
			ent->health = ent->client->pers.max_health;
	}

}

I still think it kinda sucks, though.

@CKWarner
Copy link
Contributor Author

It's a simple patch to change the behaviour, which I've done on my one because I think it kinda sucks.

461,462d460
<         if (ent->health > ent->client->pers.max_health)
<             ent->health = ent->client->pers.max_health;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants