DreadWolf Posted May 1, 2010 Share Posted May 1, 2010 Is there a way to export a local copy of rules_core script so the changes I make to it apply to a mod of mine? I know a tut does it with some fireball thing, but that method doesn't work when i want a copy of the rules_core script. It doesn't apply the effects to the game or even put them back into the toolset when the module is loaded. Reason for my asking is I am making a arcane archer class for mages. But since a mage cant get "melee archer", 90% of the time you try to attack with a bow agenst more then 1 foe results in a interrupt. If your fighting 1 melee for, you will still be interrupted 50% of the time. So, I made a skill that i want to act like "melee archer." Simple enough but the function for "melee archer" and other forms of interrupts are handled in "rules_core.nss" I don't want to twink the toolsets core scripts or mess with the games global functions. I just want the effect to apply when my mod is loaded. Any insight into the matter would be welcomed. - Dread Wolf Link to comment Share on other sites More sharing options...
hdhd Posted May 3, 2010 Share Posted May 3, 2010 You want to edit a specific part of the rules_core script or what do you mean exactly? To override specific events you can look at this tutorial: http://social.bioware.com/wiki/datoolset/index.php/Event_override Normally you don't have to override core scripts when you want to add spells. Maybe tell me exactly what you want to edit in the rules_core. I don't know much about spells but perhaps I can help you figure out how to solve your issues with effects. Link to comment Share on other sites More sharing options...
DreadWolf Posted May 3, 2010 Author Share Posted May 3, 2010 You want to edit a specific part of the rules_core script or what do you mean exactly? To override specific events you can look at this tutorial: http://social.bioware.com/wiki/datoolset/index.php/Event_override Normally you don't have to override core scripts when you want to add spells. Maybe tell me exactly what you want to edit in the rules_core. I don't know much about spells but perhaps I can help you figure out how to solve your issues with effects. What I am trying to do is make a spell that does the same function as the talent "Melee Archer". "Melee Archer" is the passive ability that make is so if your charactor is using a bow to attack, your attacks will not get interrupted every time you get hit (which is REALLY annoying). What I want is a passive spell that does the same effect for a class I am making for a mage. I have tracked "melee archer"s code to the rule_core script, in the interrupt area. if (GetGameMode() == GM_COMBAT) { // ------------------------------------------------------------- // Only significant damage disrupts // ------------------------------------------------------------- if (nDamageType == DAMAGE_TYPE_PHYSICAL) { command cmd = GetCurrentCommand(OBJECT_SELF); int nCmdType = GetCommandType(cmd); // --------------------------------------------------------- // We only interrupt attack commands at this point // --------------------------------------------------------- if (nCmdType == COMMAND_TYPE_ATTACK) { //--------------------------------------------------------- // Damage needs to exceed dexterity modifier/3 to interrupt //---------------------------------------------------------- float fModifier= GetAttributeModifier(OBJECT_SELF, ATTRIBUTE_DEX) * (1.0 / 3.0); if (fDamage > fModifier) { // ------------------------------------------------- // Melee archers ignore interruptions // ------------------------------------------------- if (!HasAbility(OBJECT_SELF,ABILITY_TALENT_MELEE_ARCHER)) { if (IsUsingMeleeWeapon(oDamager, OBJECT_INVALID)) { if (IsUsingRangedWeapon(OBJECT_SELF,OBJECT_INVALID,TRUE)) { UI_DisplayMessage(OBJECT_SELF, UI_MESSAGE_INTERRUPTED); #ifdef DEBUG Log_Trace(LOG_CHANNEL_COMBAT,"rules_core.OnDamage","Ranged attack interrupted by damage"); #endif WR_ClearAllCommands(OBJECT_SELF, TRUE); } } } } } // --------------------------------------------------------- // Experimental: Taking any damage > 1 causes spell interruption // --------------------------------------------------------- else if (nCmdType == COMMAND_TYPE_USE_ABILITY) { int nAbi = GetCommandInt(cmd,0); // Only abilities with speed >0 can be interrupted. if (CanInterruptSpell(nAbi)) { int nCombatTrainingRank = 0 ; int nModifier = 0; float fThres = 0.0f; // ----------------------------------------------------- if (!IsPartyMember(OBJECT_SELF)) { nCombatTrainingRank = GetM2DAInt(Diff_GetAutoScaleTable(),"nCombatTraining",GetCreatureRank(OBJECT_SELF)); nModifier = GetLevel(OBJECT_SELF); } else { nCombatTrainingRank = (HasAbility(OBJECT_SELF,ABILITY_SKILL_COMBAT_TRAINING_1)) + (HasAbility(OBJECT_SELF,ABILITY_SKILL_COMBAT_TRAINING_2)) + (HasAbility(OBJECT_SELF,ABILITY_SKILL_COMBAT_TRAINING_3)) + (HasAbility(OBJECT_SELF,ABILITY_SKILL_COMBAT_TRAINING_4)); nModifier = 5 + GetLevel(OBJECT_SELF)/2; } fThres = (nCombatTrainingRank * 10.0f) + nModifier; // ----------------------------------------------------- // Damage needs to exceed a certain threshold before it // can interrupt. Otherwise playing mages gets very // frustrating. // ----------------------------------------------------- if (fDamage > fThres) { // --------------------------------------------- // Since COMMAND_USEABILITY can be in a movement // subaction, filter additionally for conjure // phase. // --------------------------------------------- if (IsConjuring(OBJECT_SELF)) { UI_DisplayMessage(OBJECT_SELF, UI_MESSAGE_INTERRUPTED); #ifdef DEBUG Log_Trace(LOG_CHANNEL_COMBAT,"rules_core.OnDamage","Spell interrupted by damage"); #endif SSPlaySituationalSound(OBJECT_SELF, SOUND_SITUATION_SPELL_INTERRUPTED); bSound = FALSE; WR_ClearAllCommands(OBJECT_SELF, TRUE); } } else { #ifdef DEBUG Log_Trace(LOG_CHANNEL_COMBAT,"rules_core.OnDamage","Spell not interrupted, dmg " + ToString(fDamage) + " below threshold: " + ToString(fThres) ); #endif } } } } What I want is to make is so it also negates the interrupts if I am using one of my skills as well. So. it would just adding in the include and this in. if (!HasAbility(OBJECT_SELF,DW_ARCANE_ARCHERY_FINESSE)) { if (IsUsingMeleeWeapon(oDamager, OBJECT_INVALID)) { if (IsUsingRangedWeapon(OBJECT_SELF,OBJECT_INVALID,TRUE)) { UI_DisplayMessage(OBJECT_SELF, UI_MESSAGE_INTERRUPTED); #ifdef DEBUG Log_Trace(LOG_CHANNEL_COMBAT,"rules_core.OnDamage","Ranged attack interrupted by damage"); #endif WR_ClearAllCommands(OBJECT_SELF, TRUE); } } } Problem is when i save and compile the local copy of the script, and add it to my "addin/Module/override" folder, it doesn't read it in game or in the toolset. I read somewhere that if you compile one script, you have to compile all the scripts that are "referenced" by it. So i did compile them and exported the scripts out and moved those copies to my module/override" folder as well but still no luck. Sorry im rambling. The better questions would be, if you needed to recompile Rules_core, what other scripts would you need to recompile with it. Failing that, I have been looking into making a script that just adds the talent melee archer to the character who takes "arcane archer finesse". Link to comment Share on other sites More sharing options...
hdhd Posted May 4, 2010 Share Posted May 4, 2010 You only have to recompile the other dependencies when you do changes to them but as the only changes you did where in the rules_core you don't need to recompile them. In the header file are all the scripts listed that compile with rules_core: #include "utility_h" #include "rules_h" #include "events_h" #include "effects_h" #include "ai_main_h_2" #include "ui_h" #include "sys_soundset_h" #include "sys_stealth_h" #include "sys_ambient_h" #include "sys_itemprops_h" #include "ability_h" #include "approval_h" Another suggestion, why don't you use event_override so you don't have to change the whole rules_core: #include "utility_h" #include "wrappers_h" #include "events_h" void main() { event ev = GetCurrentEvent(); int nEventType = GetEventType(ev); int nEventHandled = FALSE; switch(nEventType) { case EVENT_TYPE_DAMAGED: { //add here your code nEventHandled = TRUE; break; } } if (!nEventHandled) { HandleEvent(ev, RESOURCE_SCRIPT_RULES_CORE); } } You also don't have to make a new if clause use:if (!HasAbility(OBJECT_SELF,ABILITY_TALENT_MELEE_ARCHER) || (!HasAbility(OBJECT_SELF,DW_ARCANE_ARCHERY_FINESSE)))if not has ability ... or not has ability ... I don't understand what you mean with "adding it in the include". Did you make a new script that references to the rules_core? Link to comment Share on other sites More sharing options...
DreadWolf Posted May 4, 2010 Author Share Posted May 4, 2010 I did as you said and used the event_override method but it hasn't gotten me anywhere. Which leads me to believe that there is more to "melee archer", which i kinda expected. I can't remember which scripts they are, but there are 2 others that also handle the interrupts. I'll have to look into that later. I thank you for the help and insight though, and would welcome more. :P Here is the event override script. You can look it over but it compiled without incident and looks fine to me. #include "utility_h" #include "wrappers_h" #include "events_h" #include "dw_ae_constants_h" void main() { event ev = GetCurrentEvent(); int nEventType = GetEventType(ev); int nEventHandled = FALSE; switch(nEventType) { case EVENT_TYPE_DAMAGED: { // This object lost 1 hit point or more if (IsDeadOrDying(OBJECT_SELF)) { return; } int bSound = TRUE; object oDamager = GetEventCreator(ev); float fDamage = GetEventFloat(ev, 0); int nDamageType = GetEventInteger(ev, 0); int nAbility = GetEventInteger(ev, 1); if(!IsFollower(OBJECT_SELF)) AI_Threat_UpdateDamage(OBJECT_SELF, oDamager, fDamage); if (IsStealthy(OBJECT_SELF) && nDamageType != DAMAGE_TYPE_PHYSICAL) { // stealth 3 and 4 have a chance to not drop on non-physical damage int nLevel = GetLevel(OBJECT_SELF); float fChance = -1.0f; if (HasAbility(OBJECT_SELF, ABILITY_SKILL_STEALTH_4) == TRUE) { fChance = nLevel * 0.02f; } else if (HasAbility(OBJECT_SELF, ABILITY_SKILL_STEALTH_3) == TRUE) { fChance = nLevel * 0.01f; } fChance = MinF(fChance, 0.8f); if (RandomFloat() > fChance) { DropStealth(OBJECT_SELF); } } // If not a follower and damaged outside of combat and does not perceive the damager // then try to move to damager. // the following check needs to be outside of gamemode=combat check because it can happen when the gamemode is not combat // for example: around a corner where no one perceives each other yet if(GetObjectType(oDamager) == OBJECT_TYPE_CREATURE && GetCombatState(OBJECT_SELF) == FALSE && !IsFollower(OBJECT_SELF) && !IsPerceiving(OBJECT_SELF, oDamager)) { location lLoc = GetLocation(oDamager); WR_ClearAllCommands(OBJECT_SELF, TRUE); command cMove = CommandMoveToLocation(lLoc, TRUE); WR_AddCommand(OBJECT_SELF, cMove); } // ----------------------------------------------------------------- // Attack Interruption // This should only ever happen in combat. // @author georg // ----------------------------------------------------------------- if (GetGameMode() == GM_COMBAT) { // ------------------------------------------------------------- // Only significant damage disrupts // ------------------------------------------------------------- if (nDamageType == DAMAGE_TYPE_PHYSICAL) { command cmd = GetCurrentCommand(OBJECT_SELF); int nCmdType = GetCommandType(cmd); // --------------------------------------------------------- // We only interrupt attack commands at this point // --------------------------------------------------------- if (nCmdType == COMMAND_TYPE_ATTACK) { //--------------------------------------------------------- // Damage needs to exceed dexterity modifier/3 to interrupt //---------------------------------------------------------- float fModifier= GetAttributeModifier(OBJECT_SELF, ATTRIBUTE_DEX) * (1.0 / 3.0); if (fDamage > fModifier) { // ------------------------------------------------- // Melee archers ignore interruptions // ------------------------------------------------- if (!HasAbility(OBJECT_SELF,ABILITY_TALENT_MELEE_ARCHER) || (!HasAbility(OBJECT_SELF,DW_ARCANE_ARCHERY_FINESSE))) { if (IsUsingMeleeWeapon(oDamager, OBJECT_INVALID)) { if (IsUsingRangedWeapon(OBJECT_SELF,OBJECT_INVALID,TRUE)) { UI_DisplayMessage(OBJECT_SELF, UI_MESSAGE_INTERRUPTED); #ifdef DEBUG Log_Trace(LOG_CHANNEL_COMBAT,"rules_core.OnDamage","Ranged attack interrupted by damage"); #endif WR_ClearAllCommands(OBJECT_SELF, TRUE); } } } } } // --------------------------------------------------------- // Experimental: Taking any damage > 1 causes spell interruption // --------------------------------------------------------- else if (nCmdType == COMMAND_TYPE_USE_ABILITY) { int nAbi = GetCommandInt(cmd,0); // Only abilities with speed >0 can be interrupted. if (CanInterruptSpell(nAbi)) { int nCombatTrainingRank = 0 ; int nModifier = 0; float fThres = 0.0f; // ----------------------------------------------------- if (!IsPartyMember(OBJECT_SELF)) { nCombatTrainingRank = GetM2DAInt(Diff_GetAutoScaleTable(),"nCombatTraining",GetCreatureRank(OBJECT_SELF)); nModifier = GetLevel(OBJECT_SELF); } else { nCombatTrainingRank = (HasAbility(OBJECT_SELF,ABILITY_SKILL_COMBAT_TRAINING_1)) + (HasAbility(OBJECT_SELF,ABILITY_SKILL_COMBAT_TRAINING_2)) + (HasAbility(OBJECT_SELF,ABILITY_SKILL_COMBAT_TRAINING_3)) + (HasAbility(OBJECT_SELF,ABILITY_SKILL_COMBAT_TRAINING_4)); nModifier = 5 + GetLevel(OBJECT_SELF)/2; } fThres = (nCombatTrainingRank * 10.0f) + nModifier; // ----------------------------------------------------- // Damage needs to exceed a certain threshold before it // can interrupt. Otherwise playing mages gets very // frustrating. // ----------------------------------------------------- if (fDamage > fThres) { // --------------------------------------------- // Since COMMAND_USEABILITY can be in a movement // subaction, filter additionally for conjure // phase. // --------------------------------------------- if (IsConjuring(OBJECT_SELF)) { UI_DisplayMessage(OBJECT_SELF, UI_MESSAGE_INTERRUPTED); #ifdef DEBUG Log_Trace(LOG_CHANNEL_COMBAT,"rules_core.OnDamage","Spell interrupted by damage"); #endif SSPlaySituationalSound(OBJECT_SELF, SOUND_SITUATION_SPELL_INTERRUPTED); bSound = FALSE; WR_ClearAllCommands(OBJECT_SELF, TRUE); } } else { #ifdef DEBUG Log_Trace(LOG_CHANNEL_COMBAT,"rules_core.OnDamage","Spell not interrupted, dmg " + ToString(fDamage) + " below threshold: " + ToString(fThres) ); #endif } } } } if (fDamage >= SOUND_THRESH_DAMAGE_AMOUNT && bSound) { SSPlaySituationalSound(OBJECT_SELF, SOUND_SITUATION_GOT_DAMAGED, oDamager); } // ------------------------------------------------------------- // Handle various effects // ------------------------------------------------------------- Ability_HandleOnDamageAbilities(OBJECT_SELF, oDamager, fDamage, nDamageType, nAbility); nEventHandled = TRUE; break; } } if (!nEventHandled) { HandleEvent(ev, RESOURCE_SCRIPT_RULES_CORE); } } } Link to comment Share on other sites More sharing options...
Recommended Posts