/** 寻路移动到(主动) */ public void moveTo(int unitMoveType, PosData pos, float dis) { if (!canMoveNow()) { return; } if (dis < 0f) { return; } //位置纠正 BaseGameUtils.makeTerrainPos(pos); //相同点 if (_d.baseMoveState == UnitBaseMoveState.MoveToPos && _moveTargetPos.isEquals(pos)) { return; } _isMoveToUnit = false; _moveTargetUnit.clear(); toMoveToList(unitMoveType, pos, MathUtils.floatEquals(dis, 0f) ? 0f:dis *dis); }
/** 服务器移动点组 */ public void onServerMovePosList(int type, SList <PosData> list, int moveTime) { PosData[] values = list.getValues(); for (int i = 0, len = list.size(); i < len; ++i) { BaseGameUtils.makeTerrainPos(values[i]); } clearMoveList(); _moveList.addAll(list); if (CommonSetting.needMoveLerp) { setServerMoveRatio(list.get(0), moveTime); } clearBaseMove(); _d.baseMoveState = UnitBaseMoveState.MoveToPos; _d.moveType = type; _currentMoveIsInitiative = false; _moveListIndex = 0; doMoveList(); }
protected override void afterReadConfig() { if (hasPrefab) { resourceNameT = BaseGameUtils.getUIModelResourceID(name + "UILogic", false); } }
public override void init() { base.init(); _camera = (_mainCameraTool = _scene.camera.mainCamera).camera; _resourceID = BaseGameUtils.getUIModelResourceID(getUIModelName()); _gameObject = AssetPoolControl.getAssetAndIncrease(AssetPoolType.UnitHead, _resourceID); if (_model == null) { _model = toCreateModel(); } if (_model != null) { _model.init(_gameObject); } (_transform = _gameObject.transform).SetParent(_scene.show.getUnitHeadRoot(), false); if (_model != null) { initModel(); } initShow(); refreshHeight(); }
/** 计算自身攻击值 */ public void calculateSelfAttackValue(UnitFightDataLogic attackerLogic) { isRecorded = true; AttackLevelConfig levelConfig = AttackLevelConfig.get(key, value); int aLen = levelConfig.varNumT; if (selfAttackValues == null || selfAttackValues.Length < aLen) { selfAttackValues = new int[aLen]; } int i = 0; int[] values = selfAttackValues; foreach (SkillVarConfig v in levelConfig.varConfigT) { foreach (int[] v2 in v.args) { values[i++] = BaseGameUtils.calculateOneSkillVarValue(v2, attackerLogic, null); } } }
/// <summary> /// 读完所有表后处理 /// </summary> public static void afterReadConfigAll() { firstLoadList = new IntList(); firstSceneLoadList = new IntList(); _dic.forEachValue(v => { int resourceID = LoadControl.getResourceIDByName(BaseGameUtils.getURLReplace(v.url)); switch (v.type) { case MarkResourceType.FirstLoad: { firstLoadList.add(resourceID); } break; case MarkResourceType.FirstSceneLoad: { firstSceneLoadList.add(resourceID); } break; } }); }
//--行为--// /** 创建玩家群 */ public void createRoleGroup(CreateRoleGroupData data) { if (isRoleGroupFull()) { me.warnLog("创建玩家群时,已达到数目限制"); return; } if (_config.createCostID > 0 && !me.bag.hasCost(_config.createCostID)) { me.warnLog("创建玩家群时,cost不满足"); return; } if (!me.role.checkRoleConditions(_config.createConditions, true)) { me.warnLog("创建玩家群时,condition不满足"); return; } if (_config.nameCharLimit > 0 && StringUtils.getCharMachineNum(data.name) > _config.nameCharLimit) { me.warnLog("创建玩家群时,名字过长"); return; } if (_config.noticeCharLimit > 0 && StringUtils.getCharMachineNum(data.notice) > _config.noticeCharLimit) { me.warnLog("创建玩家群时,公告过长"); return; } //敏感字 if (BaseGameUtils.hasSensitiveWord(data.name)) { Ctrl.warnLog("创建玩家群时,名字敏感"); GameC.info.showInfoCode(InfoCodeType.CreateRoleGroupFailed_nameIsSensitive); return; } //敏感字 if (BaseGameUtils.hasSensitiveWord(data.notice)) { Ctrl.warnLog("创建玩家群时,公告敏感"); GameC.info.showInfoCode(InfoCodeType.CreateRoleGroupFailed_noticeIsSensitive); return; } if (!canCreateRoleGroupEx()) { me.warnLog("创建玩家群时,ex不满足"); return; } //发送 me.send(FuncCreateRoleGroupRequest.create(_funcID, data)); }
/** 服务器移动点 */ public void onServerMovePos(int type, PosData pos, int moveTime) { BaseGameUtils.makeTerrainPos(pos); clearMoveList(); if (CommonSetting.needMoveLerp) { setServerMoveRatio(pos, moveTime); } baseMoveToPos(type, pos, false); }
/// <summary> /// 发送聊天 /// </summary> public void chat(ChatData data, int channel, long key) { ChatChannelConfig config = ChatChannelConfig.get(channel); //条件不满足 if (!me.role.checkRoleConditions(config.useConditions, true)) { me.warnLog("聊天条件不满足", channel); return; } ChatChannelData cData = getChatChannelData(channel, key); long now = me.getTimeMillis(); if (config.cd > 0 && (cData.lastChatTime + config.cd > now)) { me.warnLog("聊天cd中", channel); return; } if (config.costID > 0 && !me.bag.hasCost(config.costID)) { me.warnLog("聊天cost不足", channel); return; } //文字 if (data.type == ChatType.Text && BaseGameUtils.hasSensitiveWord(data.text)) { me.warnLog("聊天有屏蔽字内容", data.text); return; } if (config.cd > 0) { cData.lastChatTime = now; } //需要自行添加的 if (channel == ChatChannelType.Whisper) { RoleChatData rData = new RoleChatData(); rData.chatData = data; rData.showData = me.role.createRoleSimpleShowData(); rData.time = me.getTimeMillis(); rData.sendIndex = _chatReceiveIndex; //当前序号 onReceiveChat(rData, channel, key); } me.send(PlayerChatRequest.create(data, channel, key)); }
//--findPath--// /** 某点是否可用(地图范围内并且不是阻挡) */ public bool isPosEnabled(int moveType, PosData pos) { PosData originPos = _originPos; PosData endPos = _endPos; //超出地图边界 if (pos.x < originPos.x || pos.z < originPos.z || pos.x > endPos.x || pos.z > endPos.z) { return(false); } return(BaseGameUtils.isPosEnabled(moveType, pos)); }
public override void findRayPos(int moveType, PosData re, PosData from, float direction, float length) { re.y = from.y; polar2D(re, length, direction); addPos2D(re, from); clampPos(re); BaseGameUtils.makeTerrainPos(re); if (NavMesh.Raycast(from.getVector(), re.getVector(), out NavMeshHit hit, BaseC.constlist.mapMoveType_getMask(moveType))) { //赋值为碰撞点 re.setByVector(hit.position); } }
/** 获取阻挡类型 */ protected virtual int getBlockType(float x, float z) { Vector3 re = BaseGameUtils.getTerrainPos(new Vector3(x, 500, z)); NavMeshHit hit; if (NavMesh.SamplePosition(re, out hit, _halfGridSize, NavMesh.AllAreas)) { return(MapBlockType.Land); } //TODO:补充后续阻挡类型 return(MapBlockType.Block); }
public override int getSkillVarValueT(int varID, int adderID) { if (_unit == null) { UnitFightDataLogic self = null; if (adderID == -1) { self = this; } return(BaseGameUtils.calculateSkillVarValueFull(varID, self, this)); } return(base.getSkillVarValueT(varID, adderID)); }
/** 服务器特殊移动 */ public void onServerSpecialMove(PosDirData posDir, int id, int[] args, int lastTime, PosData baseMovePos) { if (_scene.driveType != SceneDriveType.ServerDriveDamage) { BaseGameUtils.makeTerrainPos(posDir.pos); BaseGameUtils.makeTerrainPos(baseMovePos); _unit.pos.setByPosDir(posDir); } clearBaseMove(); _d.specialMoveLastTime = lastTime; _d.baseMovePos = baseMovePos; //视为非新执行 toSpecialMove(id, args, false, false); }
/** 改公告 */ public void changeNotice(String notice) { if (!RoleGroupTitleConfig.get(_selfData.title).canChangeNotice) { me.warnLog("修改群公告时,权限不够"); return; } if (_config.noticeCharLimit > 0 && StringUtils.getCharMachineNum(notice) > _config.noticeCharLimit) { me.warnLog("修改群公告时,名字过长"); return; } //敏感字 if (BaseGameUtils.hasSensitiveWord(notice)) { Ctrl.warnLog("修改群公告时,名字敏感"); GameC.info.showInfoCode(InfoCodeType.CreateRoleGroupFailed_nameIsSensitive); return; } me.send(FuncChangeRoleGroupNoticeRequest.create(_funcID, groupID, notice)); }
protected override void afterReadConfig() { resourceNameT = BaseGameUtils.getUIModelResourceID(name + "UI", true); modalColorT = Color.blue; }
/** 刷新配置 */ public virtual void refreshConfig() { TextEnum.readConfig(); BaseGameUtils.initStrFilter(SensitiveWordConfig.getWordList(CommonSetting.languageType)); }
/** 执行攻击数据 */ private void toExecuteAttack(AttackData data) { Unit from = _scene.getFightUnit(data.fromInstanceID); if (from == null) { return; } Unit attacker = from.fight.getAttackerUnit(); if (attacker == null) { return; } int attackerInstanceID = attacker.instanceID; SkillTargetData tData = data.targetData; AttackConfig config = data.config; AttackLevelConfig levelConfig = data.levelConfig; //主目标 Unit mTarget = _scene.getFightUnit(tData.targetInstanceID); SList <Unit> tempTargets = new SList <Unit>(); //构造目标组 toMakeTargets(tempTargets, from, attacker, mTarget, tData, config, levelConfig); Unit target; //TODO:攻击前动作组 //如果跳过伤害阶段 if (config.passDamage) { for (int i = 0, len = tempTargets.size(); i < len; ++i) { target = tempTargets[i]; //不可被攻击 if (target.fight.getStatusLogic().cantBeAttackTarget()) { continue; } //添加buff if (levelConfig.addBuffProbID > 0) { if (attacker.fight.randomProb(levelConfig.addBuffProbID)) { int adderInstanceID = attackerInstanceID == target.instanceID ? -1 :attackerInstanceID; foreach (DIntData v in levelConfig.addBuffs) { target.fight.getBuffLogic().addBuff(v.key, v.value, adderInstanceID); } } } //有子弹 if (levelConfig.bullet.key > 0) { from.fight.createAndExecuteBullet(levelConfig.bullet.key, levelConfig.bullet.value, tData); } } } else { doAttackMoment(AttackMomentType.AttackBeforeHit, @from, attacker, null, data, null); if (!tempTargets.isEmpty()) { SList <Unit> tempKilledUnits = null; SList <DamageOneData> damageDataList = new SList <DamageOneData>(); StatusDataLogic attackerStatus = attacker.fight.getStatusLogic(); AttributeDataLogic attackerAttribute = attacker.fight.getAttributeLogic(); BuffDataLogic attackerBuffLogic = attacker.fight.getBuffLogic(); StatusDataLogic targetStatus; AttributeDataLogic targetAttribute; bool momentHitted = false; for (int i = 0, len = tempTargets.size(); i < len; ++i) { target = tempTargets[i]; targetStatus = target.fight.getStatusLogic(); targetAttribute = target.fight.getAttributeLogic(); //不可被攻击 if (targetStatus.cantBeAttackTarget()) { continue; } //上次血量 int lastHp = targetAttribute.getHp(); DamageOneData damageOneData = new DamageOneData(); damageOneData.instanceID = target.instanceID; damageDataList.add(damageOneData); SList <DIntData> damageList = new SList <DIntData>(); damageOneData.damages = damageList; damageOneData.isHit = toCountIsHit(data, attacker, target); doAttackMoment(AttackMomentType.BeAttackBeforeHit, target, target, attacker, data, damageOneData); int realDamage = 0; if (damageOneData.isHit) { if (!momentHitted) { momentHitted = true; doAttackMoment(AttackMomentType.AttackOnHitAnyTarget, @from, attacker, target, data, damageOneData); } if (target == mTarget) { doAttackMoment(AttackMomentType.AttackBeforeDamageMainTarget, @from, attacker, target, data, damageOneData); } doAttackMoment(AttackMomentType.AttackBeforeDamageEachTarget, @from, attacker, target, data, damageOneData); doAttackMoment(AttackMomentType.BeAttackBeforeDamage, target, target, attacker, data, damageOneData); //添加buff if (levelConfig.addBuffProbID > 0) { if (attacker.fight.randomProb(levelConfig.addBuffProbID)) { int adderInstanceID = attackerInstanceID == target.instanceID ? -1 :attackerInstanceID; foreach (DIntData v in levelConfig.addBuffs) { target.fight.getBuffLogic().addBuff(v.key, v.value, adderInstanceID); } } } //有子弹 DIntData levelConfigBullet; if ((levelConfigBullet = levelConfig.bullet).key > 0) { from.fight.createAndExecuteBullet(levelConfigBullet.key, levelConfigBullet.value, tData); } bool isCrit = damageOneData.isCrit = toCountIsCrit(data, attacker, target); SkillVarConfig varConfig; int[] damages; int damageType; int damageValue; int attackValue; int damageVarIndex = 0; //伤害组 for (int j = 0, jLen = levelConfig.damages.Length; j < jLen; ++j) { varConfig = levelConfig.varConfigT[j]; damages = levelConfig.damages[j]; damageType = damages[0]; if (data.isRecorded) { attackValue = BaseGameUtils.calculateSkillVarValueForSelf(varConfig, data.selfAttackValues, damageVarIndex, target.fight.getDataLogic()); damageVarIndex += varConfig.args.Length; } else { attackValue = BaseGameUtils.calculateSkillVarValueFull(varConfig, attacker.fight.getDataLogic(), target.fight.getDataLogic()); } damageValue = toCalculateDamage(data, damageType, damages, attackValue, isCrit, attackerAttribute, targetAttribute, attacker, target); if (damageValue > 0) { if (needDamageHurt(damageType)) { int rd = 0; if (!targetStatus.isDamageImmun()) { rd = takeDamage(damageType, damageValue, targetAttribute, target); } if (Global.damageValueUseRealDamage) { damageValue = rd; } realDamage += rd; } //TODO:反伤类 damageList.add(DIntData.create(damageType, damageValue)); } } if (realDamage > 0) { _scene.method.onUnitTakeDamage(target, realDamage, attacker); } if (target == mTarget) { doAttackMoment(AttackMomentType.AttackAfterDamageMainTarget, @from, attacker, target, data, damageOneData); } doAttackMoment(AttackMomentType.AttackAfterDamageEachTarget, @from, attacker, target, data, damageOneData); doAttackMoment(AttackMomentType.BeAttackAfterDamage, target, target, attacker, data, damageOneData); //扣除buff次数 attackerBuffLogic.subBuffNumArr(BuffSubNumType.UseAttackFromGroup, config.groups); attackerBuffLogic.subBuffNumArr(BuffSubNumType.MakeDamage, levelConfig.damageTypesT); target.fight.getBuffLogic().subBuffNumArr(BuffSubNumType.BeDamage, levelConfig.damageTypesT); //血减到0 if (lastHp > 0 && targetAttribute.getAttribute(AttributeType.Hp) <= 0 && targetStatus.isAlive()) { if (tempKilledUnits == null) { tempKilledUnits = new SList <Unit>(); } tempKilledUnits.add(target); } } //受伤(客户端受伤即使realDamage为0也需要) target.fight.onDamage(from, attacker, config, damageOneData); } onAttackDamage(from, config, tData); //处理击杀 if (tempKilledUnits != null) { for (int i = 0, len = tempKilledUnits.size(); i < len; ++i) { //活着 if ((target = tempKilledUnits[i]).fight.isAlive()) { //被击杀时刻 doAttackMoment(AttackMomentType.BeforeBeKill, target, target, attacker, data, null); //可被伤害击杀 if (!target.fight.getStatusLogic().cantBeKillByDamage()) { target.fight.doDead(attacker, config.killType); } //击杀时刻 doAttackMoment(AttackMomentType.AfterKill, from, attacker, target, data, null); } } } } doAttackMoment(AttackMomentType.AttackAfterHit, from, attacker, null, data, null); } }
//公式部分 /** 计算完整技能值 */ public int calculateSkillVar(int varID, Unit attacker, Unit target) { return(BaseGameUtils.calculateSkillVarValueFull(varID, attacker.fight.getDataLogic(), target.fight.getDataLogic())); }
protected void driveMoveFrame(float delay) { DriveLogic drive = _drive; _tempPos.clear(); DriveData dData = _d.driveData; float speedAbs = Math.Abs(drive.driveCurrentMoveSpeedM); if (speedAbs == 0 && dData.forward == 0) { if (dData.turn == 0 || !drive.canDriveTurnAtPivot) { return; } } //本次移动距离 float dis; //不启用加速度 if (drive.driveAccelerateSpeedM == 0) { dis = _useMoveSpeedM * delay * dData.forward; } else { //滑行 if (dData.forward == 0) { //需要的减速时间 float nTime = speedAbs / drive.driveGroundFrictionM; float useA = drive.driveCurrentMoveSpeedM > 0 ? -drive.driveGroundFrictionM : drive.driveGroundFrictionM; if (delay <= nTime) { float d = useA * delay; dis = drive.driveCurrentMoveSpeedM * delay + d * delay / 2; drive.driveCurrentMoveSpeedM += d; } //减到0 else { dis = drive.driveCurrentMoveSpeedM * nTime / 2; //vt/2 drive.driveCurrentMoveSpeedM = 0; } } else { float useA = drive.driveAccelerateSpeedM * dData.forward; bool sameSymbol = MathUtils.sameSymbol(useA, drive.driveCurrentMoveSpeedM); //符号相同,并且已经是最高速度 if (sameSymbol && speedAbs >= _useMoveSpeedM) { dis = drive.driveCurrentMoveSpeedM * delay; } else { //需要加速的时间 float nTime = (_useMoveSpeedM - (sameSymbol ? speedAbs : -speedAbs)) / drive.driveAccelerateSpeedM; //匀加速 if (delay <= nTime) { float d = useA * delay; dis = drive.driveCurrentMoveSpeedM * delay + d * delay / 2; drive.driveCurrentMoveSpeedM += d; } //到max else { dis = drive.driveCurrentMoveSpeedM * nTime + useA * nTime * nTime / 2; //到达最大速度 drive.driveCurrentMoveSpeedM = useA > 0 ? _useMoveSpeedM : -_useMoveSpeedM; //剩余时间用新速度 dis += (drive.driveCurrentMoveSpeedM * (delay - nTime)); } } } } bool hasPos = false; bool hasDir = false; if (dData.turn == 0) { if (dis != 0) { _scenePosLogic.calculateVectorByDir(_tempPos, _dir, dis); _scenePosLogic.addPos(_tempPos, _pos); hasPos = true; } else { return; } } else { if (dis != 0) { float angle; float radius; if (drive.canDriveTurnAtPivot) { angle = drive.driveDirectionSpeed * delay; radius = dis / angle; } else { radius = drive.driveTurnRadius; angle = dis / radius; } //正方向 float forward = (float)(radius * Math.Sin(angle)); //两侧 float side = (float)(radius * (1 - Math.Cos(angle))); _tempPos.x = forward; _tempPos.z = dData.turn * side; _tempPos.y = 0; //朝向向量 _scenePosLogic.rotatePosByDir2D(_tempPos, _dir); _scenePosLogic.addPos(_tempPos, _pos); //朝向修改 _dir.direction = MathUtils.directionCut(_dir.direction - (angle * dData.turn)); hasDir = true; hasPos = true; } else { if (drive.canDriveTurnAtPivot) { float angle = drive.driveDirectionSpeed * delay; _dir.direction = MathUtils.directionCut(_dir.direction - (angle * dData.turn)); hasDir = true; } else { return; } } } BaseGameUtils.makeTerrainPos(_tempPos); if (hasDir) { _unit.pos.onSetDir(); } if (hasPos) { if (_scenePosLogic.isPosEnabled(_moveType, _tempPos)) { _pos.copyPos(_tempPos); _unit.pos.onSetPos(); } else { // Ctrl.print("撞墙",_tempPos.toDataString()); } } if (drive.driveAccelerateSpeedM != 0 && drive.driveCurrentMoveSpeedM == 0f && dData.forward == 0 && _currentMoveIsInitiative) { if (!drive.canDriveTurnAtPivot || dData.turn == 0) { stopMove(); } } }
/** 获取机器人角色ID */ protected long getRobotPlayerID() { return(BaseGameUtils.makeCustomPlayerID(CustomPlayerType.SceneRobot, ++_robotPlayerIndex)); }
public override void init() { base.init(); _damageResourceID = BaseGameUtils.getUIModelResourceID("damageNum"); }
/** 获取某变量值表示的值(总值)(自身) */ public int getSkillVarValue(int varID) { return(BaseGameUtils.calculateSkillVarValueFull(varID, this, null)); }