1
Other Features / Re: supply-based rest?
« on: September 04, 2011, 02:31:58 PM »
Great, I'll give it a try, thanks!
This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.
//============================================================================
//
// Name: CS Resting Subsystem - Module OnPlayerRest handler.
// File: cs_rest_handler
// Author: Craig Smith (Galap) <craig@smith.dropbear.id.au>
//
// $Id: cs_rest_handler.nss,v 1.8 2005/09/14 12:36:23 cs Exp $
// $Source: /local/cvs/nwn/resting/cs_rest_handler.nss,v $
//
//----------------------------------------------------------------------------
// This software is distributed in the hope that it will be useful. It is
// provided "as is" WITHOUT WARRANTY OF ANY KIND, either expressed or implied,
// including, but not limited to, the implied warranties of merchantability
// and fitness for a particular purpose. You may redistribute or modify this
// software for your own purposes so long as all original credit information
// remains intact.
//----------------------------------------------------------------------------
//
// This script is intended to be placed on the OnPlayerRest event of the
// module. When a player chooses to rest, or finishes resting, this script
// is invoked.
//
//============================================================================
#include "cs_dbg"
#include "cs_rest"
void main() {
cs_dbg_Enter("cs_rest_handler()");
// The creature who is resting.
object creature = GetLastPCRested();
// What resting function are we performing? If resting is just starting,
// we have to check whether the player is permitted to rest, but if this
// event is a cancel or stop event, it always runs.
int restType = GetLastRestEventType();
if (restType == REST_EVENTTYPE_REST_STARTED) {
// Find the initial config for this creature.
struct cs_rest_config cfg = cs_rest_RetrieveConfig(creature);
// If we're not enabled or allowed to rest, don't do anything.
if (cfg.enabled) {
// Evaluate rest rules.
cfg = cs_rest_GetIsRestPermitted(creature, cfg);
// Store the config on the creature.
cs_rest_SetConfig(creature, cfg);
if (cfg.permitted) {
// Execute the user handler script.
if (cfg.userScript != "") {
cs_rest_SetUserScriptState(creature, CS_REST_START_RESTING);
ExecuteScript(cfg.userScript, creature);
cs_rest_DeleteUserScriptState(creature);
cfg = cs_rest_GetConfig(creature);
}
// Make sure that the user handler script has not chosen to
// override and abort a previously accepted rest request.
if (cfg.permitted) {
// Perform resting for this player.
SetLocalInt(creature, CS_REST_VAR_STARTED, CS_REST_STARTED);
cs_rest_ExecuteRestScript(creature, cfg);
cs_rest_PostRestProcessing(creature, cfg);
}
else {
// Player is not allowed to start resting.
cs_dbg_Trace("Resting is not permitted: user script override");
SetLocalInt(creature, CS_REST_VAR_STARTED, CS_REST_ABORTED);
AssignCommand(creature, ClearAllActions());
// Cleanup stray config that may be lying around.
cs_rest_DeleteConfig(creature);
}
}
else {
// Player is not allowed to start resting.
cs_dbg_Trace("Resting is not permitted");
SetLocalInt(creature, CS_REST_VAR_STARTED, CS_REST_ABORTED);
AssignCommand(creature, ClearAllActions());
// Cleanup stray config that may be lying around.
cs_rest_DeleteConfig(creature);
}
}
else {
// Player is not allowed to start resting.
cs_dbg_Trace("Resting is not enabled");
SetLocalInt(creature, CS_REST_VAR_STARTED, CS_REST_ABORTED);
AssignCommand(creature, ClearAllActions());
// Cleanup stray config that may be lying around.
cs_rest_DeleteConfig(creature);
}
}
else {
// Retrieve the stored config for this creature.
struct cs_rest_config cfg = cs_rest_GetConfig(creature);
// Execute the user handler script.
if (cfg.userScript != "") {
if (restType == REST_EVENTTYPE_REST_FINISHED) {
cs_rest_SetUserScriptState(creature, CS_REST_STOP_RESTING);
}
else {
cs_rest_SetUserScriptState(creature, CS_REST_CANCEL_RESTING);
}
ExecuteScript(cfg.userScript, creature);
cs_rest_DeleteUserScriptState(creature);
}
// Complete resting for this player.
cs_rest_ExecuteRestScript(creature, cfg);
// Cleanup stray config that may be lying around.
cs_rest_DeleteConfig(creature);
}
cs_dbg_Exit("cs_rest_handler");
}

iAttackMod += GetBaseAttackBonus(oCreature) + GetAbilityModifier (ABILITY_DEXTERITY, oCreature) + iAttackBonus;oops! forgot to clarify that!You will have to use some modified scripts because the PRC removes all feats on a pc skin when you load it up, and the 1.69 horse system uses feats on a skin. Fortunately, xwarren helped me figure out how to integrate them here: http://prc.athasreborn.com/index.php?topic=1362.0Horse Menu is only removed from pre-1.69 characters. New characters get it from lvl 1 and you don't have to change anything.

/* wr_musket
-= WulfRider's Dual-ammo Musket =-
for Neverwinter Nights
by
Peter Hanratty
Developed under version 1.28
Email : wolfrider@yellowsnow.com
MSN Messenger : dire_wolf@hotmail.com
NWN Community : WulfRider
-----------------------------------------
Feel free to use, modify, and otherwise
play with this script to your heart's
content provided that this notice stays
fully intact and at the top.
-----------------------------------------
Thanks go to :-
- The creators of the NWN Lexicon - an
invaluable resource for any script
writer
- Wizards of the Coast for the player
manual on which most of this is based
- And of course the Creators of
Neverwinter Nights without which none
of this would be.
==============================================
v1.0
It's at times like these that you get to
discover all the things the scripter CANT do.
I have had to improvise many haphazard
solutions to coding problems but I'm happy
with the end result. Shooting sprees are
great for stress relief ;)
Known Issues:
- Non-creature objects
(placeables, doors etc) show
0 damage when hit. No known
cause or solution at this
time.
- Blood will appear red for all
creatures regardless of race
or species. This is due to
the sheer ammount of different
creature types and having no
quick way to determine the
correct blood colour for every
single one. Anyone wanting to
take the time is more than
welcome ;)
==============================================
Updated under version 1.62 by Daemon Blackrazor
==============================================
v2.0 Daemon Blackrazor
What I have done here is slighty modify Wulfriders scripts added flintlock items
and 3 new effects with new sound effects. I will be updating further as time
allows.
But this is working fine for now. Future updates will be;
1. Including magical properties for flintlocks.
2. Possibility of adding a spell effect for the flintlock firing as opposed to
a straight VFX; this will allow the muzzle flash to appear at the hand nodes.
3. Addition of a custom TLK file or tlk file entries for ease of building
4. Random Check for accidental double firing of both muzzles (this was a common
problem with double barrel flintlocks).
5. The next update will be HotU/SoU.
Known Issues:
None known at this time, other than the above notes.
==============================================
7-15-2008 Axe Murderer
Updated for compatibility with NWN v1.69
*/
// Dice Constants for ease of use
int DIE_D2 = 0;
int DIE_D3 = 1;
int DIE_D4 = 2;
int DIE_D6 = 3;
int DIE_D8 = 4;
int DIE_D10 = 5;
int DIE_D12 = 6;
int DIE_D20 = 7;
int DIE_D100 = 8;
// -------------------------------------------
// Musket Constants
int MUSKET_DAMAGE_NUM_DICE = 6;
int MUSKET_DAMAGE_DIE_TYPE = DIE_D10;
int MUSKET_DAMAGE_BONUS = 5;
int MUSKET_BACKFIRE_DAMAGE_NUM_DICE = 4;
int MUSKET_BACKFIRE_DAMAGE_DIE_TYPE = DIE_D6;
int MUSKET_BACKFIRE_DAMAGE_BONUS = 0;
int MUSKET_CRITICAL_RANGE = 20;
int MUSKET_CRITICAL_MULTIPLIER = 2;
int MUSKET_ATTACK_BONUS = -4;
float MUSKET_RANGE_INCREMENT_FEET = 10.0;
int MUSKET_PERCENT_CHANCE_KNOCKDOWN = 25;
int MUSKET_PERCENT_CHANCE_BACKFIRE = 10;
// -------------------------------------------
// Musket Effects
// Effects and Other
effect MUSKET_FIRE_EFFECT = EffectVisualEffect (673);
effect MUSKET_BACKFIRE_EFFECT = EffectVisualEffect (674);
effect MUSKET_MISS_EFFECT = EffectVisualEffect (675);
//effect BOOMPOWDER_FIRE_EFFECT = EffectVisualEffect (VFX_IMP_PULSE_FIRE);
//effect BOOMPOWDER_BACKFIRE_EFFECT = EffectVisualEffect (VFX_FNF_FIREBALL);
//effect DEMONPOWDER_FIRE_EFFECT1 = EffectVisualEffect (VFX_FNF_GAS_EXPLOSION_EVIL);
//effect DEMONPOWDER_FIRE_EFFECT2 = EffectVisualEffect (VFX_FNF_HOWL_MIND);
//effect DEMONPOWDER_BACKFIRE_EFFECT1 = EffectVisualEffect (VFX_IMP_HEAD_EVIL);
//effect DEMONPOWDER_BACKFIRE_EFFECT2 = EffectVisualEffect (VFX_FNF_HOWL_MIND);
//effect CURRENT_FIRE_EFFECT = MUSKET_FIRE_EFFECT;
//effect CURRENT_BACKFIRE_EFFECT = MUSKET_BACKFIRE_EFFECT;
// Function Prototypes
int GetMyBaseAttackBonus (object oCreature, int iClassType);
// Gets a character's base attack bonus (1st
// attack only)according to D&D 3rd edition
// rules. Total multiple calls to this
// function for multiclass characters.
int GetHasPowderAndBullets (object oCreature, object oMusket);
// Check for powder and bullets
int GetHasBullets (object oCreature);
// Called by the above function
int RollRangedAttack (object oCreature, object oTarget, int iCriticalRange, int iAttackBonus, float fRangeIncrement);
// Roll a ranged attack score according to
// D&D 3rd edition rules
int RollDamage (object oCreature, int iNumDice, int iDieType, int iBonus, int bCrit = FALSE, int iCriticalMultiplier = 2);
// Roll damage according to D&D 3rd edition
// rules
void ApplyDamage (object oCreature, object oTarget, int iDamage, int iDamageType = DAMAGE_TYPE_MAGICAL, float fDelay = 0.0, int eExtraEffect = EFFECT_TYPE_INVALIDEFFECT);
// Applies damage to a creature with optional
// delay and extra visual effect
void BroadcastMsg (object oSender, string sMsg);
// Sends a message to all PC's and DM's
void BroadcastFloatMsg (string sMsg);
// Displays a floaty message for all PC's
void FireMusket (object oMusket, object oCreature, object oTarget, location lTarget);
// Main musket function
// ===========================================
// Code
void FireMusket (object oMusket, object oCreature, object oTarget, location lTarget)
{
int iHit = 0;
int iDamage = 0;
effect eSparks = EffectVisualEffect (675, TRUE);
if (!GetHasPowderAndBullets (oCreature, oMusket))
{
return;
}
if (oTarget == oCreature)
{
AssignCommand(oCreature, PlaySound("flintlock_fire"));
FloatingTextStringOnCreature ("*Suicide!*", oCreature, FALSE);
effect eBrains = EffectVisualEffect (VFX_COM_CHUNK_RED_SMALL);
eBrains = EffectLinkEffects (EffectDeath (TRUE, FALSE), eBrains);
eBrains = EffectLinkEffects (EffectVisualEffect(673), eBrains);
AssignCommand (oCreature, ActionDoCommand (ApplyEffectToObject (DURATION_TYPE_INSTANT, eBrains, oCreature)));
return;
}
ApplyEffectToObject (DURATION_TYPE_INSTANT, EffectVisualEffect(673), oCreature);
if (d100 () > (100 - MUSKET_PERCENT_CHANCE_BACKFIRE))
{
DelayCommand(0.2, AssignCommand(oCreature, PlaySound("flintlock_backf")));
FloatingTextStringOnCreature ("*Backfire!*", oCreature);
iDamage = RollDamage (oCreature, MUSKET_BACKFIRE_DAMAGE_NUM_DICE, MUSKET_BACKFIRE_DAMAGE_DIE_TYPE, MUSKET_BACKFIRE_DAMAGE_BONUS);
ApplyDamage (oCreature, oCreature, iDamage, DAMAGE_TYPE_FIRE, 0.0, 674);
return;
}
if (oTarget == OBJECT_INVALID)
{
DelayCommand(0.2, ApplyEffectAtLocation (DURATION_TYPE_INSTANT, eSparks, lTarget));
}
else
{
iHit = RollRangedAttack (oCreature, oTarget, MUSKET_CRITICAL_RANGE, MUSKET_ATTACK_BONUS, MUSKET_RANGE_INCREMENT_FEET);
if (iHit > 0)
{
iDamage = RollDamage (oCreature, MUSKET_DAMAGE_NUM_DICE, MUSKET_DAMAGE_DIE_TYPE, MUSKET_DAMAGE_BONUS, (iHit == 2), MUSKET_CRITICAL_MULTIPLIER);
effect eDamage = EffectDamage (iDamage, DAMAGE_TYPE_PIERCING);
if (GetObjectType (oTarget) == OBJECT_TYPE_CREATURE)
{
effect eBlood = EffectVisualEffect (VFX_COM_BLOOD_LRG_RED);
eBlood = EffectLinkEffects (EffectVisualEffect (VFX_COM_BLOOD_LRG_RED), eBlood);
eBlood = EffectLinkEffects (EffectVisualEffect (VFX_COM_BLOOD_LRG_RED), eBlood);
ApplyEffectAtLocation (DURATION_TYPE_INSTANT, eBlood, GetLocation (oTarget));
if (d100 () > (100 - MUSKET_PERCENT_CHANCE_KNOCKDOWN))
{
ApplyEffectToObject (DURATION_TYPE_TEMPORARY, EffectKnockdown (), oTarget, IntToFloat (d4 () + 3));
}
ApplyDamage (oCreature, oTarget, iDamage, DAMAGE_TYPE_PIERCING, 0.2);
}
else
{
ApplyDamage (oCreature, oTarget, iDamage, DAMAGE_TYPE_PIERCING, 0.2, VFX_COM_BLOOD_SPARK_LARGE);
}
}
}
}
// -------------------------------------------
int RollRangedAttack (object oCreature, object oTarget, int iCriticalRange, int iAttackBonus, float fRangeIncrement)
{
int iResult = 0;
int iAttackMod = 0;
int iRoll = 0;
int iReroll = 0;
int iCrit = FALSE;
int iDamage = 0;
int iTargetAC = 0;
int iCount = 0;
float fRangeMeters = 0.0;
float fDistance = 0.0;
int iNumIncrements = 0;
int iRangePenalty = 0;
string sHitMsg = "";
switch (GetCreatureSize (oCreature))
{
case CREATURE_SIZE_HUGE: iAttackMod = -2; break;
case CREATURE_SIZE_LARGE: iAttackMod = -1; break;
case CREATURE_SIZE_MEDIUM: iAttackMod = 0; break;
case CREATURE_SIZE_INVALID: iAttackMod = 0; break;
case CREATURE_SIZE_SMALL: iAttackMod = 1; break;
case CREATURE_SIZE_TINY: iAttackMod = 2; break;
}
iAttackMod += GetMyBaseAttackBonus (oCreature, CLASS_TYPE_FIGHTER);
iAttackMod += GetMyBaseAttackBonus (oCreature, CLASS_TYPE_BARBARIAN);
iAttackMod += GetMyBaseAttackBonus (oCreature, CLASS_TYPE_PALADIN);
iAttackMod += GetMyBaseAttackBonus (oCreature, CLASS_TYPE_RANGER);
iAttackMod += GetMyBaseAttackBonus (oCreature, CLASS_TYPE_CLERIC);
iAttackMod += GetMyBaseAttackBonus (oCreature, CLASS_TYPE_DRUID);
iAttackMod += GetMyBaseAttackBonus (oCreature, CLASS_TYPE_ROGUE);
iAttackMod += GetMyBaseAttackBonus (oCreature, CLASS_TYPE_BARD);
iAttackMod += GetMyBaseAttackBonus (oCreature, CLASS_TYPE_MONK);
iAttackMod += GetMyBaseAttackBonus (oCreature, CLASS_TYPE_WIZARD);
iAttackMod += GetMyBaseAttackBonus (oCreature, CLASS_TYPE_SORCERER);
iAttackMod += GetAbilityModifier (ABILITY_DEXTERITY, oCreature);
iAttackMod += iAttackBonus;
fRangeMeters = FeetToMeters (fRangeIncrement);
fDistance = GetDistanceBetween (oCreature, oTarget);
iNumIncrements = FloatToInt ((fDistance / fRangeMeters) - 0.5);
iRangePenalty = -2 * iNumIncrements;
iAttackMod += iRangePenalty;
iTargetAC = GetAC (oTarget);
iRoll = d20 ();
iCrit = (iRoll >= iCriticalRange);
iRoll += iAttackMod;
if (iCrit)
{
iReroll = d20 () + iAttackMod;
sHitMsg = IntToString (iRoll) + " / " + IntToString (iReroll);
if (iReroll >= iTargetAC)
{
sHitMsg += " (Critical Hit)";
FloatingTextStringOnCreature ("*Critical Hit!*", oCreature, FALSE);
iResult = 2;
}
else
{
effect eSparks = EffectVisualEffect(675, TRUE);
sHitMsg += " (Critical Miss)";
iResult = 1;
DelayCommand(0.2, ApplyEffectToObject (DURATION_TYPE_INSTANT, eSparks, oTarget));
DelayCommand(0.2, AssignCommand(oCreature, PlaySound("flintlock_miss")));
}
}
else
{
sHitMsg = IntToString (iRoll);
if (iRoll >= iTargetAC)
{
sHitMsg += " (Hit)";
iResult = 1;
}
else
{
effect eSparks = EffectVisualEffect(675, TRUE);
sHitMsg += " (Miss)";
DelayCommand(0.2, ApplyEffectToObject (DURATION_TYPE_INSTANT, eSparks, oTarget));
DelayCommand(0.2, AssignCommand(oCreature, PlaySound("flintlock_miss")));
}
}
BroadcastMsg (oCreature, "Attack Roll vs AC " + IntToString (iTargetAC) + ": " + sHitMsg);
return iResult;
}
// -------------------------------------------
int GetMyBaseAttackBonus (object oCreature, int iClassType)
{
string sCDRBM = "000001020303040506060708090910111212131415";
string sWIZSC = "000001010202030304040505060607070808090910";
int iBaseAttackBonus = 0;
switch (iClassType)
{
case CLASS_TYPE_FIGHTER:
iBaseAttackBonus = GetLevelByClass (iClassType, oCreature);
break;
case CLASS_TYPE_BARBARIAN:
iBaseAttackBonus = GetLevelByClass (iClassType, oCreature);
break;
case CLASS_TYPE_PALADIN:
iBaseAttackBonus = GetLevelByClass (iClassType, oCreature);
break;
case CLASS_TYPE_RANGER:
iBaseAttackBonus = GetLevelByClass (iClassType, oCreature);
break;
case CLASS_TYPE_CLERIC:
iBaseAttackBonus = StringToInt (GetSubString (sCDRBM, (GetLevelByClass (iClassType, oCreature) * 2), 2));
break;
case CLASS_TYPE_DRUID:
iBaseAttackBonus = StringToInt (GetSubString (sCDRBM, (GetLevelByClass (iClassType, oCreature) * 2), 2));
break;
case CLASS_TYPE_ROGUE:
iBaseAttackBonus = StringToInt (GetSubString (sCDRBM, (GetLevelByClass (iClassType, oCreature) * 2), 2));
break;
case CLASS_TYPE_BARD:
iBaseAttackBonus = StringToInt (GetSubString (sCDRBM, (GetLevelByClass (iClassType, oCreature) * 2), 2));
break;
case CLASS_TYPE_MONK:
iBaseAttackBonus = StringToInt (GetSubString (sCDRBM, (GetLevelByClass (iClassType, oCreature) * 2), 2));
break;
case CLASS_TYPE_WIZARD:
iBaseAttackBonus = StringToInt (GetSubString (sWIZSC, (GetLevelByClass (iClassType, oCreature) * 2), 2));
break;
case CLASS_TYPE_SORCERER:
iBaseAttackBonus = StringToInt (GetSubString (sWIZSC, (GetLevelByClass (iClassType, oCreature) * 2), 2));
break;
}
return iBaseAttackBonus;
}
// -------------------------------------------
int RollDamage (object oCreature, int iNumDice, int iDieType, int iBonus, int bCrit, int iCriticalMultiplier)
{
int iRoll = 0;
int iTotal = 0;
int iDiceCount = 0;
int iNumRolls = 1;
int iRollCount = 0;
string sRollStr = "";
if (bCrit)
{
iNumRolls = iCriticalMultiplier;
}
for (iRollCount = 1; iRollCount <= iNumRolls; iRollCount++)
{
if (iRollCount > 1)
{
sRollStr += " / ";
}
iRoll = 0;
for (iDiceCount = 1; iDiceCount <= iNumDice; iDiceCount++)
{
if (iDieType == DIE_D2)
{
iRoll += d2 ();
}
else
if (iDieType == DIE_D3)
{
iRoll += d3 ();
}
else
if (iDieType == DIE_D4)
{
iRoll += d4 ();
}
else
if (iDieType == DIE_D6)
{
iRoll += d6 ();
}
else
if (iDieType == DIE_D8)
{
iRoll += d8 ();
}
else
if (iDieType == DIE_D10)
{
iRoll += d10 ();
}
else
if (iDieType == DIE_D12)
{
iRoll += d12 ();
}
else
if (iDieType == DIE_D20)
{
iRoll += d20 ();
}
else
if (iDieType == DIE_D100)
{
iRoll += d100 ();
}
}
iTotal += iRoll;
sRollStr += IntToString (iRoll);
}
iTotal += iBonus;
sRollStr += " + " + IntToString (iBonus);
if (iTotal < 1)
{
iTotal = 1;
}
BroadcastMsg (oCreature, "Damage Roll: " + sRollStr + " = " + IntToString (iTotal));
return iTotal;
}
// -------------------------------------------
void ApplyDamage (object oCreature, object oTarget, int iDamage, int iDamageType, float fDelay, int eExtraEffect)
{
effect eDamage = EffectDamage (iDamage, iDamageType);
if (eExtraEffect != EFFECT_TYPE_INVALIDEFFECT)
{
eDamage = EffectLinkEffects (EffectVisualEffect (eExtraEffect), eDamage);
}
if (GetObjectType (oTarget) == OBJECT_TYPE_CREATURE)
{
switch (d4 ())
{
case 1: PlayVoiceChat (VOICE_CHAT_PAIN1, oTarget); break;
case 2: PlayVoiceChat (VOICE_CHAT_PAIN2, oTarget); break;
case 3: PlayVoiceChat (VOICE_CHAT_PAIN3, oTarget); break;
}
}
DelayCommand (fDelay, ApplyEffectToObject (DURATION_TYPE_INSTANT, eDamage, oTarget));
DelayCommand (fDelay + 0.1, ExecuteScript ("wr_m_showdam", oTarget));
if (oCreature != oTarget)
{
DelayCommand (fDelay + 0.2, FloatingTextStringOnCreature (IntToString (GetLocalInt (GetModule (), "MUSKET_LAST_DAMAGE")), oCreature, FALSE));
}
event eAttacked = EventSpellCastAt (oCreature, SPELL_MAGIC_MISSILE);
SignalEvent (oTarget, eAttacked);
}
// -------------------------------------------
int GetHasPowderAndBullets (object oCreature, object oMusket)
{
object oPowder = OBJECT_INVALID;
int iPowderLevel = 0;
int iResult = FALSE;
oPowder = GetLocalObject (oMusket, "oCurrentPouch");
if (oPowder == OBJECT_INVALID)
{
iPowderLevel = 1;
while (oPowder == OBJECT_INVALID && iPowderLevel <= 10)
{
oPowder = GetItemPossessedBy (oCreature, "GunpowderPouch_" + IntToString (iPowderLevel));
iPowderLevel++;
}
}
if (oPowder == OBJECT_INVALID)
{
FloatingTextStringOnCreature ("*No Gunpowder!*", oCreature);
AssignCommand (oCreature, PlaySound ("flintlock_un"));
}
else
{
if (GetHasBullets (oCreature))
{
iPowderLevel = StringToInt (GetStringRight (GetTag (oPowder), 1));
if (iPowderLevel == 0)
{
iPowderLevel = 10;
}
DestroyObject (oPowder);
iPowderLevel--;
if (iPowderLevel > 0)
{
oPowder = CreateItemOnObject ("gunpowderpouch" + IntToString (iPowderLevel), oCreature);
SetLocalObject (oMusket, "oCurrentPouch", oPowder);
}
else
{
SetLocalObject (oMusket, "oCurrentPouch", OBJECT_INVALID);
}
iResult = TRUE;
}
}
return iResult;
}
// -------------------------------------------
int GetHasBullets (object oCreature)
{
int iAmmount = 0;
object oBullets = OBJECT_INVALID;
string sTag = "";
int iResult = FALSE;
oBullets = GetItemInSlot (INVENTORY_SLOT_BULLETS, oCreature);
if (oBullets == OBJECT_INVALID)
{
FloatingTextStringOnCreature ("*Bullets Not Equipped!*", oCreature);
AssignCommand (oCreature, PlaySound ("flintlock_un"));
}
else
{
if (GetTag (oBullets) != "LeadBullet")
{
FloatingTextStringOnCreature ("*Incorrect Ammunition!*", oCreature);
AssignCommand (oCreature, PlaySound ("flintlock_un"));
}
else
{
iAmmount = GetNumStackedItems (oBullets);
DestroyObject (oBullets);
iAmmount--;
if (iAmmount > 0)
{
oBullets = CreateItemOnObject ("leadbullet", oCreature, iAmmount);
AssignCommand (oCreature, ActionEquipItem (oBullets, INVENTORY_SLOT_BULLETS));
}
iResult = TRUE;
}
}
return iResult;
}
// -------------------------------------------
void BroadcastMsg (object oSender, string sMsg)
{
string sMessage = GetName (oSender) + ": " + sMsg;
SendMessageToAllDMs (sMessage);
object oPC = GetFirstPC ();
while (oPC != OBJECT_INVALID)
{
SendMessageToPC (oPC, sMessage);
oPC = GetNextPC ();
}
}
//void main(){}
You will have to use some modified scripts because the PRC removes all feats on a pc skin when you load it up, and the 1.69 horse system uses feats on a skin. Fortunately, xwarren helped me figure out how to integrate them here: http://prc.athasreborn.com/index.php?topic=1362.0Sorry, one other question... Is PRC 3.5 beta 2 still incompatible with CEP 2.4 mounts? If so, could you point me in the direction of resolving this conflict?The new CEP 2.4 mounts (griffon, rhino, elephant, etc.) use the same system as the 1.69 horses from Bioware, and will work. The old CEP mounts won't work, but they looked terrible anyway.
Thanks!
Well that is awesome to know.
Man this game just keeps getting better and better because of PRC, CEP and the still amazing community.
Question
Other then importing the mounts do I as a module updater(not builder)do I need to do anything else to use those CEP special Mounts with PRC?
Sorry, one other question... Is PRC 3.5 beta 2 still incompatible with CEP 2.4 mounts? If so, could you point me in the direction of resolving this conflict?The new CEP 2.4 mounts (griffon, rhino, elephant, etc.) use the same system as the 1.69 horses from Bioware, and will work. The old CEP mounts won't work, but they looked terrible anyway.
Thanks!
void ScrubPCSkin(object oPC, object oSkin)
{
int nGeneration = PRC_NextGeneration(GetLocalInt(oPC, PRC_ScrubPCSkin_Generation));
if (DEBUG > 1) DoDebug("ScrubPCSkin Generation: " + IntToString(nGeneration));
SetLocalInt(oPC, PRC_ScrubPCSkin_Generation, nGeneration);
int iCode = GetHasFeat(FEAT_SF_CODE,oPC);
int st;
if(!(/*GetIsPolyMorphedOrShifted(oPC) || */GetIsObjectValid(GetMaster(oPC))))
{
itemproperty ip = GetFirstItemProperty(oSkin);
while(GetIsItemPropertyValid(ip))
{
// Insert Logic here to determine if we spare a property
if(GetItemPropertyType(ip) == ITEM_PROPERTY_BONUS_FEAT)
{
// Check for specific Bonus Feats
// Reference iprp_feats.2da
st = GetItemPropertySubType(ip);
// Spare 400 through 570 and 398 -- epic spells & spell effects
//also spare the new spellbook feats (1000-12000 & 17701-24704
//also spare the psionic, trunaming, tob, invocation feats (12000-16000)
// spare template, tob stuff (16300-17700)
// also spare Pnp spellschool feats and PRC options feat (231-249 & 229)
// changed by fluffyamoeba so that iprp weapon specialization, dev crit, epic weapon focus, epic weapon spec
// overwhelming crit and weapon of choice are no longer skipped.
// 259 - psionic focus
// 141 - shadowmaster shades, 142-151 bonus domains casting feats
if ((st < 400 || st > 570)
&& st != 398
&& (st < 1000 || st > 15999)
//&& (st < 1000 || st > 13999)
//&& (st < 14501 || st > 15999)
&& (st < 16300 || st > 24704)
&& (st < 223 || st > 226) //draconic feats
&& (st < 229 || st > 249)
&& st != 259
&& (st < 141 || st > 151)
&& ( (st == IP_CONST_FEAT_PRC_POWER_ATTACK_QUICKS_RADIAL ||
st == IP_CONST_FEAT_POWER_ATTACK_SINGLE_RADIAL ||
st == IP_CONST_FEAT_POWER_ATTACK_FIVES_RADIAL) ? // Remove the PRC Power Attack radials if the character no longer has Power Attack
!GetHasFeat(FEAT_POWER_ATTACK, oPC) :
TRUE // If the feat is not relevant to this clause, always pass
)
)
RemoveItemProperty(oSkin, ip);
}
else
RemoveItemProperty(oSkin, ip);
// Get the next property
ip = GetNextItemProperty(oSkin);
}
}If I un-comment this part: //&& (st < 1000 || st > 13999) and change the numbers in parenthesis to 1087 and 1095 (the range of the horse-related feats on the feats.2da), will that work? And which scripts besides prc_rest, prc_onenter, and prc_levelup call the ScrubPCSkin function?