WIP: Non Lethal Damage - UPDATED

Scripted ALFA systems & related tech discussions (ACR)

Moderators: ALFA Administrators, Staff - Technical

User avatar
Creslyn
Orc Champion
Posts: 423
Joined: Sat Jan 10, 2004 2:30 am

WIP: Non Lethal Damage - UPDATED

Post by Creslyn »

UPDATE:
Current version of code here. Information in this post updated.

Bones:
A simple toggle to turn subdual on and off, usable from PC Tools (immediate effect, free action) or with the Subdual Widget in inventory (requires a standard action to use like any other activated item). Equipped weapons get properties to negate real damage and fire a script that runs the actual subdual stuff.

Notes:
Can be used by pc's or npc's, with any (melee) weapon, within reason (bonus damage either elemental or physical will still fry a victim). Will not work for npc's who already have natural creature weapons, such as animals and shapeshifted druids. Does not work accurately with giants and other such huge creatures.

Sneak attacks are disabled while in subdual mode.
Last edited by Creslyn on Wed Mar 11, 2009 11:15 pm, edited 3 times in total.
User avatar
Wynna
Dungeon Master
Posts: 5734
Joined: Sat Jan 03, 2004 10:09 am
Location: Seattle, WA (PST)

Post by Wynna »

:eek:

No fists? That's it. I'm outta here.

Ummm...wow, Cres? That's a lot of work. Thank you for getting wrestling this system into basic submission. I'll let tech minds comment on the actual code, but thanks!
Enjoy the game
User avatar
Creslyn
Orc Champion
Posts: 423
Joined: Sat Jan 10, 2004 2:30 am

Post by Creslyn »

Original post updated with code and information.
User avatar
Teric neDhalir
Githyanki
Posts: 1495
Joined: Mon Jan 05, 2004 10:04 pm
Location: Manchester UK

Post by Teric neDhalir »

tl;dr. Heh. Thanks for this, Creslyn.
Thangorn
Haste Bear
Posts: 2081
Joined: Fri Oct 01, 2004 1:00 pm
Location: Queenstown, New Zealand

Post by Thangorn »

Thanks Cres.. remember to grab me for testing if you see me on.

These scripts are key to some of my statics (recapture the escaped slave), scripted events (taproom brawls and muggers) and city guard AI.

Yes Zhentil Keep beta at least will be a place to beat you into submission :)
On indefinite real life hiatus

[22:52] <Veilan> obviously something sinister must be afoot if a DM does not have his social security number in his avatar name!
User avatar
White Warlock
Otyugh
Posts: 920
Joined: Mon Jan 05, 2004 3:44 am
Location: Knu-Mythia
Contact:

Post by White Warlock »

*bump* Excellent stuff Cres. Definitely cannot wait to see this ingame. Such a thing as this doesn't need to be perfect, but you have brought it pretty near close, and that's plenty more than we need to make the most out of it.

Thanks again Cres.
User avatar
Wynna
Dungeon Master
Posts: 5734
Joined: Sat Jan 03, 2004 10:09 am
Location: Seattle, WA (PST)

Re: WIP: Non Lethal Damage - UPDATED

Post by Wynna »

Cres, I'm looking at environmental effects in a limited campaign environment. I've got the SRD cold effects coded, everything but making them subdual. To alter the code below to sudual, do I include your includes, toggle the NLD on and apply the damage every round? I haven't yet written the script to turn off the cold loop, but it will consist of setting the ColdRep variable back to 0 by leaving the area, which will truncate the loop. At that point I'll need to turn off subdual, too, and begin healing the effects applied below. Pointers for my first foray into your NLD code would be appreciated. Thanks!

Code: Select all

if(GetLocalInt(OBJECT_SELF, "ColdRep") == 1)
				{if(GetTag(GetArea(OBJECT_SELF)) == "5b_ext_frosthills_glacier")
					{float fTimeLoop = 91.0;
					 if(FindSubString(GetName(GetItemInSlot(INVENTORY_SLOT_CLOAK, OBJECT_SELF)), "Greatcloak") == -1)
						{fTimeLoop = 540.0;
						}
					if(GetIsSkillSuccessful(OBJECT_SELF, SKILL_SURVIVAL, 15, TRUE))
						{SetLocalInt(OBJECT_SELF, "Survival", 4);}
					int nRep = GetLocalInt(OBJECT_SELF, "nRep");
					if(FortitudeSave(OBJECT_SELF, 15 + nRep - GetLocalInt(OBJECT_SELF, "Survival"), SAVING_THROW_TYPE_COLD, OBJECT_SELF))
						{effect eCold = EffectDamage(d6(), DAMAGE_TYPE_COLD, DAMAGE_POWER_NORMAL, FALSE);
					 	 ApplyEffectToObject(DURATION_TYPE_INSTANT, eCold, OBJECT_SELF);
						 DelayCommand(fTimeLoop, ExecuteScript("slv_static_voice_cr_pc", OBJECT_SELF));
						}
					SetLocalInt(OBJECT_SELF, "Survival", 0);
					nRep = nRep++;
					SetLocalInt(OBJECT_SELF, "nRep", nRep);
					}
					
				}
Enjoy the game
User avatar
Creslyn
Orc Champion
Posts: 423
Joined: Sat Jan 10, 2004 2:30 am

Re: WIP: Non Lethal Damage - UPDATED

Post by Creslyn »

I really should wipe the stuff in this thread and post a link to the sourceforge page I guess (ed: done). Anyway, what you're after isn't too difficult. Simplest way to do it would be to use the ACR_ApplyNLDDamage() function that I oh so cleverly forgot to write. If AL can toss this into the include, you should be able to use it instead of applying the cold damage.

Code: Select all

// Apply an amount of nonlethal damage (nSubdualDamage) to oTarget directly.
// * This will simply apply a flat amount of nonlethal damage, ignoring resistances,
//    saves or anything and everything else.
void ACR_ApplyNLDDamageToCreature(object oTarget, int nSubdualDamage);


void ACR_ApplyNLDDamageToCreature(object oTarget, int nSubdualDamage)
{
    int nNLDTotal = _GetNLDTotal(oTarget);
    int nHPMax = GetMaxHitPoints(oTarget);
    int nCap = nHPMax + 10;
    nNLDTotal = ((nNLDTotal + nSubdualDamage) > nCap) ? nCap :
            nNLDTotal + nSubdualDamage;
    _SetNLDTotal(oTarget, nNLDTotal);
    ACR_ApplyNLDEffects(oTarget, nNLDTotal);
}
User avatar
Creslyn
Orc Champion
Posts: 423
Joined: Sat Jan 10, 2004 2:30 am

Re: WIP: Non Lethal Damage - UPDATED

Post by Creslyn »

Just a minor update for AL, a couple bugs fixed and a few more checks implemented.
- Shapeshifters gain their 10/Silver dr vs non lethal damage
- remaining class/feat based dr checks added
- permanent -5 damage after a server crash bug fixed (won't affect existing bugged weapons, they'll need to be replaced)
- weapon focus: unarmed strike now accounted for in unarmed non lethal combat

Code: Select all

Mostly minor changes to the following functions:
-ACR_ToggleNLDMode()
-ACR_NLD_OnWeaponSwitch()
-_NLDamageReductionCheck()
-_ApplyNLDFist()

void ACR_ToggleNLDMode(object oUser = OBJECT_SELF)
{
  object oWeapR = GetItemInSlot(4, oUser);
  object oWeapL = GetItemInSlot(5, oUser);
  object oCweap = GetItemInSlot(INVENTORY_SLOT_CWEAPON_R, oUser);
  if(_GetNLDMode(oUser))
  {
    if(GetIsObjectValid(oWeapR) && GetWeaponType(oWeapR) != WEAPON_TYPE_NONE
		&& GetWeaponRanged(oWeapR) != TRUE)
	  ACR_NLD_OnWeaponSwitch(oUser, oWeapR, FALSE);
	if(GetIsObjectValid(oWeapL) && GetWeaponType(oWeapL) != WEAPON_TYPE_NONE)
	  ACR_NLD_OnWeaponSwitch(oUser, oWeapL, FALSE);
	if(GetIsObjectValid(oCweap) && GetTag(oCweap) == "acr_nld_fist")
	{
	  DestroyObject(oCweap, 0.2, FALSE);
	}
	_RestoreNLDSneakAttackFeats(oUser);
	FeatRemove(oUser, FEAT_WEAPON_PROFICIENCY_CREATURE);
	if(GetHasFeat(FEAT_WEAPON_FOCUS_CREATURE, oUser))
	  FeatRemove(oUser, FEAT_WEAPON_FOCUS_CREATURE);
	DelayCommand(0.1,_SetNLDMode(oUser, FALSE));
  }
  else
  {
	_SetNLDMode(oUser, TRUE);
    if(GetIsObjectValid(oWeapR) && GetWeaponType(oWeapR) != WEAPON_TYPE_NONE
		&& GetWeaponRanged(oWeapR) != TRUE)
	  DelayCommand(0.1,ACR_NLD_OnWeaponSwitch(oUser, oWeapR, TRUE));
	if(GetIsObjectValid(oWeapL) && GetWeaponType(oWeapL) != WEAPON_TYPE_NONE)
	  DelayCommand(0.1,ACR_NLD_OnWeaponSwitch(oUser, oWeapL, TRUE));
	_HandleNLDSneakAttacks(oUser);
	DelayCommand(0.1, _GiveNLDFist(oUser));
  }
}

void ACR_NLD_OnWeaponSwitch(object oUser, object oWeapon, int bEquipped = TRUE)
{
  if(!_GetNLDMode(oUser))
    return;
  object oWeapR = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oUser);
  object oWeapL = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oUser);
  object oCweap = GetItemInSlot(INVENTORY_SLOT_CWEAPON_R, oUser);
// handle offhand/2handed str modifiers for currently equipped weapons
  if(GetIsObjectValid(oWeapR) && GetWeaponRanged(oWeapR) != TRUE 
  	&& GetWeaponType(oWeapR) != WEAPON_TYPE_NONE)
  {
    SetLocalInt(oWeapR,ACR_NLD_WOFFHAND,FALSE);
// item in the offhand?
    if(GetIsObjectValid(oWeapL) && oWeapL != oWeapR)
	{
	  SetLocalInt(oWeapR,ACR_NLD_W2HANDED,FALSE);
	  if(GetWeaponType(oWeapL) != WEAPON_TYPE_NONE)
	    SetLocalInt(oWeapL,ACR_NLD_WOFFHAND,TRUE);
	}
	else
	{
//check weapon size vs creature size to determine if it's wielded 2 handed
	  int nSize = StringToInt(Get2DAString("baseitems","WeaponSize",GetBaseItemType(oWeapR)));
// Debug
//	SendMessageToPC(oUser, "Weapon size is: "+IntToString(nSize));	  
	  if((GetCreatureSize(oUser) == CREATURE_SIZE_HUGE && nSize >= 4)
	  	|| (GetCreatureSize(oUser) == CREATURE_SIZE_LARGE && nSize >= 4)
	  	|| (GetCreatureSize(oUser) == CREATURE_SIZE_MEDIUM && nSize >= 3)
	  	|| (GetCreatureSize(oUser) == CREATURE_SIZE_SMALL && nSize >= 2)
		|| (GetCreatureSize(oUser) == CREATURE_SIZE_TINY && nSize >= 1))
	    SetLocalInt(oWeapR,ACR_NLD_W2HANDED,TRUE);
	  else
	    SetLocalInt(oWeapR,ACR_NLD_W2HANDED,FALSE);
	}
  }
  else if(!GetIsObjectValid(oWeapR))
  {
// need to work on barehanded subdual.
	if(!GetIsObjectValid(oCweap))
	{
	  _GiveNLDFist(oUser);
	}
  }
// now look at the weapon that was just equipped  
  if(GetTag(oWeapon) == "acr_nld_fist")
    return;
	
  if(GetIsObjectValid(oWeapon) && GetWeaponRanged(oWeapon) != TRUE 
  	&& GetWeaponType(oWeapon) != WEAPON_TYPE_NONE)
  {
    itemproperty iProp;
    itemproperty iHit = ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER,1);
	itemproperty iNoDam = ItemPropertyNoDamage();
	itemproperty iNoStr = ItemPropertyDamagePenalty(5);
	int nDiceDam, nDiceNum, nBaseItem, nSADice, nDamPenalty;
// weapon was just unequipped: remove NLD properties, zero damage/sneak vars
    if(bEquipped == FALSE)
    {
	  iProp = GetFirstItemProperty(oWeapon);
	  while(GetIsItemPropertyValid(iProp))
	  {
	    if(GetItemPropertyType(iProp) == ITEM_PROPERTY_ONHITCASTSPELL
			|| GetItemPropertyType(iProp) == ITEM_PROPERTY_NO_DAMAGE
			|| GetItemPropertyType(iProp) == ITEM_PROPERTY_DECREASED_DAMAGE)
	      DelayCommand(0.5,AssignCommand(oUser,RemoveItemProperty(oWeapon,iProp)));
		iProp = GetNextItemProperty(oWeapon);
	  }
	  SetLocalInt(oWeapon,ACR_NLD_WOFFHAND,FALSE);
	  SetLocalInt(oWeapon,ACR_NLD_W2HANDED,FALSE);
	  SetLocalInt(oWeapon,ACR_NLD_SA_DICE,0);
	  nDamPenalty = GetLocalInt(oWeapon, ACR_NLD_DAMAGE_PENALTY);
	  if(nDamPenalty >= 1 && nDamPenalty < 255)
	    AssignCommand(oUser,AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyDamagePenalty(nDamPenalty),oWeapon));
    }
// weapon was just equipped: add NLD properties, set damage/sneak vars
    else
    {
	  iProp = GetFirstItemProperty(oWeapon);
	  while(GetIsItemPropertyValid(iProp))
	  {
	    if(GetItemPropertyType(iProp) == ITEM_PROPERTY_DECREASED_DAMAGE)
		{
		  nDamPenalty = GetItemPropertyCostTableValue(iProp);
		  SetLocalInt(oWeapon, ACR_NLD_DAMAGE_PENALTY, nDamPenalty);
		}
		iProp = GetNextItemProperty(oWeapon);
	  }
	  if(nDamPenalty < 1)
	    SetLocalInt(oWeapon, ACR_NLD_DAMAGE_PENALTY, 255);
	  nBaseItem = GetBaseItemType(oWeapon);
	  nDiceDam = StringToInt(Get2DAString("baseitems","DieToRoll",nBaseItem));
	  nDiceNum = StringToInt(Get2DAString("baseitems","NumDice",nBaseItem));
	  nSADice = _GetNLDSneakAttackDice(oUser);
	  SetLocalInt(oWeapon,ACR_NLD_DICE_DAMAGE,nDiceDam);
	  SetLocalInt(oWeapon,ACR_NLD_DICE_NUMBER,nDiceNum);
	  SetLocalInt(oWeapon,ACR_NLD_SA_DICE,nSADice);
	  AssignCommand(oUser,AddItemProperty(DURATION_TYPE_PERMANENT,iHit,oWeapon));
	  AssignCommand(oUser,AddItemProperty(DURATION_TYPE_PERMANENT,iNoDam,oWeapon));
	  AssignCommand(oUser,AddItemProperty(DURATION_TYPE_PERMANENT,iNoStr,oWeapon));
    }
  }
}

string _NLDamageReductionCheck(object oTarget, object oWeapon, int nNLDamage, int nHeal)
{
  string sReturn = "";
  int nDam = 0;
  int nHigh;
  string sHeal;
  string sWeapon = GetTag(oWeapon);
  object oSkin = GetItemInSlot(INVENTORY_SLOT_CARMOUR, oTarget);
  int nSDancer = GetLevelByClass(CLASS_TYPE_SHADOWDANCER, oTarget);
// Determine if oTarget has DR bypassable by adamantine weapons (spells only) 
  int nAdm = (GetHasSpellEffect(SPELL_PREMONITION, oTarget) == TRUE
    || GetHasSpellEffect(SPELL_SHADES_TARGET_CASTER, oTarget) == TRUE) ? 30 : 
  	(GetHasSpellEffect(SPELL_GREATER_STONESKIN, oTarget) == TRUE
	|| GetHasSpellEffect(SPELL_ETHEREAL_VISAGE, oTarget) == TRUE) ? 20 :
	(GetHasSpellEffect(SPELL_STONESKIN, oTarget) == TRUE
	|| GetHasSpellEffect(SPELL_SHADES_STONESKIN, oTarget) == TRUE
	|| GetHasSpellEffect(SPELL_SHADOW_SHIELD, oTarget) == TRUE
	|| (GetHasSpellEffect(SPELL_SHADOW_EVADE, oTarget) && nSDancer >= 10)) ? 10 :
	(GetHasSpellEffect(SPELLABILITY_MERGE_WITH_STONE, oTarget) == TRUE) ? 5 : FALSE;
  if(nAdm != FALSE)
  {
// Check the attackers weapon - is it adamantine?
    if(TestStringAgainstPattern("**"+ACR_NLD_MAT_ADAMANTINE+"**", sWeapon))
	  nAdm = FALSE;
  }

// Determine if oTarget has DR bypassable by magic weapons	
  int nMgc = (GetLevelByClass(CLASS_TYPE_MONK, oTarget) >= 20) ? 10 : 
  	(GetHasSpellEffect(SPELL_GHOSTLY_VISAGE, oTarget) == TRUE
	|| GetHasSpellEffect(SPELLABILITY_AS_GHOSTLY_VISAGE, oTarget) == TRUE
	|| (GetHasSpellEffect(351, oTarget) == TRUE) || (nSDancer <= 5
	&& GetHasSpellEffect(SPELL_SHADOW_EVADE, oTarget))) ? 5 : FALSE;
  if(nMgc != FALSE)
  {
// Check the attackers weapon - is it magical?
    if(GetItemHasItemProperty(oWeapon, ITEM_PROPERTY_ENHANCEMENT_BONUS))
	  nMgc = FALSE;
  }
  
// Determine if oTarget has DR bypassable by cold iron weapons
  int nWlk = GetLevelByClass(CLASS_TYPE_WARLOCK, oTarget);
  int nCld= (nWlk >= 3 && nWlk < 7) ? 1 : (nWlk >= 7 && nWlk < 11) ? 2 :
	(nWlk >= 11 && nWlk < 15) ? 3 : (nWlk >= 15 && nWlk < 19) ? 4 :
	(nWlk >= 19 || GetLevelByClass(CLASS_TYPE_SPIRIT_SHAMAN, oTarget) >= 20) ? 5 : 
	(GetHasFeat(2087, oTarget)) ? 10 : FALSE;
  int nFey = GetHasFeat(2184, oTarget, TRUE);
  int nCnt;
  if(nFey)
  {
    for(nCnt=2181;nCnt<=2184;nCnt++)
	{
	  if(GetHasFeat(nFey, oTarget, TRUE))
	    nFey += 1;
	}
	nCld += nFey;
  }
  if(nCld != FALSE)
  {
// Check the attackers weapon - is it cold iron?	
	if(TestStringAgainstPattern("**"+ACR_NLD_MAT_COLDIRON+"**", sWeapon))
	  nCld = FALSE;
  }
  
// Determine if oTarget has DR bypassable by silver weapons	
  int nSlv = (GetHasSpellEffect(SPELL_I_DARK_FORESIGHT, oTarget) == TRUE || GetHasFeat(2088, oTarget)
  	|| (GetHasSpellEffect(SPELL_SHADOW_EVADE, oTarget) && (nSDancer == 8 || nSDancer == 9)) 
	|| GetRacialType(oTarget) == RACIAL_TYPE_SHAPECHANGER) ? 10 : 
	(GetHasSpellEffect(SPELL_SHADOW_EVADE, oTarget) && (nSDancer == 6 || nSDancer == 7)) ? 5 : FALSE;
  if(nSlv != FALSE)
  {
// Check the attackers weapon - is it alchemical silver?	
    if(TestStringAgainstPattern("**"+ACR_NLD_MAT_ALCSILVER+"**", sWeapon))
      nSlv = FALSE;
  }

  if(nAdm != FALSE || nMgc != FALSE || nSlv != FALSE || nCld != FALSE)
  {
    nHigh = (nAdm >= nMgc && nAdm >= nSlv && nAdm >= nCld) ? nAdm :
		(nSlv >= nMgc && nSlv >= nCld) ? nSlv :
		(nCld >= nMgc) ? nCld : nMgc;
  }
  else
    nHigh = FALSE;

  if(nHigh != FALSE)
  {
	effect eDam;
    if(nHigh >= nNLDamage)
	{
	  nDam = (nNLDamage > nHeal) ? nNLDamage - nHeal : 0;
	  sReturn = "ND_00";
	}
	else
	{
	  sReturn = IntToString(nNLDamage - nHigh);
	  if(GetStringLength(sReturn) == 1)
	    sReturn = "0"+sReturn;
	  if(nHigh >= nHeal)
	  {
	    nDam = nHigh - nHeal;
		sReturn = "ND_"+sReturn;
	  }
	  else
	  {
	    nDam = 0;
		sHeal = IntToString(nHeal - nHigh) + "_";
		if(GetStringLength(sHeal) == 2)
		  sHeal = "0"+sHeal;
		sReturn = sHeal+sReturn;
	  }
	}
	if(nDam > 0)
	{
      eDam = EffectDamage(nDam, DAMAGE_TYPE_BLUDGEONING);
	  AssignCommand(GetItemPossessor(oWeapon),
		ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget));
	}
  }
  else
  {
// Determine if oTarget has DR not bypassable by anything
// (barb DR or adamantine armor/shield only)
	int nBarb = GetLevelByClass(CLASS_TYPE_BARBARIAN, oTarget);
	int nDDef = GetLevelByClass(CLASS_TYPE_DWARVENDEFENDER, oTarget);
	int nNoPass = (nBarb >= 7	&& nBarb < 10) ? 1 : (nBarb >= 10 && nBarb < 13) ? 2 : 
	  ((nBarb >= 13 && nBarb < 16) || (nDDef >= 6 && nDDef < 10)) ? 3 :
	  (nBarb >= 16 && nBarb < 19) ? 4 : (nBarb >= 19) ? 5 : (nDDef >= 10) ? 6 : FALSE;
	if(nNoPass != FALSE)
	{
// Check for the Greater Resiliency feat (barb only)  
	  nNoPass = (GetHasFeat(FEAT_GREATER_RESILIENCY, oTarget) == TRUE) ?
	  nNoPass+1 : nNoPass;
	}
	int nArm = 0;
	int nRank;
	object oArm = GetItemInSlot(INVENTORY_SLOT_CHEST, oTarget);
	if(GetIsObjectValid(oArm))
	{
	  string sArm = GetTag(oArm);
	  if(TestStringAgainstPattern("**"+ACR_NLD_MAT_ADAMANTINE+"**", sArm))
	  {
    	nRank = GetArmorRank(oArm);
    	nArm = (nRank == ARMOR_RANK_HEAVY) ? 3 : (nRank == ARMOR_RANK_MEDIUM) ? 2 :
			(nRank == ARMOR_RANK_LIGHT) ? 1 : 0;
	  }
 	}
	object oShd = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oTarget);
	if(GetIsObjectValid(oShd))
	{
	  string sShd = GetTag(oShd);
	  if(TestStringAgainstPattern("**"+ACR_NLD_MAT_ADAMANTINE+"**", sShd))
	  {
    	int nType = GetBaseItemType(oShd);
		nArm = (nType == BASE_ITEM_TOWERSHIELD && nArm < 3) ? 3 :
	  		(nType == BASE_ITEM_LARGESHIELD && nArm < 2) ? 2 :
			(nType == BASE_ITEM_SMALLSHIELD && nArm < 1) ? 1 : nArm;
	  }
	}
	nNoPass = (nNoPass >= nArm) ? nNoPass : nArm;
	if(nNoPass >= 1)
	{
	  if(nNoPass < nNLDamage)
	  {
	    sReturn = IntToString(nNLDamage - nNoPass);
		if(GetStringLength(sReturn) == 1)
		  sReturn == "0"+sReturn;
		if(nNoPass >= nHeal)
		  sReturn = "ND_"+sReturn;
		else
		{
		  sHeal = IntToString(nHeal - nNoPass) + "_";
		  if(GetStringLength(sHeal) == 2)
		    sHeal = "0"+sHeal;
		  sReturn = sHeal + sReturn;
		}
	  }
	  else
	    sReturn = "ND_00";
	}
	else
	{
      sReturn = IntToString(nNLDamage);
	  if(GetStringLength(sReturn) == 1)
		sReturn = "0"+sReturn;
      sHeal = IntToString(nHeal) + "_";
	  if(GetStringLength(sHeal) == 2)
	    sHeal = "0"+sHeal;
	  sReturn = sHeal + sReturn;
	}
  }
  return sReturn;
}

void _ApplyNLDFist(object oUser)
{
  object oFist = GetItemInSlot(INVENTORY_SLOT_CWEAPON_R, oUser);
  if(!GetIsObjectValid(oFist))
  {
    return;
  }
  int nDiceDam, nDiceNum, nSADice, nSlot, nSize, nMonk;
  nSize = GetCreatureSize(oUser);
  nDiceNum = 1;
  nDiceDam = (nSize == CREATURE_SIZE_SMALL) ? 2 : 3;
  nMonk = GetLevelByClass(CLASS_TYPE_MONK, oUser) 
  	+ GetLevelByClass(CLASS_TYPE_SACREDFIST, oUser);
  if(nMonk >= 1)
  {
    if(nMonk <= 3)
	  nDiceDam = (nSize == CREATURE_SIZE_SMALL) ? 4 : 6;
	else if(nMonk <= 7)
	  nDiceDam = (nSize == CREATURE_SIZE_SMALL) ? 6 : 8;
	else if(nMonk <= 11)
	  nDiceDam = (nSize == CREATURE_SIZE_SMALL) ? 8 : 10;
	else if(nMonk <= 15)
	{
	  nDiceDam = (nSize == CREATURE_SIZE_SMALL) ? 10 : 6; 
	  nDiceNum = (nSize == CREATURE_SIZE_SMALL) ? 1 : 2;
	}
	else if(nMonk <= 19)
	{
	  nDiceDam = (nSize == CREATURE_SIZE_SMALL) ? 6 : 8; 
	  nDiceNum = 2;
	}
	else
	{
	  nDiceDam = (nSize == CREATURE_SIZE_SMALL) ? 8 : 10;
	  nDiceNum = 2;
	}
  }
  nSADice = _GetNLDSneakAttackDice(oUser);
  SetLocalInt(oFist, ACR_NLD_DICE_DAMAGE, nDiceDam);
  SetLocalInt(oFist, ACR_NLD_DICE_NUMBER, nDiceNum);
  SetLocalInt(oFist, ACR_NLD_SA_DICE, nSADice);
  SetLocalInt(oFist, ACR_NLD_WOFFHAND, FALSE);
  SetLocalInt(oFist, ACR_NLD_W2HANDED, FALSE);
  if(GetHasFeat(FEAT_WEAPON_FOCUS_UNARMED_STRIKE, oUser))
    FeatAdd(oUser, FEAT_WEAPON_FOCUS_CREATURE, FALSE);
}
User avatar
Ithildur
Dungeon Master
Posts: 3548
Joined: Wed Oct 06, 2004 7:46 am
Location: Best pizza town in the universe
Contact:

Re: WIP: Non Lethal Damage - UPDATED

Post by Ithildur »

Nice update; thanks mate and good work.
Formerly: Aglaril Shaelara, Faerun's unlikeliest Bladesinger
Current main: Ky - something

It’s not the critic who counts...The credit belongs to the man who actually is in the arena, who strives violently, who errs and comes up short again and again...who if he wins, knows the triumph of high achievement, but who if he fails, fails while daring greatly.-T. Roosevelt
danielmn
Fionn In Disguise
Posts: 4678
Joined: Sat Nov 05, 2005 9:08 pm

Re: WIP: Non Lethal Damage - UPDATED

Post by danielmn »

YAY FOR CRES!!!

Thanks for your work on that system man, greatly appreciated!
Swift wrote: Permadeath is only permadeath when the PCs wallet is empty.
Zyrus Meynolt: [Party] For the record, if this somehow blows up in our faces and I die, I want a raise

<Castano>: danielnm - can you blame them?
<danielmn>: Yes,
<danielmn>: Easily.

"And in this twilight....our choices seal our fate"
paazin
Fionn In Disguise
Posts: 3544
Joined: Thu Apr 15, 2004 1:07 am
Location: UTC +2
Contact:

Re: WIP: Non Lethal Damage - UPDATED

Post by paazin »

I'm going to add a section of this so it's available as a public call for anyone who wants to throw nonlethal damage because of in game effects or whatnot. (like the swimming fatigue on BG would be perfect to replace with this)
People talk of bestial cruelty, but that's a great injustice and insult to the beasts; a beast can never be so cruel as man, so artistically cruel.
Ronan
Dungeon Master
Posts: 4611
Joined: Sun Feb 20, 2005 9:48 am

Re: WIP: Non Lethal Damage - UPDATED

Post by Ronan »

Sweet, that should be in there anyway. It'll come in handy if anyone ever implements mage duels.
Ronan
Dungeon Master
Posts: 4611
Joined: Sun Feb 20, 2005 9:48 am

Re: WIP: Non Lethal Damage - UPDATED

Post by Ronan »

Question:

Why didn't we allow NLD to be applied as normal damage, then immediately heal that damage and add it to the creature's NLD total?

I was surprised to see that we're messing with item properties and feats. This seems very error-prone, especially with our bic backups and whatnot. Unless it was written/tested/integrated very well?
Zelknolf
Chosen of Forumamus, God of Forums
Posts: 6139
Joined: Tue Jul 05, 2005 7:04 pm

Re: WIP: Non Lethal Damage - UPDATED

Post by Zelknolf »

The only real vulnerability right now is just a lack of cleanup as part of OnClientEnter (we probably ought to clear any -5 damage that appears on the equipped weapon and the subdual damage creature weapon if that is equipped)-- lesser damage has the advantage of preventing undue OnDeath/ OnDying events (which is, currently, restricted to attempting to subdue someone who has 1 hp) -- as the both of those are effectively crude workarounds of the default NWN/ NWN2 systems of respawning (and are thus also error prone by nature, though also better-tested by nature).

I'm not sure how intentional it was, but it's easier to recover from a bugged weapon than a bugged death, so I'd probably defend its honor insofar as I'm able.
Locked