Пример #1
0
    private proto.PartFireInfo PartFire(ClientParts part, ShipEntity target)
    {
        proto.PartFireInfo fireInfo = new proto.PartFireInfo();
        fireInfo.targetid = target.ID;

        if (part.Reference.missle_vel > 0)
        {
            float distance   = Vector3.Distance(this.Ship.Position, target.Ship.Position);
            int   delayFrame = Mathf.CeilToInt(distance / (part.Reference.missle_vel * FightServiceDef.SPEED_SCALAR));
            fireInfo.delayframe = delayFrame;
        }
        else
        {
            int delayFrame = Mathf.CeilToInt(part.Reference.continued_time / FightServiceDef.FRAME_INTERVAL_TIME);
            fireInfo.delayframe = delayFrame;
        }

        int baseAtk = GetBaseAtkValue(part, target);

        if (Ship.Reference.stack)
        {
            baseAtk *= StackAliveNum_;
        }
        MessageDispatcher.Instance.DispatchMessage(TelegramType.UnderAttack, this.ID, target.ID, fireInfo.delayframe, baseAtk, part.Reference.effect_type);

        return(fireInfo);
    }
Пример #2
0
    /// <summary>
    /// 扇形区域检测算法标准版,先实现这个
    /// </summary>
    /// <param name="parts">攻击部件</param>
    /// <param name="targetShip">敌方单位</param>
    /// <param name="squareRange">检测范围平方</param>
    /// <param name="theta">扇形角度</param>
    /// <returns></returns>
    private static bool IsInCritricalSector(ClientParts parts, ClientShip targetShip, float squareRange, float theta)
    {
//         float distanceSq = GetDistanceSq( parts.Owner, targetShip );
//         if( distanceSq > squareRange )
//             return false;
        // D = P - C
        float dx = targetShip.Position.x - parts.Owner.Position.x;
        float dz = targetShip.Position.z - parts.Owner.Position.z;

        // |D|^2 = (dx^2 + dz^2)
        float disntaceSq = dx * dx + dz * dz;

        // |D|^2 > r^2
        if (disntaceSq > squareRange)
        {
            return(false);
        }

        float distance = Mathf.Sqrt(disntaceSq);


        // Normalize D
        dx /= distance;
        dz /= distance;

        return(true);
    }
Пример #3
0
    /// <summary>
    /// 播放子弹
    /// </summary>
    /// <param name="part"></param>
    /// <param name="target"></param>
    /// <param name="delayFrame"></param>
    private void ShowBullet(ClientParts clientPart, List <BulletTarget> targetList, SpellType spellType, string attackPoint, string bulletPath,
                            Effect hurtEffect, Vector3 position, ClientSkill skill = null)
    {
        Transform attackTransRoot = GetTransformByName(attackPoint);

        foreach (Transform attackTrans in attackTransRoot)
        {
            BulletDisplay.ShowBullet(attackTrans.position.x, attackTrans, targetList, clientPart, spellType, bulletPath, hurtEffect, position, skill);
        }
    }
Пример #4
0
    /// <summary>
    /// 判断是否在攻击范围内
    /// </summary>
    /// <param name="parts"></param>
    /// <param name="targetShip"></param>
    /// <returns></returns>
    private static bool CheckInAttackRange(ClientParts parts, float distanceSq)
    {
        // TODO:暂时不检查角度
        float AttackRangeSq = parts.AttackRangeMax * parts.AttackRangeMax;

        if (distanceSq <= AttackRangeSq)
        {
            return(true);
        }

        return(false);
    }
Пример #5
0
    /// <summary>
    /// 激活指挥技能(这个代码可能就是服务于Demo的)
    /// </summary>
    public void ActivateCommanderSkill(ClientParts part)
    {
        ClientSkill skill = ClientSkill.CreateSkillByID(part.Reference.skill_attach);

        if (skill == null)
        {
            return;
        }

        skill.ControlPart = part;
        this.SkillDic.Add(skill.ID, skill);
    }
Пример #6
0
    /// <summary>
    /// 判断是否进入进入了警戒范围
    /// </summary>
    /// <param name="parts"></param>
    /// <param name="Distance"></param>
    /// <returns></returns>
    private static bool CheckInGuardRange(ClientParts parts, float distanceSq)
    {
        // TODO: 暂时不检查角度
        float guardRangeSq = parts.MoveAttackRange * parts.MoveAttackRange;

        if (distanceSq <= guardRangeSq)
        {
            return(true);
        }

        return(false);
    }
Пример #7
0
    // 设置优势增幅
    private int GetAdvantageIncrease(ClientParts castPart, ShipEntity targetEntity)
    {
        if (castPart.Reference.advantage_unitstrait_type == targetEntity.Ship.Reference.unitstrait)
        {
            return(15000);
        }
        else if (castPart.Reference.disadvantage_unitstrait_type == targetEntity.Ship.Reference.unitstrait)
        {
            return(5000);
        }

        return(10000);
    }
Пример #8
0
    private int GetBaseAtkValue(ClientParts castPart, ShipEntity targetEntity)
    {
        int baseAtk = 0;

        // 攻防产生的系数
        int coefficient = 10000 + (castPart.AC - targetEntity.Ship.DC) * 10000 / (castPart.AC + targetEntity.Ship.DC);

        // 应用系数调整
        baseAtk = Utility.GetValueByRate(castPart.Reference.effect_val, coefficient);

        // 优劣式增幅
        baseAtk = Utility.GetValueByRate(baseAtk, GetAdvantageIncrease(castPart, targetEntity));

        return(baseAtk);
    }
Пример #9
0
    /// <summary>
    /// 盲区判定
    /// </summary>
    /// <param name="parts"></param>
    /// <param name="DistSq"></param>
    /// <returns></returns>
    private static bool IsInBlindZone(ClientParts parts, float DistSq)
    {
        // 最小攻击距离为0,说明木有盲区
        if (parts.AttackRagneMin == 0)
        {
            return(false);
        }

        int blindZone = parts.AttackRagneMin * parts.AttackRagneMin;

        if (DistSq < blindZone)
        {
            return(true);
        }

        return(false);
    }
Пример #10
0
    /// <summary>
    /// 扇形区域检测,U3D版本
    /// </summary>
    /// <param name="parts"></param>
    /// <param name="targetShip"></param>
    /// <returns></returns>
    private static bool IsInCricularSector2(ClientParts parts, ShipEntity targetUnit, float squareRange, float theta)
    {
        ClientShip targetShip = targetUnit.Ship;
        float      dx         = targetShip.Position.x - parts.Owner.Position.x;
        float      dz         = targetShip.Position.z - parts.Owner.Position.z;

        // |D|^2 = (dx^2 + dz^2)
        float disntaceSq = dx * dx + dz * dz;

        // |D|^2 > r^2
        if (disntaceSq > squareRange)
        {
            return(false);
        }

        Vector3 targetDir = targetShip.Position - parts.Owner.Position;


        Vector3 forward = new Vector3(0, 0, 1);

        if (targetUnit.CampType == FightServiceDef.CampType.Camp_Attacker)
        {
            forward.z = -1;
        }

        float angle = Vector3.Angle(targetDir.normalized, forward);

        // 角度小于扇形的角度,说明目标的原型在扇形区域内
        if (angle * 2 <= theta)
        {
            return(true);
        }

        // 近防距离检查
        if (parts.Reference.closein_range > 0)
        {
            int closein_range = (parts.Reference.closein_range + targetShip.Reference.vol) * ((parts.Reference.closein_range + targetShip.Reference.vol));
            if (closein_range >= disntaceSq)
            {
                return(true);
            }
        }

        return(false);
    }
Пример #11
0
 /// <summary>
 /// 部件开火
 /// </summary>
 /// <param name="fireEvent"></param>
 /// <param name="part"></param>
 private void CastPartFire(proto.PartFireEvent fireEvent, Part part)
 {
     ShowCast(part);
     // 范围攻击,只生成一个子弹
     if (part.partType == SpellType.AOE)
     {
         List <BulletTarget> targetList = new List <BulletTarget>();
         for (int i = 0; i < fireEvent.fireinfo_size(); i++)
         {
             proto.PartFireInfo info   = fireEvent.fireinfo(i);
             TeamDisplay        target = BattleSceneDisplayManager.Instance.GetTeamDisplay(info.targetid);
             if (target == null)
             {
                 continue;
             }
             BulletTarget bulletTarget = new BulletTarget();
             bulletTarget.delayFrame = info.delayframe;
             bulletTarget.Target     = target;
             targetList.Add(bulletTarget);
         }
         ClientParts parts = Team_.GetPartsByID(part.partID);
         ShowBullet(parts, targetList, part.partType, part.attackPoint, part.bulletPath, part.hitEffect, Vector3.zero);
         return;
     }
     // 个体攻击,每个对象都生成子弹
     for (int i = 0; i < fireEvent.fireinfo_size(); i++)
     {
         proto.PartFireInfo info   = fireEvent.fireinfo(i);
         TeamDisplay        target = BattleSceneDisplayManager.Instance.GetTeamDisplay(info.targetid);
         if (target == null)
         {
             continue;
         }
         List <BulletTarget> targetList   = new List <BulletTarget>();
         BulletTarget        bulletTarget = new BulletTarget();
         bulletTarget.delayFrame = info.delayframe;
         bulletTarget.Target     = target;
         targetList.Add(bulletTarget);
         ClientParts parts = Team_.GetPartsByID(part.partID);
         ShowBullet(parts, targetList, part.partType, part.attackPoint, part.bulletPath, part.hitEffect, Vector3.zero);
     }
 }
Пример #12
0
    /// <summary>
    /// 部件状态会影响舰艇的状态,具体可以查询文档,状态转换表
    /// </summary>
    /// <returns></returns>
    public int GetPartState()
    {
        // 有部件已经达到攻击射程,则判断整体为
        int state = PartState.Idle;

        for (int i = 0; i < Ship.PartsList.Count; ++i)
        {
            ClientParts part = Ship.PartsList[i];
            if (part.PartState == PartState.Attack)
            {
                return(PartState.Attack);
            }
            if (part.PartState == PartState.Guard)
            {
                state = PartState.Guard;
            }
        }

        return(state);
    }
Пример #13
0
    /// <summary>
    /// 根据部件来搜索敌人
    /// </summary>
    /// <param name="Attacker"></param>
    /// <returns></returns>
    public static List <EnemyInfo> FindTarget(ClientParts parts, int campType)
    {
        List <EnemyInfo> targeSelecttList = new List <EnemyInfo>();
        List <Entity>    targetUnitList   = EntityManager.Instance.DefenderUnitList;

        if (campType == FightServiceDef.CampType.Camp_Defender)
        {
            targetUnitList = EntityManager.Instance.AttackUnitList;
        }

        for (int i = 0; i < targetUnitList.Count; ++i)
        {
            ShipEntity targetShip = targetUnitList[i] as ShipEntity;
            if (!targetShip.IsActive())
            {
                continue;
            }
            float distanceSq = GetDistanceSq(parts.Owner, targetShip.Ship);

            // 先判断是否已经在最小攻击范围内
            if (IsInBlindZone(parts, distanceSq))
            {
                continue;
            }


            int moveAttackRange = (parts.MoveAttackRange + targetShip.Ship.Reference.vol) * (parts.MoveAttackRange + targetShip.Ship.Reference.vol);
            if (IsInCricularSector2(parts, targetShip, moveAttackRange, parts.AttackAngle))
            {
                EnemyInfo enemy;
                enemy.DistanceSQ    = distanceSq;
                enemy.EnemyShip     = targetShip;
                enemy.InAttackRange = false;
                // 2015/7/8 InAttackRange的检查放到FilterTarget里面去,会省一些计算
                //enemy.InAttackRange = CheckInAttackRange(parts, targetShip.Ship.Reference.vol, distanceSq);
                targeSelecttList.Add(enemy);
            }
        }

        return(FilterTarget(parts, targeSelecttList));
    }
Пример #14
0
    private static bool IsPriorityTarget(ClientParts castPart, ShipEntity targetEntity)
    {
        if (castPart.Reference.priority_unitstrait == Def.ShipTrait.None &&
            castPart.Reference.priority_unitstrait_extend == Def.ShipExtendTrait.None)
        {
            return(false);
        }

        if (castPart.Reference.priority_unitstrait == targetEntity.Ship.Reference.unitstrait)
        {
            return(true);
        }

        if (castPart.Reference.priority_unitstrait == Def.ShipTrait.None &&
            castPart.Reference.priority_unitstrait_extend == targetEntity.Ship.Reference.unitsextendtrait)
        {
            return(true);
        }

        return(false);
    }
Пример #15
0
    public void ReadFromId(int id)
    {
        ShipProperty_.ClearAll();

        Id    = id;
        Level = 1;
        ReadFromReference(GlobalConfig.GetUnitReference(Id));
        ShipProperty_.MaxDurability  = Reference.durability;
        ShipProperty_.MaxArmor       = Reference.armor;
        ShipProperty_.MaxEnergy      = Reference.energy;
        ShipProperty_.MaxShuttleTeam = Reference.shuttle_team;
        ShipProperty_.MaxEccm        = 0; //因为舰船不自带,所以初始化为0
        ShipProperty_.MaxSpeed       = Reference.speed_max;
        ShipProperty_.MaxSwspeed     = Reference.sw_speed;
        ShipProperty_.MaxForceShield = 0;   //因为舰船不自带,所以初始化为0

        Durability    = MaxDurability;
        DefenseClass_ = Reference.dc_initial; // 等级暂时不做处理

        // 默认开放所有的部件
        if (Reference.parts_1 != 0)
        {
            ClientParts parts = new ClientParts();
            parts.ReadFromProto(Reference.parts_1);
            parts.Level             = 1;
            parts.Owner             = this;
            this.PartsDic[parts.Id] = parts;
            this.PartsList.Add(parts);
            if (this.Reference.unitstrait == Def.ShipTrait.CommanderShip)
            {
                ActivateCommanderSkill(parts);
            }
        }

        if (Reference.parts_2 != 0)
        {
            ClientParts parts = new ClientParts();
            parts.ReadFromProto(Reference.parts_2);
            parts.Level             = 1;
            parts.Owner             = this;
            this.PartsDic[parts.Id] = parts;
            this.PartsList.Add(parts);
            if (this.Reference.unitstrait == Def.ShipTrait.CommanderShip)
            {
                ActivateCommanderSkill(parts);
            }
        }

        if (Reference.parts_3 != 0)
        {
            ClientParts parts = new ClientParts();
            parts.ReadFromProto(Reference.parts_3);
            parts.Level             = 1;
            parts.Owner             = this;
            this.PartsDic[parts.Id] = parts;
            this.PartsList.Add(parts);
            if (this.Reference.unitstrait == Def.ShipTrait.CommanderShip)
            {
                ActivateCommanderSkill(parts);
            }
        }
    }
Пример #16
0
    /// <summary>
    /// 子弹
    /// </summary>
    /// <param name="attackShipTrans"></param>
    /// <param name="attackPartTrans"></param>
    /// <param name="target"></param>
    /// <param name="attackPart"></param>
    /// <param name="part"></param>
    /// <param name="delayTime"></param>
    public static void ShowBullet(float srcX, Transform attackPartTrans, List <BulletTarget> targetList, ClientParts attackPart,
                                  SpellType spellType, string bulletPath, Effect hurtEffect, Vector3 position, ClientSkill skill)
    {
        // 范围攻击特殊处理
        if (spellType == SpellType.AOE)
        {
            BulletDisplay display = InitBullet(attackPartTrans, null, null, spellType, bulletPath, hurtEffect);
            if (display == null)
            {
                return;
            }
            display.SetAOE(targetList, position, skill);
            return;
        }

        // 其他攻击,一个子弹只对应一个目标
        if (targetList.Count != 1)
        {
            return;
        }

        if (targetList[0].Target == null)
        {
            return;
        }

        ShipDisplay targetShip = targetList[0].Target.GetHurtShip();

        if (targetShip == null)
        {
            return;
        }
        float delayTime = FightServiceDef.FRAME_INTERVAL_TIME_F * targetList[0].delayFrame;

        Transform targetTrans = targetShip.GetTransformByName(targetShip.GetHitPoint(srcX, spellType));

        if (targetTrans == null)
        {
            targetTrans = targetShip.Trans;
        }

        // 导弹特殊处理,从左右发子弹
        if (spellType == SpellType.Missile)
        {
            // TODO: 临时增加逻辑,防御节点一边扔3颗导弹
            // 后面要考虑走配置
            int missileCout = 1;
            if (attackPart.Owner.Reference.unitstrait == Def.ShipTrait.DefenseBuild)
            {
                missileCout = 3;
            }
            for (int i = 0; i < missileCout; i++)
            {
                BulletDisplay display = InitBullet(attackPartTrans, targetShip, targetTrans, spellType, bulletPath, hurtEffect);
                if (display == null)
                {
                    return;
                }
                display.SetMissile(attackPartTrans.name.Contains("left"), delayTime);
            }
        }
        // 机枪特殊处理,做成扫射效果
        else if (spellType == SpellType.MachineGun)
        {
            for (int i = 0; i < attackPart.Reference.continuity_times; i++)
            {
                BulletDisplay display = InitBullet(attackPartTrans, targetShip, targetTrans, spellType, bulletPath, hurtEffect);
                display.SetGun(delayTime, (float)attackPart.Reference.continuity_interval / 1000f * i);
            }
        }
        else
        {
            BulletDisplay display = InitBullet(attackPartTrans, targetShip, targetTrans, spellType, bulletPath, hurtEffect);
            display.SetLaserOrConnon(delayTime);
        }
    }
Пример #17
0
 /// <summary>
 /// 扇形区域算法优化版
 /// 1、优化半径检测开平方
 /// 2、优化夹角选择开平方
 /// </summary>
 /// <param name="?"></param>
 /// <returns></returns>
 private static bool IsInCricularSector1(ClientParts parts, ClientShip targetShip)
 {
     return(true);
 }
Пример #18
0
    /// <summary>
    /// 过滤目标
    /// </summary>
    /// <param name="targetList"></param>
    /// <returns></returns>
    private static List <EnemyInfo> FilterTarget(ClientParts part, List <EnemyInfo> targetList)
    {
        if (targetList.Count == 0)
        {
            return(targetList);
        }

        float distanceSq    = float.MaxValue;
        float minDistanceSq = float.MaxValue;
        int   targetIndex   = 0;
        int   priorityIndex = -1;

        // TODO
        // 此处需要优化和完善
        List <EnemyInfo> enemyList = new List <EnemyInfo>();

        for (int i = 0; i < targetList.Count; ++i)
        {
            // 这里出现了嵌套的if判断
            // 主要从优化出发,考虑一趟遍历就做完所有筛选判断
            EnemyInfo targetInfo = targetList[i];

            // 记录下偏小的一个距离
            if (minDistanceSq > targetInfo.DistanceSQ)
            {
                minDistanceSq = targetInfo.DistanceSQ;
            }

            // 判断是否是高优先级目标
            bool prioprityTarget = false;
            if (IsPriorityTarget(part, targetInfo.EnemyShip))
            {
                if (priorityIndex == -1)
                {
                    prioprityTarget = true;
                }
                else if (targetInfo.DistanceSQ < distanceSq)
                {
                    prioprityTarget = true;
                }
            }

            if (prioprityTarget)
            {
                distanceSq    = targetInfo.DistanceSQ;
                targetIndex   = i;
                priorityIndex = i;
                continue;
            }


            // 如果前面的优先级判定不成立,则遍历出距离最近的目标
            if (targetList[i].DistanceSQ < distanceSq)
            {
                distanceSq  = targetList[i].DistanceSQ;
                targetIndex = i;
            }
        }

        if (priorityIndex != -1)
        {
            targetIndex = priorityIndex;
        }

        // 对攻击距离进行修正
        EnemyInfo targetEnemy = targetList[targetIndex];

        targetEnemy.DistanceSQ    = minDistanceSq;
        targetEnemy.InAttackRange = CheckInAttackRange(part, targetEnemy.EnemyShip.Ship.Reference.vol, minDistanceSq);
        enemyList.Add(targetEnemy);
        return(enemyList);
    }
Пример #19
0
    private static bool CheckInAttackRange(ClientParts parts, int targetRaduis, float distanceSq)
    {
        float attackRangeSQ = (parts.AttackRangeMax + targetRaduis) * (parts.AttackRangeMax + targetRaduis);

        return(distanceSq <= attackRangeSQ);
    }
Пример #20
0
    private IEnumerator CastSkill(proto.UseSkill useSkill)
    {
        Skill skill = GetSkill(useSkill.partid);

        if (skill == null)
        {
            Debug.Log("skill is null");
            yield break;
        }
        ShowCast(skill);
        ClientSkill clientSkill = BattleSys.GetCommanderShip().GetSkillById(useSkill.skillid);

        // 范围攻击,只生成一个子弹
        if (skill.partType == SpellType.AOE)
        {
            List <BulletTarget> targetList = new List <BulletTarget>();
            for (int i = 0; i < useSkill.fireinfolist_size(); i++)
            {
                proto.PartFireInfo info   = useSkill.fireinfolist(i);
                TeamDisplay        target = BattleSceneDisplayManager.Instance.GetTeamDisplay(info.targetid);
                if (target == null)
                {
                    continue;
                }
                BulletTarget bulletTarget = new BulletTarget();
                bulletTarget.delayFrame = info.delayframe;
                bulletTarget.Target     = target;
                targetList.Add(bulletTarget);
            }
            ClientParts parts    = Team_.GetPartsByID(skill.partID);
            float       x        = (float)useSkill.posx / 10000f;
            float       y        = (float)useSkill.posy / 10000f;
            float       z        = (float)useSkill.posz / 10000f;
            Vector3     position = new Vector3(x, y, z);
            ShowBullet(parts, targetList, skill.partType, skill.attackPoint, skill.bulletPath, skill.hitEffect, position, clientSkill);
        }
        // 个体攻击,每个对象都生成子弹
        else
        {
            for (int i = 0; i < useSkill.fireinfolist_size(); i++)
            {
                proto.PartFireInfo info   = useSkill.fireinfolist(i);
                TeamDisplay        target = BattleSceneDisplayManager.Instance.GetTeamDisplay(info.targetid);
                if (target == null)
                {
                    continue;
                }
                List <BulletTarget> targetList   = new List <BulletTarget>();
                BulletTarget        bulletTarget = new BulletTarget();
                bulletTarget.delayFrame = info.delayframe;
                bulletTarget.Target     = target;
                targetList.Add(bulletTarget);
                ClientParts parts = Team_.GetPartsByID(skill.partID);
                ShowBullet(parts, targetList, skill.partType, skill.attackPoint, skill.bulletPath, skill.hitEffect, Vector3.zero, clientSkill);
            }
        }
        yield return(new WaitForSeconds(1.2f));

        for (int i = 0; i < SingEffectList_.Count; i++)
        {
            if (SingEffectList_[i] == null)
            {
                continue;
            }
            Destroy(SingEffectList_[i]);
        }
        SingEffectList_.Clear();
    }