Jump to content
  • Horde quest 6622 broken...


    Xenithar
    • Status: Completed
      Main Category: Quests
      Sub-Category: Quest
      Version: 2.0.11 Milestone: 20 Priority: Normal
      Implemented Version: 0.20

    Well, almost!

    The quest appears to work, except that the critically injured patients die WAY too quickly. In all the years I played WoW I never lost a single patient on official or on MaNGOS. I kept failing tonight due to two possibly related bugs. The first is that the critically injured patients die WAY too fast. Even if you start healing them before they have spawned completely in, they die at the exact moment you heal them. If you manage to get there a hair quicker they will stand up, turn, and die while thanking you. It is like even after they're healed, they keep losing life.


    User Feedback

    Recommended Comments

    Chucksta

    Posted

    This is scripted in the [B]npc_special.cpp[/B] program file (npc_injured_patient)

    The periodic loss of health is done in the UpdateAI ( ) function; line 373 onwards.

    void UpdateAI(const uint32 uiDiff) override
    {
    // lower HP on every world tick makes it a useful counter, not officlone though
    uint32 uiHPLose = uint32(0.05f * uiDiff);
    if (m_creature->IsAlive() && m_creature->GetHealth() > 1 + uiHPLose)
    {
    m_creature->SetHealth(m_creature->GetHealth() - uiHPLose);
    }

    if (m_creature->IsAlive() && m_creature->GetHealth() {
    m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT);
    m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
    m_creature->SetDeathState(JUST_DIED);
    m_creature->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD);

    if (Creature* pDoctor = m_creature->GetMap()->GetCreature(m_doctorGuid))
    {
    if (npc_doctorAI* pDocAI = dynamic_cast(pDoctor->AI()))
    {
    pDocAI->PatientDied(m_pCoord);
    }
    }
    }
    }


    Presumably the value passed in via the parameter [B]uiDiff [/B]is too high, thus resulting in the speedy loss of health, or could it be that the calculation is not being done correctly?

    I'll make this my first call tomorrow, if nobody else steps in beforehand :)

    Xenithar

    Posted

    I just did this with my shaman. Epic fail. It kept wanting to give me those critical patients. I lost fast. I even had some stand up, thank me, run two or three steps, then die. After being healed the drain should stop, they should run outside and despawn.

    Chucksta

    Posted

    [B]uiDiff [/B]receives the value of 100 which results in a perfectly acceptable periodic reduction in the patient's health, as far as I am concerned.

    [B][COLOR="#FF0000"]However[/COLOR][/B], due to the health being reduced on every tick, or whatever it is called, it results in the patient losing some life for a while even though they have been saved, but...

    We can save the patient from dying by healing it by say 20% at the point in the code where the system decides the patient has been saved, thus:

    void SpellHit(Unit* pCaster, const SpellEntry* pSpell) override
    {
    if (pCaster->GetTypeId() == TYPEID_PLAYER && m_creature->IsAlive() && pSpell->Id == 20804)
    {
    Player* pPlayer = static_cast(pCaster);
    if (pPlayer->GetQuestStatus(6624) == QUEST_STATUS_INCOMPLETE || pPlayer->GetQuestStatus(6622) == QUEST_STATUS_INCOMPLETE)
    {
    if (Creature* pDoctor = m_creature->GetMap()->GetCreature(m_doctorGuid))
    {
    if (npc_doctorAI* pDocAI = dynamic_cast(pDoctor->AI()))
    {
    pDocAI->PatientSaved(m_creature, pPlayer, m_pCoord);
    }
    }
    }

    // stop patient dying due to an UpdateAI( ) occuring before the healing can kick in
    m_creature->SetHealth(uint32(m_creature->GetMaxHealth()*0.20)); // THIS SAVES THE PATIENT

    // make not selectable
    m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
    // regen health
    m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT);
    // stand up
    m_creature->SetStandState(UNIT_STAND_STATE_STAND);

    switch (urand(0, 2))
    {
    case 0:
    DoScriptText(SAY_DOC1, m_creature);
    break;
    case 1:
    DoScriptText(SAY_DOC2, m_creature);
    break;
    case 2:
    DoScriptText(SAY_DOC3, m_creature);
    break;
    }

    m_creature->SetWalk(false);

    switch (m_creature->GetEntry())
    {
    case 12923:
    case 12924:
    case 12925:
    m_creature->GetMotionMaster()->MovePoint(0, H_RUNTOX, H_RUNTOY, H_RUNTOZ);
    break;
    case 12936:
    case 12937:
    case 12938:
    m_creature->GetMotionMaster()->MovePoint(0, A_RUNTOX, A_RUNTOY, A_RUNTOZ);
    break;
    }
    }
    }


    ----------

    [B][COLOR="#FFD700"]Injured[/COLOR][/B] / [B][COLOR="#FF8C00"]Badly Injured[/COLOR][/B] / [B][COLOR="#FF0000"]Critically Injured[/COLOR][/B]

    Each type has an equal chance of being chosen:

    case DOCTOR_ALLIANCE:
    patientEntry = AllianceSoldierId[urand(0, 2)];
    break;
    case DOCTOR_HORDE:
    patientEntry = HordeSoldierId[urand(0, 2)];
    break;


    Should this be changed ?

    ----------------------------
    [B]NEXT[/B]: Critically injured dying too fast.
    Hmm, they should all be losing health at the same rate, unless that uiDiff is not always 100.

    TOTALLY FREAKING IMPOSSIBLE TO SAVE THE CRITICALLY INJURED PATIENTS!!!

    hmm, this needs to be rethought!

    ------------------------------

    Okay, to make it so that the Critically Injured patients can actually be healed, but still requiring plenty of clenching of the buttocks situations whilst praying to your deity of choice, I slowed down the health reduction by a bit. I changed the calculation from [COLOR="#FF0000"]0.05f * uiDiff[/COLOR] to [COLOR="#008000"]0.03f * uiDiff[/COLOR]

    void UpdateAI(const uint32 uiDiff) override
    {
    // lower HP on every world tick makes it a useful counter, not officlone though
    uint32 uiHPLose = uint32(0.03f * uiDiff);
    if (m_creature->IsAlive() && m_creature->GetHealth() > 1 + uiHPLose)
    {
    m_creature->SetHealth(m_creature->GetHealth() - uiHPLose);
    }

    Xenithar

    Posted

    The way it worked on official was that each worse case had less health, but I believe the rate of loss was the same. The critical soldiers just had little to begin with so you had less time in that essence, but it was not hard to do. I have redone this repeatedly now for testing and it IS possible to save them, but the problem then is that even after being saved, they take a few steps and die. After being saved the decay should stop.

    Oh, and to save them you have to start bandaging them as they fade in. If you do not start until they are solid, you cannot save them at this point.

    Chucksta

    Posted

    [B][COLOR="#FF0000"]TESTING REQUIRED BY OTHERS[/COLOR][/B]

    Can the proposed fix be tested by someone/others, please. It worked well for me, and still nerve wracking.

    You'll need to make 2 changes to the code (See [B][COLOR="#008000"]CODE FIXES[/COLOR][/B] for how the code should look):

    [B]FILE[/B]: npcs_special.cpp
    [B]LOCATION[/B]: server\src\modules\SD2\scripts\world

    [B][SIZE=3][COLOR="#800080"]1) add this line:[/COLOR][/SIZE][/B]

    [B][COLOR="#008000"]m_creature->SetHealth(uint32(m_creature->GetMaxHealth()*0.20));[/COLOR][/B]

    to the SpellHit( ) function

    approximately line 335

    [B][SIZE=3][COLOR="#800080"]2) change this line[/COLOR][/SIZE][/B]

    [B][COLOR="#FF0000"]uint32 uiHPLose = uint32(0.05f * uiDiff); [/COLOR][/B]

    to

    [B][COLOR="#008000"]uint32 uiHPLose = uint32(0.03f * uiDiff); [/COLOR][/B]

    in the UpdatyeAI( ) function

    approximately line 380

    ---------------------------------------
    [B][COLOR="#008000"]CODE FIXES[/COLOR][/B]
    1) new code added
    Player* pPlayer = static_cast(pCaster);
    if (pPlayer->GetQuestStatus(6624) == QUEST_STATUS_INCOMPLETE || pPlayer->GetQuestStatus(6622) == QUEST_STATUS_INCOMPLETE)
    {
    if (Creature* pDoctor = m_creature->GetMap()->GetCreature(m_doctorGuid))
    {
    if (npc_doctorAI* pDocAI = dynamic_cast(pDoctor->AI()))
    {
    pDocAI->PatientSaved(m_creature, pPlayer, m_pCoord);
    }
    }
    }

    // stop patient dying due to an UpdateAI( ) occuring before the healing can kick in
    m_creature->SetHealth(uint32(m_creature->GetMaxHealth()*0.20)); // THIS SAVES THE PATIENT

    // make not selectable
    m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
    // regen health
    m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT);
    // stand up
    m_creature->SetStandState(UNIT_STAND_STATE_STAND);


    2) existing code changed
    void UpdateAI(const uint32 uiDiff) override
    {
    // lower HP on every world tick makes it a useful counter, not officlone though
    uint32 uiHPLose = uint32(0.03f * uiDiff);

    Chucksta

    Posted

    [quote=Xenithar]The way it worked on official was that each worse case had less health, but I believe the rate of loss was the same. The critical soldiers just had little to begin with so you had less time in that essence, but it was not hard to do. I have redone this repeatedly now for testing and it IS possible to save them, but the problem then is that even after being saved, they take a few steps and die. After being saved the decay should stop.

    Oh, and to save them you have to start bandaging them as they fade in. If you do not start until they are solid, you cannot save them at this point.[/quote]

    Try with the fixes I recommend, if you can. You'll see that the quest can be done, but still butt clenching!

    I tried to do it before, but the Critical ones were impossible, even if you were on top of them as they spawned!!!

    I also experienced the saving of them; they stand and thank you, then die, lol
    With the code added that gives them 20% health when saved, they no longer die like that :)

    Try it out. The calculation may need tweaking some more. If okay, then I'll PR it.

    Xenithar

    Posted

    I can try it tonight. I am not at the gaming rig right now. I will test though and get back to you.

    Xenithar

    Posted

    I forgot I was on Linux for a moment. Linux runs WoW perfectly. Had to grab the client and add my home IP address (hostname), but it worked. I still cannot see my servers in the realm list, but I manually edited the config and added it.

    Anyway, it appears to work. I will have my fiance and mother test also. That WILL be tonight or maybe even tomorrow.

    Chucksta

    Posted

    Ah, that's brilliant :)

    I'll wait for the feedback from your family and soon to be family ;)

    I have gone back to running the server on my Linux machine. I find it a LOT faster for development and testing purposes, due to it compiling the server core a hell of a lot faster than on MS windows.

    Xenithar

    Posted

    You should try it on a fully optimized Gentoo system. I replaced Debian Wheezy with Gentoo on my work laptop. I set the USE flags and such for my hardware. My GOD it is faster! I am going to be getting to my new Xeon server this month and I intend to put Gentoo on it also.

    Chucksta

    Posted

    [B][SIZE=3][COLOR="#008000"]Pull Request has now been made with this fix:[/COLOR][/SIZE][/B]

    [url]https://github.com/mangoszero/server/pull/269[/url]



    Create an account or sign in to comment

    You need to be a member in order to leave a comment

    Create an account

    Sign up for a new account in our community. It's easy!

    Register a new account

    Sign in

    Already have an account? Sign in here.

    Sign In Now

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. Privacy Policy Terms of Use