void TIH_OfficerHiredProcess(ref RefChar, bool bLowSalary, bool bAutoAssign, bool bPurgeCrud, bool bSetType, bool bCreateOfficer)
{
ref PChar = GetMainCharacter();
ref NewOfficer = &NullCharacter();
int NewOfficerIdx;
string NewOfficerID;
PChar.quest.HiringOfficerIDX = GetCharacterIndex(RefChar.id);
int freeidx = FindFreeRandomOfficer();// get an open officer slot to use (50 maximum)
if(freeidx != -1)
{
//trace("-----------------------------------------------------------------");
//trace("dialog_func.c:");
// cleaner method
NewOfficerIdx = sti(Characters[freeidx].index);
NewOfficer = GetCharacter(NewOfficerIdx);
NewOfficerID = NewOfficer.id;// store this because we have to put it back after the copyattr
PChar.quest.NewOfficerIdx = NewOfficerIdx;// store for second function
// trace("Hiring Officer IDX is " + PChar.quest.HiringOfficerIDX + " and he has id " + Characters[sti(PChar.quest.HiringOfficerIDX)].id);
// trace("Free Random Officer IDX is " + NewOfficerIdx + " and he has id " + NewOfficerID);
//MAXIMUS: hired captain will stay in location with player -->
// ChangeCharacterAddressGroup(&RefChar, "None", "", "");// get rid of the reference character
if(RefChar.sex == "woman") RefChar.greeting = "Gr_Officer_f common";
else RefChar.greeting = "Gr_Officer_m common";
RefChar.Dialog.Filename = "Enc_Officer_dialog.c";
RefChar.Dialog.CurrentNode = "Hired";
CopyAttributes(&NewOfficer, &RefChar);// copy all attr from the reference character (the hiring officer) to the new officer char
if(bSetType) { LAi_SetOfficerType(RefChar); }
LAi_group_MoveCharacter(RefChar, LAI_GROUP_PLAYER);
RefChar.location = "none";
//MAXIMUS: hired captain will stay in location with player <--
NewOfficer.index = NewOfficerIdx;// reset these after the copyattr
NewOfficer.id = NewOfficerID; // reset these after the copyattr
NewOfficer.friend = true;
NewOfficer.ship.type = "Not Used";
NewOfficer.ship.idx = 1000;
NewOfficer.nodisarm = 1;
NewOfficer.location = "none";
//trace("New Officer IDX is " + NewOfficer.index + " and he has id " + NewOfficer.id);
//trace("dialog_func.c - > officer dump before cleaning:"); DumpAttributes( Characters[sti(PChar.quest.NewOfficerIdx)] );
/*
// these do fixing
if(NewOfficer.sex == "woman") NewOfficer.greeting = "Gr_Officer_f common";
else NewOfficer.greeting = "Gr_Officer_m common";
NewOfficer.Dialog.Filename = "Enc_Officer_dialog.c";
NewOfficer.Dialog.CurrentNode = "Hired";
NewOfficer.AbordageMode = 1;// boal 05.09.03 officer set to go to abordage
*/
// TIH --> suggested additions from maximus, adjusted for this code Aug29'06
// TIH --> no, see if this attr doesnt exist for NEW officer, its because REF officer didn't have it in the first place, so trying to assign it the null field again is a bit pointless and dangerous - Oct30'06
// if (!CheckAttribute(NewOfficer,"location.locator") && CheckAttribute(RefChar, "location.locator")) NewOfficer.location.locator = RefChar.location.locator;// ? was a bug with not existent location.locator // KK now that should be OK
// if (!CheckAttribute(NewOfficer,"location.locator")) NewOfficer.location.locator = "";// TIH - actually set it to nothing for fresh reset - Oct30'06
// TIH <--
if (!CheckAttribute(NewOfficer,"model.entity")) NewOfficer.model.entity = "NPCharacter";// ? sometimes was an error - "can't create class"
if (!CheckAttribute(NewOfficer,"noFollowType")) NewOfficer.noFollowType = "nofollow";// ? new identifier for template LAi_follow.c
if (!CheckAttribute(NewOfficer,"money")) NewOfficer.money = 1+rand(100);// ? was a bug with not existent money
// TIH <--
if (bPurgeCrud) {// purge a whole bunch of broken crud that causes bugs for this new officer (captured captains only)
if ( CheckAttribute(NewOfficer,"ship") ) DeleteAttribute(NewOfficer,"ship");
if ( CheckAttribute(NewOfficer,"shiptype") ) DeleteAttribute(NewOfficer,"shiptype");
if ( CheckAttribute(NewOfficer,"shipmoney") ) DeleteAttribute(NewOfficer,"shipmoney");
if ( CheckAttribute(NewOfficer,"curshipnum") ) DeleteAttribute(NewOfficer,"curshipnum");
if ( CheckAttribute(NewOfficer,"seaai") ) DeleteAttribute(NewOfficer,"seaai");
if ( CheckAttribute(NewOfficer,"features") ) DeleteAttribute(NewOfficer,"features");
if ( CheckAttribute(NewOfficer,"seatime") ) DeleteAttribute(NewOfficer,"seatime");
if ( CheckAttribute(NewOfficer,"relation") ) DeleteAttribute(NewOfficer,"relation");
if ( CheckAttribute(NewOfficer,"fantomtype") ) DeleteAttribute(NewOfficer,"fantomtype");
if ( CheckAttribute(NewOfficer,"canfiretime") ) DeleteAttribute(NewOfficer,"canfiretime");
if ( CheckAttribute(NewOfficer,"rankscale") ) DeleteAttribute(NewOfficer,"rankscale");
if ( CheckAttribute(NewOfficer,"tmpperks") ) DeleteAttribute(NewOfficer,"tmpperks");
if ( CheckAttribute(NewOfficer,"tmpskill") ) DeleteAttribute(NewOfficer,"tmpskill");
if ( CheckAttribute(NewOfficer,"points") ) DeleteAttribute(NewOfficer,"points");
if ( CheckAttribute(NewOfficer,"randofficers") ) DeleteAttribute(NewOfficer,"randofficers");
if ( CheckAttribute(NewOfficer,"skillnatmult") ) DeleteAttribute(NewOfficer,"skillnatmult");
if ( CheckAttribute(NewOfficer,"nodisarm") ) DeleteAttribute(NewOfficer,"nodisarm");
if ( CheckAttribute(NewOfficer,"points") ) DeleteAttribute(NewOfficer,"points");
if ( CheckAttribute(NewOfficer,"isFantom") ) DeleteAttribute(NewOfficer,"isFantom");
if ( CheckAttribute(NewOfficer,"status") ) DeleteAttribute(RefChar,"status");
if ( CheckAttribute(NewOfficer,"position") ) DeleteAttribute(RefChar,"position");
if ( CheckAttribute(NewOfficer,"fight") ) DeleteAttribute(RefChar,"fight");
if ( CheckAttribute(NewOfficer,"cabinfight") ) DeleteAttribute(RefChar,"cabinfight");
}
LAi_SetOfficerType(NewOfficer);
if(bCreateOfficer)
{
/*switch(Rand(7))
{
case 0: NewOfficer.quest.officertype = OFFIC_TYPE_BOATSWAIN; break;
case 1: NewOfficer.quest.officertype = OFFIC_TYPE_CANNONEER; break;
case 2: NewOfficer.quest.officertype = OFFIC_TYPE_QMASTER; break;
case 3: NewOfficer.quest.officertype = OFFIC_TYPE_NAVIGATOR; break;
case 4: NewOfficer.quest.officertype = OFFIC_TYPE_FIRSTMATE; break;
case 5: NewOfficer.quest.officertype = OFFIC_TYPE_CARPENTER; break;
case 6: NewOfficer.quest.officertype = OFFIC_TYPE_DOCTOR; break;
case 7: NewOfficer.quest.officertype = OFFIC_TYPE_ABORDAGE; break;
}*/
if(DEBUG_EXPERIENCE>0) TraceAndLog("TIH_OfficerHiredProcess: Set officer type for " + GetMySimpleName(NewOfficer));
NewOfficer.quest.officertype = GetRandomOfficerType(); //Levis let's use a global function so we can easily add types later.
LAi_Create_Officer(rand(8), &NewOfficer);/*
NewOfficer.offgen = true;
NewOfficer.officer = true;
LAi_Create_Officer(rand(1),NewOfficer);*/
}
else
{
// if (!CheckAttribute(PChar, "IsOnDeck") && !bAbordageStarted) NewOfficer.location = "None"; // KK
//NewOfficer.location.group = "officers";// not needed
NewOfficer.chr_ai.type = "officer";
NewOfficer.offgen = true;
NewOfficer.officer = true;
NewOfficer.friend = true;
NewOfficer.land = "0";
if(CheckAttribute(NewOfficer,"wealth")) NewOfficer.wealth = makeint(NewOfficer.wealth);// clean up the ungainly float!
if(CheckAttribute(NewOfficer,"quest.officertype")) NewOfficer.current = NewOfficer.quest.officertype;
}
if (bAutoAssign)
{
// added by MAXIMUS [for placing new officer in empty slot (default for some officers)] -->
int ofNum = OFFICER_MAX-1 ;// default force into last slot
if ( CheckAttribute(NewOfficer,"quest.officertype") ) {
switch( NewOfficer.quest.officertype )
{
case OFFIC_TYPE_FIRSTMATE: ofNum = 1; break;
case OFFIC_TYPE_BOATSWAIN: ofNum = 2; break;
case OFFIC_TYPE_NAVIGATOR: ofNum = 3; break;
//case OFFIC_TYPE_QMASTER: ofNum = 1; break;
//case OFFIC_TYPE_CANNONEER: ofNum = 2; break;
}
}
SetOfficersIndex(PChar, ofNum, NewOfficerIdx);
// added by MAXIMUS [for placing new officer in empty slot (default for some officers)] <--
} else {
//SetOfficersIndex(PChar, -1, NewOfficerIdx);// put them into an available slot if one exists (do not force it)
AddPassenger(PChar,NewOfficer,false);// just add them as a passenger for now
// AssignCaptiveAsCompanion(RefChar, NewOfficer);//MAXIMUS: not needed
if(CheckAttribute(NewOfficer, "quest.officertype") && NewOfficer.quest.officertype == OFFIC_TYPE_ABORDAGE)
{
DeleteAttribute(NewOfficer, "quest.officertype");
}
}
// if they joined freely (no cost), they have a low salary ?
if(!CheckAttribute(NewOfficer,"quest.officerprice"))
{
NewOfficer.quest.officerprice = makeint((sti(PChar.rank) * 2 + 10)*100) - 330 + rand(40)*15 + rand(10);
}
if(bLowSalary) NewOfficer.quest.officerprice = makeint( sti(NewOfficer.quest.officerprice) / 2 );
if (!CheckCharacterEquipByGroup(NewOfficer, BLADE_ITEM_TYPE)) // KK
LAi_NPC_Equip(NewOfficer, sti(PChar.rank), true, 0);// give the officer some weapons and equip them (NO GUN)
// move any money they may have into their wealth, so MC can't steal their money
if (CheckAttribute(NewOfficer,"money") && sti(NewOfficer.money) > 0)
{
if (!CheckAttribute(NewOfficer,"wealth")) { NewOfficer.wealth = 0; } // set if not set
NewOfficer.wealth = makeint(sti(NewOfficer.wealth) + sti(NewOfficer.money)); // merge together into wealth
NewOfficer.money = 0; // clear out their money now that its moved
}
// keep the NewOfficerIdx attribute, as its needed in the second function
//trace("dialog_func.c -> officer dump at end:"); DumpAttributes( Characters[sti(PChar.quest.NewOfficerIdx)] );
//trace("-----------------------------------------------------------------");
}
else
{
Log_SetStringToLog(QUEST_MESSAGE12);
}
DeleteAttribute(Pchar, "quest.HiringOfficerIDX");// deleted here, because we certainly no longer need it now
// if (!CheckAttribute(PChar, "IsOnDeck") && bAbordageStarted) refEnCharacter = NewOfficer;
}