nwnxee / unified

Binaries available under the Releases tab on Github
https://nwnxee.github.io/unified
GNU General Public License v3.0
131 stars 92 forks source link

[Feature Request] 2 nwnx_cool function (level cap related) #473

Closed Wallack closed 5 years ago

Wallack commented 5 years ago

Hi all.

This is the link for nwnx_cool (worked on windows only as far as I know) and contains the source in c++: https://neverwintervault.org/project/nwn1/other/nwnx-cool

First is:

//Allows oPC to level up to nLevelAllowed EVEN if its above the cap or the PC doesnt have XP for it //If nLevelAllowed <= 0 default behavior is set instead void SetPCAllowedToLevelTo( object oPC, int nLevelAllowed );

This function was really nice to allow the PC to level up past 40. I had a 1.69 server where I was able to track the XP the char had past 40 using also the xptables 2da and when the player had enough XP I was able, by scripting, to trigger the ingame level up interface.

With proper .2da modifications the server allowed you to level up to 80 but a maximum of 40 levels of a base class and 30 of a prestige class. It leveled accordingly the base attack bonus (1 every 3 levels from 41 to 60 and 1 every 4 levels from 61 to 80) as well as saving throws and bonus feats.

This allowed you to level to 80 even if the server limit was 40 but if you leave the server and then try to join again you can't.

Second is:

//Sets the max level for the server to nLevel //if nLevel == 0 it just returns what the current is int SetServerMaxLevel( int nLevel );

This allowed you to set the level cap to 80 and also to see that level range from the server browser.

The source code is there and I don't know how hard would it be to port this but it was the best feature I had in my old action server.

Mizzajl commented 5 years ago

Increased level cap is something I would be interested in seeing as well :) also following that link and looking at features, being able to set the number of off-hand attacks seems really nice and is something I would like as well :D but if possible to set to the character instead of the weapon? to be able to make feats like Greater/Perfect Two-Weapon Fighting :)

Baaleos commented 5 years ago

If memory serves - this would require a hook on the CNWSPlayer__ValidateCharacter nwnx_cool hooked this event and would basically return a success value if the characters level was <= the server max level - which was configurable via nwscript.

Wallack commented 5 years ago

Regarding this, I only want to be able to level past 40 (to whatever limit) and to be able to show that level range on the server list. How well the level scales and how well .2da behaves will be my problem.

In the past I set maximum class level to 40 and prestige to 30 so that way everything worked normally as they were initially designed for that (base class up to 40 and prestige up to 30). .2da worked for xp, base attack, saving throw ...

Obviously fixes for spells would have need to be made in order to accept a maximum level so spell casters are no shit but that would be my problem.

Baaleos commented 5 years ago

Just speaking from memory - how it worked in 1.69 The CanLevelUp method was hooked and called with a numerical value to indicate the desired level the player was able to level to. This would trigger the client levelup prompt and then accept the client submitted character data easy peasy. The ValidateCharacter hook is necessary however, because once you level up beyond level 40, (which was the server maximum) - the in built character validation would flag characters of 41+ as being invalid bic files and prevent them from joining the server. From what I remember, the levelup functionality was not that complex in nwnx_cool - It might be an easy addition to the Player plugin?

Daztek commented 5 years ago

This should probably be easy to implement once ValidateCharacter is moved to the NWScript side, see #487

NWNX_Cool's source:

int __fastcall CNWSPlayer__ValidateCharacter( CNWSPlayer * ply, void *,int arg1 ){

    Cool.frames++;

    int nResault = CNWSPlayer__ValidateCharacterNext( ply, NULL, arg1 );

    //Level is higher then the cap
    //Custom check
    if( nResault == 57924 ){

        int nMax = (*NWN_AppManager)->app_server->srv_internal->GetSetMaxLevel( 0 );
        CNWSCreature * cre = (CNWSCreature*)ply->GetGameObject();
        if( cre->cre_stats->GetLevel( 0 ) <= nMax )     
            nResault = 0;
    }

    //Only run the script on valid characters
    if( nResault == 0 ){

        ResetParameters();

        Cool.frames++;

        Cool.Event = 18;
        Cool.nData = arg1;

        Cool.Log( 1, "o ValidateCharacter: %08lx\n", ply->GetGameObject()->obj_id );
        Cool.ScriptRunning = true;
        (*NWN_VirtualMachine)->Runscript(&CExoString("nwnx_cool"), ply->GetGameObject()->obj_id );
        Cool.ScriptRunning = false;

        if( Cool.ByPass ){
            Cool.ByPass = false;
            return Cool.nRetn;
        }
    }

    return nResault; 
}

int __fastcall CNWSCreatureStats__CanLevelUp( CNWSCreatureStats * cre, void* ){

    if( cre == NULL )
        return CNWSCreatureStats__CanLevelUpNext( cre, NULL );

    Cool.frames++;

    int nAllowed = cre->cs_original->obj.obj_vartable.GetInt( CExoString( "levelup" ) );

    if( nAllowed > 0 ){

        int nLevel = cre->GetLevel(0);
        if( nAllowed > nLevel )
            return 1;
        else if( nAllowed <= nLevel )
            return 0;
    }
    return CNWSCreatureStats__CanLevelUpNext( cre, NULL );
}
mtijanic commented 5 years ago

Considering the level check is the first thing out of 20ish checks that ValidateCharacter() does, that's a pretty pointless function altogether.. ValidateCharacter() will exit early and other checks will never be done.

jd28 commented 5 years ago

That feature never worked. There were (I don't know about now in EE) things hardcoded to 40 levels, XP Requirements, Number of Bonus Feats, Spells Gained, etc both server and client side. So you'd really need to convince someone at Beamdog to change those to get the native leveling mechanism to work right.

I created a hybrid of Legendary Levels and native leveling way back when: https://github.com/jd28/nwnx2-linux/tree/ta/plugins/levels if it's of any help.

plenarius commented 5 years ago

Those were some help @jd28 - cheers. I'm working on seeing if I can get this to work (well as much as possible).

Will require NWNX_ELC.

Anyway here's a snoop into how it's coming along. https://github.com/nwnxee/unified/compare/master...plenarius:maxlevel_plugin