"use strict";
|
cc._RF.push(module, '5ed83YCCWJFE6dExfhdam/J', 'battle_hook_model');
|
// Scripts/mod/battle/battle_hook_model.js
|
|
"use strict";
|
|
// --------------------------------------------------------------------
|
// @author: shiraho@syg.com(必填, 创建模块的人员)
|
// @description:
|
// 假战斗数据
|
// <br/>Create: new Date().toISOString()
|
// --------------------------------------------------------------------
|
// var BattleLoop = require("battle_loop")
|
var AniRes = ["hit_effect_list", // 受击点特效
|
"area_effect_list", // 范围特效
|
"act_effect_list", // 出手点特效
|
"bact_effect_list", // 施法特效
|
"trc_effect_list" // 弹道特效
|
];
|
|
var BattleResPool = require("battle_res_pool");
|
|
var BattleHookModel = cc.Class({
|
ctor: function ctor() {},
|
initConfig: function initConfig() {
|
this.unreal_battle_data = null; // 假战斗数据
|
|
this.battle_controller = require("battle_controller").getInstance();
|
this.battle_model = this.battle_controller.getModel();
|
this.skill_act = require("skill_act");
|
this.resetInitData();
|
},
|
// 更新假战斗数据
|
updateUnrealBattleData: function updateUnrealBattleData(data) {
|
this.unreal_battle_data = data;
|
},
|
// 返回假战斗数据
|
getUnrealBattleData: function getUnrealBattleData() {
|
return this.unreal_battle_data;
|
},
|
// 移除假战斗数据
|
deleteUnrealBattleData: function deleteUnrealBattleData() {
|
this.unreal_battle_data = null;
|
},
|
// 重置所有假战斗数据
|
resetInitData: function resetInitData() {
|
this.all_object = {}; //所有人物
|
|
this.group = 0;
|
this.act_playing = false;
|
this.one = null; //每个效果数据
|
|
this.ready_wait = 0; //角色等待出场
|
|
this.round_data = {}; //回合数据
|
|
this.order_list = [];
|
this.skill_plays_order_list = [];
|
this.round_data_temp = {}; //临时保存过期的回合数据
|
|
this.sum = 0; //准备人员统计
|
|
this.actor_sum = 0; //施法者总数
|
|
this.actor_play_sum = 0; //施法者动作完成总数
|
|
this.our_num = 0; //自己总数
|
|
this.is_real_battle_ready = false; //
|
|
this.res_num = 0;
|
this.res_list = {};
|
this.a_object_num = 1;
|
this.actor_plays_list = {};
|
},
|
// 假战斗初始化部分,
|
prepareStarBattle: function prepareStarBattle(start_cb) {
|
this.start_cb = start_cb;
|
this.resetInitData(); // 初始化所有的数据
|
|
var data = BattleLoop.init(this.unreal_battle_data);
|
this.startBattle(data);
|
},
|
startBattle: function startBattle(data) {
|
this.createBattleRole(data);
|
this.battle_controller.setIsNormaBattle(true);
|
},
|
// 返回战斗场景
|
getBattleScene: function getBattleScene() {
|
return this.battle_model.getBattleScene();
|
},
|
// 创建单位
|
createBattleRole: function createBattleRole(data) {
|
cc.log("创建假战斗的角色");
|
cc.log(data);
|
if (!data || !data.objects || !data.target_list) return;
|
if (!this.getBattleScene()) return;
|
this.ready_wait = 0;
|
this.sum = 0;
|
this.our_num = Object.keys(data.objects).length;
|
this.role_finish = 0;
|
var role_num = 0;
|
|
for (var key in data.objects) {
|
var play = data.objects[key];
|
this.group = play.group;
|
role_num++;
|
this.createRole(play, null, function () {
|
if (this.start_cb) {
|
this.start_cb();
|
this.start_cb = null;
|
}
|
|
this.role_finish += 1;
|
|
if (this.role_finish == role_num) {}
|
}.bind(this));
|
} // 创建敌对目标
|
|
|
for (var key in data.target_list) {
|
var _play = data.target_list[key];
|
this.createRole(_play);
|
}
|
},
|
// 创建举起单位
|
createRole: function createRole(role_data, is_next_offset, finish_cb) {
|
if (!this.getBattleScene()) return;
|
if (role_data == null) return;
|
var role_layer = this.getBattleScene().getBattleRoleLayer();
|
if (role_layer == null) return;
|
this.ready_wait += 1;
|
|
if (is_next_offset == null) {
|
is_next_offset = false;
|
}
|
|
var BattleRole = require("battle_role");
|
|
var role = new BattleRole(is_next_offset);
|
role.createRole(role_layer, role_data, false, false, false, finish_cb);
|
this.all_object[role_data.pos] = role;
|
},
|
|
/**
|
* 技能播报对象列表,返回的是一个数组
|
* @param {*} target
|
*/
|
getSkillPlayData: function getSkillPlayData(target) {
|
if (this.actor_plays_list[target]) {
|
return this.actor_plays_list[target];
|
}
|
},
|
// 更新技能
|
updateActorPlaysList: function updateActorPlaysList(data) {
|
if (data) {
|
if (this.actor_plays_list[data.actor] == null) {
|
this.actor_plays_list[data.actor] = [];
|
}
|
|
this.actor_plays_list[data.actor].push(data);
|
}
|
},
|
// 开始处理处理技能播报
|
handleSkillPlayData: function handleSkillPlayData(data, init_cb) {
|
this.preloadBattleRes(data, function (data) {
|
if (init_cb) {
|
init_cb(function (data) {
|
cc.log("开始技能播报");
|
this.skill_plays_order_list = [];
|
this.act_playing = false;
|
|
if (data) {
|
this.playSkillPlayData(data);
|
}
|
}.bind(this, data));
|
} else {
|
this.skill_plays_order_list = [];
|
this.act_playing = false;
|
|
if (data) {
|
this.playSkillPlayData(data);
|
}
|
}
|
}.bind(this, data));
|
},
|
// 技能播报
|
playSkillPlayData: function playSkillPlayData(data) {
|
if (!data) return;
|
|
for (var j = 0; j < data.skill_plays.length; j++) {
|
var skill_element = data.skill_plays[j];
|
|
for (var i = 0; i < skill_element.effect_play.length; i++) {
|
var effect_element = skill_element.effect_play[i];
|
|
if (this.round_data_temp[effect_element.order] == null) {
|
this.round_data_temp[effect_element.order] = [];
|
this.skill_plays_order_list.push({
|
skill_order: effect_element.order
|
});
|
}
|
|
effect_element.skill_bid = skill_element.skill_bid;
|
effect_element.index = i;
|
effect_element.skill_order = skill_element.order;
|
effect_element.talk_content = skill_element.talk_content;
|
effect_element.talk_pos = skill_element.talk_pos;
|
this.round_data_temp[effect_element.order].push(effect_element);
|
}
|
} // 对出手进行排序
|
|
|
this.skill_plays_order_list.sort(function (a, b) {
|
return a.skill_order - b.skill_order;
|
});
|
this.analyseTempRoundData();
|
},
|
// 分析当前的播报数据
|
analyseTempRoundData: function analyseTempRoundData() {
|
this.order_list = [];
|
this.round_data = {};
|
|
if (Object.keys(this.round_data_temp).length > 0) {
|
for (var index = 0; index < this.skill_plays_order_list.length; index++) {
|
var element = this.skill_plays_order_list[index];
|
var temp = this.round_data_temp[element.skill_order];
|
|
for (var i = 0; i < temp.length; i++) {
|
var one_temp = temp[i];
|
|
if (this.round_data[one_temp.order] == null) {
|
this.round_data[one_temp.order] = {};
|
this.order_list.push({
|
order: one_temp.order,
|
target: one_temp.target
|
});
|
}
|
|
if (this.round_data[one_temp.order][one_temp.actor] == null) {
|
this.round_data[one_temp.order][one_temp.actor] = {
|
order: one_temp.order,
|
actor: one_temp.actor,
|
target: one_temp.target,
|
skill_bid: one_temp.skill_bid,
|
index: one_temp.index,
|
talk_content: one_temp.talk_content,
|
talk_pos: one_temp.talk_pos,
|
target_list: []
|
};
|
}
|
|
var object = this.round_data[one_temp.order][one_temp.actor];
|
object.target_list.push(one_temp);
|
}
|
} // 对出售惊醒排序
|
|
|
this.order_list.sort(function (a, b) {
|
return a.order - b.order;
|
});
|
this.round_data_temp = {};
|
}
|
|
this.round();
|
},
|
// 处理回合播报
|
round: function round() {
|
this.round_data_temp = {};
|
this.actor_sum = 0;
|
this.actor_play_sum = 0;
|
this.next_round = null;
|
this.cur_round = null;
|
|
if (this.order_list.length == 0) {
|
if (!this.is_real_battle_ready) {
|
this.act_playing = false;
|
}
|
} else {
|
var first_data = this.order_list.shift();
|
var round_data = this.round_data[first_data.order];
|
|
if (this.order_list.length > 0) {
|
var second_order = this.order_list[0].order;
|
var second_data = this.round_data[second_order]; // 找到下一个回合播报,于当前回合播报做比较判断是不是多段攻击,从而在当前播报结束之后,是否需要重置
|
|
for (var actor in second_data) {
|
if (this.next_round == null) {
|
this.next_round = second_data[actor];
|
break;
|
}
|
}
|
}
|
|
for (var actor in round_data) {
|
var round_one_temp = round_data[actor];
|
|
if (this.cur_round == null) {
|
this.cur_round = round_one_temp;
|
}
|
|
if (round_one_temp.target_list.length > 0) {
|
var attacker = this.getBattleRoleByPos(round_one_temp.actor);
|
|
if (attacker) {
|
this.actor_sum = this.actor_sum + 1;
|
this.initOrder(attacker, round_one_temp);
|
} else {
|
this.round();
|
}
|
} else {
|
this.round();
|
}
|
}
|
}
|
},
|
// 初始化播报
|
initOrder: function initOrder(attacker, one) {
|
one.target_list.sort(function (a, b) {
|
return a.index - b.index;
|
});
|
var list = one.target_list;
|
var col_target = list[0].target;
|
|
if (col_target > GIRD_POS_OFFSET) {
|
col_target = col_target - GIRD_POS_OFFSET;
|
}
|
|
var col = Pos_To_Col[col_target - 1];
|
attacker.col = col;
|
attacker.is_round = false;
|
attacker.attacker_info = one;
|
attacker.skill_data = gdata('skill_data', 'data_get_skill', one.skill_bid);
|
attacker.target_pos = attacker.grid_pos;
|
attacker.play_order_index = one.target_list[0].effect_bid;
|
this.battle_model.calcTargetPos(attacker, this.all_object); // 如果没有效果id则不处理,所有播报驱动都是效果驱动
|
|
if (attacker.play_order_index == null || attacker.play_order_index == 0) {
|
this.round();
|
return;
|
}
|
|
var effect_config = gdata('skill_data', 'data_get_effect', attacker.play_order_index);
|
|
if (effect_config) {
|
attacker.play_order = Utils.deepCopy(effect_config.action_list); // 动作列表
|
|
attacker.shake_id = effect_config.shake_id; // 震屏ID
|
|
attacker.effect_type = effect_config.effect_type; // 效果类型
|
|
attacker.play_stand = effect_config.play_stand; // 是否收招
|
|
attacker.anime_res = effect_config.anime_res; // 攻击动作资源
|
|
attacker.split_hurt = effect_config.split_hurt;
|
attacker.hit_action = effect_config.hit_action; // 受击处理
|
|
attacker.effect_desc = effect_config.effect_desc; // 效果飘字
|
|
attacker.is_must_die = effect_config.is_must_die; // 这个效果是否触发无法复活
|
|
attacker.anime_user_atk = effect_config.anime_user_atk; // 攻击动作名
|
|
attacker.attack_sound = effect_config.attack_sound; // 攻击音效
|
|
attacker.ready_sound = effect_config.ready_sound; // 准备音效
|
|
attacker.shout_trick = effect_config.shout_trick; // 喊招音效
|
|
attacker.hit_sound = effect_config.hit_sound; // 受击音效
|
|
attacker.hit_effect_list = Utils.deepCopy(this.battle_model.getCurEffectList(effect_config.hit_effect_list)); // 记录打击特效列表
|
|
attacker.area_effect_list = Utils.deepCopy(this.battle_model.getCurEffectList(effect_config.area_effect_list)); // 记录范围人物特效
|
|
attacker.act_effect_list = Utils.deepCopy(this.battle_model.getCurEffectList(effect_config.act_effect_list)); // 记录出手点特效
|
|
attacker.bact_effect_list = Utils.deepCopy(this.battle_model.getCurEffectList(effect_config.bact_effect_list)); // 记录施法特效
|
|
attacker.trc_effect_list = Utils.deepCopy(this.battle_model.getCurEffectList(effect_config.trc_effect_list)); // 记录弹道特效
|
} // 是否有群攻
|
|
|
if (attacker.area_effect_list.length > 0) {
|
attacker.attacker_info.is_calc = false;
|
attacker.in_area_effect = true;
|
attacker.area_hit_num = 1;
|
attacker.area_hit_time = 0;
|
} else {
|
attacker.in_area_effect = false;
|
}
|
|
var start_attack = function () {
|
this.playOrder(attacker);
|
}.bind(this);
|
|
this.talk(attacker, start_attack);
|
this.act_playing = true;
|
},
|
// 正式播报
|
playOrder: function playOrder(attacker) {
|
if (attacker == null) {
|
return;
|
} // 没有技能效果的时候,直接移除掉
|
|
|
if (attacker.play_order_index == null || attacker.play_order_index == 0) {
|
return;
|
} // 每个动作的计数器,当一个动作开始之后开始计数,为0标识这个动作做完了
|
|
|
attacker.wait_act = 0;
|
|
if (attacker.play_order == null || attacker.play_order.length == 0) {
|
this.actor_play_sum += 1; // 初始施法者战力动作
|
|
this.resetAttackerStandStatus(attacker);
|
|
if (!attacker.is_die) {
|
attacker.resetZOrder();
|
}
|
|
if (!attacker.is_round) {
|
if (this.actor_play_sum >= this.actor_sum) {
|
this.round();
|
}
|
}
|
} else {
|
var index = attacker.play_order.shift();
|
var act = this.battle_model.singleAct(index, attacker);
|
|
if (act) {
|
attacker.runAction(act);
|
}
|
}
|
},
|
// 喊话回调
|
talk: function talk(attacker, callback) {
|
var msg = attacker.attacker_info.talk_content || "";
|
var actor = attacker.attacker_info.talk_pos;
|
|
if (msg == "") {
|
if (callback) {
|
callback();
|
}
|
|
return;
|
} // 然后播放气泡.....
|
|
|
if (callback) {
|
callback();
|
}
|
},
|
// 一个假战斗怪物被杀死之后
|
playEnd: function playEnd(pos) {
|
if (!this.getBattleScene()) return;
|
BattleLoop.playEnd(pos);
|
this.delBattleRoleByPos(pos);
|
|
for (var key in this.all_object) {
|
var battle_role = this.all_object[key];
|
|
if (battle_role) {
|
var pos = battle_role.pos;
|
|
if (this.actor_plays_list[pos]) {
|
this.actor_plays_list[pos].shift();
|
var temp_data = this.actor_plays_list[pos][0];
|
|
if (temp_data) {
|
this.handleSkillPlayData(temp_data);
|
}
|
}
|
}
|
}
|
},
|
// 下一个怪,在创建怪物定时创建下一波的时候,以及打死一只怪物之后调用创建下一波怪物
|
updateNextRoundData: function updateNextRoundData() {
|
// return;
|
if (!this.getBattleScene()) return;
|
var target_list = [];
|
var next_data = BattleLoop.nextTarget();
|
if (!next_data) return;
|
this.getMoveTime(next_data.actor, next_data.effect_bid);
|
target_list.push(next_data);
|
|
for (var index = 0; index < target_list.length; index++) {
|
var element = target_list[index];
|
var next_col = [element.pos - GIRD_POS_OFFSET - 1];
|
|
if (element.group == 2) {
|
this.createRole(element, this.checkColObjet(next_col));
|
}
|
}
|
},
|
// 判断当前pos的行上面是否已经有单位了
|
checkColObjet: function checkColObjet(next_col) {
|
if (!this.getBattleScene()) {
|
return false;
|
}
|
|
var had_col = false;
|
|
for (var key in this.all_object) {
|
var element = this.all_object[key];
|
|
if (element && element.group == 2) {
|
var cur_col = Pos_To_Col[element.pos - GIRD_POS_OFFSET - 1];
|
|
if (cur_col == next_col) {
|
had_col = true;
|
}
|
}
|
}
|
|
return had_col;
|
},
|
// 获取移动时间
|
getMoveTime: function getMoveTime(actor, play_order_index) {
|
var move_time = 200;
|
var skill_config = gdata('skill_data', 'data_get_effect', play_order_index);
|
if (!skill_config) return;
|
var battle_role = this.getBattleRoleByPos(actor);
|
if (!battle_role) return;
|
var spine_name = battle_role.spine_name; // 模型id
|
|
var play_order_anime_res = skill_config.anime_res; // 该效果所需要播放的动作文件
|
|
var action_name = PlayerAction.action_1; // 所播放的动作
|
|
var temp_config = null;
|
var act_config = Config.battle_act_data.data_info[spine_name];
|
|
if (!act_config || !act_config[play_order_anime_res] || !act_config[play_order_anime_res][action_name]) {
|
temp_config = Config.battle_act_data.data_info[0]["action1"]["action1"];
|
} else {
|
temp_config = act_config[play_order_anime_res][action_name];
|
}
|
|
if (temp_config) {
|
move_time = temp_config.move_delay_time + temp_config.move_time;
|
}
|
|
this.setAckMoveTime(1000 * move_time / 60); //由于配置是继承lua那边的.按照每帧配置所以转一下到毫秒
|
},
|
// 保存下一个播报需要移动的时间
|
setAckMoveTime: function setAckMoveTime(time) {
|
this.move_time = time;
|
},
|
// 用于处理播假战斗的时间
|
getFinalMoveTime: function getFinalMoveTime() {
|
return this.move_time || 200;
|
},
|
// 获取指定单位
|
getBattleRoleByPos: function getBattleRoleByPos(pos) {
|
if (this.all_object[pos]) {
|
return this.all_object[pos];
|
}
|
},
|
// 移除一个对象
|
delBattleRoleByPos: function delBattleRoleByPos(pos) {
|
var target = this.getBattleRoleByPos(pos);
|
|
if (target) {
|
target.deleteRole();
|
}
|
|
this.all_object[pos] = null;
|
},
|
// 清空所有单位
|
clearRealRole: function clearRealRole() {
|
this.battle_controller.setIsNormaBattle(false);
|
|
if (Object.keys(this.all_object).length == 0) {
|
return;
|
}
|
|
for (var key in this.all_object) {
|
gcore.Timer.del("attackerActTimeout" + key);
|
var battle_role = this.all_object[key];
|
|
if (battle_role) {
|
battle_role.deleteRole();
|
}
|
}
|
|
this.all_object = {};
|
},
|
// 回合播报结束设置施法者战力动作,假战斗必定重置移动动作
|
resetAttackerStandStatus: function resetAttackerStandStatus(attacker) {
|
if (this.getBattleScene() == null || attacker == null) {
|
return;
|
}
|
|
this.skill_act.setAnimation(attacker, PlayerAction.run, true);
|
},
|
// 播放伤害和受击
|
playMagic: function playMagic(attacker, effect_play, no_die) {
|
if (!this.getBattleScene()) return;
|
if (!attacker || !effect_play || !effect_play.target) return;
|
var target = this.getBattleRoleByPos(effect_play.target);
|
if (!target) return;
|
var dmg = Math.floor(effect_play.hurt);
|
var is_dead = 0;
|
|
if (effect_play.hp <= 0) {
|
is_dead = 1;
|
} // 要先处理受击,再更新血量,要不然播放死亡动作会被受击给重置掉了
|
|
|
if (!target.is_hurt_play) {
|
target.is_hurt_play = true;
|
this.battle_model.playHurtEffect(attacker, target);
|
|
if (attacker.pos != target.pos && dmg < 0 && attacker.group != target.group) {
|
// 播放受击动作
|
if (attacker.hit_action != "no-hurt") {
|
this.skill_act.hurt(attacker, target, attacker.hit_action, false);
|
}
|
}
|
}
|
|
this.battle_model.updateTargetHp(attacker, target, dmg, is_dead, 1, effect_play);
|
},
|
getEffectRes: function getEffectRes() {},
|
// 开始准备战斗资源
|
preloadBattleRes: function preloadBattleRes(data, finish_cb) {
|
// skill_plays
|
cc.log("开始加载假战斗资源");
|
var battle_res = {};
|
|
for (var skill_i in data.skill_plays) {
|
var skill_data = data.skill_plays[skill_i];
|
|
for (var effect_i in skill_data.effect_play) {
|
var effect_data = skill_data.effect_play[effect_i];
|
var effect_config = gdata('skill_data', 'data_get_effect', effect_data.effect_bid);
|
var actor = this.all_object[effect_data.actor];
|
var target = this.all_object[effect_data.target];
|
if (!effect_data.effect_bid) continue;
|
var effect_config = gdata('skill_data', 'data_get_effect', effect_data.effect_bid);
|
if (!effect_config) continue; // 攻击动作资源
|
|
if (effect_config.anime_res && actor) {
|
var anime_res_path = actor.getResPath(effect_config.anime_res);
|
if (anime_res_path) battle_res[anime_res_path] = true;
|
} // 受击动作资源
|
|
|
if (effect_config.hit_action && target) {
|
var hit_action_path = target.getResPath(effect_config.hit_action);
|
|
if (effect_config.hit_action != "no-hurt") {
|
if (hit_action_path) battle_res[hit_action_path] = true;
|
}
|
}
|
|
for (var effect_d in AniRes) {
|
var effct_list = this.getCurEffectList(effect_config[AniRes[effect_d]]);
|
|
for (var effect_i in effct_list) {
|
var effect_info = effct_list[effect_i];
|
|
if (effect_info.res_up) {
|
var action_name = PlayerAction.action; // if (effect_info.up_action_name)
|
// action_name = effect_info.up_action_name;
|
|
var res_path = "spine/" + effect_info.res_up + "/" + action_name;
|
battle_res[res_path] = true;
|
}
|
|
if (effect_info.res_down) {
|
var action_name = PlayerAction.action; // if (effect_info.down_action_name) {
|
// action_name = effect_info.down_action_name;
|
// }
|
|
var res_path = "spine/" + effect_info.res_down + "/" + action_name;
|
battle_res[res_path] = true;
|
}
|
}
|
}
|
}
|
}
|
|
var total_num = 0;
|
var finish_num = 0;
|
|
for (var battle_i in battle_res) {
|
total_num++;
|
var skeleton_path = battle_i + ".atlas";
|
BattleResPool.getInstance().preLoadRes(skeleton_path, function (res_object) {
|
finish_num++;
|
|
if (finish_num == total_num) {
|
cc.log("假战斗资源加载完成");
|
|
if (finish_cb) {
|
finish_cb();
|
}
|
}
|
}.bind(this));
|
}
|
},
|
// 效果列表
|
getCurEffectList: function getCurEffectList(list) {
|
var effect_list = [];
|
|
for (var index = 0; index < list.length; index++) {
|
var element = list[index];
|
var effect_data = Config.skill_data.data_get_effect_data[element];
|
effect_list.push(effect_data);
|
}
|
|
return effect_list;
|
}
|
});
|
|
cc._RF.pop();
|