Aller au contenu

Photo

Hideous Blow type spells possible?


  • Veuillez vous connecter pour répondre
5 réponses à ce sujet

#1
manageri

manageri
  • Members
  • 394 messages
I'd like to make the 'Inflict Pitiful Wounds' line of cleric spells more useful by basically making them behave like Hideous Blow, i.e, make the effect stay on the caster until he makes one succesful attack. Unfortunately, as far as I can tell, OE decided to only give us a stupid hardcoded function for that (EffectHideousBlow) which doesn't allow you to even throw in your own damage numbers or anything. Is there a good way to make this work without having to change a ton of stuff beyond the spell scripts?

#2
Morbane

Morbane
  • Members
  • 1 883 messages
you would have write you own spell script and add it to spells.2da

Image IPB

Modifié par Morbane, 24 octobre 2013 - 08:25 .


#3
manageri

manageri
  • Members
  • 394 messages

Morbane wrote...

you would have write you own spell script and add it to spells.2da


I'm familiar enough with the basics of spell creation (though I was just planning on overriding the standard inflict script). The problem is making an effect that lasts until removed by a succesful attack. There's no equivalent general use function for such a thing, just the hardcoded hideous blow one. I'm sure it's possible somehow, but I'd prefer it to be at least something where I don't have to individually make it compatible for every single module I play (by changing creature on damaged scripts or something), so something I could just keep in the override. Maybe if I have the spell apply an onhit effect to the char's weapon and make the script itself cancel that effect, assuming of course that the "onhit cast spell" item properties even call the spell scripts they're supposed to and aren't hardcoded.

I'll see if I can make that work. Thanks, captain Picard.

#4
Morbane

Morbane
  • Members
  • 1 883 messages
you could try a combination of delaycommand and a conditional based on if a hit is successfull - im pretty sure something along those lines could be scripted.

the actual "delay-time" could be an int based script that returns a true or false based on the conditional (1 or 0)

if the hit is successful the delaycommand would be false or 0 and the spell would fire...

after thinking about it the 1 or 0 might not be the right way - but it might work since a script would continously loop (very fast per second) until you hit but that could be several 6 second rounds - but the logic is pointing to some algorithm that could be useful - maybe recursion (which i suck at).

ok ive edited this 4 times now :)

the delay time could be RoundsToSeconds(int function) then the 1 or 0 would work since when the cycle returned true it would always be 1 more round iuntil the conditional fired the spell.

:blink:

Modifié par Morbane, 24 octobre 2013 - 09:45 .


#5
manageri

manageri
  • Members
  • 394 messages
I got it. I basically split the spellscript into two parts. One is fired when it's not being cast from a weapon (that is when it's actually being CAST), which adds the onhit cast inflict whatever wounds property onto the caster's weapon. The second part is only fired when the spell cast item is a weapon, which applies the traditional inflict damage effect to the target and removes the item property. Thanks again to Morbane and Picard's epic inspire competence.

Here are the relevant parts of the script. It's built on Kaedrin's version:

int nSpellID = GetSpellId();
	int nHasTSS = GetHasFeat(FEAT_MELEE_TOUCH_SPELL_SPECIALIZATION);
	int nIPropCasterLevel = GetCasterLevel(OBJECT_SELF);
	object oWeapon = GetItemInSlot(4, OBJECT_SELF);
	itemproperty iProp = GetFirstItemProperty(GetSpellCastItem());
	
	if (GetWeaponType(GetSpellCastItem()) == WEAPON_TYPE_NONE) //not cast by a weapon - apply iprop to user's weapon.
		{
		iProp = GetFirstItemProperty(oWeapon);
		switch (nSpellID)
	    {
		/*Minor*/   case 431:	
					while (GetIsItemPropertyValid(iProp))
							{
						//	SendMessageToPC(GetFirstPC(), "looping iprops");
							if (GetItemPropertyDurationType(iProp) == DURATION_TYPE_TEMPORARY &&
								GetItemPropertySubType(iProp) == 86 ||//numbers from iprp_onhitspell.2da rows. 
								GetItemPropertySubType(iProp) == 87 ||
								GetItemPropertySubType(iProp) == 88 ||
								GetItemPropertySubType(iProp) == 89 ||
								GetItemPropertySubType(iProp) == 90)
								{
								RemoveItemProperty(oWeapon, iProp);
							//	SendMessageToPC(GetFirstPC(), "found onhitcastspell prop and should have removed it");
								}
							iProp = GetNextItemProperty(oWeapon);	
							}
							IPSafeAddItemProperty(oWeapon, ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_INFLICT_MINOR_WOUNDS, nIPropCasterLevel), HoursToSeconds(24), X2_IP_ADDPROP_POLICY_REPLACE_EXISTING); 
							break;
				
		
		/*Light*/   case 432: case 609:	
					while (GetIsItemPropertyValid(iProp))
							{
						//	SendMessageToPC(GetFirstPC(), "looping iprops");
							if (GetItemPropertyDurationType(iProp) == DURATION_TYPE_TEMPORARY &&
								GetItemPropertySubType(iProp) == 86 ||//numbers from iprp_onhitspell.2da rows. 
								GetItemPropertySubType(iProp) == 87 ||
								GetItemPropertySubType(iProp) == 88 ||
								GetItemPropertySubType(iProp) == 89 ||
								GetItemPropertySubType(iProp) == 90)
								{
								RemoveItemProperty(oWeapon, iProp);
							//	SendMessageToPC(GetFirstPC(), "found onhitcastspell prop and should have removed it");
								}
							iProp = GetNextItemProperty(oWeapon);	
							}
							IPSafeAddItemProperty(oWeapon, ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_INFLICT_LIGHT_WOUNDS, nIPropCasterLevel), HoursToSeconds(24), X2_IP_ADDPROP_POLICY_REPLACE_EXISTING); 
							break;
			
			
			
			
	/*Moderate*/	case 433: case 610:	
					while (GetIsItemPropertyValid(iProp))
							{
						//	SendMessageToPC(GetFirstPC(), "looping iprops");
							if (GetItemPropertyDurationType(iProp) == DURATION_TYPE_TEMPORARY &&
								GetItemPropertySubType(iProp) == 86 ||//numbers from iprp_onhitspell.2da rows. 
								GetItemPropertySubType(iProp) == 87 ||
								GetItemPropertySubType(iProp) == 88 ||
								GetItemPropertySubType(iProp) == 89 ||
								GetItemPropertySubType(iProp) == 90)
								{
								RemoveItemProperty(oWeapon, iProp);
							//	SendMessageToPC(GetFirstPC(), "found onhitcastspell prop and should have removed it");
								}
							iProp = GetNextItemProperty(oWeapon);	
							}
							IPSafeAddItemProperty(oWeapon, ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_INFLICT_MODERATE_WOUNDS, nIPropCasterLevel), HoursToSeconds(24), X2_IP_ADDPROP_POLICY_REPLACE_EXISTING); 
							break;
				
				
				
				
				
		/*Serious*/ case SPELL_BG_InflictSerious: case SPELL_BG_Spellbook_2: case 434: case 611:	
					while (GetIsItemPropertyValid(iProp))
							{
						//	SendMessageToPC(GetFirstPC(), "looping iprops");
							if (GetItemPropertyDurationType(iProp) == DURATION_TYPE_TEMPORARY &&
								GetItemPropertySubType(iProp) == 86 ||//numbers from iprp_onhitspell.2da rows. 
								GetItemPropertySubType(iProp) == 87 ||
								GetItemPropertySubType(iProp) == 88 ||
								GetItemPropertySubType(iProp) == 89 ||
								GetItemPropertySubType(iProp) == 90)
								{
								RemoveItemProperty(oWeapon, iProp);
							//	SendMessageToPC(GetFirstPC(), "found onhitcastspell prop and should have removed it");
								}
							iProp = GetNextItemProperty(oWeapon);	
							}
							IPSafeAddItemProperty(oWeapon, ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_INFLICT_SERIOUS_WOUNDS, nIPropCasterLevel), HoursToSeconds(24), X2_IP_ADDPROP_POLICY_REPLACE_EXISTING); 
							break;
					
					
					
					
					
					
	/*Critical*/	case SPELL_BG_Spellbook_4: case SPELL_BG_InflictCritical: case 435: case 612:	
					while (GetIsItemPropertyValid(iProp))
							{
						//	SendMessageToPC(GetFirstPC(), "looping iprops");
							if (GetItemPropertyDurationType(iProp) == DURATION_TYPE_TEMPORARY &&
								GetItemPropertySubType(iProp) == 86 ||//numbers from iprp_onhitspell.2da rows. 
								GetItemPropertySubType(iProp) == 87 ||
								GetItemPropertySubType(iProp) == 88 ||
								GetItemPropertySubType(iProp) == 89 ||
								GetItemPropertySubType(iProp) == 90)
								{
								RemoveItemProperty(oWeapon, iProp);
							//	SendMessageToPC(GetFirstPC(), "found onhitcastspell prop and should have removed it");
								}
							iProp = GetNextItemProperty(oWeapon);	
							}
							IPSafeAddItemProperty(oWeapon, ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_INFLICT_CRITICAL_WOUNDS, nIPropCasterLevel), HoursToSeconds(24), X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
							break;
		
		
	/*Minor*///     case 431: AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_INFLICT_MINOR_WOUNDS, nIPropCasterLevel), oWeapon, HoursToSeconds(24)); break;
	/*Light*///     case 432: case 609: AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_INFLICT_LIGHT_WOUNDS, nIPropCasterLevel), oWeapon, HoursToSeconds(24)); break;
	/*Moderate*///  case 433: case 610: AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_INFLICT_MODERATE_WOUNDS, nIPropCasterLevel), oWeapon, HoursToSeconds(24)); break;
	/*Serious*/ //  case SPELL_BG_InflictSerious: case SPELL_BG_Spellbook_2: case 434: case 611: AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_INFLICT_SERIOUS_WOUNDS, nIPropCasterLevel), oWeapon, HoursToSeconds(24)); break;
	/*Critical*/ // case SPELL_BG_Spellbook_4: case SPELL_BG_InflictCritical: case 435: case 612: AddItemProperty(DURATION_TYPE_TEMPORARY, ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_INFLICT_CRITICAL_WOUNDS, nIPropCasterLevel), oWeapon, HoursToSeconds(24)); break; 
	   }
	   }
	else //being "cast" by a weapon (onhit) - do regular inflict stuff.
	{	
//	SendMessageToPC(GetFirstPC(), "Inflict being cast by weapon");
	
		if (nHasTSS)
		{
		    switch (nSpellID)
		    {
			/*Minor*/     case 431: cmi_spellsInflictTouchAttack(1, 1, 0, 1, 246, VFX_HIT_SPELL_INFLICT_1, nSpellID); break;
			/*Light*/     case 432: case 609: cmi_spellsInflictTouchAttack(1, d8() + 2, 5, 10, 246, VFX_HIT_SPELL_INFLICT_2, nSpellID); break;
			/*Moderate*/  case 433: case 610: cmi_spellsInflictTouchAttack(2, d8(2) + 4, 10, 20, 246, VFX_HIT_SPELL_INFLICT_3, nSpellID); break;
			/*Serious*/   case SPELL_BG_InflictSerious: case SPELL_BG_Spellbook_2: case 434: case 611: cmi_spellsInflictTouchAttack(3, d8(3) + 6, 15, 30, 246, VFX_HIT_SPELL_INFLICT_4, nSpellID); break;
			/*Critical*/  case SPELL_BG_Spellbook_4: case SPELL_BG_InflictCritical: case 435: case 612: cmi_spellsInflictTouchAttack(4, d8(4) + 8, 20, 40, 246, VFX_HIT_SPELL_INFLICT_5, nSpellID); break;
			}
		}
		else
		{		
		    switch (nSpellID)
		    {
		/*Minor*/     case 431: cmi_spellsInflictTouchAttack(1, 1, 0, 1, 246, VFX_HIT_SPELL_INFLICT_1, nSpellID); break;
		/*Light*/     case 432: case 609: cmi_spellsInflictTouchAttack(1, d8(), 5, 8, 246, VFX_HIT_SPELL_INFLICT_2, nSpellID); break;
		/*Moderate*/  case 433: case 610: cmi_spellsInflictTouchAttack(2, d8(2), 10, 16, 246, VFX_HIT_SPELL_INFLICT_3, nSpellID); break;
		/*Serious*/   case SPELL_BG_InflictSerious: case SPELL_BG_Spellbook_2: case 434: case 611: cmi_spellsInflictTouchAttack(3, d8(3), 15, 24, 246, VFX_HIT_SPELL_INFLICT_4, nSpellID); break;
		/*Critical*/  case SPELL_BG_Spellbook_4: case SPELL_BG_InflictCritical: case 435: case 612: cmi_spellsInflictTouchAttack(4, d8(4), 20, 32, 246, VFX_HIT_SPELL_INFLICT_5, nSpellID); break;
		
			
			}
	  	}
		while (GetIsItemPropertyValid(iProp))
			{
		//	SendMessageToPC(GetFirstPC(), "looping iprops");
			if (GetItemPropertyDurationType(iProp) == DURATION_TYPE_TEMPORARY &&
				GetItemPropertySubType(iProp) == 86 ||//numbers from iprp_onhitspell.2da rows. 
				GetItemPropertySubType(iProp) == 87 ||
				GetItemPropertySubType(iProp) == 88 ||
				GetItemPropertySubType(iProp) == 89 ||
				GetItemPropertySubType(iProp) == 90)
				{
				RemoveItemProperty(GetSpellCastItem(), iProp);
			//	SendMessageToPC(GetFirstPC(), "found onhitcastspell prop and should have removed it");
				}
			iProp = GetNextItemProperty(GetSpellCastItem());	
			}
	}


#6
Morbane

Morbane
  • Members
  • 1 883 messages
or:

"Blade of Undead Healing"!!!!

Glad you figured out a way to accomplish your goal