예제 #1
0
    /// <summary>
    /// 查找一个军营
    /// </summary>
    /// <returns></returns>
    private TileEntity FindCampEntity()
    {
        var allEntities = IsoMap.Instance.GetAllEntitiesByOwner(Entity.GetOwner());

        //  这里随便寻找一个军营  TODO:后期根据士兵分配选择一个合适的军营
        return(allEntities.RubyFind(entity => EntityTypeUtil.IsBarracks(entity.model)));
    }
예제 #2
0
    public static GameObject LoadAndCreate(EntityModel model)
    {
        //TODO remove this
        var last = model.nameForResource.Substring(model.nameForResource.Length - 2);
        int lastInt;

        if (last != "01" && int.TryParse(last, out lastInt))
        {
            Debug.LogError("由于没有其他等级的模型,暂时使用1级的模型");
            model.nameForResource = model.nameForResource.Replace(last, "01");//因为没有其他资源,暂时都使用1级的资源
        }
        string name = String.Empty;

        if (EntityTypeUtil.IsAnyActor(model.entityType))
        {
            name = "Actors/" + model.nameForResource;
        }
        else if (model.entityType == EntityType.Wall)
        {
            name = "Walls/" + model.nameForResource;
        }
        else if (EntityTypeUtil.IsAnyTrap(model))
        {
            name = "Trap/" + model.nameForResource;
        }
        else
        {
            name = "Buildings/" + model.nameForResource;
        }
        return((GameObject)ResourceManager.Instance.LoadAndCreate(model.raceType + "/Entities/" + name));
    }
예제 #3
0
    /// <summary>
    /// 对单个目标进行伤害处理
    /// </summary>
    /// <param name="targeter"></param>
    /// <param name="attackerModel"></param>
    /// <param name="attacker">技能道具等情况下 attacker 为 null </param>
    /// <param name="factor"></param>
    public static void ProcessDamageOneTargeter(TileEntity targeter, EntityModel attackerModel, TileEntity attacker = null, float factor = 1.0f)
    {
        if (!targeter.IsDead())
        {
            //  计算伤害
            float damage = CalcDamageValue(targeter.model, attackerModel, attacker, factor);

            //  处理伤害
            targeter.MakeDamage(damage);

            //  没死亡时附加buffer效果
            if (!targeter.IsDead())
            {
                GameBufferComponent bufferMgr = targeter.GetComponent <GameBufferComponent>();
                if (bufferMgr != null)
                {
                    bufferMgr.AddBuffer(attackerModel);
                }
            }
            else
            {
                //  [特殊技能] 死亡后大回复
                if (EntityTypeUtil.IsTraitBlessing(targeter.model))
                {
                    //  TODO:
                }
            }

            //  [特殊技能] 吸血   REMARK:考虑是否需要回血光效?
            if (attacker != null && damage > 0 && EntityTypeUtil.IsTraitSuckBlood(attackerModel))
            {
                attacker.MakeDamage(-damage * Constants.SUCK_BLOOD_RATIO);
            }
        }
    }
예제 #4
0
    public override void Update(float dt)
    {
        //  更新飞天陷阱
        if (m_FlyTrapUpdateProc != null)
        {
            m_FlyTrapUpdateProc(dt);
            return;
        }

        //  可见-已经触发
        if (Entity.IsVisible())
        {
            m_timePassed += dt;
            if (m_timePassed >= Entity.model.rate)
            {
                if (EntityTypeUtil.IsFlyTrap(Entity.model))
                {
                    m_FlyTrapUpdateProc = UpdateFlyTrace;
                }
                else
                {
                    ProcessExplode(false);
                }
            }
        }
        //  不可见-检测是否触发
        else if (IsTriggered())
        {
            Entity.ShowEntity();
        }
    }
예제 #5
0
    public override ReqWrapper Execute()
    {
        //占用工人数量
        DataCenter.Instance.FreeWorker += 1;
        EntityModel replaceModel = null;
        if (entity.buildingVO.buildingStatus == BuildingVO.BuildingStatus.Construct)
        {
            replaceModel = entity.model;
            //判断是否是军营
            if (EntityTypeUtil.IsBarracks(entity.model))
            {
                DataCenter.Instance.TotalSpace += entity.model.spaceProvide;
            }
        }
        else if (entity.buildingVO.buildingStatus == BuildingVO.BuildingStatus.Upgrade)//升级
        {
            replaceModel = DataCenter.Instance.FindEntityModelById(entity.model.upgradeId);
            //判断是否是军营
            if (EntityTypeUtil.IsBarracks(entity.model))
            {
                DataCenter.Instance.TotalSpace += (replaceModel.spaceProvide - entity.model.spaceProvide);//军营空间升级
            }
            else if (EntityTypeUtil.IsCenterBuilding(entity.model))
            {
                DataCenter.Instance.Defender.player.baseId = replaceModel.baseId;
            }
        }
        else
        {
            Assert.Fail("building status error!");
        }
        DataCenter.Instance.AddExp(replaceModel.buildExp);

        //替换成建造或者升级完成后的建筑
        entity.buildingVO.buildingStatus = BuildingVO.BuildingStatus.On;
        entity.buildingVO.cid = replaceModel.baseId;
        var newEntity = entity.ReplaceWith(replaceModel, entity.buildingVO);
        ((IsoWorldModeBuilder)GameWorld.Instance.CurrentWorldMode).SelectBuilding(newEntity);

        EventDispather.DispatherEvent(GameEvents.BUILDING_COMPLETE, entity.buildingVO);

        var buildingCompleteReq = new BuildingCompleteReq();
        buildingCompleteReq.sid = sid;
        if (immediately)
        {
            buildingCompleteReq.completeType = BuildingCompleteReq.CompleteType.CompleteImmediately;
            var now = ServerTime.Instance.Now();
            buildingCompleteReq.timestamp = DateTimeUtil.DateTimeToUnixTimestampMS(now);

            int deltaTime = (int)(DateTimeUtil.UnixTimestampMSToDateTime(entity.buildingVO.endTime) - now).TotalSeconds;
            DataCenter.Instance.RemoveResource(ResourceType.Diamond, GameDataAlgorithm.TimeToGem(deltaTime));
        }
        else
        {
            buildingCompleteReq.completeType = BuildingCompleteReq.CompleteType.Normal;
        }
        return new ReqWrapper() { requestType = ReqWrapper.RequestType.BuildingComplete, buildingCompleteReq = buildingCompleteReq };
    }
예제 #6
0
 /// <summary>
 /// 获取自身的战斗目标的阵营
 /// </summary>
 /// <returns></returns>
 public OwnerType GetTargetOwner()
 {
     //  治疗者(获取自身
     if (EntityTypeUtil.IsCurer(model))
     {
         return(GetOwner());
     }
     //  其他(获取对方
     else
     {
         return(GetPeerOwner());
     }
 }
예제 #7
0
 public static string GetItemIconByModel(EntityModel model)
 {
     if (EntityTypeUtil.IsSkill(model))
     {
         //技能
         return("UI_IconSkill_" + model.nameForResource);
     }
     else if (EntityTypeUtil.IsAnyActor(model.entityType))
     {
         //兵种
         return(model.nameForResource.Substring(0, model.nameForResource.Length - 2) + "_IconSmall");
     }
     return("");
 }
예제 #8
0
    /// <summary>
    /// 战斗开始
    /// </summary>
    public void StartBattle()
    {
        if (IsBattleStarted)
        {
            return;
        }
        IsBattleStarted = true;
        IsoMap.Instance.HideGuardAreaMap();

        //计算每个建筑的百分比
        var allEntities = IsoMap.Instance.GetAllEntitiesByOwner(OwnerType.Defender);

        foreach (var tileEntity in allEntities)
        {
            if (EntityTypeUtil.IsAnyNonWallBuilding(tileEntity.entityType))
            {
                ++defenderBuildingCount;
            }
        }
        totalDefenderBuildingCount = defenderBuildingCount;

        //计算士兵数量
        foreach (var armyVo in DataCenter.Instance.Attacker.armies)
        {
            attackerArmyCount += armyVo.amount;

            var model = DataCenter.Instance.FindEntityModelById(armyVo.cid);
            if (EntityTypeUtil.IsCurer(model))
            {
                attackerCurerCount += armyVo.amount;
            }
        }
        //加上援军的士兵数量
        foreach (var donatedArmy in DataCenter.Instance.Attacker.donatedArmies)
        {
            attackerArmyCount += donatedArmy.amount;

            var model = DataCenter.Instance.FindEntityModelById(donatedArmy.cid);
            if (EntityTypeUtil.IsCurer(model))
            {
                attackerCurerCount += donatedArmy.amount;
            }
        }

        //备份进攻方和防守方的数据,提交服务器时使用
        attackerData = ProtoBuf.Serializer.DeepClone(DataCenter.Instance.Attacker);
        defenderData = ProtoBuf.Serializer.DeepClone(DataCenter.Instance.Defender);
    }
예제 #9
0
    public override com.pureland.proto.ReqWrapper Execute()
    {
        var buildTime  = entity.model.buildTime;
        var buildingVO = new BuildingVO();

        buildingVO.buildingStatus = buildTime == 0 ? BuildingVO.BuildingStatus.On : BuildingVO.BuildingStatus.Construct;
        buildingVO.cid            = entity.model.baseId;
        buildingVO.sid            = DataCenter.Instance.CreateNextItemSid();
        buildingVO.endTime        = ServerTime.Instance.GetTimestamp(buildTime);
        buildingVO.x = entity.GetTilePos().x;
        buildingVO.y = entity.GetTilePos().y;

        if (EntityTypeUtil.IsGatherResourceBuilding(entity.model))
        {
            buildingVO.resourceBuildingVO = new ResourceBuildingVO()
            {
                lastGatherTime = buildingVO.endTime
            };                                                                                               //建造完成开始计算产量
        }
        //替换为有建筑动画的对象
        var newEntity = entity.ReplaceWith(entity.model, buildingVO);

        IsoMap.Instance.ForceAddEntity(newEntity);

        if (buildTime != 0)
        {
            //占用工人数量
            DataCenter.Instance.FreeWorker -= 1;
        }
        //添加到建筑vo,方便计数等
        DataCenter.Instance.AddBuilding(buildingVO);
        //消耗资源
        DataCenter.Instance.AddResource(new ResourceVO()
        {
            resourceType = entity.model.costResourceType, resourceCount = -entity.model.costResourceCount
        });


        var buildingConsReq = new BuildingConsReq();

        buildingConsReq.buildingVO   = buildingVO;
        buildingConsReq.resourceType = resourceType;
        return(new ReqWrapper()
        {
            requestType = ReqWrapper.RequestType.BuildingCons, buildingConsReq = buildingConsReq
        });
    }
예제 #10
0
 /// <summary>
 /// 获取建筑工人小屋组件
 /// </summary>
 /// <returns></returns>
 public WorkerHouseComponent GetWorkerHouseComponent()
 {
     if (_cacheWorkerHouse == null)
     {
         //  REMARK:建筑工人小屋就一个设施、并且属于防御方。
         foreach (var entity in GetAllEntitiesByOwner(OwnerType.Defender))
         {
             if (EntityTypeUtil.IsWorkerHouse(entity.model))
             {
                 _cacheWorkerHouse = entity.GetComponent <WorkerHouseComponent>();
                 break;
             }
         }
     }
     Assert.Should(_cacheWorkerHouse != null);
     return(_cacheWorkerHouse);
 }
예제 #11
0
    /// <summary>
    /// 准备攻击1(旋转动画对准目标)
    /// </summary>
    /// <param name="onlyProcessAnimation"></param>
    protected void ProcessReadyAttack(bool onlyProcessAnimation = false)
    {
        //  [速度提升] 动画频率加快
        float animatorSpeedRate     = 0.0f;
        GameBufferComponent buffMgr = Entity.GetComponent <GameBufferComponent>();

        if (buffMgr != null)
        {
            var buffer = buffMgr.GetBuffer(Constants.BUFF_TYPE_SPPEDUP);
            if (buffer != null)
            {
                animatorSpeedRate = buffer.buffDamage;
            }
        }
        //animatorSpeedRate = 2.0f;   //  DEBUG

        //  REMARK:对准目标动画 仅针对炮塔并且目标数量为1时才有效
        if (EntityTypeUtil.IsAnyTower(Entity.entityType) && Entity.AimTarget)
        {
            if (AuxIsAllDead())
            {
                //  重新行动
                TryAction();
            }
            else
            {
                Entity.State = EntityStateType.Rotating;

                //  旋转对准目标 REMARK:这里Stand就是旋转动画
                Entity.PlayAnimationTowardsTarget(AnimationNames.Stand, m_tempTargeters[0], animatorSpeedRate, animationName =>
                {
                    if (Entity.State != EntityStateType.Rotating)
                    {
                        return;
                    }
                    ProcessReadyAttack2(onlyProcessAnimation, animatorSpeedRate);
                });
            }
        }
        else
        {
            ProcessReadyAttack2(onlyProcessAnimation, animatorSpeedRate);
        }
    }
예제 #12
0
    virtual public void MakeDamage(float damage)
    {
#if UNITY_EDITOR
        BattleManager.logDamageList.Add(GameRecord.Frame + ":" + this.model.nameForView + ":" + damage + ":" + currentHp);
#endif  //  UNITY_EDITOR

        //  REMARK:damage如果为负则回血
        currentHp -= damage;
        HandleMessage(EntityMessageType.MakeDamage, damage);
        //  限制不能超过最大maxHp(在回血的情况下)
        currentHp = Mathf.Clamp(currentHp, 0, maxHp);
        float percent = currentHp / (float)maxHp;
        view.SetHpBarPercent(percent);

        if (halfDestroyEffectId == 0 && percent < 0.5f && EntityTypeUtil.IsAnyBuilding(entityType))
        {
            halfDestroyEffectId = GameEffectManager.Instance.AddEffect("Phouse_huo", GetRenderPosition(), true);
        }
    }
예제 #13
0
    /// <summary>
    /// 填充地表建筑数据(0为清除)
    /// </summary>
    /// <param name="entity"></param>
    /// <param name="value"></param>
    private void FillBuildingMapData(TileEntity entity, int entity_id)
    {
        if (!EntityTypeUtil.IsCostMapGrid(entity.entityType))
        {
            return;
        }
        int x = entity.GetTilePos().x;
        int y = entity.GetTilePos().y;
        //  填充建筑全部区域
        int w = entity.width;
        int h = entity.height;

        for (int i = x; i < x + w; ++i)
        {
            for (int j = y; j < y + h; ++j)
            {
                m_buildingMap[i, j] = entity_id;
            }
        }

        //  填充建筑不可通行区域(blockingRange最大值为边数减1,所以不会导致建筑边上的entity_id重合。)
        int blocking = entity.blockingRange;

        if (blocking > 0)
        {
            int offset_x = (int)((w + 1 - blocking) / 2);
            int offset_y = (int)((h + 1 - blocking) / 2);
            Assert.Should(offset_x >= 1 && offset_y >= 1, "Entity的blockingRange不正确...");
            for (int i = x + offset_x; i < x + offset_x + blocking; ++i)
            {
                for (int j = y + offset_y; j < y + offset_y + blocking; ++j)
                {
                    m_routeMap[i, j].EntityID = entity_id;
                }
            }
        }

        //  更新墙之间的连接器 并 刷新墙的方向(显示用)
        if (entity.entityType == EntityType.Wall)
        {
            RefreshWallLinkerAndDirection(entity, entity_id);
        }
    }
예제 #14
0
    private void UpdateDestroy(float dt)
    {
        //  死亡了 但尚未置于死亡状态(则释放)
        if (currentHp <= 0 && this.State != EntityStateType.Dead)
        {
            this.State = EntityStateType.Dead;

            if (GameWorld.Instance.worldType == WorldType.Battle || GameWorld.Instance.worldType == WorldType.Replay)
            {
                BattleManager.Instance.OnEntityDestroy(this);
            }

            //创建战斗时被销毁的残渣
            if (EntityTypeUtil.IsAnyBuilding(entityType))
            {
                GameObject.Destroy(view.body.gameObject);
                GameObject.Destroy(view.hpBar.gameObject);
                if (view.shadow != null)
                {
                    GameObject.Destroy(view.shadow.gameObject);
                }
                GameEffectManager.Instance.AddEffect("Phouse_die", GetRenderPosition());//TODO
                var destroyView = (GameObject)ResourceManager.Instance.LoadAndCreate("Misc/DestroyedBuildingView");
                view.AddSubView(destroyView, Vector3.zero);
                IsoHelper.FaceToWorldCamera(destroyView.transform);
                IsoHelper.MoveAlongCamera(destroyView.transform, 19);
                Destroy(false);
                IsoMap.Instance.RemoveBuildingMapData(this);//移除占地数据,对象还是在IsoMap中
            }
            else if (EntityTypeUtil.IsAnyActor(entityType))
            {
                GameEffectManager.Instance.AddEffect("Psoldier_die", GetRenderPosition());
                IsoMap.Instance.DelayRemoveEntity(this);
                Destroy();
            }
            else
            {
                IsoMap.Instance.DelayRemoveEntity(this);
                Destroy();
            }
        }
    }
예제 #15
0
    virtual public void Init()
    {
        if (!inited)
        {
            inited = true;

            view.Init();
            view.transform.position = GetRenderPosition();

            if (EntityTypeUtil.IsFlyable(model.entityType))
            {
                view.body.Translate(0, Constants.FLY_HEIGHT, 0, Space.Self);
                IsoHelper.MoveAlongCamera(view.shadow, -2 * Constants.SHADOW_Z_ORDER);//空军的阴影显示在建筑上面
            }

            foreach (var tileEntityComponent in components)
            {
                tileEntityComponent.Init();
            }
        }
    }
예제 #16
0
    /// <summary>
    /// 获取指定范围内的对象列表(攻击范围、溅射范围、治疗范围等)
    /// </summary>
    /// <param name="attacker">过滤掉的对象</param>
    /// <param name="ownerType">阵营</param>
    /// <param name="x">范围的中心点X</param>
    /// <param name="y">范围的中心点Y</param>
    /// <param name="range">范围</param>
    /// <param name="blindrange">盲区范围</param>
    /// <param name="filter">过滤器,如果过滤器返回true,则指定的对象被过滤掉。</param>
    /// <returns></returns>
    public List <TileEntity> GetEntitiesByRange(TileEntity attacker, OwnerType ownerType, float x, float y, float range, float blindrange, Func <TileEntity, bool> filter = null)
    {
        List <TileEntity> ret         = new List <TileEntity>();
        float             blindrange2 = blindrange * blindrange;

        foreach (TileEntity targeter in m_entities[(int)ownerType])
        {
            if (attacker == targeter)
            {
                continue;
            }

            if (targeter.IsDead())
            {
                continue;
            }

            if (!EntityTypeUtil.IsAnyTargeter(targeter.entityType))
            {
                continue;
            }

            //  不是限定类型的目标则过滤掉
            if (attacker != null && EntityTypeUtil.IsAnyActor(targeter.entityType) && attacker.model.onlyAttackTargetType != EntityType.None && attacker.model.onlyAttackTargetType != targeter.entityType)
            {
                continue;
            }

            if (filter != null && filter(targeter))
            {
                continue;
            }

            if (targeter.IsInAttackRange(x, y, range, blindrange2))
            {
                ret.Add(targeter);
            }
        }
        return(ret);
    }
예제 #17
0
    /// <summary>
    /// 计算目标的伤害值(伤害公式)
    /// </summary>
    /// <param name="targeterModel"></param>
    /// <param name="attackerModel"></param>
    /// <param name="attacker">技能道具等情况下 attacker 为 null </param>
    /// <param name="factor">伤害修正系数</param>
    /// <returns></returns>
    private static float CalcDamageValue(EntityModel targeterModel, EntityModel attackerModel, TileEntity attacker = null, float factor = 1.0f)
    {
        float damage = 0.0f;

        if (EntityTypeUtil.IsCurer(attackerModel))
        {
            //  回血为负
            damage = -factor * attackerModel.cure;
        }
        else
        {
            //  REMARK:伤害公式可以调整
            damage = attackerModel.damage - targeterModel.defense;
            if (attackerModel.additionDamageSubType != Constants.EMPTY && attackerModel.additionDamageSubType == targeterModel.subType)
            {
                damage *= attackerModel.additionDamageRatio;
            }

            //  技能伤害的时候 attacker 不存在
            if (attacker != null)
            {
                //  [攻击提升] buffer 的情况下乘以伤害倍率
                GameBufferComponent attackerBufferMgr = attacker.GetComponent <GameBufferComponent>();
                if (attackerBufferMgr != null)
                {
                    var buffer = attackerBufferMgr.GetBuffer(Constants.BUFF_TYPE_ATTACKUP);
                    if (buffer != null)
                    {
                        damage *= buffer.buffDamage;
                    }
                }
            }

            damage = Mathf.Max(damage * factor, 0);
        }

        //  处理伤害
        return(damage);
    }
예제 #18
0
    /// <summary>
    /// 是否可通行判断
    /// </summary>
    /// <param name="edge_x"></param>
    /// <param name="edge_y"></param>
    /// <param name="destroy_wall">墙默认是不可通行的,如果可摧毁则认为墙可通行。 </param>
    /// <param name="whiteList">白名单列表,该列表中的对象不阻挡通行。</param>
    /// <returns></returns>
    public bool IsPassable(int edge_x, int edge_y, bool destroy_wall = false, Dictionary <TileEntity, bool> whiteList = null)
    {
        int entity_id = m_routeMap[edge_x, edge_y].EntityID;

        if (entity_id != 0)
        {
            //  连接器的情况下(是否通行根据墙标记确定)
            if (entity_id == m_wallLinkerId)
            {
                return(destroy_wall);
            }

            TileEntity entity = m_entityHash[entity_id];
            Assert.Should(entity != null);

            //  白名单中的对象可通行
            if (whiteList != null && whiteList.ContainsKey(entity))
            {
                return(true);
            }

            if (destroy_wall)
            {
                if (entity.entityType != EntityType.Wall && EntityTypeUtil.IsAnyBlockage(entity.entityType))
                {
                    return(false);
                }
            }
            else
            {
                if (EntityTypeUtil.IsAnyBlockage(entity.entityType))
                {
                    return(false);
                }
            }
        }
        return(true);
    }
예제 #19
0
    protected override List <TileEntity> TryLockTargeters(out TilePoint?_targetPos, out LinkedList <IMoveGrid> _targetRoute)
    {
        _targetPos   = null;
        _targetRoute = null;

        //  获取全部目标
        List <TileEntity> allTargeters = new List <TileEntity>();

        foreach (var entity in IsoMap.Instance.GetAllEntitiesByOwner(Entity.GetTargetOwner()))
        {
            if (entity.IsDead() || !EntityTypeUtil.IsAnyActor(entity.entityType))
            {
                continue;
            }

            //  不是限定类型的目标则过滤掉
            if (EntityTypeUtil.IsAnyActor(entity.entityType) && Attacker.model.onlyAttackTargetType != EntityType.None && Attacker.model.onlyAttackTargetType != entity.entityType)
            {
                continue;
            }

            allTargeters.Add(entity);
        }
        if (allTargeters.Count == 0)
        {
            return(null);
        }

        //  筛选1个直线最近的目标
        var     nearest_targets = FindTargetsNearestLinear(Attacker.GetCurrentPositionCenter(), allTargeters, 1);
        var     targeter        = nearest_targets[0];
        Vector2 p = targeter.GetCurrentPositionCenter();

        _targetPos = new TilePoint((int)p.x, (int)p.y);
        return(nearest_targets);
    }
예제 #20
0
 private bool MyTargeterFilter(TileEntity tar)
 {
     //  过滤掉治疗兵
     return(EntityTypeUtil.IsCurer(tar.model));
 }
예제 #21
0
    /// <summary>
    /// 类型获取对象列表
    /// </summary>
    /// <param name="ownerType"></param>
    /// <param name="aiType"></param>
    /// <param name="attacker"></param>
    /// <param name="includeFriend">是否包含友军(默认只获取建筑型目标)</param>
    /// <returns></returns>
    public List <TileEntity> GetEntitiesByTT(OwnerType ownerType, EntityAiType aiType, TileEntity attacker, bool includeFriend = false)
    {
        List <TileEntity> ret = new List <TileEntity>();

        foreach (TileEntity entity in m_entities[(int)ownerType])
        {
            if (entity == attacker)
            {
                continue;
            }

            if (entity.IsDead())
            {
                continue;
            }

            //  不是限定类型的目标则过滤掉
            if (EntityTypeUtil.IsAnyActor(entity.entityType) && attacker.model.onlyAttackTargetType != EntityType.None && attacker.model.onlyAttackTargetType != entity.entityType)
            {
                continue;
            }

            switch (aiType)
            {
            case EntityAiType.PriorToWall:
                if (entity.entityType == EntityType.Wall)
                {
                    ret.Add(entity);
                }
                break;

            case EntityAiType.PriorToTower:
                if (entity.entityType == EntityType.Tower)
                {
                    ret.Add(entity);
                }
                break;

            case EntityAiType.PriorToResource:
                if (entity.entityType == EntityType.Resource)
                {
                    ret.Add(entity);
                }
                break;

            default:
            {
                //  建筑目标
                if (EntityTypeUtil.IsAnyNonWallBuilding(entity.entityType))
                {
                    ret.Add(entity);
                }
                //  援军
                else if (includeFriend && entity.Friendly)
                {
                    ret.Add(entity);
                }
            }
            break;
            }
        }
        return(ret);
    }
예제 #22
0
    /// <summary>
    /// 初始化战斗中的防御区域
    /// </summary>
    public void InitGuardAreaMap()
    {
        //  1、初始化空
        m_guardAreaMap = new GuardAreaValue[Constants.EDGE_WIDTH, Constants.EDGE_HEIGHT];
        for (int x = 0; x < Constants.EDGE_WIDTH; x++)
        {
            for (int y = 0; y < Constants.EDGE_HEIGHT; y++)
            {
                m_guardAreaMap[x, y] = GuardAreaValue.NIL;
            }
        }

        //  2、根据建筑初始化防御区域,这里获取Defender方建筑。

        //  REMARK:扩展范围宽度 这个值可以调整
        int extendWidth = 2;

        foreach (var entity in GetAllEntitiesByOwner(OwnerType.Defender))
        {
            if (!EntityTypeUtil.IsAnyBuilding(entity.entityType))
            {
                continue;
            }

            int bgnX = Mathf.Max(entity.GetTilePos().x - extendWidth, 0);
            int endX = Mathf.Min(entity.GetTilePos().x + entity.width + extendWidth, Constants.EDGE_WIDTH - 1);

            int bgnY = Mathf.Max(entity.GetTilePos().y - extendWidth, 0);
            int endY = Mathf.Min(entity.GetTilePos().y + entity.height + extendWidth, Constants.EDGE_HEIGHT - 1);

            for (int x = bgnX; x <= endX; x++)
            {
                for (int y = bgnY; y <= endY; y++)
                {
                    m_guardAreaMap[x, y] = GuardAreaValue.Uninitialized;
                }
            }
        }

        //  3、计算每个防御区域格子贴图方向
        for (int x = 0; x < Constants.EDGE_WIDTH; x++)
        {
            for (int y = 0; y < Constants.EDGE_HEIGHT; y++)
            {
                if (m_guardAreaMap[x, y] == GuardAreaValue.NIL || m_guardAreaMap[x, y] != GuardAreaValue.Uninitialized)
                {
                    continue;
                }

                //  计算防御区域方向(默认为zero无方向)
                GuardAreaValue dir = GuardAreaValue.Zero;
                {
                    //  上
                    if (y + 1 < Constants.EDGE_HEIGHT && m_guardAreaMap[x, y + 1] == GuardAreaValue.NIL)
                    {
                        dir |= GuardAreaValue.Top;
                    }

                    //  下
                    if (y - 1 >= 0 && m_guardAreaMap[x, y - 1] == GuardAreaValue.NIL)
                    {
                        dir |= GuardAreaValue.Bottom;
                    }

                    //  左
                    if (x - 1 >= 0 && m_guardAreaMap[x - 1, y] == GuardAreaValue.NIL)
                    {
                        dir |= GuardAreaValue.Left;
                    }

                    //  右
                    if (x + 1 < Constants.EDGE_WIDTH && m_guardAreaMap[x + 1, y] == GuardAreaValue.NIL)
                    {
                        dir |= GuardAreaValue.Right;
                    }
                }

                //  设置新的方向
                m_guardAreaMap[x, y] = dir;
            }
        }

        if (m_guardAreaView == null)
        {
            var go = new GameObject();
            go.name         = "GuardAreaView";
            m_guardAreaView = go.AddComponent <GuardAreaView>();
            go.SetActive(false);
        }
        m_guardAreaView.Init(m_guardAreaMap);
    }
예제 #23
0
    public void PlayerPlaceSoldierOrSkill(int entityId, int x, int y, bool record = true)
    {
        if (!IsBattleStarted)
        {
            return;
        }
        var model = DataCenter.Instance.FindEntityModelById(entityId);

        //是否是使用的援军
        if (entityId == Constants.DENOTED_ARMY_ID)
        {
            if (!useDonatedArmy)
            {
                if (IsoMap.Instance.CanPlaceSoldier(x, y))
                {
                    useDonatedArmy = true;
                    Debug.Log("使用的援军");
                    //  战斗模式 [录像] 记录操作数据
                    if (record)
                    {
                        GameRecord.RecordPlaceSoldier(x, y, Constants.DENOTED_ARMY_ID);
                    }
                    var spawnHelper = new SpawnDonatedArmyHelper(DataCenter.Instance.Attacker.donatedArmies.Clone(), x, y);
                    UpdateManager.Instance.AddUpdate(spawnHelper);

                    DataCenter.Instance.Attacker.donatedArmies.Clear();
                }
                else
                {
                    GameTipsManager.Instance.ShowGameTips(EnumTipsID.Fight_10301);
                    IsoMap.Instance.ShowGuardAreaMap(true);
                }
            }
        }
        else if (EntityTypeUtil.IsSkill(model))
        {
            if (IsoMap.Instance.CanPlaceSkill(x, y))
            {
                foreach (var skillVo in DataCenter.Instance.Attacker.skills)
                {
                    if (skillVo.cid == model.baseId && skillVo.amount > 0)
                    {
                        if (record)
                        {
                            GameRecord.RecordPlaceSoldier(x, y, model.baseId);
                        }
                        GameSkillManager.Instance.AddSkill(model, x, y);
                        skillVo.amount--;
                        break;
                    }
                }
            }
            else
            {
                GameTipsManager.Instance.ShowGameTips(EnumTipsID.Fight_10301);
            }
        }
        else
        {
            if (IsoMap.Instance.CanPlaceSoldier(x, y))
            {
                foreach (var armyVo in DataCenter.Instance.Attacker.armies)
                {
                    if (armyVo.cid == model.baseId && armyVo.amount > 0)
                    {
                        //  战斗模式 [录像] 记录操作数据
                        if (record)
                        {
                            GameRecord.RecordPlaceSoldier(x, y, model.baseId);
                        }
                        //  创建对象
                        IsoMap.Instance.CreateEntityAt(OwnerType.Attacker, model.baseId, x, y);
                        armyVo.amount--;
                        break;
                    }
                }
            }
            else
            {
                GameTipsManager.Instance.ShowGameTips(EnumTipsID.Fight_10301);
                IsoMap.Instance.ShowGuardAreaMap(true);
            }
        }
        EventDispather.DispatherEvent(GameEvents.BATTLE_SPAWN, entityId);
    }
예제 #24
0
    /// <summary>
    /// 有单位死亡了
    /// </summary>
    /// <param name="entity"></param>
    public void OnEntityDestroy(TileEntity entity)
    {
        //如果死亡的是建筑
        if (EntityTypeUtil.IsAnyNonWallBuilding(entity.entityType))
        {
            defenderBuildingCount--;
            DestroyBuildingPercent = (float)(totalDefenderBuildingCount - defenderBuildingCount) / totalDefenderBuildingCount;
            //摧毁50% 获得一颗星
            if (!hasGotHalfDestroyStar && DestroyBuildingPercent > 0.5f)
            {
                hasGotHalfDestroyStar = true;
                BattleStar++;
            }
            Debug.Log("摧毁:" + DestroyBuildingPercent + "%");

            //摧毁基地 获得一颗星
            if (EntityTypeUtil.IsCenterBuilding(entity.model))
            {
                BattleStar++;
            }
            //摧毁100% 获得一颗星
            if (defenderBuildingCount == 0)
            {
                BattleStar++;
            }

            EventDispather.DispatherEvent(GameEvents.BATTLE_PROGRESS_CHANGE);
        }
        else if (entity.GetOwner() == OwnerType.Attacker && EntityTypeUtil.IsAnyActor(entity.entityType))
        {
            attackerArmyCount--;
            if (EntityTypeUtil.IsCurer(entity.model))
            {
                attackerCurerCount--;
            }
        }
        else if (entity.GetOwner() == OwnerType.Defender)
        {
            if (EntityTypeUtil.IsAnyActor(entity.entityType))
            {
                if (entity.Friendly)
                {
                    var found = false;
                    foreach (var killedDefenderDonatedArmy in killedDefenderDonatedArmies)
                    {
                        if (killedDefenderDonatedArmy.cid == entity.model.baseId)
                        {
                            killedDefenderDonatedArmy.amount++;
                            found = true;
                            break;
                        }
                    }
                    if (!found)
                    {
                        killedDefenderDonatedArmies.Add(new ArmyVO()
                        {
                            amount = 1, cid = entity.model.baseId
                        });
                    }
                }
            }
            else if (EntityTypeUtil.IsAnyTrap(entity.model))
            {
                brokenTraps.Add(entity.buildingVO.sid);
            }
        }
        CheckBattleEnd();
    }
예제 #25
0
    protected override List <TileEntity> TryLockTargeters(out TilePoint?_targetPos, out LinkedList <IMoveGrid> _targetRoute)
    {
        _targetPos   = null;
        _targetRoute = null;

        var allTargeters = IsoMap.Instance.GetAllEntitiesByOwner(Attacker.GetTargetOwner()).RubySelect(tar =>
        {
            if (tar.IsDead())
            {
                return(false);
            }

            //  不是限定类型的目标则过滤掉
            if (EntityTypeUtil.IsAnyActor(tar.entityType) && Attacker.model.onlyAttackTargetType != EntityType.None && Attacker.model.onlyAttackTargetType != tar.entityType)
            {
                return(false);
            }

            return(true);
        });

        if (allTargeters.Count == 0)
        {
            return(null);
        }

        List <TileEntity> targets = null;

        //  1、有优先目标的士兵先筛选优先目标
        if (Entity.aiType != EntityAiType.Other)
        {
            targets = allTargeters.RubySelect(tar => { return(tar.entityType == (EntityType)Entity.aiType); });
        }

        //  2、没有优先目标 or 优先目标为空 则优先筛选援军
        if (targets == null || targets.Count == 0)
        {
            targets = allTargeters.RubySelect(tar => { return(tar.Friendly); });
        }

        //  3、没有援军则筛选默认的非墙建筑
        if (targets.Count == 0)
        {
            targets = allTargeters.RubySelect(tar => { return(EntityTypeUtil.IsAnyNonWallBuilding(tar.entityType)); });
        }

        //  4、未找到目标直接返回
        if (targets.Count == 0)
        {
            return(null);
        }

#if REALTIME_AI
        //float t1 = UnityEngine.Time.realtimeSinceStartup;
        //for (int i = 0; i < 5000; i++)
        //{
        //    FindTargetsNearestTimeCost(Attacker, targets);
        //}
        //float t2 = UnityEngine.Time.realtimeSinceStartup;
        //Debug.Log(t2 - t1);
        //Debug.Break();

        //  筛选最近目标(最小时间 or 最近距离)
        return(SelectTargeters(targets, out _targetPos, out _targetRoute));
#else
        //  从备选列表中筛选最近的目标
        IEnumerator <IsoGridTarget> iterator = FindTargetsNearestTimeCost(Attacker, targets);
        if (iterator == null)
        {
            return(null);
        }

        //  延迟处理
        DelayManager.Instance.AddDelayAi <IsoGridTarget>(Attacker, OnDelayLockTargetersCompleted, iterator);
        Entity.State = EntityStateType.Thinking;
        return(null);
#endif
    }
예제 #26
0
    public void Create(WorldType worldType, CampVO defender = null, CampVO attacker = null, BattleReplayVO replayVO = null)
    {
        this.worldType = worldType;

        IsoMap.Instance.Clear();
        GameBulletManager.Instance.Init();
        GameEffectManager.Instance.Init();
        GameSkillManager.Instance.Init();
        UpdateManager.Instance.Clear();
        DelayManager.Instance.Init();
        BattleManager.Instance.Init();
        PoolManager.Instance.Clear();
        ResourceManager.Instance.ClearCache();

        //  初始化数据
        if (defender != null)
        {
            DataCenter.Instance.Defender = defender;
        }
        if (attacker != null)
        {
            DataCenter.Instance.Attacker = attacker;
        }

        //  REMARK:录像模式或回放模式从这里开始处理(之前的模块释放完毕,开始放置建筑之前。)
        if (worldType == WorldType.Battle)
        {
            GameRecord.StartRecord();
        }
        else if (worldType == WorldType.Replay)
        {
            Assert.Should(replayVO != null);
            DataCenter.Instance.Attacker = replayVO.attacker;
            DataCenter.Instance.Defender = replayVO.defender;
            GameRecord.StartReplay(replayVO);
        }

        //  添加建筑
        for (int i = 0; i < DataCenter.Instance.Defender.buildings.Count; i++)
        {
            var buildingVO  = DataCenter.Instance.Defender.buildings[i];
            var entityModel = DataCenter.Instance.FindEntityModelById(buildingVO.cid);
            Assert.Should(entityModel != null);
            var tileEntity = TileEntity.Create(OwnerType.Defender, entityModel);
            tileEntity.buildingVO = buildingVO;
            tileEntity.SetTilePosition(new TilePoint(buildingVO.x, buildingVO.y));
            IsoMap.Instance.ForceAddEntity(tileEntity);
        }

        //  添加工人,士兵(仅在建造模式下)
        if (worldType == WorldType.Home)
        {
            foreach (var armyVo in DataCenter.Instance.Defender.armies)
            {
                for (int i = 0; i < armyVo.amount; i++)
                {
                    var actor      = DataCenter.Instance.FindEntityModelById(armyVo.cid);
                    var tileEntity = TileEntity.Create(OwnerType.Defender, actor);
                    tileEntity.SetTilePosition(new TilePoint(0, 0));
                    IsoMap.Instance.ForceAddEntity(tileEntity);
                }
            }
            //  TODO:临时
            for (int i = 0; i < DataCenter.Instance.Defender.player.maxWorker; i++)
            {
                var actor      = DataCenter.Instance.FindEntityModelByResourceName("Pworker");
                var tileEntity = TileEntity.Create(OwnerType.Defender, actor);
                tileEntity.SetTilePosition(new TilePoint(5, 5));
                IsoMap.Instance.ForceAddEntity(tileEntity);
                tileEntity.HideEntity();
            }

            //计算最大人口
            DataCenter.Instance.TotalSpace = 0;
            foreach (var buildingVo in DataCenter.Instance.Defender.buildings)
            {
                var model = DataCenter.Instance.FindEntityModelById(buildingVo.cid);
                if (EntityTypeUtil.IsBarracks(model))
                {
                    DataCenter.Instance.TotalSpace += model.spaceProvide;
                }
            }
            //计算已使用人口
            DataCenter.Instance.SpaceUsed = 0;
            foreach (var armyVo in DataCenter.Instance.Defender.armies)
            {
                var model = DataCenter.Instance.FindEntityModelById(armyVo.cid);
                DataCenter.Instance.SpaceUsed += model.spaceUse * armyVo.amount;
            }
        }

        //把资源平均分配到资源库
        AverageResourceStorageComponents(ResourceType.Gold);
        AverageResourceStorageComponents(ResourceType.Oil);

        switch (worldType)
        {
        case WorldType.Battle:
            IsoMap.Instance.InitGuardAreaMap();
            IsoMap.Instance.ShowGuardAreaMap(false);
            CurrentWorldMode = new IsoWorldModeAttack();
            BattleManager.Instance.PreStartBattle();
            BattleUIManager.Instance.ShowBattleUI();
            break;

        case WorldType.Replay:
            CurrentWorldMode = new IsoWorldModeReplay();
            BattleManager.Instance.PreStartBattle();
            BattleManager.Instance.StartBattle();       //  TODO:暂时先放这里
            BattleUIManager.Instance.ShowReplayUI();
            break;

        case WorldType.Visit:
            CurrentWorldMode = new IsoWorldModeVisit();
            break;

        case WorldType.Home:
            CurrentWorldMode = new IsoWorldModeBuilder();
            HomeLandManager.Instance.ShowMyHomeLandUI();
            break;
        }
    }
예제 #27
0
    public static TileEntity Create(OwnerType owner, EntityModel model, bool isFriendly = false)
    {
        var entityObj  = LoadAndCreate(model);
        var tileEntity = new TileEntity();

        tileEntity.owner      = owner;
        tileEntity.model      = model;
        tileEntity.State      = EntityStateType.Idle;
        tileEntity.aiType     = (EntityAiType)model.targetType;
        tileEntity.entityType = model.entityType;
        tileEntity.Friendly   = isFriendly;
        if (model.tileSize > 0)
        {
            tileEntity.width = tileEntity.height = model.tileSize * 2;      //  REMARK:建筑实际占用格子扩大2倍
        }
        else
        {
            tileEntity.width = tileEntity.height = 1;
        }
        tileEntity.currentHp           = tileEntity.maxHp = Mathf.Max(model.hp, 1); //  REMARK:这里设置最大hp的最小值为1,不然对于工人等直接就是dead状态。
        tileEntity.animationNamePrefix = model.nameForResource + "_";

        //  REMARK:建筑按照格子建造、士兵按照边行走(所以士兵位置比建筑偏移(0.5,0.5))
        if (EntityTypeUtil.IsAnyActor(model.entityType))
        {
            tileEntity.renderTileSizeOffset = new Vector2((tileEntity.width * 0.5f) - 1.0f, (tileEntity.height * 0.5f) - 1.0f);
        }
        else
        {
            tileEntity.renderTileSizeOffset = new Vector2((tileEntity.width * 0.5f) - 0.5f, (tileEntity.height * 0.5f) - 0.5f);
        }
        tileEntity.view = entityObj.GetComponent <EntityViewComponent>();
        if (tileEntity.view == null)
        {
            if (EntityTypeUtil.IsAnyActor(tileEntity.entityType))
            {
                tileEntity.view = entityObj.AddComponent <ActorView>();
            }
            else if (EntityTypeUtil.IsAnyTower(tileEntity.entityType))
            {
                tileEntity.view = entityObj.AddComponent <TowerView>();
            }
            else
            {
                tileEntity.view = entityObj.AddComponent <EntityViewComponent>();
            }
        }

        if (EntityTypeUtil.IsAnyBuilding(tileEntity.entityType))//[建筑类]
        {
            //1格以上建筑有地皮
            if (model.tileSize > 2)
            {
                var floorBase = (GameObject)ResourceManager.Instance.LoadAndCreate(model.raceType + "/Entities/Misc/Floor4");//地皮
                tileEntity.view.AddSubView(floorBase, Vector3.zero);
                IsoHelper.FaceToWorldCamera(floorBase.transform);
                IsoHelper.MoveAlongCamera(floorBase.transform, Constants.FLOOR_Z_ORDER);
                floorBase.transform.localScale = Vector3.one * model.tileSize / 4;//REMARK 现有素材占4x4个tilesize
            }

            if (EntityTypeUtil.IsBarracks(model))
            {
                tileEntity.blockingRange = 3;
            }
            else
            {
                tileEntity.blockingRange = model.tileSize * 2 - 1;
            }
            tileEntity.AddComponent <ConstructBuildingComponent>();
            if (model.entityType == EntityType.Tower)
            {
                tileEntity.AddComponent <TowerComponent>();
            }
            else if (model.entityType == EntityType.Wall)
            {
                tileEntity.AddComponent <WallComponent>();
            }
            else if (EntityTypeUtil.IsGatherResourceBuilding(model))
            {
                tileEntity.AddComponent <GatherResourceBuildingComponent>();
            }
            else if (EntityTypeUtil.IsStorageResoruceBuilding(model))
            {
                tileEntity.AddComponent <ResourceStorageBuildingComponent>();
            }
            else if (EntityTypeUtil.IsArmyShop(model))
            {
                tileEntity.AddComponent <ProductSoldierBuildingComponent>();
            }
            else if (EntityTypeUtil.IsSkillShop(model))
            {
                tileEntity.AddComponent <ProductSkillBuildingComponent>();
            }
            else if (EntityTypeUtil.IsWorkerHouse(model))
            {
                tileEntity.AddComponent <WorkerHouseComponent>();
            }
            else if (EntityTypeUtil.IsFederal(model))
            {
                tileEntity.AddComponent <FederalComponent>();
            }
            else if (EntityTypeUtil.IsResearch(model))
            {
                tileEntity.AddComponent <ResearchBuildingComponent>();
            }
        }
        else if (EntityTypeUtil.IsAnyActor(model.entityType))   //[角色类]
        {
            //  战斗模式 家园模式 通用组件
            tileEntity.AddComponent <ActorMoveComponent>();
            if (GameWorld.Instance.worldType == WorldType.Home || GameWorld.Instance.worldType == WorldType.Visit) //家园模式 或者 访问模式
            {
                //  家园模式
                //  工人(添加工人组件&添加到工人小屋中)
                if (EntityTypeUtil.IsWorker(model))
                {
                    tileEntity.AddComponent <WorkmanComponent>();
                    var houseComp = IsoMap.Instance.GetWorkerHouseComponent();
                    Assert.Should(houseComp != null, "worker house is not exist...");
                    houseComp.AddAWorkman(tileEntity);
                }
                else
                {
                    tileEntity.AddComponent <ArmyComponent>();
                }
            }
            else                                                                                                    //战斗模式
            {
                tileEntity.AddComponent <GameBufferComponent>();
                //  设置士兵的监视范围(寻找目标用)    REMARK:设定为4.0秒可以移动的范围
                tileEntity.monitorRange = Mathf.Clamp(model.speed * 4.0f, 5.0f, 20.0f);
                if (EntityTypeUtil.IsBombMan(model))
                {
                    tileEntity.monitorRange = 0.0f;     //  暂时不限制炸弹人
                    tileEntity.AddComponent <BombManComponent>();
                }
                else if (EntityTypeUtil.IsCurer(model))
                {
                    tileEntity.AddComponent <CurerComponent>();
                }
                else if (isFriendly)                    //  友军/援军
                {
                    tileEntity.AddComponent <FriendComponent>();
                }
                else
                {
                    tileEntity.AddComponent <ActorComponent>();
                }
                //  除【友军/援军】以外添加拆墙组件(REMARK:友军/援军不可拆墙)
                if (!isFriendly)
                {
                    tileEntity.AddComponent <ActorDestroyWallComponent>();
                }
            }
        }
        else if (EntityTypeUtil.IsAnyTrap(model))   //  [陷阱类]
        {
            tileEntity.AddComponent <TrapComponent>();
        }
        Assert.Should((tileEntity.blockingRange == 0 || (tileEntity.blockingRange % 2) == 1), "invalid blockingRange...");
        Assert.Should(tileEntity.blockingRange <= tileEntity.width - 1 && tileEntity.blockingRange <= tileEntity.height - 1, "invalid blockingRange...");
        return(tileEntity);
    }
예제 #28
0
 /// <summary>
 /// 是否可飞行
 /// </summary>
 /// <returns></returns>
 public bool CanFlying()
 {
     return(EntityTypeUtil.IsFlyable(model.entityType));
 }
예제 #29
0
 /// <summary>
 /// 特性:是否可穿越墙(飞行兵种和特殊技能和援军)
 /// </summary>
 /// <returns></returns>
 public bool CanOverTheWall()
 {
     return(EntityTypeUtil.IsFlyable(model.entityType) || EntityTypeUtil.IsTraitOverTheWall(model) || this.Friendly);
 }