1function select_target_actor(src_actor) 2 local var_10 = 0x7fff 3 local target_actor 4 for i=0,0xff do 5 local actor = Actor.get(i) 6 local actor_align = actor.align 7 local actor_obj_n = actor.obj_n 8 local src_actor_align = src_actor.align 9 local src_actor_obj_n = src_actor.obj_n 10 if actor_obj_n ~= 0 and actor.alive and actor.visible and actor.actor_num ~= src_actor.actor_num and actor_obj_n ~= 381 then --OBJ_DUST_DEVIL 11 if src_actor_align ~= ALIGNMENT_NEUTRAL or actor_align ~= ALIGNMENT_NEUTRAL then 12 if src_actor_align ~= ALIGNMENT_CHAOTIC or (src_actor_obj_n ~= actor_obj_n 13 and (src_actor_obj_n ~= 372 or (actor_obj_n ~= 370 and actor_obj_n ~= 371)) 14 and ((src_actor_obj_n ~= 362 and src_actor_obj_n ~= 373 and src_actor_obj_n ~= 254) 15 or (actor_obj_n ~= 362 and actor_obj_n ~= 373 and actor_obj_n ~= 254))) 16 and (src_actor_align ~= ALIGNMENT_GOOD or actor_align == ALIGNMENT_EVIL or actor_align == ALIGNMENT_CHAOTIC) 17 and (src_actor_align ~= ALIGNMENT_EVIL or actor_align == ALIGNMENT_GOOD or actor_align == ALIGNMENT_CHAOTIC) 18 and actor_find_max_wrapped_xy_distance(src_actor, actor.x, actor.y) <= 0xb 19 and (actor.wt ~= 7 or actor_find_max_wrapped_xy_distance(Actor.get_player_actor(), actor.x, actor.y) <= 5) 20 then 21 local var_C = get_wrapped_dist(actor.x, src_actor.x)^2 + get_wrapped_dist(actor.y, src_actor.y)^2 22 if var_C < var_10 23 or (var_C == var_10 and actor_get_damage(actor) > actor_get_damage(target_actor)) then 24 var_10 = var_C 25 target_actor = actor 26 end 27 end 28 end 29 end 30 end 31 return target_actor 32end 33 34function worktype_8_combat_attack(actor) 35 g_selected_obj = select_target_actor(actor) 36 37end 38 39function worktype_15_your_mother(actor) 40 if actor_move(actor, DIR_SOUTH) == false then 41 local target_actor = select_target_actor(actor) 42 if target_actor ~= nil then 43 --FIXME do combat range check. sub_1B305 44 actor_take_hit(actor, target_actor, 6, 0) 45 end 46 end 47 subtract_movement_pts(actor, 3) 48end 49 50function worktype_stomp_around(actor) 51 subtract_movement_pts(actor, 5) 52 if actor.obj_n == 398 and g_current_dream_stage == 0x44 then 53 if math.random(0, 1) == 0 then 54 play_md_sfx(0, true) 55 quake_start(1,50) 56 else 57 return 58 end 59 end 60 61 local direction = math.random(0, 3) 62 actor_move(actor, direction, 0) 63 for obj in objs_at_loc(actor.xyz) do 64 actor_hit(obj, math.random(0, 0xa) + math.random(0, 0xa), 0) 65 end 66 67end 68 69function worktype_16_minotaur(actor) 70 if g_current_dream_stage == 0x60 then 71 Actor.kill(actor) 72 return 73 end 74 75 local dream_actor = Actor.get(0) 76 local target 77 if Actor.inv_has_obj_n(dream_actor, 162) then --OBJ_RED_CAPE 78 target = dream_actor 79 g_selected_obj = target 80 else 81 for obj in find_obj_from_area(0x21, 0x33, 2, 0x1c, 0x10) do 82 if obj.obj_n == 162 then --OBJ_RED_CAPE 83 target = obj 84 end 85 end 86 end 87 88 if target == nil then 89 worktype_stomp_around(actor) 90 return 91 end 92 93 if actor_get_combat_range(actor, target.x, target.y) <= 1 then 94 if target.luatype == "actor" then 95 attack_target_with_weapon(actor, target.x, target.y, actor) 96 subtract_movement_pts(actor, 0xa) 97 return 98 end 99 100 hit_target(target, RED_HIT_TILE) 101 if not Actor.get_talk_flag(0x54, 6) and target.x >= 0x37 and target.y <= 0x37 then 102 complete_tiffany_stage() 103 return 104 end 105 end 106 107 actor_move_towards_loc(actor, target.x, target.y) 108 play_md_sfx(0, true) 109 quake_start(1,50) 110 for obj in objs_at_loc(actor.xyz) do 111 actor_hit(obj, math.random(1, 0xa) + math.random(1, 0xa), 0) 112 end 113 subtract_movement_pts(actor, 5) 114 115end 116 117 118 119function worktype_99_coker_move_to_coal_vein(actor) 120 if actor_move(actor, DIR_NORTH) == false then 121 local vein = map_get_obj(actor.x, actor.y-1, actor.z, 446) --OBJ_VEIN_OF_COAL FIXME should be -2 not -1 need to fix actor_move for coker. 122 if vein ~= nil then 123 if map_is_on_screen(actor.x, actor.y, actor.z) then 124 play_md_sfx(0x10) 125 end 126 actor.wt = 0x9A 127 end 128 end 129end 130 131function worktype_9A_coker_drop_coal(actor) 132 local obj = map_get_obj(actor.x, actor.y+1, actor.z, 188) --OBJ_CONVEYOR_BELT 133 if obj ~= nil then 134 local coal = Obj.new(447) --OBJ_HUGE_LUMP_OF_COAL 135 Obj.moveToMap(coal, actor.x, actor.y+1, actor.z) 136 else 137 obj = map_get_obj(actor.x, actor.y+1, actor.z, 192) --OBJ_BARE_ROLLERS 138 if obj == nil then 139 actor_move(actor, DIR_SOUTH) 140 return 141 end 142 end 143 actor.wt = 0x9B 144end 145 146function worktype_9B_coker_wait_for_coal_to_move_away(actor) 147 local obj = map_get_obj(actor.x, actor.y+1, actor.z, 447) --OBJ_HUGE_LUMP_OF_COAL 148 if obj == nil then 149 obj = map_get_obj(actor.x, actor.y+1, actor.z, 192) --OBJ_BARE_ROLLERS 150 if obj == nil then 151 actor.wt = 0x99 152 end 153 end 154end 155 156function worktype_9D_stoker_wait_for_coal(actor) 157 local coal 158 coal = map_get_obj(actor.x, actor.y+1, actor.z, 447) --OBJ_HUGE_LUMP_OF_COAL 159 160 if coal ~= nil then 161 while coal ~= nil do 162 Obj.removeFromEngine(coal) 163 coal = map_get_obj(actor.x, actor.y+1, actor.z, 447) --OBJ_HUGE_LUMP_OF_COAL 164 end 165 actor.wt = 0x9E 166 end 167 168end 169 170function worktype_9E_stoker_walk_to_furnace(actor) 171 if actor_move(actor, DIR_NORTH) == false then 172 local furnace = map_get_obj(actor.x, actor.y-1, actor.z, 233) 173 if furnace == nil then 174 furnace = map_get_obj(actor.x+1, actor.y-1, actor.z, 233) 175 end 176 177 if furnace ~= nil then 178 if Actor.get_talk_flag(0x72, 2) == false then 179 activate_power_system() 180 else 181 if Actor.get_talk_flag(0x73, 2) == false or Actor.get_talk_flag(0x71, 3) == true then 182 if Actor.get_talk_flag(0x71, 3) == true then 183 Actor.clear_talk_flag(0x73, 2) 184 Actor.clear_talk_flag(0x71, 3) 185 --FIXME sub_3F740 186 end 187 Actor.set_talk_flag(0x73, 2) 188 activate_power_update_tiles() 189 activate_tower_electricity() 190 midgame_cutscene_2() 191 end 192 end 193 actor.wt = 0x9C 194 else 195 stoker_blocked(actor) 196 end 197 end 198end 199 200function activate_tower_electricity() 201 for obj in find_obj(0, 201) do --OBJ_TOWER_TOP 202 if obj ~= nil then 203 if obj.x >= 0x3d0 and obj.x <= 0x3f0 and obj.y >= 0x1d0 and obj.y <= 0x1e7 then 204 local frame_n = obj.frame_n 205 obj.frame_n = bit32.bor(frame_n, 4) 206 end 207 end 208 end 209 210 for obj in find_obj(0, 214) do --OBJ_POWER_CABLE 211 if obj ~= nil then 212 if obj.x >= 0x3d0 and obj.x <= 0x3f0 and obj.y >= 0x1d0 and obj.y <= 0x1e7 then 213 obj.obj_n = 215 --OBJ_POWER_CABLE1 214 end 215 end 216 end 217 218end 219 220function stoker_blocked(stoker) 221 if map_is_on_screen(stoker.x, stoker.y, stoker.z) then 222 printl("STOKERS_PATH_IS_BLOCKED") 223 play_md_sfx(0) 224 end 225end 226 227function worktype_9C_stoker_return_to_conveyor_belt(actor) 228 if map_get_obj(actor.x, actor.y+2, actor.z, 191) == nil then --OBJ_CONVEYOR_BELT2 229 if actor_move(actor, DIR_SOUTH) == false then 230 stoker_blocked(actor) 231 end 232 else 233 actor.wt = 0x9D 234 end 235end 236 237local worktype_tbl = { 238 [0x15]=worktype_15_your_mother, 239 [0x16]=worktype_16_minotaur, 240 [0x99]=worktype_99_coker_move_to_coal_vein, 241 [0x9a]=worktype_9A_coker_drop_coal, 242 [0x9b]=worktype_9B_coker_wait_for_coal_to_move_away, 243 [0x9c]=worktype_9C_stoker_return_to_conveyor_belt, 244 [0x9d]=worktype_9D_stoker_wait_for_coal, 245 [0x9e]=worktype_9E_stoker_walk_to_furnace, 246} 247 248function perform_worktype(actor) 249 --print("wt="..actor.wt.."\n") 250 local mpts = actor.mpts 251 if worktype_tbl[actor.wt] ~= nil then 252 local func = worktype_tbl[actor.wt] 253 func(actor) 254 end 255 256 if mpts == actor.mpts then 257 subtract_movement_pts(actor, 10) 258 end 259end 260