//-1 will return equipping feature block
//otherwise returns the n'th feature block
EffectQueue *Item::GetEffectBlock(Scriptable *self, const Point &pos, int usage, ieDwordSigned invslot, ieDword pro) const
{
	Effect *features;
	int count;

	if (usage>=ExtHeaderCount) {
		return NULL;
	}
	if (usage>=0) {
		features = ext_headers[usage].features;
		count = ext_headers[usage].FeatureCount;
	} else {
		features = equipping_features;
		count = EquippingFeatureCount;
	}
	EffectQueue *fxqueue = new EffectQueue();

	for (int i=0;i<count;i++) {
		Effect *fx = features+i;
		fx->InventorySlot = invslot;
		fx->CasterLevel = ITEM_CASTERLEVEL; //items all have casterlevel 10
		if (usage >= 0) {
			//this is not coming from the item header, but from the recharge flags
			fx->SourceFlags = ext_headers[usage].RechargeFlags;
		} else {
			fx->SourceFlags = 0;
		}
		if (fx->Target != FX_TARGET_SELF) {
			fx->Projectile = pro;
			fxqueue->AddEffect( fx );
		} else {
			Actor *target = (self->Type==ST_ACTOR)?(Actor *) self:NULL;
			fx->Projectile = 0;
			fx->PosX=pos.x;
			fx->PosY=pos.y;
			if (target) {
				core->ApplyEffect(fx, target, self);
			}
		}
	}

	//adding a pulse effect for weapons (PST)
	//if it is an equipping effect block
	if ((usage==-1) && (WieldColor!=0xffff)) {
		if (Flags&IE_ITEM_PULSATING) {
			Effect *tmp = BuildGlowEffect(WieldColor);
			if (tmp) {
				tmp->InventorySlot = invslot;
				tmp->Projectile=pro;
				fxqueue->AddEffect( tmp );
				delete tmp;
			}
		}
	}
	return fxqueue;
}
Beispiel #2
0
EffectQueue *Spell::GetEffectBlock(Scriptable *self, const Point &pos, int block_index, int level, ieDword pro) const
{
	bool pst_hostile = false;
	Effect *features;
	int count;

	//iwd2 has this hack
	if (block_index>=0) {
		if (Flags & SF_SIMPLIFIED_DURATION) {
			features = ext_headers[0].features;
			count = ext_headers[0].FeatureCount;
		} else {
			features = ext_headers[block_index].features;
			count = ext_headers[block_index].FeatureCount;
			if (pstflags && !(ext_headers[block_index].Hostile&4)) {
				pst_hostile = true;
			}
		}
	} else {
		features = casting_features;
		count = CastingFeatureCount;
	}
	EffectQueue *fxqueue = new EffectQueue();
	EffectQueue *selfqueue = NULL;

	for (int i=0;i<count;i++) {
		Effect *fx = features+i;

		if ((Flags & SF_SIMPLIFIED_DURATION) && (block_index>=0)) {
			//hack the effect according to Level
			//fxqueue->AddEffect will copy the effect,
			//so we don't risk any overwriting
			if (EffectQueue::HasDuration(features+i)) {
				fx->Duration = (TimePerLevel*block_index+TimeConstant)*core->Time.round_sec;
			}
		}
		//fill these for completeness, inventoryslot is a good way
		//to discern a spell from an item effect

		fx->InventorySlot = 0xffff;
		//the hostile flag is used to determine if this was an attack
		fx->SourceFlags = Flags;
		//pst spells contain a friendly flag in the spell header
		if (pst_hostile) {
			fx->SourceFlags|=SF_HOSTILE;
		}
		fx->CasterLevel = level;
		fx->SpellLevel = SpellLevel;

		// apply the stat-based spell duration modifier
		if (self->Type == ST_ACTOR) {
			Actor *caster = (Actor *) self;
			if (caster->Modified[IE_SPELLDURATIONMODMAGE] && SpellType == IE_SPL_WIZARD) {
				fx->Duration = (fx->Duration * caster->Modified[IE_SPELLDURATIONMODMAGE]) / 100;
			} else if (caster->Modified[IE_SPELLDURATIONMODPRIEST] && SpellType == IE_SPL_PRIEST) {
				fx->Duration = (fx->Duration * caster->Modified[IE_SPELLDURATIONMODPRIEST]) / 100;
			}

			//evaluate spell focus feats
			//TODO: the usual problem: which saving throw is better? Easy fix in the data file.
			if (fx->PrimaryType<(ieDword) schoolcount) {
				ieDword stat = spellfocus[fx->PrimaryType].stat;
				if (stat>0) {
					switch (caster->Modified[stat]) {
						case 0: break;
						case 1: fx->SavingThrowBonus += spellfocus[fx->PrimaryType].val1; break;
						default: fx->SavingThrowBonus += spellfocus[fx->PrimaryType].val2; break;
					}
				}
			}
		}

		if (fx->Target != FX_TARGET_PRESET && EffectQueue::OverrideTarget(fx)) {
			fx->Target = FX_TARGET_PRESET;
		}

		if (fx->Target != FX_TARGET_SELF) {
			fx->Projectile = pro;
			fxqueue->AddEffect( fx );
		} else {
			fx->Projectile = 0;
			fx->PosX=pos.x;
			fx->PosY=pos.y;
			if (!selfqueue) {
				selfqueue = new EffectQueue();
			}
			// effects should be able to affect non living targets
			//This is done by NULL target, the position should be enough
			//to tell which non-actor object is affected
			selfqueue->AddEffect( fx );
		}
	}
	if (selfqueue) {
		Actor *target = (self->Type==ST_ACTOR)?(Actor *) self:NULL;
		core->ApplyEffectQueue(selfqueue, target, self);
		delete selfqueue;
	}
	return fxqueue;
}