2026/01/26 Update

Added Wispling race.
Wispling qualifies for Shifter (PnP).
Bioware poisons now work with "new" PRC8 weapons.
Updated PRC8 Tester mod store to have Bioware venoms.
Updated PRC8 version.
Added Alchemy expansion notes.
Updated Starting package TLK notes.
This commit is contained in:
Jaysyn904
2026-01-20 09:11:57 -05:00
parent 829d9d7999
commit 0f1c10c279
87 changed files with 26516 additions and 26200 deletions

View File

@@ -0,0 +1,147 @@
//::///////////////////////////////////////////////
//:: Poison Weapon spellscript
//:: x2_s2_poisonwp
//:: Copyright (c) 2003 Bioware Corp.
//:://////////////////////////////////////////////
/*
Spell allows to add temporary poison properties
to a melee weapon or stack of arrows
The exact details of the poison are loaded from
a 2da defined in x2_inc_itemprop X2_IP_POSIONWEAPON_2DA
taken from the row that matches the last three letters
of GetTag(GetSpellCastItem())
Example: if an item is given the poison weapon property
and its tag ending on 004, the 4th row of the
2da will be used (1d2IntDmg DC14 18 seconds)
Rows 0 to 99 are bioware reserved
Non Assassins have a chance of poisoning themselves
when handling an item with this spell
Restrictions
... only weapons and ammo can be poisoned
... restricted to piercing / slashing damage
Brought this into the PRC8 corpus so that new weapons could use
Bioware poisons. -Jasysyn 2026-01-18 12:35:03
*/
//:://////////////////////////////////////////////
//:: Created By: Georg Zoeller
//:: Created On: 2003-05-11
//:: Updated On: 2003-08-21
//:://////////////////////////////////////////////
#include "prc_x2_itemprop"
#include "X2_inc_switches"
void main()
{
object oItem = GetSpellCastItem();
object oPC = OBJECT_SELF;
object oTarget = PRCGetSpellTargetObject();
string sTag = GetTag(oItem);
if (oTarget == OBJECT_INVALID || GetObjectType(oTarget) != OBJECT_TYPE_ITEM)
{
SendMessageToPC(oPC, "Failure: You may only apply poisons to food & weapons.");
//FloatingTextStrRefOnCreature(83359,oPC); //"Invalid target "
return;
}
int nType = GetBaseItemType(oTarget);
if (DEBUG) DoDebug("x2_s2_poisonwp is running.");
if (DEBUG) DoDebug("Base Item Type: " + IntToString(nType) + " (Expected: 203)");
if (DEBUG) DoDebug("Is Melee Weapon: " + IntToString(IPGetIsMeleeWeapon(oTarget)));
if (DEBUG) DoDebug("Sharp Weapons Switch: " + IntToString(GetPRCSwitch(PRC_ALLOW_ONLY_SHARP_WEAPONS)));
if (DEBUG) DoDebug("Is Bludgeoning: " + IntToString(IPGetIsBludgeoningWeapon(oTarget)));
if (!IPGetIsMeleeWeapon(oTarget) &&
!IPGetIsProjectile(oTarget) &&
nType != BASE_ITEM_SHURIKEN &&
nType != BASE_ITEM_DART &&
nType != BASE_ITEM_THROWINGAXE)
{
FloatingTextStrRefOnCreature(83359,oPC); //"Invalid target "
return;
}
if (IPGetIsBludgeoningWeapon(oTarget))
{
FloatingTextStrRefOnCreature(83367,oPC); //"Weapon does not do slashing or piercing damage "
return;
}
if (IPGetItemHasItemOnHitPropertySubType(oTarget, 19)) // 19 == itempoison
{
FloatingTextStrRefOnCreature(83407,oPC); // weapon already poisoned
return;
}
// Get the 2da row to lookup the poison from the last three letters of the tag
int nRow = StringToInt(GetStringRight(sTag,3));
if (nRow ==0)
{
FloatingTextStrRefOnCreature(83360,oPC); //"Nothing happens
WriteTimestampedLogEntry ("Error: Item with tag " +GetTag(oItem) + " has the PoisonWeapon spellscript attached but tag does not contain 3 letter receipe code at the end!");
return;
}
int nSaveDC = StringToInt(Get2DAString(X2_IP_POISONWEAPON_2DA,"SaveDC",nRow));
int nDuration = StringToInt(Get2DAString(X2_IP_POISONWEAPON_2DA,"Duration",nRow));
int nPoisonType = StringToInt(Get2DAString(X2_IP_POISONWEAPON_2DA,"PoisonType",nRow)) ;
int nApplyDC = StringToInt(Get2DAString(X2_IP_POISONWEAPON_2DA,"ApplyCheckDC",nRow)) ;
int bHasFeat = GetHasFeat(960, oPC);
if (!bHasFeat) // without handle poison feat, do ability check
{
// * Force attacks of opportunity
AssignCommand(oPC,ClearAllActions(TRUE));
// Poison restricted to assassins and blackguards only?
if (GetModuleSwitchValue(MODULE_SWITCH_RESTRICT_USE_POISON_TO_FEAT) == TRUE)
{
FloatingTextStrRefOnCreature(84420,oPC); //"Failed"
return;
}
int nDex = GetAbilityModifier(ABILITY_DEXTERITY,oPC) ;
int nCheck = d10(1)+10+nDex;
if (nCheck < nApplyDC)
{
FloatingTextStrRefOnCreature(83368,oPC); //"Failed"
return;
}
else
{
FloatingTextStrRefOnCreature(83370,oPC); //"Success"
}
}
else
{
// some feedback to
FloatingTextStrRefOnCreature(83369,oPC); //"Auto success "
}
itemproperty ip = ItemPropertyOnHitProps(IP_CONST_ONHIT_ITEMPOISON,nSaveDC,nPoisonType);
IPSafeAddItemProperty(oTarget, ip,IntToFloat(nDuration),X2_IP_ADDPROP_POLICY_KEEP_EXISTING,TRUE,TRUE);
effect eVis = EffectVisualEffect(VFX_IMP_PULSE_NATURE);
//technically this is not 100% safe but since there is no way to retrieve the sub
//properties of an item (i.e. itempoison), there is nothing we can do about it
if (IPGetItemHasItemOnHitPropertySubType(oTarget, 19))
{
FloatingTextStrRefOnCreature(83361,oPC); //"Weapon is coated with poison"
IPSafeAddItemProperty(oTarget, ItemPropertyVisualEffect(ITEM_VISUAL_ACID),IntToFloat(nDuration),X2_IP_ADDPROP_POLICY_KEEP_EXISTING,TRUE,FALSE);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, GetItemPossessor(oTarget));
}
else
{
FloatingTextStrRefOnCreature(83360,oPC); //"Nothing happens
}
}