#!/usr/bin/ruby system 'ruby update.rb put log_mh update' require 'libmhbot' Mounty.bot_mainloop('log_mh') if ARGV.delete 'loop' m = Mounty.bot_start('todo') dest = m.bot_getdest enfuite = ((m[:pv] < m[:pvmax]/2 and m.vue(2).anim.first and m.dist_to(dest) < 16) or (m[:pv] < m[:pvmax] and m[:n] == 0)) # ramasse un parcho a portee m.each_pa { # XXX recheck vue, en cas de chute if e = m.vue_filt.tresors.find { |e| m.dist_to(e.pos) <= m[:pa] and e.nom == 'Parchemin' } m.bot_ramasse e end } # attaque si a portee et cible entammee m.each_pa { target = m.bot_gettarget r = m.bot_attaque target, false if target and target.hit exec "ruby #$0" if r and r.kill # ramasse parcho } # proche de dest sans target, designe une nouvelle target (sur la cased d'un equipier ou proche des trolls de la team dans la vue, profondeur en fonction du niveau xp de ces trolls) if m.dist_to(dest) <= m[:vue_tot]*2/3 and (File.read('targetid').to_i == -1 or not curtarg = m.bot_gettarget or not curtarg.hit) teamtrolls = m.vue.trolls # temp teamtrolls = m.teamlist.map { |tm| teamtrolls.find { |tv| tv.mat == tm } }.compact # << m # niveau de chasse ideal : moyenne des niveaux wantn = teamtrolls.map { |tt| -tt.lvl * 1.7 / teamtrolls.length }.inject(0) { |a, b| a+b }.round lvlmax = teamtrolls.empty? ? -20 : [(teamtrolls.map { |tt| tt.lvl*2 }.inject(0.0) { |a,b| a+b } / teamtrolls.length).round, 40].min if teamtrolls.empty? wantdest = m.pos else wantdest = [] 3.times { |i| wantdest[i] = teamtrolls.map { |tt| tt.pos[i] }.inject { |a,b| a+b } / teamtrolls.length } end if File.exist? 'wantdest' wd = File.read('wantdest').split.map { |i| i.to_i } wantdest[0] += (wantdest[0] > wd[0] ? -5 : 5) if (wantdest[0] - wd[0]).abs > 3 wantdest[1] += (wantdest[1] > wd[1] ? -5 : 5) if (wantdest[1] - wd[1]).abs > 3 wantdest[2] += (wantdest[2] > wd[2] ? -2 : 2) if (wantdest[2] - wd[2]).abs > 1 else wantdest[0] += ((wantdest[0] < 0) ? -3 : 3) if wantdest[0].abs < 60 wantdest[1] += ((wantdest[1] < 0) ? -3 : 3) if wantdest[1].abs < 60 wantdest[2] += ((wantdest[2] == wantn) ? 0 : ((wantdest[2] > wantn) ? -1 : 1)) wantdest[2] = -45 if wantdest[2] < -48 end if File.exist? 'targetwantlevel' lvls = File.read('targetwantlevel').split.map { |l| l.to_i } else lvls = [] end # choix d'une nouvelle cible # TODO flee from high levels if not target = m.vue.monstres.sort_by { rand }.find { |t| # real monster on team member teamtrolls.find { |tt| tt.pos == t.pos } and t.nom !~ /Gowap Appr|Familier|niym/i } teampos = teamtrolls.map { |tt| tt.pos } << wantdest cls = {} monstres = m.vue_filt.monstres monstres.each { |t| cls[t] = \ (lvls.include?(t.niveau) ? -500 : 0) + # targetwantlevel (t.niveau.to_i < lvlmax ? -(t.niveau||15)*10 : 200) + # avoid high level teampos.map { |ps| # dist to team members m.dist_to(ps, t.pos, 2) }.inject(0) { |a, b| a + b*b } # least sqr } tab = monstres.sort_by { |t| cls[t] } target = tab.first puts "wantdest: #{wantdest.inspect}" tab[3..-3] = [] if tab.length > 5 tab.each { |t| puts "dbg_new_target - #{cls[t]} #{t}" } end if target if not curtarg or curtarg.id != target.id puts "New target: #{target}" m.team_message('target', target) if rand(4) == 1 m.bot_settarget target end dest = target.pos if dest != m.bot_getdest File.open('dest', 'w') { |fd| fd.puts dest * ', ' } system 'ruby update.rb yell dest' end else puts "no new target found :(", cls.to_a.map { |m, n| "#{n.to_s.ljust(6)} #{m}" } end end # maj position de target dest = m.bot_getdest if target = m.bot_gettarget and dist = m.dist_to(target.pos, dest) and dist > 0 and dist < 8 File.open('dest', 'w') { |fd| fd.puts target.pos.join(', ') } system 'ruby update.rb yell dest' m.team_message('pos', target) if dist > 3 dest = target.pos puts target end # entrainement full m.each_pa { m.entrainement } if m[:pa] == 6 and m[:px] >= [5,2*m[:lvl]].max*3 + 4 if m[:pa] == 6 and m[:portation] and m.dist_to(m.bot_getdest) > 16 and m[:n] != 0 and not m.vue(0).lieux.first m.bot_move_to_dest m.profil end if enfuite and m[:n] != 0 and m[:pa] >= 2 dest[2] = m[:n] if m.dist_to(dest) < 10 x = m[:x]+rand(25)-12 y = m[:y]+rand(25)-12 else x = dest[0] y = dest[1] end puts " fuite -> #{x} #{y}" m.each_pa { m.move_to_dest [x, y, m[:n]] if m[:pa] > 2 or m[:camoufled] or m.vue(0).anim.first } dest = m.bot_getdest enfuite = ((m[:pv] < m[:pvmax]/2 and m.vue(2).anim.first) or (m[:pv] < m[:pvmax] and m[:n] == 0)) end # camou m.each_pa { m.camouflage if (not target = m.bot_gettarget or m[:tried_sort] or target.n != m[:n] or m.dist_to(target.pos) > 5 or enfuite) and m[:pa] >= 2 and not m[:tried_comp] and not m[:camoufled] and m[:n] != 0 } m.until_px { if target = m.bot_gettarget and (not target.esq or (target.hit and target.hit > 0)) and cdm = m.cdm(target.id) and cdm.reussi target.arm = (cdm.arm[0] + cdm.arm[1]) / 2 if not target.arm or target.arm == 0 target.rm = (cdm.rm[0] + cdm.rm[1]) / 2 if not target.rm and cdm.rm target.esq = (cdm.esq[0] + cdm.esq[1]) * 7 / 4 target.hit = (cdm.blessure > 0 ? (cdm.pv[0] + cdm.pv[1]) / -2 : nil) m.bot_settarget target end } m.bot_waitcumul unless nowait = ARGV.delete('nowait') if m[:pa] >= 5 p_ref = m.cout_amelio(:vue) case when m[:pi] >= m.cout_amelio(:vue) m.amelioration 'vue' when (m[:pi] >= m.cout_amelio(:pv) and m.cout_amelio(:pv) < p_ref/2) m.amelioration 'points.*vie' when (m[:pi] >= m.cout_amelio(:esq) and m.cout_amelio(:esq) < p_ref/2) m.amelioration 'd.*d.*esquive' when (m[:pi] >= m.cout_amelio(:reg) and m.cout_amelio(:reg) < p_ref/3) m.amelioration 'D.*de.*r.*g.*n.*ration' when (m[:pi] >= m.cout_amelio(:dla) and m.cout_amelio(:dla) < p_ref/3) m.amelioration 'Dur.*e.*du.*tour' end end m.each_pa { m.bot_goinfre } m.until_success { if m[:pa] == 6 and rand(3) == 1 and not m.vue_filt.tresors.find { |e| e.nom == 'Parchemin' and m.dist_to(e.pos) < m[:pa] } and m.dist_to(m.bot_getdest) < 20 if t = m.vue.monstres.find { |mm| not mm.niveau } m.cdm t.id else m.cdm '.' end end } m.until_success { m.bot_idt '.' } mtr = lambda { |n| m[n].to_a[1].to_i } case rand(4) when 0; m.vlc if m[:pa] >= 2 and mtr['voir le cach'] >= 10 and (mtr['voir le cach'] < 80 or rand(4) == 0) when 1; m.va if m[:pa] >= 2 and mtr['vision accrue'] >= 10 and mtr['vision accrue'] < 80 when 2; m.aa '.' if m[:pa] >= 1 and mtr['analyse atomique'] >= 10 and mtr['analyse atomique'] < 80 end # ramasse tresors proche de dest ou parchos a portee, sinon attaque/rapproche target, sinon move to dest, camou si 2pa m.each_pa { enfuite = ((m[:pv] < m[:pvmax]/2 and m.vue(2).anim.first) or (m[:pv] < m[:pvmax] and m[:n] == 0)) ts = m.vue_filt.tresors if e = ts.find { |e| e.nom == 'Parchemin' and m.dist_to(e.pos) < m[:pa] } || ts.find { |e| e.nom =~ /gigot/i and m.dist_to(e.pos) < 3 } || ts.sort_by { |e| [-ts.find_all { |ee| ee.pos == e.pos }.length / 5, m.dist_to(e.pos)] }.find { |e| m.dist_to(dest, e.pos) <= m.projodist or (e.dist <= 1 and e.n == m[:n]) } r = m.bot_ramasse e m.bot_idt e.id if r and m[:pa] > 1 and e.nom !~ /gigot/i elsif m.bot_gettarget m.bot_attaque m.bot_gettarget, !enfuite elsif m[:pa] == 2 and not m[:tried_comp] and not m[:camoufled] m.camouflage else m.bot_move_to_dest end } m.bot_waitcumul unless nowait m.each_pa { m.bot_idt '.' } m.each_pa { m.bot_move_to_dest } m.each_pa { # cdm target, sinon move to dest if target = m.vue.monstres.find { |mm| not mm.niveau } m.cdm target.id elsif target = m.bot_gettarget # TODO target = troll if cdm = m.cdm(target.id) and cdm.reussi target.arm = (cdm.arm[0] + cdm.arm[1]) / 2 if not target.arm or target.arm == 0 target.rm = (cdm.rm[0] + cdm.rm[1]) / 2 if target.rm and cdm.rm target.esq ||= (cdm.esq[0] + cdm.esq[1]) * 7 / 4 target.hit = (cdm.blessure > 0 ? (cdm.pv[0] + cdm.pv[1]) / -2 : nil) m.bot_settarget target end end } m.bot_stop