protected override void onStarted() { if (mImpactRes.shakeCameraDuration != 0) { CameraController.Instance.ShakeCamera(mImpactRes.shapeCameraAmount, mImpactRes.shakeCameraDuration / 1000f, (ShakeType)mImpactRes.shapeCameraType); } int hpChanged = 0, manaChanged = 0; bool critical = false; if (!computeImpactModify(out hpChanged, out manaChanged, out critical)) { mOwner.Die(mAttackerAttr, mImpactRes.impactDamageType); return; } // 有益的impact, 或者可以被减血. if (!mImpactRes.harmful || mOwner.CanBeDamaged()) { impactModify(hpChanged, manaChanged, critical); } // 表示是增益的impact(产生了加血, 有益的impact的特效没有CD, 且不会触发材质特效) // || (减益imapct, 且添加被击特效成功(表示被击材质特效不在CD中且目标未死亡)). if (!mImpactRes.harmful || mOwner.AddMaterialBehaviour(MaterialBehaviourDef.OnMaterialBeHit, mImpactRes.impactDamageType, mAttackerAttr.EffectStartDirection) == ErrorCode.Succeeded) { // 播放impact自带的特效. // 注意: 带有伤害的impact的特效, 与被击材质特效共同CD. SkillClientBehaviour.AddEffect2Object(mOwner, mImpactRes._3DEffectID, mImpactRes._3DEffectBindpoint, mAttackerAttr.EffectStartDirection); } base.onStarted(); }
protected override void onStopped(SkillEffectStopReason stopReason) { if (getState(StateEnabled)) { ErrorHandler.Parse(enable(false, stopReason)); } // buff被回收时, 不会再继续触发效果. if (stopReason != SkillEffectStopReason.Recycled) { // 消失时的特效. SkillClientBehaviour.AddEffect2Object(mOwner, mBuffRes.endEffectID, mBuffRes.endEffectBindpoint, 0f); // buff死亡创建. // 对buff拥有者产生效果. SkillDetails.AddSkillEffectByResource(mAttackerAttr, mOwner, mBuffRes.effect2OwnerOnExpired); // 对buff拥有者周围产生效果. SkillDetails.SelectTargetAndAddSkillEffect(mAttackerAttr, mOwner.GetPosition(), mOwner.GetDirection(), mBuffRes.targetSelectionOnExpired, mBuffRes.effect2OthersOnExpired ); // 在buff拥有者周围进行创建. SkillDetails.CreateCreationAround(mAttackerAttr, mBuffRes.creationAroundOwnerOnExpired, mOwner.GetPosition(), mOwner.GetDirection()); } base.onStopped(stopReason); }
/// <summary> /// 开始进入爆炸倒计时. /// </summary> private void explodeCountBackwards(object param) { if (!mAwake) { return; } RemoveSkillBuffByResID(mTrapResource.buffID); if (mTrapResource.delayEffect != uint.MaxValue) { if (mTrapResource.loopDelayEffect) { mLoopClientBehaviours = new ClientBehaviourIdContainer(); } SkillClientBehaviour.AddEffect2Object(this, mTrapResource.delayEffect, mTrapResource.delayEffectBindpoint, GetDirection(), mTrapResource.loopDelayEffect, mLoopClientBehaviours ); } mAwake = false; }
/// <summary> /// 当triggerType指定的事件发生时, 检查randEventContainer列表, 触发随机事件. /// </summary> /// <param name="theOther">触发事件的单位.</param> /// <param name="eventOwner">为随机事件的拥有者.</param> /// <remarks>randevent的技能效果不由任何技能发起(只可以得知该随机事件是如何被注册的)</remarks> public static void ApplyRandEvent( BattleUnit theOther, BattleUnit eventOwner, BattleUnitRandEventContainer randEventContainer, RandEventTriggerType triggerType, RandEventArg triggerArg ) { List <uint> buffNeed2Remove = new List <uint>(); List <BattleUnitRandEvent> typedContainer = randEventContainer[triggerType]; //LinkedListNode<BattleUnitRandEvent> currentNode = typedContainer.First; // SkillScript可能产生新的randevent加入容器中, 导致容器改变, 因此不能通过foreach遍历. // 获取当前指定类型的容器中的元素个数, 只遍历当前的元素(新的randevent通过AddLast加入到容器中, 因此不会被遍历到). for (int i = typedContainer.Count - 1; i >= 0; --i) { BattleUnitRandEvent randEvent = typedContainer[i]; SkillRandEventTableItem randEventRes = randEvent.randEventResource; // 检查CD. if (randEvent.cdMilliseconds != 0) { continue; } // 检查概率. if (!SkillUtilities.Random100(randEventRes.probability)) { continue; } SkillClientBehaviour.AddEffect2Object(eventOwner, randEventRes._3DEffectID, randEventRes._3DEffectBindpoint); if (randEvent.mScript != null && !randEvent.mScript.RunScript(triggerArg)) { buffNeed2Remove.Add((uint)randEvent.fromBuffRes.resID); } randEvent.cdMilliseconds = randEventRes.cdMilliseconds; } // for (int count = typedContainer.Count; count != 0; --count, currentNode = currentNode.Next) // { // // } for (int i = 0; i < buffNeed2Remove.Count; ++i) { eventOwner.RemoveSkillBuffByResID(buffNeed2Remove[i]); } /* foreach (uint id in buffNeed2Remove)*/ }
protected override void onStarted() { // 如果该位移会打断当前技能, 那么需要将动态标记的改变应用到当前的action上. // 否则, 只记录标记, 保证过程中不能施放新的技能即可. mOwner.AddActiveFlag(ActiveFlagsDef.DisableAttack, true, InterruptSkillUsing); mOwner.AddActiveFlag(ActiveFlagsDef.DisableSkillUse, true, InterruptSkillUsing); mOwner.AddActiveFlag(ActiveFlagsDef.DisableMovement, true, true); mOwner.AddActiveFlag(ActiveFlagsDef.DisableRotate, true, true); // 特效和动作. SkillClientBehaviour.PlayAnimation(mOwner, AnimationName, LoopAnimation, mLoopClientBehaviours); SkillClientBehaviour.AddEffect2Object(mOwner, EffectID, EffectBindPoint, 0f, LoopEffect, mLoopClientBehaviours ); base.onStarted(); }
/// <summary> /// 创建投掷物. /// </summary> public static ErrorCode createProjectiles(BattleUnit user, uint skillResID, uint projResID, Vector3 targetPosition) { ProjectileSettingsTableItem projSettings = DataManager.ProjectileSettingsTable[projResID] as ProjectileSettingsTableItem; for (uint i = 0; i < ProjectileSettingsTableItem.ProjectileCount; ++i) { ProjectileItem item = projSettings.items[i]; if (item.bulletResID == uint.MaxValue) { break; } BulletTableItem bulletRes = DataManager.BulletTable[item.bulletResID] as BulletTableItem; // 枪口特效. if (item.bindpointEffect != uint.MaxValue) { SkillClientBehaviour.AddEffect2Object(user, item.bindpointEffect, item.initBindpoint); } ProjectileCreateParam param = new ProjectileCreateParam() { User = user, StartPosition = user.GetBonePositionByName(item.initBindpoint), TargetPosition = targetPosition, DistributionType = item.distributionType, DistributionArgument = item.distributionArgument, BulletRes = bulletRes, SkillResID = skillResID }; createProjectiles(param); } return(ErrorCode.Succeeded); }
void create3DEffect(object resource) { EffectCreateStructure argument = (EffectCreateStructure)resource; SkillClientBehaviour.AddEffect2Object(mOwner, argument.effectID, argument.bindpoint, float.NaN, argument.loop, mLoopClientBehaviours); }
/// <summary> /// 添加材质特效和声音. /// </summary> /// <param name="owner">被添加特效和声音的单位</param> /// <param name="cdContainer">cd的容器, 该函数会检查并设置CD.</param> /// <param name="name">添加的类型(被击, 死亡等)</param> /// <param name="impactDamageType">impact的伤害类型</param> public static ErrorCode AddMaterialBehaviour(BattleUnit owner, HitMaterialEffectCdContainer cdContainer, MaterialBehaviourDef name, ImpactDamageType impactDamageType, float dir ) { // 无效的伤害类型. if (impactDamageType >= ImpactDamageType.Count) { return(ErrorCode.Succeeded); } // CD中, 只有被击的材质特效有CD, 死亡材质特效没有CD. if (name == MaterialBehaviourDef.OnMaterialBeHit && cdContainer.IsCoolingDown(impactDamageType)) { return(ErrorCode.CoolingDown); } uint materialID = owner.GetMaterialResourceID(); if (materialID == uint.MaxValue) { ErrorHandler.Parse(ErrorCode.ConfigError, owner.dbgGetIdentifier() + " 没有材质!"); return(ErrorCode.ConfigError); } MaterialTableItem material = DataManager.MaterialTable[materialID] as MaterialTableItem; if (material == null) { SkillUtilities.ResourceNotFound("material", materialID); return(ErrorCode.ConfigError); } if (name == MaterialBehaviourDef.OnMaterialBeHit) { cdContainer.StartCd(impactDamageType); } MaterialItem item = material.items[(int)impactDamageType]; uint effectID = uint.MaxValue; uint sound = uint.MaxValue; string bindpoint = ""; switch (name) { case MaterialBehaviourDef.OnMaterialBeHit: effectID = item.hitEffect; bindpoint = material.hitEffectBindpoint; sound = item.sound; // 被击材质特效在被击者身上播放. /* SkillClientBehaviour.AddEffect2Object(owner, effectID, bindpoint, dir);*/ if (string.IsNullOrEmpty(bindpoint)) { SkillClientBehaviour.AddSceneEffect(effectID, owner.GetPosition(), dir); } else { SkillClientBehaviour.AddEffect2Object(owner, effectID, bindpoint, dir); } break; case MaterialBehaviourDef.OnMaterialDie: effectID = item.deathEffect; bindpoint = material.deathEffectBindpoint; if (string.IsNullOrEmpty(bindpoint)) { SkillClientBehaviour.AddSceneEffect(effectID, owner.GetPosition(), dir); } else { SkillClientBehaviour.AddEffect2Object(owner, effectID, bindpoint, dir); } break; default: break; } if (sound != uint.MaxValue) { SkillClientBehaviour.PlaySound(sound); } return(ErrorCode.Succeeded); }
/// <summary> /// buff开始作用. 添加属性, 动态标记等. /// </summary> protected virtual void onEnabled(bool bEnabled, SkillEffectStopReason stopReason) { // 特效 if (bEnabled) { SkillClientBehaviour.AddEffect2Object(mOwner, mBuffRes._3DEffectID, mBuffRes._3DEffectBindpoint, 0f, mBuffRes.loop3DEffect, mClientBehaviourIdContainer); SkillClientBehaviour.PlayAnimation(mOwner, mBuffRes.animationName, mBuffRes.loopAnimation, mClientBehaviourIdContainer); } else { SkillClientBehaviour.RemoveAll(mOwner, mClientBehaviourIdContainer); } // 检查目标是否可以被控制, 并保存标记, 表示该buff是否对目标产生了控制. if ((bEnabled && mOwner.CanBeStuned()) || (!bEnabled && mStunEnabled)) { enableStun(bEnabled); mStunEnabled = bEnabled; } if (mBuffRes.stunImmunity) { mOwner.AddActiveFlag(ActiveFlagsDef.StunImmunity, bEnabled, true); } if (mBuffRes.damageImmunity) { mOwner.AddActiveFlag(ActiveFlagsDef.DamageImmunity, bEnabled, true); } if (mBuffRes.inviolability) { mOwner.AddActiveFlag(ActiveFlagsDef.Inviolability, bEnabled, true); } if (mBuffRes.magneticEffect) { mOwner.AddActiveFlag(ActiveFlagsDef.MagneticEffect, bEnabled, true); } if (mBuffRes.strokeEffect) { mOwner.AddActiveFlag(ActiveFlagsDef.StrokeEffect, bEnabled, true); } if (mBuffRes.randEvent != uint.MaxValue) { if (bEnabled) { mOwner.AddRandEvent(mBuffRes, mAttackerAttr); } else { mOwner.RemoveRandEvent(mBuffRes, stopReason); } } if (bEnabled) // mStackCount == 0. { AddStack(); if (mBuffRes.newModelID != uint.MaxValue) { mOwner.Transform((int)mBuffRes.newModelID); } if (mBuffRes.newWeaponID != uint.MaxValue) { mOwner.ChangeWeapon((int)mBuffRes.newWeaponID); mOwner.AddActiveFlag(ActiveFlagsDef.DisableChangeWeaponModel, true, false); } if (mBuffRes.superNewWeaponID != uint.MaxValue) { if (mOwner is Player) { if ((mOwner as Player).HasSuperWeapon()) { (mOwner as Player).UnEquipSuperWeapon(); } mLastUseWeapon = (uint)mOwner.GetMainWeaponID(); (mOwner as Player).SceneChangeWeapon((int)mBuffRes.superNewWeaponID); mOwner.AddActiveFlag(ActiveFlagsDef.DisableChangeWeapon, true, false); } else { GameDebug.LogError("只有玩家支持使用buff更换武器"); } } if (mSkillTransform != null) { mOwner.SkillTransform(mSkillTransform); } } else { removeAllStacks(); if (mBuffRes.newModelID != uint.MaxValue) { mOwner.UndoTransform(); } if (mBuffRes.newWeaponID != uint.MaxValue && mOwner is Player) { mOwner.AddActiveFlag(ActiveFlagsDef.DisableChangeWeaponModel, false, false); mOwner.ChangeWeapon(mOwner.GetMainWeaponID()); } if (mBuffRes.superNewWeaponID != uint.MaxValue) { if (mOwner is Player) { mOwner.AddActiveFlag(ActiveFlagsDef.DisableChangeWeapon, false, false); (mOwner as Player).SceneChangeWeapon((int)mLastUseWeapon); } else { GameDebug.LogError("只有玩家支持使用buff更换武器"); } } if (mSkillTransform != null) { mOwner.SkillTransform(null); } } }