Problems when level changes [Coding] Created 2 years ago2022-02-24 14:45:53 UTC by Alexis_of_Steel Alexis_of_Steel

Created 2 years ago2022-02-24 14:45:53 UTC by Alexis_of_Steel Alexis_of_Steel

Posted 2 years ago2022-02-24 14:45:53 UTC Post #346292
Hello everyone. I need help with a programming question (please, Lords of Coding, help!).

I have created an item that when picked up gives you 200 health points (the item is called "item_megahealth").
After 6 seconds have passed, the player's health points begin to drop until they reach 100 health points.

This works correctly on the map where I pick up the item, but when I go to another map (that is, when I go through a "trigger_changelevel") the item no longer works (ie the player's health points don't keep going down to 100).

If I go back to the original map, the health points continue to go down to 100.

I show you the code that I implemented (you can use it if you want):
// NEW MEGAHEALTH
#include "extdll.h"
#include "util.h"
#include "cbase.h"
#include "player.h"
#include "items.h"

extern int gmsgItemPickup;

class CMegaHealth : public CItem
{
    void Spawn( void );
    void Precache( void );
    BOOL MyTouch( CBasePlayer *pPlayer );
    void EXPORT HealthThink( void );
};

LINK_ENTITY_TO_CLASS( item_megahealth, CMegaHealth );

void CMegaHealth :: Spawn( void )
{
    Precache();
    SET_MODEL(ENT(pev), "models/tool_box.mdl");
    CItem::Spawn();
}

void CMegaHealth :: Precache( void )
{
    PRECACHE_MODEL("models/tool_box.mdl");
    PRECACHE_SOUND("items/megahealth.wav");
}

BOOL CMegaHealth::MyTouch( CBasePlayer *pPlayer )
{
    if ( pPlayer->pev->deadflag != DEAD_NO )
    {
        return FALSE;
    }
    if ( ( pPlayer->pev->weapons & (1<<WEAPON_SUIT) ) )
    {
        pPlayer->pev->health = 200;
        EMIT_SOUND( pPlayer->edict(), CHAN_ITEM, "items/megahealth.wav", 1, ATTN_NORM );
        MESSAGE_BEGIN( MSG_ONE, gmsgItemPickup, NULL, pPlayer->pev );
            WRITE_STRING( STRING(pev->classname) );
        MESSAGE_END();
        pev->effects |= EF_NODRAW;
        SetTouch( NULL );
        SUB_UseTargets( pPlayer, USE_TOGGLE, 0 );
        SetThink( &CMegaHealth::HealthThink );
        pev->nextthink = gpGlobals->time + 6;
        return FALSE;
    }
    return TRUE;
}

void CMegaHealth::HealthThink( void )
{
    auto pPlayer = GetClassPtr( ( CBasePlayer* ) &g_engfuncs.pfnPEntityOfEntIndex( 1 )->v );
    if ( pPlayer->pev->health > pPlayer->pev->max_health )
    {
        pPlayer->pev->health--;
        pev->nextthink = gpGlobals->time + 1;
        return;
    }
}
I need that when I switch from one map to another, the health points continue to go down to 100. If anyone has a clue or whatever, I would really appreciate it.
Posted 2 years ago2022-02-24 22:26:00 UTC Post #346293
So you've made the mega-health item responsible for reducing the players health back to 100? I can see why that causes problems: if the mega-health item isn't included when transitioning to another level, it won't exist in that other level, and so it can't reduce the players health. There's also another problem: if you pick up multiple mega-health items, all of them will eventually be reducing the players health back to 100, so the more of these items you pick up, the faster you'll lose any extra health.

I would move this health-reducing code somewhere to the player code (right after the call to CheckTimeBasedDamage seems like a reasonable spot), so it'll always work no matter which level you move to, and you'll avoid the rapid-health-reducing bug as well. This also means that mega-health items can delete themselves once they've been picked up, just like other items.

PS: calling programmers 'Lords of Coding' feels awkward... :\
Posted 2 years ago2022-02-25 11:22:47 UTC Post #346295
Thanks for finding another problem and giving a hint on how I could improve the item I created. :)

PS: I will no longer use the expression I used to refer to highly skilled programmers.
Posted 2 years ago2022-03-06 06:06:08 UTC Post #346322
Agreed - the logic for HealthThink should be part of CBasePlayer.
You must be logged in to post a response.