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] Party percentage HP #1485

Open Christian-Vassallo opened 2 years ago

Christian-Vassallo commented 2 years ago

In the previous nwnx 1.69, there was the option

party_percentage_hp=1

which allowed to hide the HP in the portraits' player inside a group. This was useful to avoid that other people could see the HP points of the others

I don't remember exactly in which repo I saw that but it was existing. In case you need, I can search it

Christian-Vassallo commented 2 years ago

Here the file of interests: https://github.com/NWNX/nwnx2-linux/blob/master/plugins/extend/Hooks.cpp

void Hook_WriteGameObjUpdate_PercentPartyHP(void)
{
    asm("leave");

    asm("movl 0x8(%ebp),%eax");
    asm("movl %eax,WGOU_pMsg");

    asm("movl 0xC(%ebp),%eax");
    asm("movl %eax,WGOU_pPlayer");

    asm("movl 0x10(%ebp),%eax");
    asm("movl %eax,WGOU_pObject");

    Local_PercentPartyHP();

    asm("push $0x08073244");
    asm("ret");
}

__attribute__((noinline))
static void Local_PercentPartyHP()
{
    CNWSCreature *pTarget = WGOU_pObject->obj_vtable->AsNWSCreature((void *)WGOU_pObject);
    uint8_t assoc = 0;
    if (pTarget != NULL) {
        if (pTarget->cre_master_id != OBJECT_INVALID && nwn_GetPlayerByID(pTarget->cre_master_id) == WGOU_pPlayer) {
            assoc = 1;
        }
    }
    if (!assoc && nwn_GetPlayerByID(WGOU_pObject->obj_id) != WGOU_pPlayer && (int) * ((char*)WGOU_pPlayer + 0x74) != 2) {
        int p = (int)((float)WGOU_pObject->obj_vtable->GetCurrentHitPoints((void *)WGOU_pObject, 1) / (float)WGOU_pObject->obj_vtable->GetMaxHitPoints((void *)WGOU_pObject, 1) * 100);
        if (p > 100) p = 100;
        else if (p < 0) p = 0;
        CNWMessage__WriteSHORT((CNWMessage *)WGOU_pMsg, p, 16); /* CurrentHP */
        CNWMessage__WriteSHORT((CNWMessage *)WGOU_pMsg, 100, 16); /* MaxHP */
        CNWMessage__WriteSHORT((CNWMessage *)WGOU_pMsg, 0, 16); /* TempHP */
        CNWMessage__WriteSHORT((CNWMessage *)WGOU_pMsg, 100, 16); /* MaxHP */
    } else {
        CNWMessage__WriteSHORT((CNWMessage *)WGOU_pMsg, WGOU_pObject->obj_vtable->GetCurrentHitPoints((void *)WGOU_pObject, 1), 16); /* CurrentHP */
        CNWMessage__WriteSHORT((CNWMessage *)WGOU_pMsg, WGOU_pObject->obj_hp_max, 16); /* MaxHP */
        CNWMessage__WriteSHORT((CNWMessage *)WGOU_pMsg, WGOU_pObject->obj_hp_temp, 16); /* TempHP */
        CNWMessage__WriteSHORT((CNWMessage *)WGOU_pMsg, WGOU_pObject->obj_vtable->GetMaxHitPoints((void *)WGOU_pObject, 1), 16); /* MaxHP */
    }
}
Daztek commented 2 years ago

Can't do inline hooks with NWNX:EE so this would requires a whole bunch more effort, but not impossible I think.

niv commented 2 years ago

Can you test experimental as of 5933e8c820e59853869576b44f2c970cac9b69fd (via #1499) and report what works and what does not?