• New Horizons on Maelstrom
    Maelstrom New Horizons


    Visit our website www.piratehorizons.com to quickly find download links for the newest versions of our New Horizons mods Beyond New Horizons and Maelstrom New Horizons!

Medicaments

Serge Grey

Powder Monkey
In the description:
They'll help to rescue injured and heal the diseased crewmembers during sailing.

But they're not decrease. Wounded heal or die (last happens more often), but medicaments number is still same one. Didn't tried it with character's high defence skill if it has meaning.

Anybody knows has it any useful property?
 
Relevant code is in PROGRAM\WorldMap\DailyCrewUpdate.c:
Code:
// KK & PB -->
    int wounded_total = 0;
    int healed_total = 0;
    int killed_total = 0;
    for (i = 0; i < COMPANION_MAX; i++)
    {
        cn = GetCompanionIndex(pchar, i);
        if (cn < 0) continue;
        chref = GetCharacter(cn);
        int wounded_qty = GetWoundedCrewQuantity(chref);
        if (wounded_qty > 0) {
            int healed_qty = GetWoundedHealedPerDay(chref);
            if(healed_qty > wounded_qty) healed_qty = wounded_qty;
            HealCharacterWoundedCrew(chref, healed_qty);

            wounded_qty = GetWoundedCrewQuantity(chref);
            int killed_qty = GetWoundedKilledPerDay(chref);
            if(killed_qty > wounded_qty) killed_qty = wounded_qty;
            RemoveCharacterWoundedCrew(chref, killed_qty);

            if (GetCargoGoods(chref, GOOD_TREATMENT) > 0) RemoveCharacterGoods(chref, GOOD_TREATMENT, 1);

            wounded_total = wounded_total + GetWoundedCrewQuantity(chref);
            healed_total  = healed_total  + healed_qty;
            killed_total  = killed_total  + killed_qty;
        }
    }
    if (wounded_total > 0 || healed_total > 0 || killed_total > 0) {
        LogIt(wounded_total + " wounded crewmembers: " + healed_total + " healed and " + killed_total + " died from gangrene.");
    }
// KK & PB <--

And also PROGRAM\Characters\CharacterUtilite.c:
Code:
// PB -->
int GetWoundedHealedPerDay(ref _refCharacter)
{
    int healing_rate = HEALED_PER_DAY;
    if(CharacterHasOfficerType(_refCharacter, OFFIC_TYPE_DOCTOR))
        healing_rate = healing_rate + CharacterGetOfficerSkill(_refCharacter, OFFIC_TYPE_DOCTOR, "defence");
    if(GetCargoGoods(_refCharacter, GOOD_TREATMENT) > 0)
        healing_rate = healing_rate + HEALED_WITH_MEDS;
    return makeint(0.5 * healing_rate + rand(healing_rate));
}

int GetWoundedKilledPerDay(ref _refCharacter)
{
    int death_rate = KILLED_PER_DAY;
    if(CharacterHasOfficerType(_refCharacter, OFFIC_TYPE_DOCTOR))
        death_rate = death_rate - CharacterGetOfficerSkill(_refCharacter, OFFIC_TYPE_DOCTOR, "defence");
    if(GetCargoGoods(_refCharacter, GOOD_TREATMENT) > 0)
        death_rate = death_rate - HEALED_WITH_MEDS;
    return makeint(0.5 * death_rate + rand(death_rate));
}

bool CharacterHasOfficerType(ref _refCharacter, string OfficerType)
{
    int i, cn;
    if(IsMainCharacter(_refCharacter))
    {
        int num = GetPassengersQuantity(_refCharacter);
        for(i = 0; i < num; i++)
        {
            cn = GetPassenger(_refCharacter, i);
            if(cn < 0) continue;
            if(GetAttribute(GetCharacter(cn),"quest.officertype") == OfficerType &&
                !IsPrisoner(GetCharacter(cn)) && !IsCompanion(GetCharacter(cn))) return true;
        }
    }
    else
    {
        for(i = 1; i < OFFICER_MAX; i++)
        {
            cn = GetOfficersIndex(&_refCharacter,i);
            if(cn < 0) continue;
            if(GetAttribute(GetCharacter(cn),"quest.officertype") == OfficerType) return true;
        }
    }
    return false;
}

int CharacterGetOfficerSkill(ref _refCharacter, string OfficerType, string skillName)
{
    int i, cn;
    int skillvalue = 0;
    if(IsMainCharacter(_refCharacter))
    {
        int num = GetPassengersQuantity(_refCharacter);
        for(i = 0; i < num; i++)
        {
            cn = GetPassenger(_refCharacter, i);
            if(cn < 0) continue;
            if(GetAttribute(GetCharacter(cn),"quest.officertype") == OfficerType &&
                !IsPrisoner(GetCharacter(cn)) && !IsCompanion(GetCharacter(cn)))
            {
                if(CalcCharacterSkill(GetCharacter(cn), skillName) > skillvalue)
                    skillvalue = CalcCharacterSkill(GetCharacter(cn), skillName);
            }
        }
    }
    else
    {
        for(i = 1; i < OFFICER_MAX; i++)
        {
            cn = GetOfficersIndex(&_refCharacter,i);
            if(cn < 0) continue;
            if(GetAttribute(GetCharacter(cn),"quest.officertype") == OfficerType &&
                !IsPrisoner(GetCharacter(cn)) && !IsCompanion(GetCharacter(cn)))
            {
                if(CalcCharacterSkill(GetCharacter(cn), skillName) > skillvalue)
                    skillvalue = CalcCharacterSkill(GetCharacter(cn), skillName);
            }
        }
    }
    return skillvalue;
}
// PB <--
 
In the description:
They'll help to rescue injured and heal the diseased crewmembers during sailing.

But they're not decrease. Wounded heal or die (last happens more often), but medicaments number is still same one. Didn't tried it with character's high defence skill if it has meaning.

Anybody knows has it any useful property?
That's odd. For me, medicaments does decrease by one and injured crew are healed - some of them, anyway.

Do you have any of your officers assigned as surgeon? Looking at the code in "CharacterUtilite.c", crew are only healed if you have a surgeon. Even if none of your officers has "Defence" skill better than 1, assign one of them as surgeon anyway, then at least you get some crew healed. (Or go into a tavern, talk to the keeper, and ask for specific type of officer, surgeon.)
 
Do you have any of your officers assigned as surgeon? Looking at the code in "CharacterUtilite.c", crew are only healed if you have a surgeon. Even if none of your officers has "Defence" skill better than 1, assign one of them as surgeon anyway, then at least you get some crew healed. (Or go into a tavern, talk to the keeper, and ask for specific type of officer, surgeon.)
Huh? It should be and/or.
If you only have medicine and no doctor, some crew should still be healed.
It should just be less than if you do have a doctor.
Did I mess something up on your coding?

Also, this feature is seriousl simplified.
Probably a clever person could improve on the formulas used.
I don't think what I did is particularly fancy or even fair.
 
I was sure that, in another discussion on the forum, someone said that crew are only healed if there is a surgeon present. But indeed, looking again at that code, there are default values for crew healed per day and crew killed per day. So even if you have no surgeon, some crew ought to be healed even without medicaments; more should be healed if you do have medicaments; and both ought to be improved if you have a surgeon.

This is the bit which detects if you have a surgeon:
Code:
   if(CharacterHasOfficerType(_refCharacter, OFFIC_TYPE_DOCTOR))
       healing_rate = healing_rate + CharacterGetOfficerSkill(_refCharacter, OFFIC_TYPE_DOCTOR, "defence");
What I didn't notice on the first quick read-through is that, right above it, is:
Code:
   int healing_rate = HEALED_PER_DAY;
And "HEALED_PER_DAY" is set in "InternalSettings.h". Similar code exists for crew killed per day - a default value set in "InternalSettings.h" and a check if you have a surgeon to improve it.

There's not much point in trying to improve the formula unless someone knows exactly what is in "medicaments" and someone with medical knowledge knows what it did to the chances of survival. You'd also need to figure out exactly what skill level 1, skill level 5 and skill level 10 in "Defence" correspond to in real world medical skill. Alternatively, let's just keep it simple so we can easily see what's going on. :D
 
if (GetCargoGoods(chref, GOOD_TREATMENT) > 0) RemoveCharacterGoods(chref, GOOD_TREATMENT, 1);

Thank you, @Pieter Boelen ! I'm sorry, it really works. I was confused with message about it: there no information about ship - so, i thought it is on my ship, but it was on my companion's ship.

I'm sorry, i have confused you. :)

It is funny. When i was checking medicament's capability to help, there was a chance to exchange ships with Evan Glover. I was done it. Quest to convoy him to Barbados was completed and continued as well, while i had new light naval brig with all Evan's crew and cargo on it. May be there must no chance to exchange?
 
There's not much point in trying to improve the formula unless someone knows exactly what is in "medicaments" and someone with medical knowledge knows what it did to the chances of survival. You'd also need to figure out exactly what skill level 1, skill level 5 and skill level 10 in "Defence" correspond to in real world medical skill. Alternatively, let's just keep it simple so we can easily see what's going on.

Why not to add such character's skill influence as a surgeon has: player's character has higher value of defence than surgeon - it will be player's skill, else it will be surgeon's skill?

Although, it adds some difficultly. :)
 
Last edited:
It is funny. When i was checking medicament's capability to help, there was a chance to exchange ships with Evan Glover. I was done it. Quest to convoy him to Barbados was completed and continued as well, while i had new light naval brig with all Evan's crew and cargo on it. May be there must no chance to exchange?
@Grey Roger: there is a way to lock companion ships so you can't touch them.
Do you remember how that works?

Why not to add such character's skill influence as a surgeon has: player's character has higher value of defence than surgeon - it will be player's skill, else it will be surgeon's skill?
The would reduce game difficulty, I think.
I made the game look specifically at the doctor's skill so that having officers is useful.
Otherwise, once you're a maxed out player character, you might as well get rid of it officers.

This was actually the first step of an experiment of mine that was never taken further.
Still, I think the idea has merit...
 
@Grey Roger: there is a way to lock companion ships so you can't touch them.
Do you remember how that works?
This ought to do it:
Code:
SetCharacterRemovable(characterFromID("Ewan Glover"), false);
That's set at case "Ewan_Glover_exit_join", which activates when you talk to Ewan at Port Royale and he becomes a companion. It's not cancelled until case "Ewan_goodbye_exit", at which point he's also removed as a companion so he's no longer in your fleet.

'SetCharacterRemovable(character, false)' is used to lock companion ships in various quests, so if it's not secure then this isn't the only quest which can potentially break...
 
I was confused with message about it: there no information about ship - so, i thought it is on my ship, but it was on my companion's ship.

May be it is not so significant, but to avoid such situations in the future it will be reasonable to change some code in the PROGRAM\WorldMap\DailyCrewUpdate.c to:
Code:
// KK & PB -->
       
    for (i = 0; i < COMPANION_MAX; i++)
    {
        cn = GetCompanionIndex(pchar, i);
        if (cn < 0) continue;
        chref = GetCharacter(cn);
        int wounded_qty = GetWoundedCrewQuantity(chref);
        if (wounded_qty > 0) {
            int healed_qty = GetWoundedHealedPerDay(chref);
            if(healed_qty > wounded_qty) healed_qty = wounded_qty;
            HealCharacterWoundedCrew(chref, healed_qty);

            wounded_qty = GetWoundedCrewQuantity(chref);
            int killed_qty = GetWoundedKilledPerDay(chref);
            if(killed_qty > wounded_qty) killed_qty = wounded_qty;
            RemoveCharacterWoundedCrew(chref, killed_qty);

            if (GetCargoGoods(chref, GOOD_TREATMENT) > 0) RemoveCharacterGoods(chref, GOOD_TREATMENT, 1);
       
            if (GetWoundedCrewQuantity(chref) > 0 || healed_qty > 0 || killed_qty > 0)
            {
                LogIt(GetWoundedCrewQuantity(chref) + " wounded crewmembers: " + healed_qty + " healed and " + killed_qty + " died from gangrene on "+chref.name+" "+chref.lastname+"'s ship.");
            }
        }

    }

       
// KK & PB <--
I didn't verified it with two or more ships in the fleet with wounded crew, only on one of two. If you agree with my changes and have such situations in the game, you may do it.
Of course, if wounded_total, healed_total and killed_total are uses anywhere else, they must be restored.
 

Attachments

  • DailyCrewUpdate.c
    27.4 KB · Views: 175
Nice one, @Serge Grey!

There is a function to display the name of the ship for a certain captain character reference.
Can't remember which one it is (GetMyShipName or something like that), but it sounds like you could put it to good use here. :onya
 
Thank you, Pieter!

There is a function to display the name of the ship for a certain captain character reference.
Yes, i found it. It is GetMyShipNameShow(_refCharacter). Thanks for it. Now there is a ship name, in the log message. It is better to define a ship by it's name as well as no "'s" on the end of word. ;)
I have re-uploaded the file.
 

Attachments

  • DailyCrewUpdate.c
    27.4 KB · Views: 172
Yes, i found it. It is GetMyShipNameShow(_refCharacter).
Good find! That's exactly the one I meant. :woot

There is a similar function for character names.
I think it was 'GetMySimpleNameShow' or something like that.
 
There are a whole range for characters, defined in "PROGRAM\Dialog_func.c". Basic first name + last name (and middle name if the character has it) is 'GetMySimpleName(ref chr)', e.g. "Edward Pellew". At the other end of the spectrum is 'GetMyFullName(ref chr)', with rank and title if the character has them, e.g. "Captain Sir Edward Pellew".
 
Back
Top