Files
heros/assets/script/game/hero/Mon.ts
2025-07-28 00:14:20 +08:00

177 lines
6.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { instantiate, Node, Prefab, Vec3 ,v3,resources,SpriteFrame,Sprite,SpriteAtlas, BoxCollider2D} from "cc";
import { oops } from "../../../../extensions/oops-plugin-framework/assets/core/Oops";
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
import { smc } from "../common/SingletonModuleComp";
import { HeroViewComp } from "./HeroViewComp";
import { BoxSet, FacSet } from "../common/config/BoxSet";
import { HeroInfo } from "../common/config/heroSet";
import { MonModelComp } from "./MonModelComp";
import { BattleMoveComp } from "../common/ecs/position/BattleMoveComp";
import { SkillConComp } from "./SkillConComp";
import { BuffAttr } from "../common/config/SkillSet";
/** 角色实体 */
@ecs.register(`Monster`)
export class Monster extends ecs.Entity {
HeroModel!: MonModelComp;
HeroView!: HeroViewComp;
BattleMove!: BattleMoveComp;
protected init() {
this.addComponents<ecs.Comp>(
BattleMoveComp,
MonModelComp,
);
}
destroy(): void {
this.remove(HeroViewComp);
this.remove(MonModelComp);
super.destroy();
}
/** 加载角色 */
load(pos: Vec3 = Vec3.ZERO,scale:number = 1,uuid:number=1001,is_boss:boolean=false,is_call:boolean=false,lv:number=1,rogueBuffData?: any[], rogueHp?: number, rogueAttack?: number) {
scale=-1
let box_group=BoxSet.MONSTER
console.log("mon load",uuid)
// this.addComponents<ecs.Comp>( MonModelComp, BattleMoveComp);
var scene = smc.map.MapView.scene;
this.brith_light(pos,scene)
var path = "game/heros/"+HeroInfo[uuid].path;
var prefab: Prefab = oops.res.get(path, Prefab)!;
var node = instantiate(prefab);
node.parent = scene.entityLayer!.node!
const collider = node.getComponent(BoxCollider2D);
if (collider) collider.enabled = false; // 先禁用 // 延迟一帧启用碰撞体
node.setPosition(pos)
this.hero_init(uuid,node,scale,box_group,is_boss,is_call,lv,rogueBuffData,rogueHp,rogueAttack)
oops.message.dispatchEvent("monster_load",this)
// 初始化移动参数
const move = this.get(BattleMoveComp);
move.direction = -1; // 向左移动
move.targetX = -800; // 左边界
}
brith_light(pos:Vec3,scene:any){
var path = "game/skills/map_birth";
var prefab: Prefab = oops.res.get(path, Prefab)!;
var node = instantiate(prefab);
node.parent = scene.entityLayer!.node!
node.setPosition(pos)
}
hero_init(uuid:number=1001,node:Node,scale:number=1,box_group=BoxSet.HERO,is_boss:boolean=false,is_call:boolean=false,lv:number=1,rogueBuffData?: any[], rogueHp?: number, rogueAttack?: number) {
var hv = node.getComponent(HeroViewComp)!;
hv.hide_info()
// console.log("hero_init",buff)
let hero= HeroInfo[uuid] // 共用英雄数据
hv.scale = scale;
hv.fac = FacSet.MON;
hv.type = hero.type;
hv.is_boss = is_boss;
if(!is_boss){
hv.is_kalami=true
}
hv.box_group = box_group;
hv.hero_uuid= uuid;
hv.hero_name= hero.name;
hv.speed =hv.ospeed = hero.speed;
hv.dis = hero.dis;
// 肉鸽模式使用固定数值,否则使用等级计算
if (rogueHp !== undefined && rogueAttack !== undefined) {
// 肉鸽模式:使用固定数值
hv.hp = hv.hp_max = rogueHp;
hv.ap = rogueAttack;
hv.ap_base = rogueAttack;
console.log(`[Monster-Rogue]: 怪物${hero.name} - 固定HP:${rogueHp}, 固定AP:${rogueAttack}`);
} else {
// 普通模式根据Design.md设计文档计算怪物等级属性
const baseHp = hero.hp;
const baseAp = hero.ap;
// 怪物属性随等级增长 (根据Design.md中的公式)
// HP增长: Math.floor(baseHp * (1 + (level-1) * 0.3))
// AP增长: Math.floor(baseAp * (1 + (level-1) * 0.25))
const levelHp = Math.floor(baseHp * (1 + (lv - 1) * 0.5));
const levelAp = Math.floor(baseAp * (1 + (lv - 1) * 0.1));
hv.hp = hv.hp_max = levelHp;
hv.ap = levelAp;
hv.ap_base=levelAp
console.log(`[Monster]: 怪物${hero.name}(等级${lv}) - 基础HP:${baseHp}->等级HP:${levelHp}, 基础AP:${baseAp}->等级AP:${levelAp}`);
}
hv.cd = hero.cd
hv.atk_skill=hero.skills[0]
// 处理原有Buff
hero.buff.forEach((buff:any)=>{
this.applyBuffToMonster(hv, buff);
})
// 处理肉鸽模式的词条Buff
if (rogueBuffData && rogueBuffData.length > 0) {
console.log(`[Monster]: 怪物${hero.name}应用肉鸽词条:`, rogueBuffData);
rogueBuffData.forEach((buff:any)=>{
this.applyBuffToMonster(hv, buff);
})
}
// 重新计算最终HP因为buff可能修改了hp_max
hv.hp = hv.hp_max;
this.add(hv);
}
/**
* 应用Buff到怪物的通用方法
*/
private applyBuffToMonster(hv: any, buff: any) {
switch(buff.buff_type){
case BuffAttr.CRITICAL:
hv.crit+=buff.value
break
case BuffAttr.CRITICAL_DMG:
hv.crit_d+=buff.value
break
case BuffAttr.DODGE:
hv.dod+=buff.value
break
case BuffAttr.DODGE_NO:
hv.dod_no+=buff.value
break
case BuffAttr.CRITICAL_NO:
hv.crit_no+=buff.value
break
case BuffAttr.BURN_COUNT:
hv.burn_count+=buff.value
break
case BuffAttr.PUNCTURE:
hv.puncture+=buff.value
break
case BuffAttr.PUNCTURE_DMG:
hv.puncture_damage+=buff.value
break
case BuffAttr.WFUNY:
hv.wfuny+=buff.value
break
case BuffAttr.ATK_CD:
hv.cd=hv.cd*(100+buff.value)/100
break
case BuffAttr.HP:
hv.hp_max=hv.hp_max*(100+buff.value)/100
break
case BuffAttr.DEF:
hv.def+=buff.value
break
case BuffAttr.ATK:
hv.ap=hv.ap*(100+buff.value)/100
break
case BuffAttr.FROST_RATIO:
hv.frost_ratto+=buff.value
break
}
}
}