Even better!
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!
Quick links for Beyond New Horizons
- Download latest version
- Wiki
- FAQ
- Report bugs here
- Bug Tracker on Github
Quick links for Maelstrom
- Download the latest version of Maelstrom
- Download the latest version of ERAS II
- Download the latest version of New Horizons on Maelstrom
Quick links for PotC: New Horizons
- Download latest version
- Wiki
- FAQ
- Report bugs here
Thanks to YOUR votes, GOG.com now sells:
- Sea Dogs
- Sea Dogs: Caribbean Tales
- Sea Dogs: City of Abandoned Ships
Vote now to add Pirates of the Caribbean to the list!
Quick links for AoP2: Gentlemen of Fortune 2
- Downloads and info
- ModDB Profile
- Forums Archive
A Pirate Podcast with Interviews
Music, Comedy and all things Pirate!
- Episode Guide - About - Subscribe -
- Twitter - Facebook - iTunes - Android -
- Youtube - Fill the Coffers -
if(GetServedNation() == PIRATE && GetCurrentLocationNation() != PIRATE) // PB: Link this to acting as a pirate
{
Dialog.Text = DLG_TEXT[0] + GetMySimpleName(PChar) + DLG_TEXT[1];
Link.l1 = DLG_TEXT[2];
Link.l1.go = "exit";
}
else
{
if(GetFlagRMRelation(sti(Npchar.nation)) <= REL_WAR && frnd()>0.8)
{
Dialog.Text = DLG_TEXT[7] + GetMySimpleName(PChar) + DLG_TEXT[8] + GetNationDescByType(sti(PChar.nation)) + DLG_TEXT[10];
Link.l1 = DLG_TEXT[9];
Link.l1.go = "exit";
LAi_group_SetRelation("random_guards_group", LAI_GROUP_PLAYER, LAI_GROUP_ENEMY);
}
else
{
Dialog.Text = DLG_TEXT[18];
Link.l1 = DLG_TEXT[19];
Link.l1.go = "exit";
}
}
//Levis smuggling addon -->
if(CheckAttribute(Pchar,"quest.Contraband.scout"))
{
if(!CheckAttribute(Pchar,"quest.Contraband.Talked") || !CheckAttribute(Pchar,"quest.Contraband.Cardwon"))
{
Link.l2 = DLG_TEXT[3];
Link.l2.go = "patrolquestion";
}
}
"Your name is ",
" right? You look very familiar. Did we meet before?",
"I don't think so. But I should be going now.",
Indeed that is NOT intentional on my part.Lines 0 to 2 are currently this:
Code:"Your name is ", " right? You look very familiar. Did we meet before?", "I don't think so. But I should be going now.",
Interestingly, that actually makes it the only instance where you don't get attacked for being a pirate. It is currently safer to talk to the guards when you're a pirate than when you're a non-pirate at war with the nation the guard belongs to. I should probably change that, which seems easy enough. I'll wait for your input though.
if(GetServedNation() == PIRATE && GetCurrentLocationNation() != PIRATE) // PB: Link this to acting as a pirate // MT: If serving the pirates and in a non-pirate location, then:
{
Dialog.Text = DLG_TEXT[0] + GetMyFullName(PChar) + DLG_TEXT[1];
Link.l1 = RandSwear() + [11];
Link.l1.go = "exit";
switch(makeint(Npchar.nation))
{
case ENGLAND : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Eng_m_a_057.wav");}break;
case FRANCE : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Fre_m_c_018.wav");}break;
case SPAIN : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Spa_m_b_037.wav");}break;
case HOLLAND : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Dut_m_a_008.wav");}break;
case PORTUGAL : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Por_m_a_038.wav");}break;
case AMERICA : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Eng_m_a_057.wav");}break;
}
LAi_LocationFightDisable(&locations[FindLocation(Pchar.location)], false);
Random_Raid("soldiers", 5, makeint(NPchar.nation),"enemy","friend","");
Diag.TempNode = "exit";
LAi_group_SetRelation("random_sailors_group", LAI_GROUP_PLAYER, LAI_GROUP_ENEMY);
}
That could be tricky, yes. Through the "False Flag Detection chance" in there could be a solution.Allright, i'll make sure it starts making sense. Are there other effective ways to smuggle when you're a pirate though? If you get attacked for being a pirate, there is by my knowledge no way to get the smuggling schedule anymore, but i don't know how the new system works, so correct me if i'm wrong.
Agreed. I see no reason to keep it, so please get rid of it.The last line's the odd bit. While i believe it's intended to make the person you're talking to hostile, this person is actually sitting at a table at that point. Does that work? I've noticed a single instance where that line was commented out and replaced by a tavern brawl, but the code up here already summons a group of guards. It's not the only spot it's been coded this way.
That could be tricky, yes. Through the "False Flag Detection chance" in there could be a solution.
But the one you propose sounds plausible as well.
Eventually I would like ALL "recognized as a pirate" code to use the same logic.
Right now it is a 100% certainty from Enc_Walker.c, but ONLY from one of the randomly chosen dialog options.
But that may have to be tweaked. If you have some nice logic to apply, we can use that in the other similar spots too.
That would make "becoming a pirate" less potentially annoying too.
if(GetServedNation() == PIRATE && GetCurrentLocationNation() != PIRATE) // PB: Link this to acting as a pirate // MT: If serving the pirates and in a non-pirate location, then:
{
if(frnd()<makefloat(GetFame(ref pchar, int iNation)))/12.0) //MT: Meant to make you easier to detect as a pirate as you go up in pirate rank
{
Dialog.Text = DLG_TEXT[7] + GetMySimpleName(PChar) + DLG_TEXT[11];
Link.l1 = DLG_TEXT[9];
Link.l1.go = "exit";
LAi_group_SetRelation("random_guards_group", LAI_GROUP_PLAYER, LAI_GROUP_ENEMY);
}
else
{
Dialog.Text = DLG_TEXT[0] + GetMySimpleName(PChar) + DLG_TEXT[1];
Link.l1 = DLG_TEXT[2];
Link.l1.go = "exit";
}
}
Agreed. I see no reason to keep it, so please get rid of it.
"False Flag Detection Chance" is just that: A chance that you are discovered.Using false flag detection sounds like something that would provide a solution for the player throughout the entire game, which does sound better. I dunno though... my solution sounds a bit more realistic. A false flag won't help you much if you've got wanted posters all over the place.
Also fine by me.I would like to make it exactly the same everywhere, but haven't quite done that because of an issue with realism. The pirates have a different reaction based on wether they spot you in a pirate town or not. I could remove that, i suppose, but i've always liked little nuances in dialogue myself. I do think i can manage to make the rest of those pirating instances all the same though. The code i'm going to use for that is this:
if(frnd()<makefloat(GetFame(ref pchar, int iNation)))/12.0)
if(frnd()<makefloat(GetRank(pchar, sti(NPChar.nation))))/12.0)
That's good practice for sure! I do always try to do the same, but have to admit that sometimes I am better at it than other times.It's fairly simple really. I've also taken up the habit of clarifying things wherever i can so future modders will have less of a hard time learning what the code means, or alternatively, have an easier time spotting any mistakes i made.
Not sure. I've never tried setting TempNode to "Exit". Maybe that would make "talking to that character" immediately skip to exiting the dialog?if you beat the tavern brawl, what happens then? I've noticed that whenever there's a hostile conclusion it says 'Diag.TempNode = "exit";' while it says 'Diag.TempNode = "first time";' for friendly or neutral ones, but would that work if the instigator of the fight is still alive afterwards, since he's still sat at his table? 'first time' is the name of the case which contains most of the dialogue.
"False Flag Detection Chance" is just that: A chance that you are discovered.
This could be used to detect false flags at sea, but also for anything else where it seems appropriate.
Technically it doesn't have any relation to "flags" at all, though that is what it was originally added for.
Not sure. I've never tried setting TempNode to "Exit". Maybe that would make "talking to that character" immediately skip to exiting the dialog?
if(GetFlagRMRelation(sti(Npchar.nation)) <= REL_WAR && frnd()>0.8)
{
Dialog.Text = DLG_TEXT[17];
Link.l1 = DLG_TEXT[18];
Link.l1.go = "exit";
//LAi_group_MoveCharacter(Npchar, LAI_GROUP_MONSTERS);
//LAi_group_SetRelation("random_sailors_group", LAI_GROUP_PLAYER, LAI_GROUP_ENEMY);
switch(makeint(Npchar.nation))
{
case ENGLAND : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Eng_m_a_056.wav");}break;
case FRANCE : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Fre_m_a_048.wav");}break;
case SPAIN : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Spa_m_b_042.wav");}break;
case PIRATE : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Fre_m_b_052.wav");}break;
case HOLLAND : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Dut_m_a_043.wav");}break;
case PORTUGAL : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Por_m_b_042.wav");}break;
case AMERICA : if(Npchar.sex=="man"){PlaySound("VOICE\" + LanguageGetLanguage() + "\Eng_m_a_056.wav");}break;
}
if(TAVERNBRAWL_FROMDIALOG)
{// TIH -->
PChar.TAVERNBRAWL = true;
if(frnd()<=0.1)
{LAi_LocationFightDisable(&locations[FindLocation(Pchar.location)], false);Random_Raid("smugglers", 5, PIRATE,"enemy","friend",LanguageConvertString(tmpLangFileID,"TAVERNBRAWL") + "!!!!");}
DeleteAttribute(PChar,"TAVERNBRAWL");
}// TIH <--
Diag.TempNode = "exit";
}
PChar.TAVERNBRAWL = true;
LAi_LocationFightDisable(&locations[FindLocation(Pchar.location)], false);
Random_Raid("smugglers", 5, PIRATE,"enemy","friend",LanguageConvertString(tmpLangFileID,"TAVERNBRAWL") + "!!!!");
DeleteAttribute(PChar,"TAVERNBRAWL");
TAVERNBRAWL_FROMDIALOG is defined as '1', so that is ALWAYS true. Unless someone decides to disable it in InternalSettings.h .
^ That code looks to be the correct way of triggering a tavern brawl.Code:PChar.TAVERNBRAWL = true; LAi_LocationFightDisable(&locations[FindLocation(Pchar.location)], false); Random_Raid("smugglers", 5, PIRATE,"enemy","friend",LanguageConvertString(tmpLangFileID,"TAVERNBRAWL") + "!!!!"); DeleteAttribute(PChar,"TAVERNBRAWL");
The adding of that "player attribute" and deleting it again afterwards seems to be to convince the enemies generated in a tavern brawl to use only their fists.
That to make it seem like an actual tavern brawl, rather than yet another swordfight.
If you do such a "Random Raid" with soldiers, you may want to not do that.
As soon as you add the attribute, it starts to take effect. The deleting is just to clean up so it doesn't affect any enemies generated after the tavern brawl starts.Yes, i see. Does that mean i should still add the attribute but not delete it for the soldiers, or should i neither add nor delete it?
LAi_LocationFightDisable(&locations[FindLocation(Pchar.location)], false);
Random_Raid("smugglers", 5, PIRATE,"enemy","friend",LanguageConvertString(tmpLangFileID,"TAVERNBRAWL") + "!!!!");
Here is the full function for your reference:I´ve made a rather interesting observation. The detection chance is dependent on leadership, and not national rank and/or fame rank, right?
float GetChanceDetectFalseFlag()
{
// original code -->
// float rank = GetRankFromPoints(GetScore(GetMainCharacter()));
// return CHANCE_DETECT_FALSE_FLAG_BASE+(CHANCE_DETECT_FALSE_FLAG_MAX-CHANCE_DETECT_FALSE_FLAG_BASE)*rank/MAX_RANK;
// original code <--
// PB -->
if (iForceDetectionFalseFlag == 1) return 1.0;
if (iForceDetectionFalseFlag == -1) return 0.0;
// PB <--
// LDH -->
ref mchr = GetMainCharacter(); // KK
float score = GetScore(mchr); // KK
float rank = GetRankFromPoints(score);
int sneak = CalcCharacterSkill(mchr, SKILL_SNEAK);
int difficulty = GetDifficulty();
float chance = rank/MAX_RANK * (11.0-sneak)/10.0;
chance = chance * difficulty/2.0; // 0.5, 1.0, 1.5, 2.0
if(IsCharacterPerkOn(mchr, "Disguiser")) chance = chance * 0.9;
// chance = chance * (difficulty+1)/3.0; // alternate difficulty calculation 0.67, 1,0, 1.33, 1.67
chance = fclamp(CHANCE_DETECT_FALSE_FLAG_BASE, CHANCE_DETECT_FALSE_FLAG_MAX, chance); // PURSEON: so chance doesn't go over min/max
// LogIt("False Flag Detection - Score: " + score + ", rank: " + rank + ", Sneak: " + sneak + ", Chance: " + chance*100.0 + "%"); // for testing
// LogIt("The chance of your false flag being detected is " + chance*100.0 + "%"); // Tell the player, it might get him used to looking for it.
return chance;
// LDH <--
}
Fame IS factored in. But I will probably change how that works at some point in the future.
I've got in mind to "multiply your fame points by your reputation" in some way.
So if your reputation is "Neutral", then by default you would have a low Score/Fame.
You can then become famous either by becoming a Hero OR a Bloody Terror.
This will be tackled in Beta 5, but not before. There I want to make it much harder to get to either extreme of the Reputation scale.
So for now, I'd suggest getting the basic logic working in a clear, clean and simple way. The balancing will probably end up changing later anyway.
That function just returns "the theoretical chance value that a false flag IS detected".One thing though: You said a false flag detection can only happen when at war with a nation, but i see no check to see if you're at war in that code. What's up with that?
bool CheckForMainCharacterfalseflag(ref chr, float visibility_range, float ship_range)
{
if (IsCompanion(chr)) return false; // Companions don't care
if (CheckForPirateException(chr)) return false; // You are friendly to the pirates, flying a pirate flag and the town is tolerant of pirates
if (GetAttribute(chr, "skipFalseFlag")) return false; // Quest ship that will always believe your false flag
ref PChar = GetMainCharacter();
bool Recognized = false;
float chance = 1 - (ship_range / visibility_range);
float randVal = frnd();
if (SeaAI_GetRelation(sti(chr.index), sti(PChar.index)) != RELATION_ENEMY && GetNationRelation(PERSONAL_NATION, sti(chr.nation)) == RELATION_ENEMY)
{
if (ship_range < visibility_range)
{
chance = 0.5 + chance; // 0.5 will be decreased if you are too easily recognized
chance = chance * GetChanceDetectFalseFlag();
// chance = 1.0;
if(randVal <= chance)
{
Trace("FLAGS: The " + GetMyShipNameShow(chr) + " has recognized our false " + GetNationDescByType(GetCurrentFlag()) + " flag at range=" + ship_range + " with visibility=" + visibility_range + ", chance=" + chance + " and frnd=" + randVal);
Recognized = true;
SetGroupHostile(chr, false); // They start firing on you, so it is no immediate betrayal
}
}
}
return Recognized;
}
That function just returns "the theoretical chance value that a false flag IS detected".
The actual checking is done outside that function. Here in PROGRAM\Screwface_functions.c to be exact:
So you're very much correct that the "only when at war with a nation" check is NOT in there.Code:bool CheckForMainCharacterfalseflag(ref chr, float visibility_range, float ship_range) { if (IsCompanion(chr)) return false; // Companions don't care if (CheckForPirateException(chr)) return false; // You are friendly to the pirates, flying a pirate flag and the town is tolerant of pirates if (GetAttribute(chr, "skipFalseFlag")) return false; // Quest ship that will always believe your false flag ref PChar = GetMainCharacter(); bool Recognized = false; float chance = 1 - (ship_range / visibility_range); float randVal = frnd(); if (SeaAI_GetRelation(sti(chr.index), sti(PChar.index)) != RELATION_ENEMY && GetNationRelation(PERSONAL_NATION, sti(chr.nation)) == RELATION_ENEMY) { if (ship_range < visibility_range) { chance = 0.5 + chance; // 0.5 will be decreased if you are too easily recognized chance = chance * GetChanceDetectFalseFlag(); // chance = 1.0; if(randVal <= chance) { Trace("FLAGS: The " + GetMyShipNameShow(chr) + " has recognized our false " + GetNationDescByType(GetCurrentFlag()) + " flag at range=" + ship_range + " with visibility=" + visibility_range + ", chance=" + chance + " and frnd=" + randVal); Recognized = true; SetGroupHostile(chr, false); // They start firing on you, so it is no immediate betrayal } } } return Recognized; }
No worries. If you can post your changes at the end of the weekend, I can add them to a new update on Monday.Concerning the progress of my modifications, the pirates and random guards are pretty much done, but i keep coming up with new ways to streamline things or make things make more sense. The current versions do seem functional to me though. I'm just waiting to see if i can get the random sitting sailors to work too before i upload the files, since fixing it may involve new changes for the other files.
No worries. If you can post your changes at the end of the weekend, I can add them to a new update on Monday.
if (TAVERNBRAWL_FISTSONLY)
{
PChar.TAVERNBRAWL = true; //MT: makes spawned enemies fight with their fists
}
{LAi_LocationFightDisable(&locations[FindLocation(Pchar.location)], false);
Random_Raid("smugglers", 5, PIRATE,"enemy","friend",LanguageConvertString(tmpLangFileID,"TAVERNBRAWL") + "!!!!");}
if (TAVERNBRAWL_FISTSONLY)
{
DeleteAttribute(PChar,"TAVERNBRAWL"); //MT: makes spawned enemies fight with their fists
}
That seems about right to me. If this is something you have to call often, you could make it a function:I've also noticed that internalsettings has a toggle for tavernbrawlers to fight with their fists, while the code i found in the dialogue doesn't take this toggle into account. I've devised the following code to fix that, but i suspect it could be done more efficiently. Can it?
Code:if (TAVERNBRAWL_FISTSONLY) { PChar.TAVERNBRAWL = true; //MT: makes spawned enemies fight with their fists } {LAi_LocationFightDisable(&locations[FindLocation(Pchar.location)], false); Random_Raid("smugglers", 5, PIRATE,"enemy","friend",LanguageConvertString(tmpLangFileID,"TAVERNBRAWL") + "!!!!");} if (TAVERNBRAWL_FISTSONLY) { DeleteAttribute(PChar,"TAVERNBRAWL"); //MT: makes spawned enemies fight with their fists }
void Random_Brawl()
{
ref PChar = GetMainCharacter();
if (TAVERNBRAWL_FISTSONLY) PChar.TAVERNBRAWL = true; //MT: makes spawned enemies fight with their fists
LAi_LocationFightDisable(LoadedLocation, false);
Random_Raid("smugglers", 5, PIRATE,"enemy","friend",LanguageConvertString(tmpLangFileID,"TAVERNBRAWL") + "!!!!");
DeleteAttribute(PChar,"TAVERNBRAWL"); //MT: makes spawned enemies fight with normal weapons again
}
if (TAVERNBRAWL_FROMDIALOG) Random_Brawl();