218 lines
8.9 KiB
TypeScript
218 lines
8.9 KiB
TypeScript
|
|
// 军团活动蛮夷入侵城门血量等数据存储
|
|
|
|
import { Member, GateMembersRec, WoodenHorse, Event } from "../../domain/battleField/guildActivity";
|
|
import { RewardInter } from "../../pubUtils/interface";
|
|
import { getRaceEventItems, gameData } from "../../pubUtils/data";
|
|
import { GuildModel } from "../../db/Guild";
|
|
import { sendSingleRaceActEndMsg } from "./guildActivityService";
|
|
import { REDIS_KEY, RACE_EVENT_TYPE, RACE_EVENT_EFFECT_TYPE, RACE_EVENT, STATUS, RACE_ACTIVITY_STATUS } from "../../consts";
|
|
import { getGuildChannelSid } from "../chatService";
|
|
import { pinus } from "pinus";
|
|
import { getRandEelm, sortArrRandom, resResult } from "../../pubUtils/util";
|
|
import { Rank } from "../rankService";
|
|
import { getTimeFun } from "../../pubUtils/timeUtil";
|
|
|
|
// 粮草先行
|
|
export class RaceActivityObject {
|
|
private status = RACE_ACTIVITY_STATUS.WAITING; // 活动状态 0-未开始 1-已开始 2-已结束
|
|
public guildList: Array<{ serverId: number, guildCode: string }> = []; // 所有军团
|
|
private members: Map<string, Array<Member>> = new Map(); // 每个军团参与的成员 guildCode => [{roleId, job}]
|
|
private woodenHorses: Map<string, WoodenHorse> = new Map(); // 每个军团的木牛流马 guildCode => WoodenHorse
|
|
private events: Map<string, Event[]> = new Map(); // 每个军团遇到的事件
|
|
private items: Map<string, RewardInter[]> = new Map(); // 每个玩家的道具 roleId => [{id, count}]
|
|
private hasSentGuild: string[] = [];
|
|
|
|
public getItem(roleId: string) {
|
|
return this.items.get(roleId)||[]
|
|
}
|
|
|
|
// 是否加入过
|
|
public getMember(guildCode: string, roleId: string) {
|
|
let member = this.members.get(guildCode)||[];
|
|
return member.find(cur => cur.roleId == roleId);
|
|
}
|
|
|
|
// 加入member
|
|
private pushMember(guildCode: string, roleId: string, job: number, code: string) {
|
|
if(!this.members.has(guildCode)) {
|
|
this.members.set(guildCode, []);
|
|
}
|
|
this.members.get(guildCode).push({roleId, job, code});
|
|
}
|
|
|
|
public getMembersOfGuild(guildCode: string) {
|
|
return this.members.get(guildCode)||[];
|
|
}
|
|
|
|
public getAllWoodenHorses() {
|
|
return this.woodenHorses;
|
|
}
|
|
|
|
public async joinWoodenHorse(guildCode: string, roleId: string, roleName: string, serverId: number, sid: string, job: number, code: string) {
|
|
let woodenHorse = await this.getWoodenHorse(guildCode, serverId);
|
|
if(!woodenHorse) return false;
|
|
woodenHorse.joinMember(roleId, roleName, sid, code)
|
|
this.pushMember(guildCode, roleId, job, code);
|
|
|
|
if(this.status == RACE_ACTIVITY_STATUS.START) {
|
|
let item = getRaceEventItems();
|
|
this.handleItems(roleId, sid, item);
|
|
this.woodenHorseStartRace(woodenHorse);
|
|
}
|
|
return await this.getWoodenHorse(guildCode, serverId);
|
|
}
|
|
|
|
// 获取某个军团的木马状态
|
|
public async getWoodenHorse(guildCode: string, serverId: number) {
|
|
if(!this.woodenHorses.has(guildCode)) {
|
|
this.initEvents(guildCode);
|
|
let guild = await GuildModel.findByCode(guildCode, serverId);
|
|
if(!guild) return false;
|
|
let { name: guildName, guildCe } = guild;
|
|
this.woodenHorses.set(guildCode, new WoodenHorse(guildCode, guildName, guildCe, serverId));
|
|
this.guildList.push({guildCode, serverId});
|
|
}
|
|
let woodenHorse = this.woodenHorses.get(guildCode);
|
|
let events = this.events.get(guildCode)||[];
|
|
let needSendEnd = woodenHorse.calCurWoodenHorse(events);
|
|
|
|
if(woodenHorse.status == RACE_ACTIVITY_STATUS.START || woodenHorse.status == RACE_ACTIVITY_STATUS.END) { // 更新距离
|
|
let r = new Rank(REDIS_KEY.RACE_ACTIVITY, { serverId }, true, 5);
|
|
await r.setRank({guildCode}, [Math.floor(woodenHorse.distance * 1000), woodenHorse.time - woodenHorse.startTime], false);
|
|
let tomorrow = <number>getTimeFun().getAfterDayWithHour();
|
|
await r.setExpire(tomorrow);
|
|
|
|
if (needSendEnd) { // 抵达后发送奖励,发送消息,结算
|
|
await sendSingleRaceActEndMsg(guildCode, woodenHorse);
|
|
}
|
|
}
|
|
this.handleItemsByWoodenHorse(woodenHorse);
|
|
return woodenHorse;
|
|
}
|
|
|
|
public async useItem(fromRoleId: string, sid: string, fromGuild: string, toGuild: string, id: number, count: number) {
|
|
let rec = this.handleItems(fromRoleId, sid, [{id, count: -1 * count}]);
|
|
if(!rec) return false;
|
|
let event = new Event(id, fromGuild, toGuild, count);
|
|
if(!this.events.has(toGuild)) {
|
|
this.events.set(toGuild, [event]);
|
|
} else {
|
|
let events = this.events.get(toGuild)||[];
|
|
events.push(event);
|
|
this.events.set(toGuild, events);
|
|
}
|
|
let chatSid = await getGuildChannelSid(toGuild);
|
|
pinus.app.rpc.chat.guildRemote.sendRaceEvent.toServer(chatSid, toGuild, [event]);
|
|
|
|
return event;
|
|
}
|
|
|
|
// 定时任务到,开始比赛,设置开始赛道,发放初始道具
|
|
public startRace() {
|
|
this.status = RACE_ACTIVITY_STATUS.START;
|
|
let guildCodes = new Array<string>();
|
|
for(let [code, woodenHorse] of this.woodenHorses) {
|
|
if(woodenHorse.memberCnt > 0) {
|
|
this.woodenHorseStartRace(woodenHorse);
|
|
guildCodes.push(code);
|
|
}
|
|
}
|
|
return guildCodes;
|
|
}
|
|
|
|
private woodenHorseStartRace(woodenHorse: WoodenHorse) {
|
|
woodenHorse.status = RACE_ACTIVITY_STATUS.START;
|
|
woodenHorse.time = Date.now();
|
|
woodenHorse.startTime = Date.now();
|
|
let members = woodenHorse.members;
|
|
for(let { roleId, sid } of members) {
|
|
let item = getRaceEventItems();
|
|
this.handleItems(roleId, sid, item);
|
|
}
|
|
}
|
|
|
|
// 初始进入就随机9个灵球事件
|
|
public initEvents(guildCode: string) {
|
|
if(!this.events.get(guildCode)) {
|
|
this.events.set(guildCode, []);
|
|
}
|
|
let dicEncounter = gameData.raceActivityEncounter; // 距离=>事件类型
|
|
let goodEventNum = Math.floor(dicEncounter.eventNum/2);
|
|
let badEventNum = dicEncounter.eventNum - goodEventNum;
|
|
|
|
let dicRaceTypes = gameData.raceTypes.get(RACE_EVENT_TYPE.EVENT);
|
|
let goodEvents = getRandEelm(dicRaceTypes.get(RACE_EVENT_EFFECT_TYPE.GOOD), goodEventNum);
|
|
let badEvents = getRandEelm(dicRaceTypes.get(RACE_EVENT_EFFECT_TYPE.BAD), badEventNum);
|
|
let events = sortArrRandom(goodEvents.concat(badEvents));
|
|
let index = 0;
|
|
|
|
for(let [distance, type] of dicEncounter.events) {
|
|
if(type == RACE_EVENT_TYPE.ITEM) {
|
|
let event = new Event(RACE_EVENT.ITEM, guildCode, guildCode, 1, distance);
|
|
this.events.get(guildCode).push(event);
|
|
} else if (type == RACE_EVENT_TYPE.EVENT) {
|
|
let event = new Event(events[index], guildCode, guildCode, 1, distance);
|
|
this.events.get(guildCode).push(event);
|
|
index ++;
|
|
}
|
|
}
|
|
}
|
|
|
|
public getEvents(guildCode: string, distance: number) {
|
|
let events = this.events.get(guildCode)||[];
|
|
let result = new Array<Event>();
|
|
for(let event of events) {
|
|
let { endTime, endDistance } = event;
|
|
if(endTime) {
|
|
if(Date.now() > endTime) continue;
|
|
}
|
|
if(endDistance) {
|
|
if(distance > endDistance) continue;
|
|
}
|
|
result.push(event);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private handleItemsByWoodenHorse(woodenHorse: WoodenHorse) {
|
|
let { members } = woodenHorse;
|
|
for(let curMember of members) {
|
|
let { roleId, sid, items = [] } = curMember;
|
|
if(items.length > 0) this.handleItems(roleId, sid, items);
|
|
curMember.items = [];
|
|
}
|
|
}
|
|
|
|
private handleItems(roleId: string, sid: string, incItems: {id: number, count: number}[]) {
|
|
let items = this.items.get(roleId)||[];
|
|
let sendItems = new Array<{id: number, count: number}>();
|
|
for(let {id, count: inc} of incItems) {
|
|
let curItem = items.find(cur => cur.id == id);
|
|
if(!curItem) {
|
|
curItem = { id, count: 0 };
|
|
items.push(curItem);
|
|
}
|
|
if(curItem.count + inc < 0 ) return false;
|
|
if(inc != 0) {
|
|
curItem.count += inc;
|
|
sendItems.push({ id, count: curItem.count });
|
|
}
|
|
}
|
|
this.items.set(roleId, items);
|
|
let uids = [{uid: roleId, sid}];
|
|
pinus.app.get('channelService').pushMessageByUids('onRaceItemUpdate', resResult(STATUS.SUCCESS, { items: sendItems }), uids);
|
|
|
|
return items;
|
|
}
|
|
|
|
public deleteFromList(guildCode: string) {
|
|
this.hasSentGuild.push(guildCode);
|
|
}
|
|
|
|
public hasSend(guildCode: string) {
|
|
return this.hasSentGuild.indexOf(guildCode) != -1;
|
|
}
|
|
}
|
|
|