There is the DISARM_MODE toggle at the bottom of PROGRAM\InternalSettings.h that triggers this section in PROGRAM\Loc_ai\LAi_events.c:What does the "disarm" attribute on swords do?
Code:
// CCC and PB: New attribute to weapons to allow for disarming opponents
bool tbool = CheckAttribute(enemy, "equip.blade");
if(tbool) tbool = GetCharacterEquipByGroup(enemy,BLADE_ITEM_TYPE) != "bladeX4";
if( DISARM_MODE && CheckAttribute(weapon, "disarm" ) && LAi_IsFightMode(enemy) && !CheckAttribute(enemy, "nodisarm" ) && tbool)
{
int disarmbonus = 0;
if(CheckAttribute(attack,"perks.list.SwordplayProfessional")) {disarmbonus = 20;}
// if attacker has professional fencing skill, increase disarm chance with 20%
int disarmpenalty = 0;
if(CheckAttribute(enemy,"perks.list.SwordplayProfessional")) {disarmpenalty = 10;}
// if attacked victim has professional fencing skill, decrease disarm chance with 10%
if(sti(rand(100)+enemy.skill.Fencing) < sti(weapon.disarm)+sti(attack.skill.Fencing) + disarmbonus - disarmpenalty)
{
LAi_CharacterPlaySound(enemy,"OBJECTS\duel\sword_fallen.wav");
string enemy_blade = GetCharacterEquipByGroup(enemy,BLADE_ITEM_TYPE);
RemoveCharacterEquip(enemy, BLADE_ITEM_TYPE );
GiveItem2Character(attack, enemy_blade);
if ( enemy.chr_ai.group != LAI_GROUP_PLAYER && !bAbordageStarted )
// no disarming opponents during boarding
{
LAi_SetCitizenTypeNoGroup(enemy);
Log_SetStringToLog(TranslateString("","Opponent disarmed !"));
}
else
{
TakeItemFromCharacter(enemy, enemy_blade);
if ( sti(enemy.index) != GetMainCharacterIndex() && !bAbordageStarted ) // if NOT player
// officers safe from being disarmed boarding; player NOT safe from being disarmed during boarding
{
RemoveCharacterEquip(attack, BLADE_ITEM_TYPE ); // makes enemy use your blade against your officer
EquipCharacterByItem(attack, enemy_blade); // and enables you to get it back by killing him/her
Log_SetStringToLog(TranslateString("","One of your officers was disarmed!"));
LAi_tmpl_afraid_SetAfraidCharacter(enemy, attack, true); // makes officer flee
LAi_SetAfraidDead(enemy);
}
else
{
RemoveCharacterEquip(attack, BLADE_ITEM_TYPE ); // makes enemy use your blade against you
EquipCharacterByItem(attack, enemy_blade); // and enables you to get it back by killing him/her
EquipCharacterByItem(enemy, "bladeX4");
Log_SetStringToLog(TranslateString("","You were disarmed!"));
}
}
}
}
I don't think it serves any real purpose anymore, since the bladedamage mod kind-of took over from it.
Either the enemy continues to fight with his fists (in which case: no problem), OR he gives up and tries to run away.There's certainly a problem with enemies who attack you with a worn weapon, it breaks, you don't notice it, and you lose reputation for continuing to attack.
Only in the second case you would get the reputation loss. (And this second case never happens in boardings.)
I don't think fighting, let alone killing, someone who is running away is a very respectable thing to do; so the reputation loss makes sense.
I can see the problem though when it just happened and you haven't had the chance to notice it.
At sea, a similar situation applies to ships that surrender in the middle of a cannon volley.
This is why there is a 'grace period' coded in per ship so that any hits right after a surrender don't immediately trigger the reputation loss.
This doesn't happen on shore.
Adding this could be done here (also in PROGRAM\Loc_ai\LAi_events.c:
Code:
if(BladeBreak)
{
if(sti(enemy.index) == GetMainCharacterIndex()){
Continue_Bladedamage = false;
LogIt("Your blade decreased in quality!"); }
if(CheckAttribute(enemy, "nodisarm")) Continue_Bladedamage = false;
if(enemy.chr_ai.group == LAI_GROUP_PLAYER) Continue_Bladedamage = false;
if(bAbordageStarted) Continue_Bladedamage = false;
if(Continue_Bladedamage && rand(1) > 0)
{
LAi_SetCitizenTypeNoGroup(enemy);
}
else
{
if(CheckCharacterItem(enemy, FindCharacterItemByGroup(enemy, BLADE_ITEM_TYPE)) && GetItemQualityByID(FindCharacterItemByGroup(enemy, BLADE_ITEM_TYPE)) != 0 && BLADEDAMAGE_USEOTHERBLADE)
// If character has another blade and the other blade is not broken and USEOTHERBLADE is on
{
// Then use the other blade
EquipCharacterByItem(enemy, FindCharacterItemByGroup(enemy, BLADE_ITEM_TYPE));
}
else
{
// Else use the default blade
if(!CheckCharacterItem(enemy, BLADEDAMAGE_DEFAULTBLADE))
{GiveItem2Character(enemy, BLADEDAMAGE_DEFAULTBLADE);}
// To prevent characters being given another defaultblade if they already have one
EquipCharacterByItem(enemy, BLADEDAMAGE_DEFAULTBLADE);
}
}
}
And here is an example of how to code a delayed execution of a custom function from PROGRAM\NK.c:
Code:
PostEvent("KrakenAttackFinished", delay, "i", rCharacter);
}
#event_handler("KrakenAttackFinished", "FinishKrakenAttack");
void FinishKrakenAttack()
{
ref pchar = GetMainCharacter();
aref rCharacter = GetEventData();
LogIt("Captain, the Kraken has finished its attack on the " + rCharacter.ship.name + "!");
if(CheckAttribute(pchar, "KrakenAttack")) PostEvent("EnableKraken", 5*60*1000);
}
Then again in LAi_events.c, this is where the reputation loss for unarmed victims is applied:
Code:
if(!isSetBalde)
{
// ccc mar05 REPLOSS tweak added
if(enemy.chr_ai.group != LAi_monsters_group)
{
if(!CheckAttribute(enemy,"corpse")) enemy.corpse = false; //Fix by levis
if(enemy.corpse==false) //Levis: fix so you won't get reploss from hitting corpses
{
if (!CheckAttribute(enemy,"pickgold") || GetCharacterEquipByGroup(attack, BLADE_ITEM_TYPE) != "bladeX3") // GR: no reploss if he robbed you and you use a thief's knife
{
if(GetAttribute(attack, "index") && sti(attack.index) == GetMainCharacterIndex()) LogIt(TranslateString("","CHANGE REP for player:") + " " + -REPLOSS + " - " + TranslateString("","undrawn blade 2")); // LDH 19Dec08
LAi_ChangeReputation(attack, - REPLOSS); // NK tempfix for un-drawn blades 04-17
}
}
}
//exp = 0.0;
}

On a side-note... I think this code has never functioned as intended:
Code:
bool isSetBalde = (SendMessage(enemy, "ls", MSG_CHARACTER_EX_MSG, "IsSetBalde") != 0);
But as far as I know, it only returns 'true' for characters who don't have a blade equipped at all.
Which is stupid, because we can check that easily on the PROGRAM side; without a need to ask the engine itself using 'SendMessage' .
I wonder if that was ever fixed in later releases like CoAS or TEHO...