by mvgulik » Thu Aug 06, 2015 4:33 pm
"Walk around object" experiment.
Anemone client.- Code: Select all
//import java.util.* // default Groovy import.
//import java.lang.* // default Groovy import.
import haven.*
maid.doSay("")
maid.doSay("Walk around object experiment)")
startSound()
Map negMAP = load_ResNEG_data("scripts/ResNEG.dat")
test_case()
return
def void test_case() {
// walk around some object(with known hitbox).
// optionals
def int range = 8
def String name = "cart"
def int steps = 8 // Pos:clockwise, Neg:anti-clockwise. FullCircle:8.
def skip1st = true // false|true
name = "trough"
name = "raftpart"
name = "plow"
name = "cart"
steps = 0
steps = -8
steps = -8-8
def home = maid.getCoord()
def targ_gob = maid.doAreaFind(range, name)
if (!targ_gob) {
maid.doSay('No "'+name+'" Found!')
warningSound()
return
}
if(!moveAroundObject(targ_gob, steps, skip1st)) return
// assuming character finished at general same side as home location.
if (!move_checked(home)) return
}
// ---- MAIN STUFF ----
def boolean moveAroundObject(targ_gob, steps, skip1st=true){
def targ_hit = getHitboxPoints(targ_gob)
if (!targ_hit) {warningSound();return false}
def player_gob = maid.getPlayer()
def player_hit = getHitboxPoints(player_gob)
if (!player_hit) {warningSound();return false}
def hit_both = listMath(targ_hit, player_hit, {a,b -> a+b})
def Map d = [W:0, N:1, E:2, S:3]
def Map hb = [
0:new Coord(-hit_both[d.E], -hit_both[d.S]),
1:new Coord( 0, -hit_both[d.S]),
2:new Coord(-hit_both[d.W], -hit_both[d.S]),
3:new Coord(-hit_both[d.W], 0),
4:new Coord(-hit_both[d.W], -hit_both[d.N]),
5:new Coord( 0, -hit_both[d.N]),
6:new Coord(-hit_both[d.E], -hit_both[d.N]),
7:new Coord(-hit_both[d.E], 0),
]
// ISSUE: when to close to the target, it could pick an angle that will not work as intended.
// Case: picking diagonal angle when start location is inside ver/hor width of target.
def double rad = getDirectionAngle(player_gob.c, targ_gob.c)
def int di = radToOrientationId(rad)
if (!skip1st && !steps) {
if (!move_checked(cord_offset(targ_gob.c, hb[di], 1))) return false
}
// InCON: same steps can give different result for perpendicular or diagonal starting point.
while (steps!=0) { // kinda unsave bailout.
if (steps>0) {
if (di%2 || steps==1) {di++;steps--}else{di+=2;steps-=2}
if (di>7) di-=8
if (steps<0) steps=0 // failsafe.
}else{
if (di%2 || steps==-1) {di--;steps++}else{di-=2;steps+=2}
if (di<0) di+=8
if (steps>0) steps=0 // failsafe.
}
if (!move_checked(cord_offset(targ_gob.c, hb[di], 1))) return false
}
return true
}
def double getDirectionAngle(cord1, cord2) {
def delta = cord_offset(cord2, cord1)
return Math.atan2(delta.y, delta.x)
}
def int radToOrientationId(double rad) {
def tmp = rad/Math.PI * 4 + 1/2 + 3
if (tmp < 0) tmp+=8
return tmp
}
def Coord orientationIdToCoord(int di) {
//def Map o1 = [0:'SE', 1:'S', 2:'SW', 3:'W', 4:'NW', 5:'N', 6:'NE', 7:'E']
def Map o2 = [0:[-1,-1], 1:[0,-1], 2:[1,-1], 3:[1,0], 4:[1,1], 5:[0,1], 6:[-1,1], 7:[-1,0]]
return new Coord(o2[di][0], o2[di][1])
}
def List getHitboxPoints(Gob targ_gob) {
def Coord bc1, bc2
def List neg_alt = null
def Map map = file_base_data()
for (e in map) {
if (targ_gob.resname().contains(e.key.toLowerCase())) {
neg_alt = e.value
bc1 = new Coord(neg_alt[0], neg_alt[1])
bc2 = new Coord(neg_alt[2], neg_alt[3])
bc1 = MapView.s2m(bc1)
bc2 = MapView.s2m(bc2)//.add(bc1.inv())
break
}
}
if (!neg_alt) {
def neg = targ_gob.getneg()
bc1 = neg.bc
bc2 = neg.bs.add(bc1)
}
def List hitpoints = null
if (bc1.x || bc1.y || bc2.x || bc2.y) {
hitpoints = [bc1.x, bc1.y, bc2.x, bc2.y]
}
return hitpoints
}
// ---- GENERAL STUFF ----
def startSound() {
def Resource resSound = Resource.load("sfx/fail")
Audio.play(resSound)
Thread.sleep(100)
}
def warningSound() {
def Resource resSound = Resource.load("sfx/fail")
Audio.play(resSound)
Thread.sleep(150)
Audio.play(resSound)
Thread.sleep(100)
}
def Coord cord_offset(Coord cord1, Coord cord2, int f=1) {
return new Coord(cord1.x - (cord2.x * f), cord1.y - (cord2.y * f))
}
static List listMath(List A, List B, Closure closure){
def tmp = []
A.eachWithIndex { item, i -> tmp << closure.call(A[i], B[i]) }
return tmp
}// Quick 'copied and pasted' general list-math solution code.
def move_checked(Coord ct) {
maid.doLeftClick(ct)
maid.waitForMoveStop(5000, 100)
if (maid.getCoord() != ct) {
maid.doSay("\tPath Blocked ?")
maid.doSay("\t\tct" +" == "+ ct)
maid.doSay("\t\tmaid.getCoord()" +" == "+ maid.getCoord())
maid.doLeftClick(ct)
maid.waitForMoveStop(5000, 100)
if (maid.getCoord() != ct) {
maid.doSay("\tPath Blocked !")
maid.doSay("\t\tct" +" == "+ ct)
maid.doSay("\t\tmaid.getCoord()" +" == "+ maid.getCoord())
warningSound()
return false
}
}
return true
}
def Map load_ResNEG_data(String filespec) {
def Map map = null
def file = new File(filespec)
if (file.isFile()) {
map = Eval.me(file.text)
} else {
map = file_base_data()
file.text = map.inspect()
}
return map
}
def file_base_data() {
Map map = [:]
map["/boat/"] = [0,-24,0,28] // WNES:[-12,-12,14,14]
map["/cart/"] = [0,-10,0,10] // WNES:[-5,-5,5,5]
map["/plow/"] = [0,-6,0,6] // WNES:[-3,-3,3,3]
map["/bed-sturdy"] = [-6,-13,4,18] // WNES:[-8,-5,10,8]
map["/cclosed"] = [0,-6,6,5] // WNES:[-3,-3,4,1] // chest
map["/copen"] = [0,-6,6,5] // WNES:[-3,-3,4,1] // chest
map["/htable"] = [6,-7,-4,12] // WNES:[-2, -5, 5, 7]
map["/ladder"] = [-6,-5,8,6] // WNES:[-4, -1, 5, 1]
map["/trough"] = [-6,-11,16,20] // WNES:[-7,-4,14,6]
map["/vclaim"] = [-16,-16,22,19] // WNES:[-12,-4,15,4]
//map["/hare/"] = [0,0,0,2] // WNES:[..] // issue: is using other named res as base res.
//map["/frog/"] = [0,0,0,2] // WNES:[..] // issue: is using other named res as base res.
// general fix for none blocking items.
map["/plants/"] = [0,0,0,0]
map["/anthill-r"] = [0,0,0,0]
map["/flavobjs/"] = [0,0,0,0]
//map["/moth/"] = [0,0,0,0] // seems not really needed.
//map["/eagle/"] = [0,0,0,0] // seems not really needed.
// verified to be ok:
// [borka,skeleton,raftpart,runestone,wbasket|wbasketo,lbox,coffer,bhive|bhived,
// bumlings/02|,bumlings/03,barrel,chair,table,dreca,demijohn,winepress,quern|querna,
// alloyer,churn|churna,sbasket|sbasketo,ttub|ttuba|ttubw,cndlbr|cndlbrc|cndlbrl,
// cupboard,cauldron,cheeserack,swheel|swheela,mgrind,loom,crate,birchbasket,torchpost,
// urn,oven,kiln|kilna,pow|powf|powr/roast|hearth-play,well|wella,bed-sprucebough,anthill,
// bonfire,germania,sherlock,surg,(all tree's:06), ..]
return map
// Xcom converted leftover data.
// Source-link: http://www.havenandhearth.com/forum/viewtopic.php?p=471487#p471487
map["gfx/arch/door-inn"] = [-18,-13,10,11]
map["gfx/arch/gates/brick-ns"] = [12,-16,-10,15]
map["gfx/arch/gates/brick-we"] = [-12,-16,10,15]
map["gfx/arch/gates/fence-ns"] = [12,-16,-10,15]
map["gfx/arch/gates/fence-we"] = [-12,-16,10,15]
map["gfx/arch/gates/palisade-ns"] = [12,-16,-10,15]
map["gfx/arch/gates/palisade-we"] = [-12,-16,10,15]
map["gfx/arch/stairs-inn"] = [8,-18,-14,17]
map["gfx/kritter/bear/s"] = [0,-16,0,16]
map["gfx/kritter/cow/s"] = [0,-8,0,14]
map["gfx/kritter/deer/s"] = [0,-8,0,14]
map["gfx/kritter/fox/s"] = [0,-6,0,8]
map["gfx/kritter/rat/s"] = [0,0,0,2]
map["gfx/kritter/troll/s"] = [0,-16,0,16]
map["gfx/terobjs/blood"] = [0,-10,0,12] // none blocking.(?)
map["gfx/terobjs/dframe2"] = [10,-11,-18,11]
map["gfx/terobjs/furniture/leanto"] = [-8,-14,14,17]
map["gfx/terobjs/furniture/wardrobe"] = [-10,-11,12,18]
map["gfx/terobjs/mining/ladder"] = [-6,-5,8,6]
map["gfx/terobjs/ridges/grass/e"] = [20,-14,-14,17]
map["gfx/terobjs/ridges/grass/e2s"] = [44,-22,44,28]
map["gfx/terobjs/ridges/grass/ee"] = [12,-14,-2,7]
map["gfx/terobjs/ridges/grass/es"] = [2,-11,-16,12]
map["gfx/terobjs/ridges/grass/s2w"] = [0,-22,-2,23]
map["gfx/terobjs/ridges/grass/ss"] = [-12,-14,2,7]
map["gfx/terobjs/ridges/mountain/ee"] = [20,-10,22,11]
map["gfx/terobjs/ridges/mountain/ne"] = [0,-22,-22,11]
map["gfx/terobjs/ridges/mountain/ns"] = [22,-11,0,22]
map["gfx/terobjs/ridges/mountain/ss"] = [-20,-10,-22,11]
map["gfx/terobjs/ridges/mountain/we"] = [-22,-11,0,22]
map["gfx/terobjs/ridges/mountain/ws"] = [0,-22,22,11]
}
[v0.2]: working test example.Main v0.2 fix: Hitbox processing. Should now work for all solid objects (with correct Neg-Res data).
++ Added additional checked hitbox data.◄index►
Last edited by
mvgulik on Tue Aug 18, 2015 12:31 pm, edited 3 times in total.