2012-04-26 11:38:15 -06:00
|
|
|
module DFHack
|
2012-06-24 09:30:26 -06:00
|
|
|
class << self
|
|
|
|
# return an Unit
|
|
|
|
# with no arg, return currently selected unit in df UI ('v' or 'k' menu)
|
|
|
|
# with numeric arg, search unit by unit.id
|
|
|
|
# with an argument that respond to x/y/z (eg cursor), find first unit at this position
|
2012-07-04 10:34:41 -06:00
|
|
|
def unit_find(what=:selected, y=nil, z=nil)
|
2012-06-24 09:30:26 -06:00
|
|
|
if what == :selected
|
2012-07-11 16:44:07 -06:00
|
|
|
case curview._rtti_classname
|
|
|
|
when :viewscreen_itemst
|
2012-07-03 11:51:52 -06:00
|
|
|
ref = curview.entry_ref[curview.cursor_pos]
|
|
|
|
ref.unit_tg if ref.kind_of?(GeneralRefUnit)
|
2012-07-11 16:44:07 -06:00
|
|
|
when :viewscreen_unitlistst
|
|
|
|
v = curview
|
2012-09-26 10:13:01 -06:00
|
|
|
v.units[v.page][v.cursor_pos[v.page]]
|
|
|
|
when :viewscreen_petst
|
|
|
|
v = curview
|
|
|
|
case v.mode
|
|
|
|
when :List
|
|
|
|
v.animal[v.cursor].unit if !v.is_vermin[v.cursor]
|
|
|
|
when :SelectTrainer
|
|
|
|
v.trainer_unit[v.trainer_cursor]
|
|
|
|
end
|
2012-11-16 09:39:08 -07:00
|
|
|
when :viewscreen_dwarfmodest
|
2012-07-03 11:51:52 -06:00
|
|
|
case ui.main.mode
|
|
|
|
when :ViewUnits
|
|
|
|
# nobody selected => idx == 0
|
|
|
|
v = world.units.active[ui_selected_unit]
|
|
|
|
v if v and v.pos.z == cursor.z
|
|
|
|
when :LookAround
|
|
|
|
k = ui_look_list.items[ui_look_cursor]
|
|
|
|
k.unit if k.type == :Unit
|
2012-09-17 13:16:01 -06:00
|
|
|
else
|
|
|
|
ui.follow_unit_tg if ui.follow_unit != -1
|
2012-07-03 11:51:52 -06:00
|
|
|
end
|
2012-11-16 09:39:08 -07:00
|
|
|
when :viewscreen_dungeonmodest
|
|
|
|
case ui_advmode.menu
|
|
|
|
when :Default
|
|
|
|
world.units.active[0]
|
|
|
|
else
|
|
|
|
unit_find(cursor) # XXX
|
|
|
|
end
|
|
|
|
when :viewscreen_dungeon_monsterstatusst
|
|
|
|
curview.unit
|
2012-06-24 09:30:26 -06:00
|
|
|
end
|
|
|
|
elsif what.kind_of?(Integer)
|
2012-07-04 10:34:41 -06:00
|
|
|
# search by id
|
|
|
|
return world.units.all.binsearch(what) if not z
|
|
|
|
# search by coords
|
|
|
|
x = what
|
|
|
|
world.units.all.find { |u| u.pos.x == x and u.pos.y == y and u.pos.z == z }
|
2012-06-24 09:30:26 -06:00
|
|
|
elsif what.respond_to?(:x) or what.respond_to?(:pos)
|
|
|
|
world.units.all.find { |u| same_pos?(what, u) }
|
|
|
|
else
|
|
|
|
raise "what what?"
|
|
|
|
end
|
|
|
|
end
|
2012-04-26 11:38:15 -06:00
|
|
|
|
2012-06-24 09:30:26 -06:00
|
|
|
# returns an Array of all units that are current fort citizen (dwarves, on map, not hostile)
|
|
|
|
def unit_citizens
|
|
|
|
world.units.active.find_all { |u|
|
2012-08-12 14:13:01 -06:00
|
|
|
unit_iscitizen(u)
|
2012-06-24 09:30:26 -06:00
|
|
|
}
|
|
|
|
end
|
2012-04-26 11:38:15 -06:00
|
|
|
|
2012-12-06 03:00:19 -07:00
|
|
|
def unit_testflagcurse(u, flag)
|
|
|
|
return false if u.curse.rem_tags1.send(flag)
|
|
|
|
return true if u.curse.add_tags1.send(flag)
|
|
|
|
return false if u.caste < 0
|
|
|
|
u.race_tg.caste[u.caste].flags[flag]
|
|
|
|
end
|
|
|
|
|
|
|
|
def unit_isfortmember(u)
|
|
|
|
# RE from viewscreen_unitlistst ctor
|
|
|
|
return false if df.gamemode != :DWARF or
|
|
|
|
u.mood == :Berserk or
|
|
|
|
unit_testflagcurse(u, :CRAZED) or
|
|
|
|
unit_testflagcurse(u, :OPPOSED_TO_LIFE) or
|
|
|
|
u.unknown8.unk2 or
|
|
|
|
u.flags3.ghostly or
|
|
|
|
u.flags1.marauder or u.flags1.active_invader or u.flags1.invader_origin or
|
|
|
|
u.flags1.forest or
|
|
|
|
u.flags1.merchant or u.flags1.diplomat
|
|
|
|
return true if u.flags1.tame
|
|
|
|
return false if u.flags2.underworld or u.flags2.resident or
|
|
|
|
u.flags2.visitor_uninvited or u.flags2.visitor or
|
|
|
|
u.civ_id == -1 or
|
|
|
|
u.civ_id != df.ui.civ_id
|
|
|
|
true
|
|
|
|
end
|
|
|
|
|
|
|
|
# return the page in viewscreen_unitlist where the unit would appear
|
|
|
|
def unit_category(u)
|
|
|
|
return if u.flags1.left or u.flags1.incoming
|
|
|
|
# return if hostile & unit_invisible(u) (hidden_in_ambush or caged+mapblock.hidden or caged+holder.ambush
|
|
|
|
return :Dead if u.flags1.dead
|
|
|
|
return :Dead if u.flags3.ghostly # hostile ?
|
|
|
|
return :Others if !unit_isfortmember(u)
|
|
|
|
casteflags = u.race_tg.caste[u.caste].flags if u.caste >= 0
|
|
|
|
return :Livestock if casteflags and (casteflags[:PET] or casteflags[:PET_EXOTIC])
|
|
|
|
return :Citizens if unit_testflagcurse(u, :CAN_SPEAK)
|
|
|
|
:Livestock
|
|
|
|
# some other stuff with ui.race_id ? (jobs only?)
|
|
|
|
end
|
|
|
|
|
2012-09-26 10:13:01 -06:00
|
|
|
def unit_iscitizen(u)
|
2012-12-06 03:00:19 -07:00
|
|
|
unit_category(u) == :Citizens
|
|
|
|
end
|
|
|
|
|
|
|
|
def unit_ishostile(u)
|
|
|
|
unit_category(u) == :Others and
|
|
|
|
# TODO
|
|
|
|
true
|
2012-08-12 14:13:01 -06:00
|
|
|
end
|
|
|
|
|
2012-06-24 09:30:26 -06:00
|
|
|
# list workers (citizen, not crazy / child / inmood / noble)
|
|
|
|
def unit_workers
|
2012-08-12 14:13:01 -06:00
|
|
|
world.units.active.find_all { |u|
|
|
|
|
unit_isworker(u)
|
2012-06-24 09:30:26 -06:00
|
|
|
}
|
|
|
|
end
|
2012-04-26 11:38:15 -06:00
|
|
|
|
2012-08-12 14:13:01 -06:00
|
|
|
def unit_isworker(u)
|
|
|
|
unit_iscitizen(u) and
|
|
|
|
u.mood == :None and
|
|
|
|
u.profession != :CHILD and
|
|
|
|
u.profession != :BABY and
|
|
|
|
# TODO MENIAL_WORK_EXEMPTION_SPOUSE
|
|
|
|
!unit_entitypositions(u).find { |pos| pos.flags[:MENIAL_WORK_EXEMPTION] }
|
|
|
|
end
|
|
|
|
|
2012-06-24 09:30:26 -06:00
|
|
|
# list currently idle workers
|
|
|
|
def unit_idlers
|
2012-08-12 14:13:01 -06:00
|
|
|
world.units.active.find_all { |u|
|
|
|
|
unit_isidler(u)
|
2012-06-24 09:30:26 -06:00
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2012-08-12 14:13:01 -06:00
|
|
|
def unit_isidler(u)
|
|
|
|
unit_isworker(u) and
|
|
|
|
# current_job includes eat/drink/sleep/pickupequip
|
|
|
|
!u.job.current_job and
|
|
|
|
# filter 'attend meeting'
|
|
|
|
not u.specific_refs.find { |s| s.type == :ACTIVITY } and
|
|
|
|
# filter soldiers (TODO check schedule)
|
2012-10-20 14:35:39 -06:00
|
|
|
u.military.squad_id == -1 and
|
2012-08-12 14:13:01 -06:00
|
|
|
# filter 'on break'
|
|
|
|
not u.status.misc_traits.find { |t| t.id == :OnBreak }
|
|
|
|
end
|
|
|
|
|
2012-06-24 09:30:26 -06:00
|
|
|
def unit_entitypositions(unit)
|
|
|
|
list = []
|
2012-08-12 14:13:01 -06:00
|
|
|
return list if not hf = unit.hist_figure_tg
|
2012-06-24 09:30:26 -06:00
|
|
|
hf.entity_links.each { |el|
|
|
|
|
next if el._rtti_classname != :histfig_entity_link_positionst
|
2012-08-12 14:13:01 -06:00
|
|
|
next if not ent = el.entity_tg
|
2012-06-24 09:30:26 -06:00
|
|
|
next if not pa = ent.positions.assignments.binsearch(el.assignment_id)
|
|
|
|
next if not pos = ent.positions.own.binsearch(pa.position_id)
|
|
|
|
list << pos
|
|
|
|
}
|
|
|
|
list
|
|
|
|
end
|
|
|
|
end
|
2012-07-04 07:18:36 -06:00
|
|
|
|
|
|
|
class LanguageName
|
2012-09-17 13:16:01 -06:00
|
|
|
def to_s(english=false)
|
2012-07-04 07:18:36 -06:00
|
|
|
df.translate_name(self, english)
|
|
|
|
end
|
|
|
|
end
|
2012-04-26 11:38:15 -06:00
|
|
|
end
|