func (f *Fight) ExecuteEffects(attacker *Creature, defender *Creature, damage int64) (int64, int64) { dot, hot := int64(0), int64(0) curAttacker := f.FighterA curDefender := f.FighterA if f.FighterA.CId == attacker.CId { curAttacker = f.FighterA curDefender = f.FighterB } else { curAttacker = f.FighterB curDefender = f.FighterA } if curDefender.confusion[0] > 0 && rand.Intn(2) == 1 { rnd := float64(util.CRandInt(2, 5)) * 0.01 dot = int64(rnd * float64(defender.hpmax)) } if curDefender.dmge_ov_t[0] > 0 { rnd := float64(util.CRandInt(2, 5)) * 0.01 dot = int64(rnd * float64(defender.hpmax)) } if curAttacker.heal_ov_t[0] > 0 { rnd := float64(util.CRandInt(2, 5)) * 0.01 hot = int64(rnd * float64(attacker.hpmax)) } return dot, hot }
func (pl *Player) RPC_PoiFight(poi *POI) (string, error) { cr := pl.GetCurrentCreature() if cr == nil { return "", errors.New("no_monster_equipped") } // create random creature element := rand.Intn(5) xp := cr.XP //xpFactor := util.CRandFloat(0.75, 1.1) //xp = int64(float64(xp) * util.CRandFloat(0.75, 1.1)) random := util.CRandInt(0, 1000) // -----------------------> consts from file ? if random < 1 { xp = int64(float64(xp) * util.CRandFloat(1.1, 1.25)) } else if random < 100 { xp = int64(float64(xp) * util.CRandFloat(0.9, 1.1)) } else if random < 250 { xp = int64(float64(xp) * util.CRandFloat(0.85, 0.9)) } else if random < 500 { xp = int64(float64(xp) * util.CRandFloat(0.8, 0.85)) } else { xp = int64(float64(xp) * util.CRandFloat(0.75, 0.8)) } mid := int64(rand.Intn(2)) name := "Monster" if mid == 0 { name = "Fenris" } else { name = "Lucas" //TODO: other name ? } //TODO get name from file or something... enemy := &Creature{Name: name, Element: int64(element), XP: xp, ModelId: mid} enemy.ResolveTechTree() enemy.HP = enemy.hpmax enemy.Slots = make([]*CreatureSlot, 0) // TODO slot depends on level ??? lvl := enemy.level enemy.RandSkill(lvl) for i := 0; i < len(enemy.Slots); i++ { enemy.Slots[i].EquipSlot(int64(rand.Intn(5)), 2) } f, err := CreateWildFight(pl, enemy, poi) if f == nil { return "", err } return "fight", nil }
// ################################ ATTACK ################################ func (f *Fight) ExecuteAttack(attacker *Creature, defender *Creature, s0 int, s1 int, s2 int, s3 int) bool { if attacker.CId == defender.CId { log.Println("========== attack self !!!!!! ", attacker.CId) return true } f.TimeLastAttack = time.Now().Unix() curAttacker := f.FighterA curDefender := f.FighterA if f.FighterA.CId == attacker.CId { curAttacker = f.FighterA curDefender = f.FighterB } else { curAttacker = f.FighterB curDefender = f.FighterA } if curAttacker.skip { log.Println("========== attack skipped ==========") curAttacker.skip = false return true } // Effect round -- //confusion if curAttacker.confusion[0] > 0 { curAttacker.confusion[0]-- } if curAttacker.confusion[0] <= 0 { curAttacker.confusion[1] = 0 } //damage over time if curAttacker.dmge_ov_t[0] <= 0 { curAttacker.dmge_ov_t[1] = 0 } if curAttacker.dmge_ov_t[0] > 0 { curAttacker.dmge_ov_t[0]-- } //heal over time if curAttacker.heal_ov_t[0] <= 0 { curAttacker.heal_ov_t[1] = 0 } if curAttacker.heal_ov_t[0] > 0 { curAttacker.heal_ov_t[0]-- } //extra defense if curAttacker.exdefense[0] <= 0 { curAttacker.exdefense[1] = 0 } if curAttacker.exdefense[0] > 0 { curAttacker.exdefense[0]-- } if curAttacker.evade > 0 { curAttacker.evade-- } // some values combo := []int{} specComb := "" damage := int64(0) attackElement := int64(-1) elementbonus := float64(1) effects := []int{-1, -1} extradef := int64(0) imprint := int64(0) special := -1 //TODO: get strength for calculation if curDefender.exdefense[0] > 0 { extradef = int64(rand.Intn(4) + 1) // * curDefender.exdefense[1] curDefender.exdefense[0]-- } //check input if s0 >= 0 && s0 <= 3 && len(attacker.Slots) > s0 { combo = append(combo, s0) } if s1 >= 0 && s1 <= 3 && len(attacker.Slots) > s1 { combo = append(combo, s1) // select type of effect effects[0] = int(attacker.Slots[s1].EquipElement) } if s2 >= 0 && s2 <= 3 && len(attacker.Slots) > s2 { combo = append(combo, s2) } if s3 >= 0 && s3 <= 3 && len(attacker.Slots) > s3 { combo = append(combo, s3) } // check if driods are used multiple times for i := 0; i < len(combo); i++ { for j := 1; j < len(combo); j++ { if i != j && combo[i] == combo[j] { combo = []int{} } } } if len(combo) > 0 && len(attacker.Slots) > combo[0] { attackElement = attacker.Slots[combo[0]].EquipElement // element pentagram if (attackElement+1)%5 == defender.Element { elementbonus = MOD_E_ELEMENT_S } else if (attackElement+2)%5 == defender.Element { elementbonus = MOD_E_ELEMENT_L } } // write combo in string for i := 0; i < len(combo); i++ { if attacker.Slots[combo[i]].EquipElement >= 0 { specComb += RSC[attacker.Slots[combo[i]].EquipElement].Name if i+1 < len(combo) { specComb += "," } } } log.Println("--------> COMBO : ", specComb) // special attacks for i := 1; i < len(comboInfo); i++ { if comboInfo[i].Comb == specComb && attacker.Element == attackElement { if crInfo[attacker.ModelId] != comboInfo[i].Monster && "All" != comboInfo[i].Monster { log.Println("Creature can't use this Skill !!") continue } for j := 0; j < len(effectInfo); j++ { for k := 0; k < len(comboInfo[i].Effects); k++ { if comboInfo[i].Effects[k] == effectInfo[j] { effects[k] = j } } } // driod using special = i break } } // ############################ DAMAGE ############################ dfltdmg := float64(attacker.damage + rand.Int63n(attacker.dexterity)) countdmg := 1.0 + MOD_COUNT_BON*float64(len(combo)-1) avoidstrngth := float64(rand.Int63n(defender.dexterity)) * 0.1 cr_elmnt := 0.0 driodbonus := 0.0 defense := 0.0 if attacker.Element == attackElement && curAttacker.weaken < 1 { cr_elmnt = MOD_BASIC_ELEMENT } for i := 0; i < len(combo); i++ { currentSl := attacker.Slots[combo[i]] switch currentSl.EquipElement { case 0: imprint += currentSl.Element0 case 1: imprint += currentSl.Element1 case 2: imprint += currentSl.Element2 case 3: imprint += currentSl.Element3 case 4: imprint += currentSl.Element4 } driodbonus += float64(currentSl.EquipLevel) //driod using currentSl.EquipHealth -= (0.02 + 0.01*float64(currentSl.EquipLevel)) * (float64(len(combo)) / 2.0) currentSl.CheckState() tblCreature.MarkChildEntryMod(attacker, tblSlotsIdx, currentSl) } defense = (1.0 - float64(defender.defense+extradef)/100 + avoidstrngth) if defense < 0 { defense = 0 } driodbonus = float64(driodbonus) * 0.5 // greater damage if special combo if special > -1 { ok := false for i := 0; i < len(effects); i++ { if effects[i] == DAMAGE { countdmg *= 2 ok = true } } if ok { damage = int64((dfltdmg*countdmg*(1+elementbonus+cr_elmnt) + float64(attacker.extradamage) + (driodbonus+float64(imprint))*0.1) * defense) } else { damage = 0 } log.Println("------------SPECIAL------------", comboInfo[special].Name, damage, effects) } else { damage = int64((dfltdmg*countdmg*(1+elementbonus+cr_elmnt) + float64(attacker.extradamage) + (driodbonus+float64(imprint))*0.1) * defense) log.Println("------------DEFAULT------------", "Default", damage, effects) } // No slots selected if len(combo) <= 0 { damage = attacker.damage + rand.Int63n(attacker.dexterity) log.Println("------------NO-SLOTS-----------", damage) } confused := int64(0) if curAttacker.confusion[0] > 0 { confused = int64(float64(damage) * float64(util.CRandInt(2, 5)) * 0.01 * float64(curAttacker.confusion[1])) } if curAttacker.weaken > 0 { curAttacker.weaken-- } // ############################ EFFECTS ############################ for i := 0; i < len(effects); i++ { if effects[i] == RANDOM { effects[i] = rand.Intn(4) } //rnd := rand.Intn(4) switch effects[i] { case DOT: if curDefender.dmge_ov_t[0] > 0 { curDefender.dmge_ov_t[0]++ } else { if special >= 0 { curDefender.dmge_ov_t[0] = comboInfo[special].Length curDefender.dmge_ov_t[1] = comboInfo[special].Strength } else { curDefender.dmge_ov_t[0] = EFFECT_LENGTH curDefender.dmge_ov_t[1] = 1 } } case SELFDOT: if curAttacker.dmge_ov_t[0] > 0 { curAttacker.dmge_ov_t[0]++ } else { if special >= 0 { curAttacker.dmge_ov_t[0] = comboInfo[special].Length curAttacker.dmge_ov_t[1] = comboInfo[special].Strength } else { curAttacker.dmge_ov_t[0] = EFFECT_LENGTH curAttacker.dmge_ov_t[1] = 1 } } case CONFUSION: if curDefender.confusion[0] > 0 { curDefender.confusion[0]++ } else { if special >= 0 { curDefender.confusion[0] = comboInfo[special].Length curDefender.confusion[1] = comboInfo[special].Strength } else { curDefender.confusion[0] = EFFECT_LENGTH curDefender.confusion[1] = 1 } } case HEAL: if curAttacker.heal_ov_t[i] > 0 { curAttacker.heal_ov_t[i]++ } else { if special >= 0 { curAttacker.heal_ov_t[0] = comboInfo[special].Length curAttacker.heal_ov_t[1] = comboInfo[special].Strength } else { curAttacker.heal_ov_t[0] = EFFECT_LENGTH curAttacker.heal_ov_t[1] = 1 } } case DEF_BOOST: if curAttacker.exdefense[i] > 0 { curAttacker.exdefense[i]++ } else { if special >= 0 { curAttacker.exdefense[0] = comboInfo[special].Length curAttacker.exdefense[1] = comboInfo[special].Strength } else { curAttacker.exdefense[0] = EFFECT_LENGTH curAttacker.exdefense[1] = 1 } } case EVADE: if special >= 0 { curAttacker.evade = comboInfo[special].Strength } else { curAttacker.evade = 1 } case SKIP: curAttacker.skip = true case WEAK: if curDefender.weaken > 0 { if special >= 0 { curDefender.weaken = comboInfo[special].Length } else { curDefender.weaken = EFFECT_LENGTH } } else { curDefender.weaken++ } } } // hpRegen attacker attacker.FightRegen() // write effects from last round dmg, heal := f.ExecuteEffects(attacker, defender, damage) //stuff for client anim := -1 if len(combo) < 1 { attackElement = attacker.Element } if len(combo) > 2 { anim = combo[1] } else { anim = int(attackElement) } // ---- EVADE ---- curDefender.evaded = false evade := rand.Intn(2) if evade == 0 && curDefender.evade > 0 { curDefender.evaded = true damage = 0 } if special < 0 { f.LastResult = fmt.Sprintf("Default %v %v %v %v %v", damage, dmg, heal, attackElement, anim) } else { f.LastResult = fmt.Sprintf("%v %v %v %v %v %v", comboInfo[special].Name, damage, dmg, heal, attackElement, anim) } // ---- SET DAMAGE ---- defender.SetHP(defender.HP - (dmg + damage) + heal + confused) if defender.CId != 0 { if !defender.WriteChildren(nil, uint64(1)<<uint(tblSlotsIdx)) { log.Println("write fail ☺ defender", defender.CId, defender.Version) return false } } if attacker.CId != 0 { if !attacker.WriteChildren(nil, uint64(1)<<uint(tblSlotsIdx)) { log.Println("write fail ☺ attacker", attacker.CId, attacker.Version) return false } } return true }
func (pl *Player) POI_Farm(resources []string, poi *POI) (string, error) { count := util.CRandInt(int32(FarmItemsMin), int32(FarmItemsMax)) if count < 1 { return "", nil } if poi == nil || poi.info == nil { return "", errors.New("invalid_poi") } elements := make([]int, count) levels := make([]int, count) for i := 0; i < int(count); i++ { rscName := resources[int(util.CRandInt(0, int32(len(resources)-1)))] elements[i] = FindElement(rscName) random := util.CRandInt(0, 1000) level := poi.info.Level if random < 25 { level -= 2 } else if random < 50 { level += 2 } else if random < 100 { level -= 1 } else if random < 150 { level += 1 } if level < 0 { level = 0 } if level > FarmLevelMax { level = FarmLevelMax } levels[i] = level //log.Println(">>>>>>>>>>>>>", i, elements[i], levels[i]) } var result string DoRepeat(func() bool { result = "" for i := 0; i < int(count); i++ { element := elements[i] level := levels[i] if element < 0 { continue } rscNew := tblPlayer.GetChildEntryAdd(pl, tblResourceIdx, func(rsc db.EntryCached) bool { return rsc.(*Resource).Level == int64(level) }).(*Resource) rscNew.Level = int64(level) rscNew.SetCount(element, rscNew.GetCount(element)+1) result += fmt.Sprintf("%d %d", element, level) if (i + 1) < int(count) { result += ";" } } if !pl.WriteChildren(nil, uint64(1)<<uint(tblResourceIdx)) { return false } return true }, WRITE_REPEAT) return result, nil //log.Println(">>>>>>>>>>>>>", result) }