/// <summary> /// 查找一个军营 /// </summary> /// <returns></returns> private TileEntity FindCampEntity() { var allEntities = IsoMap.Instance.GetAllEntitiesByOwner(Entity.GetOwner()); // 这里随便寻找一个军营 TODO:后期根据士兵分配选择一个合适的军营 return(allEntities.RubyFind(entity => EntityTypeUtil.IsBarracks(entity.model))); }
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)); }
/// <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); } } }
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(); } }
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 }; }
/// <summary> /// 获取自身的战斗目标的阵营 /// </summary> /// <returns></returns> public OwnerType GetTargetOwner() { // 治疗者(获取自身 if (EntityTypeUtil.IsCurer(model)) { return(GetOwner()); } // 其他(获取对方 else { return(GetPeerOwner()); } }
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(""); }
/// <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); }
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 }); }
/// <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); }
/// <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); } }
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); } }
/// <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); } }
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(); } } }
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(); } } }
/// <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); }
/// <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); }
/// <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); }
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); }
private bool MyTargeterFilter(TileEntity tar) { // 过滤掉治疗兵 return(EntityTypeUtil.IsCurer(tar.model)); }
/// <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); }
/// <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); }
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); }
/// <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(); }
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 }
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; } }
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); }
/// <summary> /// 是否可飞行 /// </summary> /// <returns></returns> public bool CanFlying() { return(EntityTypeUtil.IsFlyable(model.entityType)); }
/// <summary> /// 特性:是否可穿越墙(飞行兵种和特殊技能和援军) /// </summary> /// <returns></returns> public bool CanOverTheWall() { return(EntityTypeUtil.IsFlyable(model.entityType) || EntityTypeUtil.IsTraitOverTheWall(model) || this.Friendly); }