xy-server/game/object/TaskState.ts
2025-04-23 09:34:08 +08:00

426 lines
18 KiB
TypeScript
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import GameUtil from "../core/GameUtil";
import TalkEventState from "../event/TalkEventState";
import GatherNpcState from "../event/GatherNpcState";
import KillDynamicNpcState from "../event/KillDynamicNpcState";
import ActionAreaEventState from "../event/ActionAreaEventState";
import ArriveAreaState from "../event/ArriveAreaState";
import GatherItemToNpcEventState from "../event/GatherItemToNpcEventState";
import FailEventPlayerDeadState from "../event/FailEventPlayerDeadState";
import FailEventTimeOutState from "../event/FailEventTimeOutState";
import TaskConfigMgr from "../task/TaskConfigMgr";
import NpcMgr from "../core/NpcMgr";
import DynamicNpc from "../core/DynamicNpc";
import TeamMgr from "../core/TeamMgr";
import Player from "./Player";
import SKLogger from "../gear/SKLogger";
import { EEventType, ENpcCreater, ETaskKind, ETaskState } from "../role/EEnum";
import Task from "../task/Task";
import Npc from "../core/Npc";
import EventStateBase from "../event/EventStateBase";
import SKDataUtil from "../gear/SKDataUtil";
import e from "express";
export default class TaskState {
nTaskID: any;
nKind: any;
nTaskGrop: any;
nTaskFinish: ETaskState;
vecEventState: any[];
vecFailEvent: any;
player: any;
constructor() {
this.nTaskID = 0;
this.nKind = 0;
this.nTaskGrop = 0;
this.nTaskFinish = 0;
this.vecEventState = [];
this.vecFailEvent = [];
this.player = null;
}
initState(task: Task, step: number) {
this.nTaskID = task.nTaskID;
this.nKind = task.nKind;
this.nTaskGrop = task.nTaskGrop;
for (let i = 0; i < task.vecEvent.length; i++) {
let taskState = null;
if (task.vecEvent[i].nEventType == EEventType.PLAYER_TALK_NPC) {
taskState = new TalkEventState();
taskState.vecRemainNpc = [];
}
if (task.vecEvent[i].nEventType == EEventType.PLAYER_GATHER_NPC) {
taskState = new GatherNpcState();
taskState.vecRemainNpc = [];
}
if (task.vecEvent[i].nEventType == EEventType.PLAYER_KILL_NPC) {
taskState = new KillDynamicNpcState();
taskState.vecRemainNpc = [];
}
if (task.vecEvent[i].nEventType == EEventType.PLAYER_DO_ACITION) {
taskState = new ActionAreaEventState();
}
if (task.vecEvent[i].nEventType == EEventType.PLAYER_ARRIVE_AREA) {
taskState = new ArriveAreaState();
taskState.nMap = task.vecEvent[i].nMap;
taskState.nX = task.vecEvent[i].nX;
taskState.nY = task.vecEvent[i].nY;
}
if (task.vecEvent[i].nEventType == EEventType.PLAYER_GIVE_NPC_ITEM) {
taskState = new GatherItemToNpcEventState();
}
if (taskState) {
taskState.nEventType = task.vecEvent[i].nEventType;
taskState.nState = ETaskState.LOCK;
if (i < step) {
taskState.nState = ETaskState.DONE;
}
this.vecEventState.push(taskState);
}
}
for (let i = 0; i < task.vecFailEvent.length; i++) {
let failEvent = null;
if (task.vecFailEvent[i].nEventType == EEventType.PLAYER_DEAD) {
failEvent = new FailEventPlayerDeadState();
failEvent.nDeadCnt = 0;
}
if (task.vecFailEvent[i].nEventType == EEventType.TIMEOUT) {
failEvent = new FailEventTimeOutState();
failEvent.nStartTime = GameUtil.getTime();
}
if (failEvent) {
this.vecFailEvent.push(failEvent);
}
}
this.reconCurrentEvent();
}
BuildCreaterInfo() {
if (TaskConfigMgr.shared.isTeamTask(this.nTaskID))
return {
nKind: ENpcCreater.TEAM,
nID: this.player.teamid
}
else
return {
nKind: ENpcCreater.PLAYER,
nID: this.player.roleid
}
}
IsBangMap(nMap: any) {
if (nMap == 3002)
return true;
return false;
}
reconCurrentEvent() {
for (let i = 0; i < this.vecEventState.length; i++) {
let taskState: EventStateBase = this.vecEventState[i];
if (taskState.nState == ETaskState.DONE) {
continue;
}
if (taskState.nState == ETaskState.DOING) {
break;
}
this.vecEventState[i].nState = ETaskState.DOING;
let stepConf: any = TaskConfigMgr.shared.getTaskStepInfo(this.nTaskID, i);
if (stepConf.hasOwnProperty("vecCreateNpc") && stepConf.vecCreateNpc.length > 0) {
for (let itCreate in stepConf.vecCreateNpc) {
let stData = stepConf.vecCreateNpc[itCreate];
let nOnlyID = NpcMgr.shared.CreateNpc(stData.nNpc, stData.nMap, stData.nX, stData.nY, this.BuildCreaterInfo(), this.IsBangMap(stData.nMap) ? this.player.bangid : 0);
let npc: DynamicNpc = new DynamicNpc(nOnlyID, stData.nNpc);
this.vecEventState[i].vecRemainNpc.push(npc);
}
} else {
for (let key in stepConf.vecNpc) {
let confId: number = stepConf.vecNpc[key];
let worldNpc: Npc = NpcMgr.shared.getNpcByConfigID(confId);
if (worldNpc == null) {
SKLogger.debug(`找不到NPC[${confId}]`);
continue;
}
this.vecEventState[i].vecRemainNpc.push(new DynamicNpc(worldNpc.onlyid, worldNpc.configid));
}
}
if (stepConf.nEventType == EEventType.PLAYER_KILL_NPC &&
stepConf.bAutoTrigle == 1 &&
this.vecEventState[i].vecRemainNpc.length > 0 &&
this.player.getTaskMgr().bCanAutoFight == 1) {
let npcOnlyId = this.vecEventState[i].vecRemainNpc[0].nOnlyID;
let npc: Npc = NpcMgr.shared.findNpc(npcOnlyId);
if (npc == null) {
SKLogger.debug(`找不到NPC[${npcOnlyId}]`);
return;
}
let battle = this.player.monsterBattle(npc.monster_group,this.nTaskGrop);
if (battle == null) {
return;
}
battle.source = this.vecEventState[i].vecRemainNpc[0].nOnlyID;
}
break;
}
}
// 事件完成
onEventDone(step: any) {
let task: Task = TaskConfigMgr.shared.getTaskConf(this.nTaskID);
let vecPrize = task.vecEvent[step].vecPrize;
let playerList: Player[];
if (TaskConfigMgr.shared.isTeamTask(this.nTaskID) && this.player.isleader) {
playerList = TeamMgr.shared.getTeamPlayer(this.player.teamid);
} else {
playerList = [this.player];
}
for (let key in playerList) {
let member: Player = playerList[key];
if (member == null || member.getTaskMgr() == null || member.pause == 1) {
continue;
}
if (task.nKind == ETaskKind.FUBEN && member.getTaskMgr().GetFuBenCnt(this.nTaskID) > step) {
member.send('s2c_notice', {
strRichText: '此关卡已完成,无法再次获得任务奖励'
});
SKLogger.debug(`玩家[${member.roleid}:${member.name}][${this.nTaskID}:${task.strTaskName}]步骤[${step}]此关卡已完成,无法再次获得任务奖励,跳过`);
continue;
}
let list: any = [];
for (let it in vecPrize) {
if (task.nKind == ETaskKind.DAILY && member.getTaskMgr().getKindTaskCnt(task.nTaskGrop) >= TaskConfigMgr.shared.getDailyMaxCount(task.nTaskGrop)) {
let flag = list.indexOf(member.roleid);
if (flag == -1){
member.send('s2c_notice', {
strRichText: `您的任务[${task.strTaskName}]已完成,本次无法获得任务奖励!`
});
list.push(member.roleid);
SKLogger.debug(`玩家[${member.roleid}:${member.name}][${this.nTaskID}:${task.strTaskName}]已完成,本次无法获得任务奖励!`);
}
continue;
}
if (vecPrize[it].nKey == 'exp') {
let exp = parseInt(vecPrize[it].nValue);
if(task.nTaskGrop == 2){
member.addMoney(GameUtil.goldKind.bang_Score,500,'帮派任务');
member.send('s2c_you_money', {
nKind: GameUtil.goldKind.bang_Score,
nNum: member.bangscore,
nChange: 500
});
}
if(task.nTaskGrop == 3){
member.addMoney(GameUtil.goldKind.shi_Score,500,'师门任务');
member.send('s2c_you_money', {
nKind: GameUtil.goldKind.shi_Score,
nNum: member.shiscore,
nChange: 500
});
}
if(task.nTaskGrop == 9){
member.addMoney(GameUtil.goldKind.di_Score,500,'地宫任务');
member.send('s2c_you_money', {
nKind: GameUtil.goldKind.di_Score,
nNum: member.discore,
nChange: 500
});
}
if(task.nTaskGrop == 8 || task.nTaskGrop == 12){
member.addMoney(GameUtil.goldKind.xiu_Score,500,'修罗');
member.send('s2c_you_money', {
nKind: GameUtil.goldKind.xiu_Score,
nNum: member.xiuscore,
nChange: 500
});
}
if(member.doublecnt > 0 && (task.nTaskGrop == 6 || task.nTaskGrop == 7)){
exp = exp * 2;
}
if(member.isleader){
exp = exp + exp * 0.1;
member.send_notice("队长额外获得10%经验加成")
}
member.addExp(exp);
} else if (vecPrize[it].nKey == 'petexp') {
if (member.curPet) {
let nExp = parseInt(vecPrize[it].nValue);
if (nExp > 0) {
member.curPet.addExp(nExp);
}
}
}
if(member.getTaskMgr().getKindTaskCnt(task.nTaskGrop) < TaskConfigMgr.shared.getDailyMaxCount(task.nTaskGrop)){
if (vecPrize[it].nKey == 'exp') {
continue;
} else if (vecPrize[it].nKey == 'petexp') {
continue;
} else if (vecPrize[it].nKey == 'money') {
member.addMoney(GameUtil.goldKind.Money, parseInt(vecPrize[it].nValue), '任务奖励');
} else if (vecPrize[it].nKey == 'jade') {
member.addMoney(GameUtil.goldKind.Jade, parseInt(vecPrize[it].nValue), '任务奖励');
} else if (vecPrize[it].nKey == 'item') {
member.addItem(parseInt(vecPrize[it].nValue), 1, true);
}
else if (vecPrize[it].nKey == 'active') {
member.getTaskMgr().AddActive(this.getThisTaskActiveScoreKind(), parseFloat(vecPrize[it].nValue));
} else {
member.addItem(vecPrize[it].nKey, vecPrize[it].nValue, true, '任务奖励');
}
}
}
}
this.vecEventState[step].nState = ETaskState.DONE;
if (this.nKind == ETaskKind.FUBEN) {
if (this.player.getTaskMgr()) {
let nCurStep = GameUtil.getDefault(this.player.getTaskMgr().mapFuBenCnt[this.nTaskID], 0);
this.player.getTaskMgr().mapFuBenCnt[this.nTaskID] = Math.max(nCurStep, parseInt(step) + 1);
}
}
SKLogger.debug(`玩家[${this.player.roleid}:${this.player.name}]完成任务[${this.nTaskID}:${task.strTaskName}]步骤[${step}]`);
}
getThisTaskActiveScoreKind(): number {
let task: Task = TaskConfigMgr.shared.getTaskConf(this.nTaskID);
if (task == null) {
return 0;
}
if (task.nKind == ETaskKind.DAILY) {
return task.nTaskGrop;
}
if (task.nKind == ETaskKind.FUBEN) {
return task.nTaskID;
}
return 0;
}
TaskOnFialEvent(nEventType: any, stData: any): boolean {
for (let it in this.vecFailEvent) {
if (this.vecFailEvent[it].nEventType != nEventType)
continue;
let pInfo = TaskConfigMgr.shared.GetFailEventInfo(this.nTaskID, it);
if (null == pInfo)
continue;
if (this.vecFailEvent[it].nEventType == EEventType.PLAYER_DEAD) {
this.vecFailEvent[it].nDeadCnt += 1;
if (this.vecFailEvent[it].nDeadCnt >= pInfo.nDeadCnt) {
this.nTaskFinish = ETaskState.FALIED;
return true;
}
}
if (this.vecFailEvent[it].nEventType == EEventType.TIMEOUT) {
if (stData - this.vecFailEvent[it].nStartTime > pInfo.nMaxTime) {
this.nTaskFinish = ETaskState.FALIED;
return true;
}
}
}
return false;
}
//获取任务信息及进度
getTaskStepByNpcOnlyid(npcOnlyid: number) {
for (let it in this.vecEventState) {
if (this.vecEventState[it].nEventType == EEventType.PLAYER_KILL_NPC) {
for (let nIndex in this.vecEventState[it].vecRemainNpc) {
if (this.vecEventState[it].vecRemainNpc[nIndex].nOnlyID == npcOnlyid) {
return it;
}
}
}
}
return null;
}
// 游戏任务事件
taskOnGameEvent(nEventType: EEventType, data: any): boolean {
let stepChange = false;
for (let key in this.vecEventState) {
let taskState: EventStateBase = this.vecEventState[key];
if (taskState.nState != ETaskState.DOING) {
continue;
}
if (taskState.nEventType != nEventType) {
continue;
}
if (taskState.nEventType == EEventType.PLAYER_TALK_NPC && data.nTaskID == this.nTaskID && data.nStep == key) {
let temp: TalkEventState = <TalkEventState>taskState;
this.onEventDone(key);
stepChange = true;
} else if (taskState.nEventType == EEventType.PLAYER_GATHER_NPC) {
let temp: GatherNpcState = <GatherNpcState>taskState;
for (let index in this.vecEventState[key].vecRemainNpc) {
if (temp.vecRemainNpc[index].nOnlyID == data) {
temp.vecRemainNpc.splice(index, 1);
stepChange = true;
break;
}
}
if (this.vecEventState[key].vecRemainNpc.length == 0) {
this.onEventDone(key);
stepChange = true;
}
} else if (taskState.nEventType == EEventType.PLAYER_DO_ACITION) {
let temp: ActionAreaEventState = <ActionAreaEventState>taskState;
this.onEventDone(key);
stepChange = true;
} else if (this.vecEventState[key].nEventType == EEventType.PLAYER_ARRIVE_AREA) {
let temp: ArriveAreaState = <ArriveAreaState>taskState;
if (data.mapid == temp.nMap && GameUtil.getDistance({
x: data.x,
y: data.y
}, {
x: temp.nX,
y: temp.nY
}) < 10) {
this.onEventDone(key);
stepChange = true;
}
} else if (taskState.nEventType == EEventType.PLAYER_GIVE_NPC_ITEM) {
let temp: GatherItemToNpcEventState = <GatherItemToNpcEventState>taskState;
this.onEventDone(key);
stepChange = true;
} else if (taskState.nEventType == EEventType.PLAYER_KILL_NPC) {
let temp: KillDynamicNpcState = <KillDynamicNpcState>taskState;
for (let key in temp.vecRemainNpc) {
if (temp.vecRemainNpc[key].nOnlyID == data) {
let index = SKDataUtil.numberBy(key);
temp.vecRemainNpc.splice(index, 1);
stepChange = true;
break;
}
}
if (temp.vecRemainNpc.length == 0) {
this.onEventDone(key);
stepChange = true;
}
}
}
if (stepChange == false) {
return false;
}
this.player.getTaskMgr().bCanAutoFight = 1;
this.reconCurrentEvent();
this.CheckAndFinish();
return true;
}
CheckAndFinish() {
let bAllOK = true;
for (let it in this.vecEventState) {
if (this.vecEventState[it].nState != ETaskState.DONE) {
bAllOK = false;
break;
}
}
if (bAllOK == true) {
this.nTaskFinish = ETaskState.DONE;
}
return bAllOK;
}
}