func (self *SkillItem) Install() { releaser := self.SkillParent.Carrier //在技能持有者身上订阅触发技能的事件 if releaser != nil { //在指定的阶段 stepName := self.PluginStep.StepName //技能项在指定阶段决定是否进行效果释放处理。 //返回信息 //类型:*SkillItem releaser.On(stepName, event.NewEventHandler(func(contextParams ...interface{}) (isCancel bool, handleResult interface{}) { //先看概率是否释放 thisTimeProbabilityHit := math.IsHitByFloatProbability(self.Probability.GetValue().Get()) if thisTimeProbabilityHit { //概率命中了,还要看是否能找到作用对象 //再找到指定的作用对象 targets, err := self.Chooser.Choose(releaser, stepName, contextParams...) if !err && targets != nil && len(targets) > 0 { //有作用对象,还要看pre 阶段是否被取消 cancel := false //触发技能持有者的技能释放事件(前) //处理函数将得到一个参数:*SkillItem onBeforeResults := releaser.Emit(EVENT_BEFORE_SKILL_ITEM_RELEASE, releaser, self) for _, r := range onBeforeResults { if r.IsCancel { cancel = true //执行cancel 阶段[技能被取消释放] releaser.Emit(EVENT_CANCEL_SKILL_ITEM_RELEASE, releaser, self) break } } //没取消,进入释放 if !cancel { releaser.Emit(EVENT_SKILL_ITEM_RELEASE, releaser, self) for _, target := range targets { //对每一个效果,使用PutOn进行触发 for _, effectItem := range self.EffectItems { effectItem.PutOn(releaser, target) } } handleResult = self //释放成功 //释放结束,执行 after 阶段 releaser.Emit(EVENT_AFTER_SKILL_ITEM_RELEASE, releaser, self) } } } return })) } }
func NewComputedAttribute(name, desc string, rawValue float64, computer RawComputer, dependencies ...AttributeLike) *ComputedAttribute { c := &ComputedAttribute{ Attribute: NewAttribute(name, desc, rawValue), dependencies: dependencies, rawComputer: computer, cachedRaw: false, } if dependencies != nil && len(dependencies) > 0 { for _, a := range dependencies { a.On(EVENT_VALUE_CHANGED, //订阅所依赖属性的变化事件,第一个参数是变化的属性 event.NewEventHandler(func(contextParams ...interface{}) (isCancel bool, handleResult interface{}) { // fmt.Printf("[%s]订阅所依赖属性的变化事件 \n",c.GetName()) c.cachedRaw = false //只要有依赖项变化,就修改自己的脏标记 return })) } } return c }
//效果施加 func (self *AttributeDecResistance) PutOn(from interface{}, target effect.EffectCarrier) bool { //如果该效果可以被添加到对象上 if self.EffectBase.PutOn(from, target) { //功能1:对于在本效果释放之后再释放的效果,直接进行抵抗 //注册一个处理事件,到对象的 效果生效前 阶段 self.HandlerId = target.OnBeforePutOnEffect(event.NewEventHandler(func(contextParams ...interface{}) (isCancel bool, handleResult interface{}) { isCancel = false //默认不取消 //看看即将生效的效果,是不是 "属性修正效果" effectWantPutOn, ok := contextParams[0].(*AttributeModify) if ok { //如果是,则获取效果修正的所有属性 allAttr := effectWantPutOn.GetAllAttr() for _, v := range allAttr { // 检查修正值是否为负数,并且进行处理 if v.GetValue().Get() < 0.0 { //获取削减值的绝对值 decVal := -v.GetValue().Get() //如果抵消之后,最终削弱效果<=0,则只抵消 被削弱的部分 resistVal := math.Min(decVal, self.Amount) //进行抵消(对修改效果的值,进行抵消加成) v.GetValue().Add(resistVal, self) } } } return })) //功能2:如果在此之前,已经中了减少属性的效果,则立刻进行修正(这是因为,属性修正的效果是在putOn就已经触发了的) allModifyEffectsBeforeMe := target.GetAllEffects()["AttributeModify"] if allModifyEffectsBeforeMe != nil { // fmt.Printf(" 在此之前,已经中了减少属性的效果,则立刻进行修正 %v , %v \n",allModifyEffectsBeforeMe,len(allModifyEffectsBeforeMe)) for i, _ := range allModifyEffectsBeforeMe { //转化为 "属性修正效果"对象 e, ok := allModifyEffectsBeforeMe[i].(*AttributeModify) if ok { // fmt.Printf(" 如果是,则获取效果修正的所有属性 \n") //如果是,则获取效果修正的所有属性 allAttr := e.GetAllAttr() for _, v := range allAttr { // 检查修正值是否为负数,并且进行处理(这样,当这个效果消失的时候,他会正确的恢复用户属性,而不会多加) if v.GetValue().Get() < 0.0 { //获取削减值的绝对值 decVal := -v.GetValue().Get() //如果抵消之后,最终削弱效果<=0,则只抵消 被削弱的部分 resistVal := math.Min(decVal, self.Amount) //进行抵消(对修改效果的值,进行抵消加成) v.GetValue().Add(resistVal, self) //改变了修正效果之后,修改用户当前属性“被属性修改效果改变的大小” t := target.(attribute.AttributeCarrier) attr := t.GetAttr(v.GetName()) if attr != nil { // fmt.Printf(" 修正被削弱的属性:%v 加成 %v \n",attr.GetName(),resistVal) attr.GetValue().Add(resistVal, e) } } } } } } return true } else { return false } }
//加入某个角色到战斗中 func (self *Battle) AddWarrior(c *Warrior, pos int) bool { // fmt.Printf("add warrior [%s]\n",c.GetShowName()) _, exist := self.Players[c.Player.Id] if exist { //判断这个角色是不是已经添加过了 // fmt.Printf("判断这个角色是不是已经添加过了 warrior [%s]\n",c.GetShowName()) _, existWarrior := self.PlayerCharacters[c.Player.Id][c.Id] if !existWarrior { // fmt.Printf("new warrior [%s]\n",c.GetShowName()) c.BattleIn = self //加入战场 self.Field.AddCharacter(c, pos) //发射事件 func(目前为止总时间,加入的角色信息) self.Emit(EVENT_CHARACTER_ENTER, self.Report.TimeConsumed, c) //添加日志: rc := &CharacterEnterAction{ ActionRecordBase: NewActionRecordBase(self.Report.TimeConsumed, c, ACTION_TYPE_CHARACTER_ENTER, fmt.Sprintf("%v 加入战斗", c.GetShowName())), Props: make(map[string]float64), } rc.Props[c.HP.GetName()] = c.HP.GetValue().Get() rc.Props[c.AP.GetName()] = c.AP.GetValue().Get() rc.Props[c.OP.GetName()] = c.OP.GetValue().Get() rc.Props["Position"] = float64(c.Position) self.Report.AddRecord(rc) self.PlayerCharacters[c.Player.Id][c.Id] = c self.PlayerCharactersList[c.Player.Id] = append(self.PlayerCharactersList[c.Player.Id], c) //角色没有添加过,添加之,并订阅其行动顺序变化事件,来更新行动先后列表 // fmt.Printf("before insert,ActSeq.len is %v/%v \n",self.ActSeq.Len(),self.ActSeq.Limit) cNode := self.ActSeq.PutOnTop(c) // fmt.Printf("after insert,ActSeq.len is %v/%v \n",self.ActSeq.Len(),self.ActSeq.Limit) c.ActSeq.On(attribute.EVENT_VALUE_CHANGED, //订阅所依赖属性的变化事件,第一个参数是变化的属性 event.NewEventHandler(func(contextParams ...interface{}) (isCancel bool, handleResult interface{}) { //先从行动顺序队列中移出 // fmt.Printf("before remove %v/%v \n",self.ActSeq.Len(),self.ActSeq.Limit) self.ActSeq.Remove(cNode) // fmt.Printf("after remove %v/%v \n",self.ActSeq.Len(),self.ActSeq.Limit) //再重新插入 cNode = self.ActSeq.PutOnTop(c) // fmt.Printf("变更的属性是“行动”顺序,ActSeq.len is %v/%v \n",self.ActSeq.Len(),self.ActSeq.Limit) return })) //监听器,处理一些数值变化事件 attributeListener := event.NewEventHandler(func(contextParams ...interface{}) (isCancel bool, handleResult interface{}) { attr := contextParams[0].(*attribute.Attribute) record := &AttrChangeAction{ ActionRecordBase: NewActionRecordBase(self.Report.TimeConsumed, c, ACTION_TYPE_ATTRIBUTE_CHANGE, fmt.Sprintf("%v 属性变化: [%v]", c.GetShowName(), attr)), AttrName: attr.GetName(), AttrValue: attr.GetValue().Get(), } self.Report.AddRecord(record) return }) //订阅角色的数值变化事件,记录战斗日志 c.AP.On(attribute.EVENT_VALUE_CHANGED, attributeListener) c.HP.On(attribute.EVENT_VALUE_CHANGED, attributeListener) c.OP.On(attribute.EVENT_VALUE_CHANGED, attributeListener) //订阅角色的各种事件,记录各种日志 c.On("*", event.NewEventHandler(func(contextParams ...interface{}) (isCancel bool, handleResult interface{}) { evtName := contextParams[0].(string) r := AnalyzeReportFromEvent(self.Report.TimeConsumed, contextParams...) if r != nil { self.Report.AddRecord(r) } //角色的死亡事件,用于计算战斗结束条件 if evtName == EVENT_WARRIOR_DEAD { self.judgeEnd() } return })) return true } return false } else { return false } }
func main() { fmt.Println("---------test begin---------") //暂且创建的时间速度都是和现实一样 godTimeSrc := time.NewSource(dataStructure.Time{ RealTime: systime.Time{}, GameTime: systime.Time{}, }, 1000, 1) //创建 player players := dataCreator.GetPlayers(2) //create arena,time tick is 1s //rate 1,means like real world //rate 10,means 10X real world speed arena1 := arena.NewArena(500, 20) //arena为了尽快完成比赛结果,时间流逝速度为20倍,每个时间片为500ms fieldLen := 900 battle1 := battle.NewBattle(fieldLen, players...) battle1.Desc = "test battle" arena1.AddBattle(battle1) //让 arena 可以接收时间片 godTimeSrc.AppendReceiver(arena1) //添加双方 warriors (一方5个) warriors := dataCreator.GetWarriors(len(players) * 2) //对第一个角色做特殊加强处理 w1, w2 := warriors[0], warriors[1] w1.EachOpMoveDistance.GetValue().Add(1, nil) w1.GetAttr(attribute.AGI).GetValue().Add(490, nil) w1.GetAttr(attribute.VIT).GetValue().Add(290, nil) w2.GetAttr(attribute.AGI).GetValue().Add(-4, nil) w2.GetAttr(attribute.STR).GetValue().Add(-5, nil) w2.GetAttr(attribute.VIT).GetValue().Add(-5, nil) //对第二个角色做特殊削弱处理 for i := 0; i < len(players)*2; i++ { //前5个 属于player1 if i < 2 { warriors[i].SetPlayer(players[0]) battle1.AddWarrior(warriors[i], 0) } else { //后5个,属于player2 warriors[i].SetPlayer(players[1]) battle1.AddWarrior(warriors[i], fieldLen-1) } } //订阅日志 battle1.On(battle.EVENT_END, event.NewEventHandler(func(contextParams ...interface{}) (isCancel bool, handleResult interface{}) { //写入文件 userFile := "record.json" fout, err := os.Create(userFile) defer fout.Close() if err != nil { fmt.Println(userFile, err) return } b, err := json.Marshal(battle1.Report) if err != nil { fmt.Println("json err:", err) } // fmt.Println(string(b)) fout.WriteString(string(b)) fmt.Println("write over!") return })) //时间开始 godTimeSrc.Begin() fmt.Println("-----Sleep---------") systime.Sleep(300 * systime.Second) }