import { GUILDACTIVITY } from "../../pubUtils/dicParam"; import { SimpleGuildRankParam, SimpleRoleRankParam } from '../rank' import { prop } from "@typegoose/typegoose"; import { CITY_STATUS, RACE_ACTIVITY_STATUS, RACE_EVENT } from "../../consts"; import { gameData, getRaceEventItems } from "../../pubUtils/data"; import { getRandEelm, getRandResultByMember, } from "../../pubUtils/util"; import { RewardInter } from "../../pubUtils/interface"; export class GateMembersRec { roleId: string; round: number = 0; enemies: number[] = []; constructor(roleId: string) { this.roleId = roleId; } } export class WoodenHorseMember { roleId: string; roleName: string; sid: string; items: RewardInter[] = []; code?: string; hasReceiveInitItems: boolean = false; constructor(roleId: string, roleName: string, sid: string, code: string) { this.roleId = roleId; this.roleName = roleName; this.sid = sid; this.code = code; } addTempItem(item: RewardInter) { this.items.push(item); } addTempItems(items: RewardInter[]) { this.items.push(...items); } getTempItems() { return this.items; } receiveTempItems() { let items = [...this.items]; this.items = []; return items; } isReceived() { return this.hasReceiveInitItems; } setReceived(hasReceiveInitItems: boolean) { this.hasReceiveInitItems = hasReceiveInitItems; } } // 木牛流马 export class WoodenHorse { @prop({required: true}) serverId: number = 0; // 服务器id @prop({required: true}) guildCode: string = ""; // 军团code 木马的唯一标识 @prop({required: true}) guildName: string = ""; // 军团名 @prop({required: true}) guildCe: number = 0; // 军团战力 @prop({required: true}) status: number = 0; // 状态 0-停止 1-开启 2-结束 @prop({required: true}) speed: number = GUILDACTIVITY.RACE_INIT_SPEED; // 速度 @prop({required: true}) durability: number = 100; // 耐久度 @prop({required: true}) distance: number = 0; // 距离 @prop({required: true}) allStartTime: number = 0; // 全服开启世界 @prop({required: true}) startTime: number = 0; // 开始时间 @prop({required: true}) time: number = 0; // 到达时间 @prop({required: true}) memberCnt: number = 0; // 成员人数 @prop({required: true}) members: WoodenHorseMember[] = []; // 成员 @prop({required: true}) shield: number = 0; // 护盾数量 @prop({required: true}) shieldTime: number = 0; // 天师盾符 remainItems: Map = new Map(); isRobot: boolean = false; // debug接口生成 constructor(guildCode: string, guildName: string, guildCe: number, serverId: number, allStartTime: number, isRobot: boolean) { this.guildCode = guildCode; this.guildName = guildName; this.guildCe = guildCe; this.serverId = serverId; this.allStartTime = allStartTime; this.isRobot = isRobot; } public startRace(allStartTime: number) { this.status = RACE_ACTIVITY_STATUS.START; this.time = Date.now(); this.startTime = Date.now(); this.allStartTime = allStartTime; } /** * 根据时间计算当前木马速度距离耐久等 * @param events * @returns {boolean} needSendEnd 是否跑到终点发送结束新号 */ public calCurWoodenHorse(events: Event[]): boolean { if(this.status == RACE_ACTIVITY_STATUS.END) return false; if(this.status == RACE_ACTIVITY_STATUS.START) { if(this.distance >= GUILDACTIVITY.RACEACTIVITY_LENGTH) { this.distance = GUILDACTIVITY.RACEACTIVITY_LENGTH; this.status = RACE_ACTIVITY_STATUS.END; this.speed = 0; return true; } this.distance = Math.floor((this.distance + (Date.now() - this.time)/1000 * this.speed ) * 1000)/1000; // 1位小数点 this.time = Date.now(); } let effectiveEvents = new Array(); for(let i = 0; i < events.length; i++) { let event = events[i]; if(!event.startTime && event.startDistance && this.distance > event.startDistance) { let startTime = Date.now() - Math.floor((this.distance - event.startDistance) / this.speed); event.setStartTime(startTime); // 距离生效的事件的实际生效时间,主要用于速度叠加顺序 } let isEffective = false; if(event.startTime <= Date.now() && event.endTime > Date.now()) { isEffective = true; } else if (event.startDistance <= this.distance && event.endDistance > this.distance) { isEffective = true; } else if (event.endTime < Date.now() || event.endDistance < this.distance) { if(event.endTime && event.startTime == event.endTime) { isEffective = true; } if(event.endDistance && event.startDistance == event.endDistance) { isEffective = true; } let index = events.findIndex(cur => cur.id == event.id); events.splice(index, 1); } if(isEffective) { effectiveEvents.push(event); } } effectiveEvents.sort((a, b) => a.startTime - b.startTime); this.speed = GUILDACTIVITY.RACE_INIT_SPEED + this.memberCnt * GUILDACTIVITY.RACE_PER_SPEED; for(let { id, count, endTime } of effectiveEvents) { this.calEvent(id, count, endTime); } if(this.durability <= 0) { this.status = RACE_ACTIVITY_STATUS.BREAK; this.speed = 0; } return false; } private calEvent(id: number, count: number = 1, endTime?: number) { let { effect } = gameData.raceActivityEvents.get(id); switch (id) { case RACE_EVENT.LIANNU: if (this.shieldTime < Date.now()) { if (this.shield >= count) { this.shield -= count; } else { this.shield = 0; this.durability -= (count - this.shield) * effect[0]; if(this.durability > 100) this.durability = 100; if(this.durability < 0) this.durability = 0; } } break; case RACE_EVENT.GUISHOUYINFU: if (this.shieldTime < Date.now()) { this.time = endTime; this.speed = effect[1]; } break; case RACE_EVENT.FENGCHE: case RACE_EVENT.WUGUIBANYUNFU: this.speed *= Math.pow(1 + effect[0] / 100, count); break; case RACE_EVENT.LUDUN: this.shield += count * effect[0]; break; case RACE_EVENT.TIANSHIDUNFU: this.shieldTime = endTime; break; case RACE_EVENT.JIASU_1: this.speed *= Math.pow(1 + effect[0] / 100, count); break; case RACE_EVENT.JIASU_2: this.speed += effect[0]; break; case RACE_EVENT.HUIFU_1: this.durability += effect[0]; if(this.durability > 100) this.durability = 100; if(this.durability < 0) this.durability = 0; break; case RACE_EVENT.JIANSU_1: this.speed *= Math.pow(1 - effect[0] / 100, count); break; case RACE_EVENT.JIANSU_2: this.speed -= effect[0]; if(this.speed < 0) this.speed = 0; break; case RACE_EVENT.SHANGHAI_1: this.durability -= effect[0]; if(this.durability > 100) this.durability = 100; if(this.durability < 0) this.durability = 0; break; case RACE_EVENT.ITEM: let ranMember: WoodenHorseMember[] = getRandEelm(this.members, GUILDACTIVITY.RACEACTIVITY_EVENT_MEMBERCNT); if(ranMember.length <= 0) ranMember = this.members; for(let member of ranMember) { let item = gameData.raceEventItems; member.addTempItems(item); } let normalItems = getRaceEventItems(); for(let [id, {total, max}] of normalItems) { let randResult = getRandResultByMember(total, max, this.members.length); for(let i = 0; i < this.members.length; i++) { let count = randResult.arr[i]||0; if(count > 0) { this.members[i].addTempItem({ id, count }); normalItems.get(id).total -= count; } } } break; } } public joinMember(roleId: string, roleName: string, sid: string, code: string) { let index = this.members.findIndex(cur => cur.roleId == roleId) if(index == -1) { let member = new WoodenHorseMember(roleId, roleName, sid, code); this.members.push(member); this.speed++; this.memberCnt++; return member; } else { return this.members[index]; } } public setRemainItem(id: number, remain: number, max: number) { this.remainItems.set(id, { total: remain, max }); } public getTreatTime() { return {...this, time: this.time - this.allStartTime } } } export class Event { @prop({required: true}) id: number; @prop({required: true}) fromGuild: string; @prop({required: true}) toGuild: string; @prop({required: true}) startTime?: number; @prop({required: true}) startDistance?: number; @prop({required: true}) endTime?: number; @prop({required: true}) endDistance?: number; @prop({required: true}) count: number = 1; constructor(id: number, fromGuild: string, toGuild: string, count?: number, distance?: number) { let dicEvent = gameData.raceActivityEvents.get(id); this.id = id; this.fromGuild = fromGuild; this.toGuild = toGuild; if(distance) { this.startDistance = distance; this.endDistance = this.startDistance + dicEvent.continueDistance; } if(dicEvent.effectTime) { this.startTime = Date.now() + dicEvent.effectTime * 1000; this.endTime = this.startTime + dicEvent.continueTime * 1000; } if(count) { this.count = count; } } setStartTime(time: number) { this.startTime = time; } needReCalHorse() { let importantEvents = [ RACE_EVENT.LIANNU, // 连弩,可能durability突然变0 RACE_EVENT.GUISHOUYINFU, // 鬼手阴符 RACE_EVENT.FENGCHE, // 风车 RACE_EVENT.WUGUIBANYUNFU, // 五鬼搬运符 ]; return importantEvents.indexOf(this.id) != -1 } } export interface GuildRankParams { guildRank: SimpleGuildRankParam[], myGuildRank: SimpleGuildRankParam, memberRank?: SimpleRoleRankParam[], myMemberRank?: SimpleRoleRankParam } export class Member { @prop({required: true}) roleId: string; // 玩家id @prop({required: true}) job: number; // 在军团的职位 @prop({required: false}) code?: string; // 玩家的当前记录的code } export class CityParam { cityId: number = 0; // 城池id guardGuildCode: string = ''; // 占领军团id guardGuildName: string = ''; // 占领军团名 declareCount: number = 0; // 宣战数 status: number = CITY_STATUS.NOT_OPEN; // 城池对于我军状态 constructor(cityId: number) { this.cityId = cityId; } } export class RaceActivityRankParam { rank: number = 0; code: string; name: string; time: number; sortTime: number; sortDistance: number; num: number; durability: number; constructor(woodenHorse: WoodenHorse) { this.code = woodenHorse.guildCode; this.name = woodenHorse.guildName; this.durability = woodenHorse.durability; let distance = woodenHorse.distance > 1000? 1000: woodenHorse.distance; this.sortDistance = distance; this.sortTime = woodenHorse.time - woodenHorse.allStartTime; this.num = Math.floor(distance); this.time = Math.floor((woodenHorse.time - woodenHorse.allStartTime)/1000) } setRank(rank: number) { this.rank = rank; } }