| 
									
										
										
										
											2023-03-22 07:25:55 -07:00
										 |  |  | local socket = require("socket") | 
					
						
							|  |  |  | local json = require('json') | 
					
						
							|  |  |  | local math = require('math') | 
					
						
							| 
									
										
										
										
											2023-04-15 00:17:33 -07:00
										 |  |  | require("common") | 
					
						
							| 
									
										
										
										
											2023-03-22 07:25:55 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | local STATE_OK = "Ok" | 
					
						
							|  |  |  | local STATE_TENTATIVELY_CONNECTED = "Tentatively Connected" | 
					
						
							|  |  |  | local STATE_INITIAL_CONNECTION_MADE = "Initial Connection Made" | 
					
						
							|  |  |  | local STATE_UNINITIALIZED = "Uninitialized" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | local SCRIPT_VERSION = 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | local APItemValue = 0xA2 | 
					
						
							|  |  |  | local APItemRam = 0xE7 | 
					
						
							|  |  |  | local BatAPItemValue = 0xAB | 
					
						
							|  |  |  | local BatAPItemRam = 0xEA | 
					
						
							|  |  |  | local PlayerRoomAddr = 0x8A -- if in number room, we're not in play mode | 
					
						
							|  |  |  | local WinAddr = 0xDE -- if not 0 (I think if 0xff specifically), we won (and should update once, immediately) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | -- If any of these are 2, that dragon ate the player (should send update immediately | 
					
						
							|  |  |  | -- once, and reset that when none of them are 2 again) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | local DragonState = {0xA8, 0xAD, 0xB2} | 
					
						
							|  |  |  | local last_dragon_state = {0, 0, 0} | 
					
						
							|  |  |  | local carryAddress = 0x9D -- uses rom object table | 
					
						
							|  |  |  | local batRoomAddr = 0xCB | 
					
						
							|  |  |  | local batCarryAddress = 0xD0 -- uses ram object location | 
					
						
							|  |  |  | local batInvalidCarryItem = 0x78 | 
					
						
							|  |  |  | local batItemCheckAddr = 0xf69f | 
					
						
							|  |  |  | local batMatrixLen = 11 -- number of pairs | 
					
						
							|  |  |  | local last_carry_item = 0xB4 | 
					
						
							|  |  |  | local frames_with_no_item = 0 | 
					
						
							|  |  |  | local ItemTableStart = 0xfe9d | 
					
						
							|  |  |  | local PlayerSlotAddress = 0xfff9 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | local nullObjectId = 0xB4 | 
					
						
							|  |  |  | local ItemsReceived = nil | 
					
						
							|  |  |  | local sha256hash = nil | 
					
						
							|  |  |  | local foreign_items = nil | 
					
						
							|  |  |  | local foreign_items_by_room = {} | 
					
						
							|  |  |  | local bat_no_touch_locations_by_room = {} | 
					
						
							|  |  |  | local bat_no_touch_items = {} | 
					
						
							|  |  |  | local autocollect_items = {} | 
					
						
							|  |  |  | local localItemLocations = {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | local prev_bat_room = 0xff | 
					
						
							|  |  |  | local prev_player_room = 0 | 
					
						
							|  |  |  | local prev_ap_room_index = nil | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | local pending_foreign_items_collected = {} | 
					
						
							|  |  |  | local pending_local_items_collected = {} | 
					
						
							|  |  |  | local rendering_foreign_item = nil | 
					
						
							|  |  |  | local skip_inventory_items = {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | local inventory = {} | 
					
						
							|  |  |  | local next_inventory_item = nil | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | local input_button_address = 0xD7 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | local deathlink_rec = nil | 
					
						
							|  |  |  | local deathlink_send = 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | local deathlink_sent = false | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | local prevstate = "" | 
					
						
							|  |  |  | local curstate =  STATE_UNINITIALIZED | 
					
						
							|  |  |  | local atariSocket = nil | 
					
						
							|  |  |  | local frame = 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | local ItemIndex = 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | local yorgle_speed_address = 0xf725 | 
					
						
							|  |  |  | local grundle_speed_address = 0xf740 | 
					
						
							|  |  |  | local rhindle_speed_address = 0xf70A | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | local read_switch_a = 0xf780 | 
					
						
							|  |  |  | local read_switch_b = 0xf764 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | local yorgle_speed = nil | 
					
						
							|  |  |  | local grundle_speed = nil | 
					
						
							|  |  |  | local rhindle_speed = nil | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | local slow_yorgle_id = tostring(118000000 + 0x103) | 
					
						
							|  |  |  | local slow_grundle_id = tostring(118000000 + 0x104) | 
					
						
							|  |  |  | local slow_rhindle_id = tostring(118000000 + 0x105) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | local yorgle_dead = false | 
					
						
							|  |  |  | local grundle_dead = false | 
					
						
							|  |  |  | local rhindle_dead = false | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | local diff_a_locked = false | 
					
						
							|  |  |  | local diff_b_locked = false | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | local bat_logic = 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | local is_dead = 0 | 
					
						
							|  |  |  | local freeincarnates_available = 0 | 
					
						
							|  |  |  | local send_freeincarnate_used = false | 
					
						
							|  |  |  | local current_bat_ap_item = nil | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | local was_in_number_room = false | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function uRangeRam(address, bytes) | 
					
						
							|  |  |  | 	data = memory.read_bytes_as_array(address, bytes, "Main RAM") | 
					
						
							|  |  |  | 	return data | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | function uRangeRom(address, bytes) | 
					
						
							|  |  |  | 	data = memory.read_bytes_as_array(address+0xf000, bytes, "System Bus") | 
					
						
							|  |  |  | 	return data | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | function uRangeAddress(address, bytes) | 
					
						
							|  |  |  | 	data = memory.read_bytes_as_array(address, bytes, "System Bus") | 
					
						
							|  |  |  | 	return data | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | local function createForeignItemsByRoom() | 
					
						
							|  |  |  |     foreign_items_by_room = {} | 
					
						
							|  |  |  |     if foreign_items == nil then | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |     for _, foreign_item in pairs(foreign_items) do | 
					
						
							|  |  |  |         if foreign_items_by_room[foreign_item.room_id] == nil then | 
					
						
							|  |  |  |             foreign_items_by_room[foreign_item.room_id] = {} | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |         new_foreign_item = {} | 
					
						
							|  |  |  |         new_foreign_item.room_id = foreign_item.room_id | 
					
						
							|  |  |  |         new_foreign_item.room_x = foreign_item.room_x | 
					
						
							|  |  |  |         new_foreign_item.room_y = foreign_item.room_y | 
					
						
							|  |  |  |         new_foreign_item.short_location_id = foreign_item.short_location_id | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         table.insert(foreign_items_by_room[foreign_item.room_id], new_foreign_item) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function debugPrintNoTouchLocations() | 
					
						
							|  |  |  |     for room_id, list in pairs(bat_no_touch_locations_by_room) do | 
					
						
							|  |  |  |         for index, notouch_location in ipairs(list) do | 
					
						
							|  |  |  |             print("ROOM "..tostring(room_id).. "["..tostring(index).."]: "..tostring(notouch_location.short_location_id)) | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function processBlock(block) | 
					
						
							|  |  |  |     if block == nil then | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |     local block_identified = 0 | 
					
						
							|  |  |  |     local msgBlock = block['messages'] | 
					
						
							|  |  |  |     if msgBlock ~= nil then | 
					
						
							|  |  |  |         block_identified = 1 | 
					
						
							|  |  |  |         for i, v in pairs(msgBlock) do | 
					
						
							|  |  |  |             if itemMessages[i] == nil then | 
					
						
							|  |  |  |                 local msg = {TTL=450, message=v, color=0xFFFF0000} | 
					
						
							|  |  |  |                 itemMessages[i] = msg | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |     local itemsBlock = block["items"] | 
					
						
							|  |  |  |     if itemsBlock ~= nil then | 
					
						
							|  |  |  |         block_identified = 1 | 
					
						
							|  |  |  | 	    ItemsReceived = itemsBlock | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |     local apItemsBlock = block["foreign_items"] | 
					
						
							|  |  |  |     if apItemsBlock ~= nil then | 
					
						
							|  |  |  |         block_identified = 1 | 
					
						
							|  |  |  |         print("got foreign items block") | 
					
						
							|  |  |  |         foreign_items = apItemsBlock | 
					
						
							|  |  |  |         createForeignItemsByRoom() | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |     local autocollectItems = block["autocollect_items"] | 
					
						
							|  |  |  |     if autocollectItems ~= nil then | 
					
						
							|  |  |  |         block_identified = 1 | 
					
						
							|  |  |  |         autocollect_items = {} | 
					
						
							|  |  |  |         for _, acitem in pairs(autocollectItems) do | 
					
						
							|  |  |  |             if autocollect_items[acitem.room_id] == nil then | 
					
						
							|  |  |  |                 autocollect_items[acitem.room_id] = {} | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  |             table.insert(autocollect_items[acitem.room_id], acitem) | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |     local localLocalItemLocations = block["local_item_locations"] | 
					
						
							|  |  |  |     if localLocalItemLocations ~= nil then | 
					
						
							|  |  |  |         block_identified = 1 | 
					
						
							|  |  |  |         localItemLocations = localLocalItemLocations | 
					
						
							|  |  |  |         print("got local item locations") | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |     local checkedLocationsBlock = block["checked_locations"] | 
					
						
							|  |  |  |     if checkedLocationsBlock ~= nil then | 
					
						
							|  |  |  |         block_identified = 1 | 
					
						
							|  |  |  |         for room_id, foreign_item_list in pairs(foreign_items_by_room) do | 
					
						
							|  |  |  |             for i, foreign_item in pairs(foreign_item_list) do | 
					
						
							|  |  |  |                 short_id = foreign_item.short_location_id | 
					
						
							|  |  |  |                 for j, checked_id in pairs(checkedLocationsBlock) do | 
					
						
							|  |  |  |                     if checked_id == short_id then | 
					
						
							|  |  |  |                         table.remove(foreign_item_list, i) | 
					
						
							|  |  |  |                         break | 
					
						
							|  |  |  |                     end | 
					
						
							|  |  |  |                 end | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |         if foreign_items ~= nil then | 
					
						
							|  |  |  |             for i, foreign_item in pairs(foreign_items) do | 
					
						
							|  |  |  |                 short_id = foreign_item.short_location_id | 
					
						
							|  |  |  |                 for j, checked_id in pairs(checkedLocationsBlock) do | 
					
						
							|  |  |  |                     if checked_id == short_id then | 
					
						
							|  |  |  |                         foreign_items[i] = nil | 
					
						
							|  |  |  |                         break | 
					
						
							|  |  |  |                     end | 
					
						
							|  |  |  |                 end | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |     local dragon_speeds_block = block["dragon_speeds"] | 
					
						
							|  |  |  |     if dragon_speeds_block ~= nil then | 
					
						
							|  |  |  |         block_identified = 1 | 
					
						
							|  |  |  |         yorgle_speed = dragon_speeds_block[slow_yorgle_id] | 
					
						
							|  |  |  |         grundle_speed = dragon_speeds_block[slow_grundle_id] | 
					
						
							|  |  |  |         rhindle_speed = dragon_speeds_block[slow_rhindle_id] | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |     local diff_a_block = block["difficulty_a_locked"] | 
					
						
							|  |  |  |     if diff_a_block ~= nil then | 
					
						
							|  |  |  |         block_identified = 1 | 
					
						
							|  |  |  |         diff_a_locked = diff_a_block | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |     local diff_b_block = block["difficulty_b_locked"] | 
					
						
							|  |  |  |     if diff_b_block ~= nil then | 
					
						
							|  |  |  |         block_identified = 1 | 
					
						
							|  |  |  |         diff_b_locked = diff_b_block | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |     local freeincarnates_available_block = block["freeincarnates_available"] | 
					
						
							|  |  |  |     if freeincarnates_available_block ~= nil then | 
					
						
							|  |  |  |         block_identified = 1 | 
					
						
							|  |  |  |         if freeincarnates_available ~= freeincarnates_available_block then | 
					
						
							|  |  |  |             freeincarnates_available = freeincarnates_available_block | 
					
						
							|  |  |  |             local msg = {TTL=450, message="freeincarnates: "..tostring(freeincarnates_available), color=0xFFFF0000} | 
					
						
							|  |  |  |             itemMessages[-2] = msg | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |     local bat_logic_block = block["bat_logic"] | 
					
						
							|  |  |  |     if bat_logic_block ~= nil then | 
					
						
							|  |  |  |         block_identified = 1 | 
					
						
							|  |  |  |         bat_logic = bat_logic_block | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |     local bat_no_touch_locations_block = block["bat_no_touch_locations"] | 
					
						
							|  |  |  |     if bat_no_touch_locations_block ~= nil then | 
					
						
							|  |  |  |         block_identified = 1 | 
					
						
							|  |  |  |         for _, notouch_location in pairs(bat_no_touch_locations_block) do | 
					
						
							|  |  |  |             local room_id = tonumber(notouch_location.room_id) | 
					
						
							|  |  |  |             if bat_no_touch_locations_by_room[room_id] == nil then | 
					
						
							|  |  |  |                 bat_no_touch_locations_by_room[room_id] = {} | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  |             table.insert(bat_no_touch_locations_by_room[room_id], notouch_location) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if notouch_location.local_item ~= nil and notouch_location.local_item ~= 255 then | 
					
						
							|  |  |  |                 bat_no_touch_items[tonumber(notouch_location.local_item)] = true | 
					
						
							|  |  |  |                 -- print("no touch: "..tostring(notouch_location.local_item)) | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |         -- debugPrintNoTouchLocations() | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |     deathlink_rec = deathlink_rec or block["deathlink"] | 
					
						
							|  |  |  |     if( block_identified == 0 ) then | 
					
						
							|  |  |  |         print("unidentified block") | 
					
						
							|  |  |  |         print(block) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function getAllRam() | 
					
						
							|  |  |  |     uRangeRAM(0,128); | 
					
						
							|  |  |  |     return data | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | local function alive_mode() | 
					
						
							|  |  |  |     return (u8(PlayerRoomAddr) ~= 0x00 and u8(WinAddr) == 0x00) | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | local function generateLocationsChecked() | 
					
						
							|  |  |  |     list_of_locations = {} | 
					
						
							|  |  |  |     for s, f in pairs(pending_foreign_items_collected) do | 
					
						
							|  |  |  |         table.insert(list_of_locations, f.short_location_id + 118000000) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |     for s, f in pairs(pending_local_items_collected) do | 
					
						
							|  |  |  |         table.insert(list_of_locations, f + 118000000) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |     return list_of_locations | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function receive() | 
					
						
							|  |  |  |     l, e = atariSocket:receive() | 
					
						
							|  |  |  |     if e == 'closed' then | 
					
						
							|  |  |  |         if curstate == STATE_OK then | 
					
						
							|  |  |  |             print("Connection closed") | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |         curstate = STATE_UNINITIALIZED | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  |     elseif e == 'timeout' then | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  |     elseif e ~= nil then | 
					
						
							|  |  |  |         print(e) | 
					
						
							|  |  |  |         curstate = STATE_UNINITIALIZED | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |     if l ~= nil then | 
					
						
							|  |  |  |         processBlock(json.decode(l)) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |     -- Determine Message to send back | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     newSha256 = memory.hash_region(0xF000, 0x1000, "System Bus") | 
					
						
							|  |  |  |     if (sha256hash ~= nil and sha256hash ~= newSha256) then | 
					
						
							|  |  |  |         print("ROM changed, quitting") | 
					
						
							|  |  |  |         curstate = STATE_UNINITIALIZED | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |     sha256hash = newSha256 | 
					
						
							|  |  |  |     local retTable = {} | 
					
						
							|  |  |  |     retTable["scriptVersion"] = SCRIPT_VERSION | 
					
						
							|  |  |  |     retTable["romhash"] = sha256hash | 
					
						
							|  |  |  |     if (alive_mode()) then | 
					
						
							|  |  |  |         retTable["locations"] = generateLocationsChecked() | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |     if (u8(WinAddr) ~= 0x00) then | 
					
						
							|  |  |  |         retTable["victory"] = 1 | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |     if( deathlink_sent or deathlink_send == 0 ) then | 
					
						
							|  |  |  |         retTable["deathLink"] = 0 | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         print("Sending deathlink "..tostring(deathlink_send)) | 
					
						
							|  |  |  |         retTable["deathLink"] = deathlink_send | 
					
						
							|  |  |  |         deathlink_sent = true | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |     deathlink_send = 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if send_freeincarnate_used == true then | 
					
						
							|  |  |  |         print("Sending freeincarnate used") | 
					
						
							|  |  |  |         retTable["freeincarnate"] = true | 
					
						
							|  |  |  |         send_freeincarnate_used = false | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     msg = json.encode(retTable).."\n" | 
					
						
							|  |  |  |     local ret, error = atariSocket:send(msg) | 
					
						
							|  |  |  |     if ret == nil then | 
					
						
							|  |  |  |         print(error) | 
					
						
							|  |  |  |     elseif curstate == STATE_INITIAL_CONNECTION_MADE then | 
					
						
							|  |  |  |         curstate = STATE_TENTATIVELY_CONNECTED | 
					
						
							|  |  |  |     elseif curstate == STATE_TENTATIVELY_CONNECTED then | 
					
						
							|  |  |  |         print("Connected!") | 
					
						
							|  |  |  |         curstate = STATE_OK | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function AutocollectFromRoom() | 
					
						
							|  |  |  |     if autocollect_items ~= nil and autocollect_items[prev_player_room] ~= nil then | 
					
						
							|  |  |  |         for _, item in pairs(autocollect_items[prev_player_room]) do | 
					
						
							|  |  |  |             pending_foreign_items_collected[item.short_location_id] = item | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function SetYorgleSpeed() | 
					
						
							|  |  |  |     if yorgle_speed ~= nil then | 
					
						
							|  |  |  |         emu.setregister("A", yorgle_speed); | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function SetGrundleSpeed() | 
					
						
							|  |  |  |     if grundle_speed ~= nil then | 
					
						
							|  |  |  |         emu.setregister("A", grundle_speed); | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function SetRhindleSpeed() | 
					
						
							|  |  |  |     if rhindle_speed ~= nil then | 
					
						
							|  |  |  |         emu.setregister("A", rhindle_speed); | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function SetDifficultySwitchB() | 
					
						
							|  |  |  |     if diff_b_locked then | 
					
						
							|  |  |  |         local a = emu.getregister("A") | 
					
						
							|  |  |  |         if a < 128 then | 
					
						
							|  |  |  |             emu.setregister("A", a + 128) | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function SetDifficultySwitchA() | 
					
						
							|  |  |  |     if diff_a_locked then | 
					
						
							|  |  |  |         local a = emu.getregister("A") | 
					
						
							|  |  |  |         if (a > 128 and a < 128 + 64) or (a < 64) then | 
					
						
							|  |  |  |             emu.setregister("A", a + 64) | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function TryFreeincarnate() | 
					
						
							|  |  |  |     if freeincarnates_available > 0 then | 
					
						
							|  |  |  |         freeincarnates_available = freeincarnates_available - 1 | 
					
						
							|  |  |  |         for index, state_addr in pairs(DragonState) do | 
					
						
							|  |  |  |             if last_dragon_state[index] == 1 then | 
					
						
							|  |  |  |                 send_freeincarnate_used = true | 
					
						
							|  |  |  |                 memory.write_u8(state_addr, 1, "System Bus") | 
					
						
							|  |  |  |                 local msg = {TTL=450, message="used freeincarnate", color=0xFF00FF00} | 
					
						
							|  |  |  |                 itemMessages[-1] = msg | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function GetLinkedObject() | 
					
						
							|  |  |  |     if emu.getregister("X") == batRoomAddr then | 
					
						
							|  |  |  |         bat_interest_item = emu.getregister("A") | 
					
						
							|  |  |  |         -- if the bat can't touch that item, we'll switch it to the number item, which should never be | 
					
						
							|  |  |  |         -- in the same room as the bat. | 
					
						
							|  |  |  |         if bat_no_touch_items[bat_interest_item] ~= nil then | 
					
						
							|  |  |  |             emu.setregister("A", 0xDD ) | 
					
						
							|  |  |  |             emu.setregister("Y", 0xDD ) | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function CheckCollectAPItem(carry_item, target_item_value, target_item_ram, rendering_foreign_item) | 
					
						
							|  |  |  |     if( carry_item == target_item_value and rendering_foreign_item ~= nil ) then | 
					
						
							|  |  |  |         memory.write_u8(carryAddress, nullObjectId, "System Bus") | 
					
						
							|  |  |  |         memory.write_u8(target_item_ram, 0xFF, "System Bus") | 
					
						
							|  |  |  |         pending_foreign_items_collected[rendering_foreign_item.short_location_id] = rendering_foreign_item | 
					
						
							|  |  |  |         for index, fi in pairs(foreign_items_by_room[rendering_foreign_item.room_id]) do | 
					
						
							|  |  |  |             if( fi.short_location_id == rendering_foreign_item.short_location_id ) then | 
					
						
							|  |  |  |                 table.remove(foreign_items_by_room[rendering_foreign_item.room_id], index) | 
					
						
							|  |  |  |                 break | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |         for index, fi in pairs(foreign_items) do | 
					
						
							|  |  |  |             if( fi.short_location_id == rendering_foreign_item.short_location_id ) then | 
					
						
							|  |  |  |                 foreign_items[index] = nil | 
					
						
							|  |  |  |                 break | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |         prev_ap_room_index = 0 | 
					
						
							|  |  |  |         return true | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |     return false | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function BatCanTouchForeign(foreign_item, bat_room) | 
					
						
							|  |  |  |     if bat_no_touch_locations_by_room[bat_room] == nil or bat_no_touch_locations_by_room[bat_room][1] == nil then | 
					
						
							|  |  |  |         return true | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for index, location in ipairs(bat_no_touch_locations_by_room[bat_room]) do | 
					
						
							|  |  |  |         if location.short_location_id == foreign_item.short_location_id then | 
					
						
							|  |  |  |             return false | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |     return true; | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function main() | 
					
						
							|  |  |  |     memory.usememorydomain("System Bus") | 
					
						
							| 
									
										
										
										
											2023-06-26 16:53:44 +10:00
										 |  |  |     if not checkBizHawkVersion() then | 
					
						
							| 
									
										
										
										
											2023-03-22 07:25:55 -07:00
										 |  |  |         return | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |     local playerSlot = memory.read_u8(PlayerSlotAddress) | 
					
						
							|  |  |  |     local port = 17242 + playerSlot | 
					
						
							|  |  |  |     print("Using port"..tostring(port)) | 
					
						
							|  |  |  |     server, error = socket.bind('localhost', port) | 
					
						
							|  |  |  |     if( error ~= nil ) then | 
					
						
							|  |  |  |         print(error) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |     event.onmemoryexecute(SetYorgleSpeed, yorgle_speed_address); | 
					
						
							|  |  |  |     event.onmemoryexecute(SetGrundleSpeed, grundle_speed_address); | 
					
						
							|  |  |  |     event.onmemoryexecute(SetRhindleSpeed, rhindle_speed_address); | 
					
						
							|  |  |  |     event.onmemoryexecute(SetDifficultySwitchA, read_switch_a) | 
					
						
							|  |  |  |     event.onmemoryexecute(SetDifficultySwitchB, read_switch_b) | 
					
						
							|  |  |  |     event.onmemoryexecute(GetLinkedObject, batItemCheckAddr) | 
					
						
							|  |  |  |     -- TODO: Add an onmemoryexecute event to intercept the bat reading item rooms, and don't 'see' an item in the | 
					
						
							|  |  |  |     -- room if it is in bat_no_touch_locations_by_room.  Although realistically, I may have to handle this in the rom | 
					
						
							|  |  |  |     -- for it to be totally reliable, because it won't work before the script connects (I might have to reset them?) | 
					
						
							|  |  |  |     -- TODO: Also remove those items from the bat_no_touch_locations_by_room if they have been collected | 
					
						
							|  |  |  |     while true do | 
					
						
							|  |  |  |         frame = frame + 1 | 
					
						
							|  |  |  |         drawMessages() | 
					
						
							|  |  |  |         if not (curstate == prevstate) then | 
					
						
							|  |  |  |             print("Current state: "..curstate) | 
					
						
							|  |  |  |             prevstate = curstate | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         local current_player_room = u8(PlayerRoomAddr) | 
					
						
							|  |  |  |         local bat_room = u8(batRoomAddr) | 
					
						
							|  |  |  |         local bat_carrying_item = u8(batCarryAddress) | 
					
						
							|  |  |  |         local bat_carrying_ap_item = (BatAPItemRam == bat_carrying_item) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if current_player_room == 0x1E then | 
					
						
							|  |  |  |             if u8(PlayerRoomAddr + 1) > 0x4B then | 
					
						
							|  |  |  |                 memory.write_u8(PlayerRoomAddr + 1, 0x4B) | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if current_player_room == 0x00 then | 
					
						
							|  |  |  |             if not was_in_number_room then | 
					
						
							|  |  |  |                 print("reset "..tostring(bat_carrying_ap_item).." "..tostring(bat_carrying_item)) | 
					
						
							|  |  |  |                 memory.write_u8(batCarryAddress, batInvalidCarryItem) | 
					
						
							|  |  |  |                 memory.write_u8(batCarryAddress+ 1, 0) | 
					
						
							|  |  |  |                 createForeignItemsByRoom() | 
					
						
							|  |  |  |                 memory.write_u8(BatAPItemRam, 0xff) | 
					
						
							|  |  |  |                 memory.write_u8(APItemRam, 0xff) | 
					
						
							|  |  |  |                 prev_ap_room_index = 0 | 
					
						
							|  |  |  |                 prev_player_room = 0 | 
					
						
							|  |  |  |                 rendering_foreign_item = nil | 
					
						
							|  |  |  |                 was_in_number_room = true | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             was_in_number_room = false | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if bat_room ~= prev_bat_room then | 
					
						
							|  |  |  |             if bat_carrying_ap_item then | 
					
						
							|  |  |  |                 if foreign_items_by_room[prev_bat_room] ~= nil then | 
					
						
							|  |  |  |                     for r,f in pairs(foreign_items_by_room[prev_bat_room]) do | 
					
						
							|  |  |  |                         if f.short_location_id == current_bat_ap_item.short_location_id then | 
					
						
							|  |  |  |                             -- print("removing item from "..tostring(r).." in "..tostring(prev_bat_room)) | 
					
						
							|  |  |  |                             table.remove(foreign_items_by_room[prev_bat_room], r) | 
					
						
							|  |  |  |                             break | 
					
						
							|  |  |  |                         end | 
					
						
							|  |  |  |                     end | 
					
						
							|  |  |  |                 end | 
					
						
							|  |  |  |                 if foreign_items_by_room[bat_room] == nil then | 
					
						
							|  |  |  |                     foreign_items_by_room[bat_room] = {} | 
					
						
							|  |  |  |                 end | 
					
						
							|  |  |  |                 -- print("adding item to "..tostring(bat_room)) | 
					
						
							|  |  |  |                 table.insert(foreign_items_by_room[bat_room], current_bat_ap_item) | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |                 -- set AP item room and position for new room, or to invalid room | 
					
						
							|  |  |  |                 if foreign_items_by_room[bat_room] ~= nil and foreign_items_by_room[bat_room][1] ~= nil | 
					
						
							|  |  |  |                             and BatCanTouchForeign(foreign_items_by_room[bat_room][1], bat_room) then | 
					
						
							|  |  |  |                     if current_bat_ap_item ~= foreign_items_by_room[bat_room][1] then | 
					
						
							|  |  |  |                         current_bat_ap_item = foreign_items_by_room[bat_room][1] | 
					
						
							|  |  |  |                         -- print("Changing bat item to "..tostring(current_bat_ap_item.short_location_id)) | 
					
						
							|  |  |  |                     end | 
					
						
							|  |  |  |                     memory.write_u8(BatAPItemRam, bat_room) | 
					
						
							|  |  |  |                     memory.write_u8(BatAPItemRam + 1, current_bat_ap_item.room_x) | 
					
						
							|  |  |  |                     memory.write_u8(BatAPItemRam + 2, current_bat_ap_item.room_y) | 
					
						
							|  |  |  |                 else | 
					
						
							|  |  |  |                     memory.write_u8(BatAPItemRam, 0xff) | 
					
						
							|  |  |  |                     if current_bat_ap_item ~= nil then | 
					
						
							|  |  |  |                         -- print("clearing bat item") | 
					
						
							|  |  |  |                     end | 
					
						
							|  |  |  |                     current_bat_ap_item = nil | 
					
						
							|  |  |  |                 end | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |         prev_bat_room = bat_room | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         -- update foreign_items_by_room position and room id for bat item if bat carrying an item | 
					
						
							|  |  |  |         if bat_carrying_ap_item then | 
					
						
							|  |  |  |             -- this is setting the item using the bat's position, which is somewhat wrong, but I think | 
					
						
							|  |  |  |             -- there will be more problems with the room not matching sometimes if I use the actual item position | 
					
						
							|  |  |  |             current_bat_ap_item.room_id = bat_room | 
					
						
							|  |  |  |             current_bat_ap_item.room_x = u8(batRoomAddr + 1) | 
					
						
							|  |  |  |             current_bat_ap_item.room_y = u8(batRoomAddr + 2) | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (alive_mode()) then | 
					
						
							|  |  |  |             if (current_player_room ~= prev_player_room) then | 
					
						
							|  |  |  |                 memory.write_u8(APItemRam, 0xFF, "System Bus") | 
					
						
							|  |  |  |                 prev_ap_room_index = 0 | 
					
						
							|  |  |  |                 prev_player_room = current_player_room | 
					
						
							|  |  |  |                 AutocollectFromRoom() | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  |             local carry_item = memory.read_u8(carryAddress, "System Bus") | 
					
						
							|  |  |  |             bat_no_touch_items[carry_item] = nil | 
					
						
							|  |  |  |             if (next_inventory_item ~= nil) then | 
					
						
							|  |  |  |                 if ( carry_item == nullObjectId and last_carry_item == nullObjectId ) then | 
					
						
							|  |  |  |                     frames_with_no_item = frames_with_no_item + 1 | 
					
						
							|  |  |  |                     if (frames_with_no_item > 10) then | 
					
						
							|  |  |  |                         frames_with_no_item = 10 | 
					
						
							|  |  |  |                         local input_value = memory.read_u8(input_button_address, "System Bus") | 
					
						
							|  |  |  |                         if( input_value >= 64 and input_value < 128 ) then -- high bit clear, second highest bit set | 
					
						
							|  |  |  |                             memory.write_u8(carryAddress, next_inventory_item) | 
					
						
							|  |  |  |                             local item_ram_location = memory.read_u8(ItemTableStart + next_inventory_item) | 
					
						
							|  |  |  |                             if( memory.read_u8(batCarryAddress) ~= 0x78 and | 
					
						
							|  |  |  |                                     memory.read_u8(batCarryAddress) == item_ram_location) then | 
					
						
							|  |  |  |                                 memory.write_u8(batCarryAddress, batInvalidCarryItem) | 
					
						
							|  |  |  |                                 memory.write_u8(batCarryAddress+ 1, 0) | 
					
						
							|  |  |  |                                 memory.write_u8(item_ram_location, current_player_room) | 
					
						
							|  |  |  |                                 memory.write_u8(item_ram_location + 1, memory.read_u8(PlayerRoomAddr + 1)) | 
					
						
							|  |  |  |                                 memory.write_u8(item_ram_location + 2, memory.read_u8(PlayerRoomAddr + 2)) | 
					
						
							|  |  |  |                             end | 
					
						
							|  |  |  |                             ItemIndex = ItemIndex + 1 | 
					
						
							|  |  |  |                             next_inventory_item = nil | 
					
						
							|  |  |  |                         end | 
					
						
							|  |  |  |                     end | 
					
						
							|  |  |  |                 else | 
					
						
							|  |  |  |                     frames_with_no_item = 0 | 
					
						
							|  |  |  |                 end | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  |             if( carry_item ~= last_carry_item ) then | 
					
						
							|  |  |  |                 if ( localItemLocations ~= nil and localItemLocations[tostring(carry_item)] ~= nil ) then | 
					
						
							|  |  |  |                     pending_local_items_collected[localItemLocations[tostring(carry_item)]] = | 
					
						
							|  |  |  |                         localItemLocations[tostring(carry_item)] | 
					
						
							| 
									
										
										
										
											2023-04-15 07:28:37 -07:00
										 |  |  |                     localItemLocations[tostring(carry_item)] = nil | 
					
						
							| 
									
										
										
										
											2023-03-22 07:25:55 -07:00
										 |  |  |                     skip_inventory_items[carry_item] = carry_item | 
					
						
							|  |  |  |                 end | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  |             last_carry_item = carry_item | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             CheckCollectAPItem(carry_item, APItemValue, APItemRam, rendering_foreign_item) | 
					
						
							|  |  |  |             if CheckCollectAPItem(carry_item, BatAPItemValue, BatAPItemRam, current_bat_ap_item) and bat_carrying_ap_item then | 
					
						
							|  |  |  |                 memory.write_u8(batCarryAddress, batInvalidCarryItem) | 
					
						
							|  |  |  |                 memory.write_u8(batCarryAddress+ 1, 0) | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             rendering_foreign_item = nil | 
					
						
							|  |  |  |             if( foreign_items_by_room[current_player_room] ~= nil ) then | 
					
						
							|  |  |  |                 if( foreign_items_by_room[current_player_room][prev_ap_room_index] ~= nil ) and memory.read_u8(APItemRam) ~= 0xff then | 
					
						
							|  |  |  |                     foreign_items_by_room[current_player_room][prev_ap_room_index].room_x = memory.read_u8(APItemRam + 1) | 
					
						
							|  |  |  |                     foreign_items_by_room[current_player_room][prev_ap_room_index].room_y = memory.read_u8(APItemRam + 2) | 
					
						
							|  |  |  |                 end | 
					
						
							|  |  |  |                 prev_ap_room_index = prev_ap_room_index + 1 | 
					
						
							|  |  |  |                 local invalid_index = -1 | 
					
						
							|  |  |  |                 if( foreign_items_by_room[current_player_room][prev_ap_room_index] == nil ) then | 
					
						
							|  |  |  |                     prev_ap_room_index = 1 | 
					
						
							|  |  |  |                 end | 
					
						
							|  |  |  |                 if( foreign_items_by_room[current_player_room][prev_ap_room_index] ~= nil and current_bat_ap_item ~= nil and | 
					
						
							|  |  |  |                     foreign_items_by_room[current_player_room][prev_ap_room_index].short_location_id == current_bat_ap_item.short_location_id) then | 
					
						
							|  |  |  |                     invalid_index = prev_ap_room_index | 
					
						
							|  |  |  |                     prev_ap_room_index = prev_ap_room_index + 1 | 
					
						
							|  |  |  |                     if( foreign_items_by_room[current_player_room][prev_ap_room_index] == nil ) then | 
					
						
							|  |  |  |                         prev_ap_room_index = 1 | 
					
						
							|  |  |  |                     end | 
					
						
							|  |  |  |                 end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if( foreign_items_by_room[current_player_room][prev_ap_room_index] ~= nil and prev_ap_room_index ~= invalid_index ) then | 
					
						
							|  |  |  |                     memory.write_u8(APItemRam, current_player_room) | 
					
						
							|  |  |  |                     rendering_foreign_item = foreign_items_by_room[current_player_room][prev_ap_room_index] | 
					
						
							|  |  |  |                     memory.write_u8(APItemRam + 1, rendering_foreign_item.room_x) | 
					
						
							|  |  |  |                     memory.write_u8(APItemRam + 2, rendering_foreign_item.room_y) | 
					
						
							|  |  |  |                 else | 
					
						
							|  |  |  |                     memory.write_u8(APItemRam, 0xFF, "System Bus") | 
					
						
							|  |  |  |                 end | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  |             if is_dead == 0 then | 
					
						
							|  |  |  |                 dragons_revived = false | 
					
						
							|  |  |  |                 player_dead = false | 
					
						
							|  |  |  |                 new_dragon_state = {0,0,0} | 
					
						
							|  |  |  |                 for index, dragon_state_addr in pairs(DragonState) do | 
					
						
							|  |  |  |                     new_dragon_state[index] = memory.read_u8(dragon_state_addr, "System Bus" ) | 
					
						
							|  |  |  |                     if last_dragon_state[index] == 1 and new_dragon_state[index] ~= 1 then | 
					
						
							|  |  |  |                         dragons_revived = true | 
					
						
							|  |  |  |                     elseif last_dragon_state[index] ~= 1 and new_dragon_state[index] == 1 then | 
					
						
							|  |  |  |                         dragon_real_index = index - 1 | 
					
						
							|  |  |  |                         print("Killed dragon: "..tostring(dragon_real_index)) | 
					
						
							|  |  |  |                         local dragon_item = {} | 
					
						
							|  |  |  |                         dragon_item["short_location_id"] = 0xD0 + dragon_real_index | 
					
						
							|  |  |  |                         pending_foreign_items_collected[dragon_item.short_location_id] = dragon_item | 
					
						
							|  |  |  |                     end | 
					
						
							|  |  |  |                     if new_dragon_state[index] == 2 then | 
					
						
							|  |  |  |                         player_dead = true | 
					
						
							|  |  |  |                     end | 
					
						
							|  |  |  |                 end | 
					
						
							|  |  |  |                 if dragons_revived and player_dead == false then | 
					
						
							|  |  |  |                     TryFreeincarnate() | 
					
						
							|  |  |  |                 end | 
					
						
							|  |  |  |                 last_dragon_state = new_dragon_state | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  |         elseif (u8(PlayerRoomAddr) == 0x00) then -- not alive mode, in number room | 
					
						
							|  |  |  |             ItemIndex = 0  -- reset our inventory | 
					
						
							|  |  |  |             next_inventory_item = nil | 
					
						
							|  |  |  |             skip_inventory_items = {} | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |         if (curstate == STATE_OK) or (curstate == STATE_INITIAL_CONNECTION_MADE) or (curstate == STATE_TENTATIVELY_CONNECTED) then | 
					
						
							|  |  |  |             if (frame % 5 == 0) then | 
					
						
							|  |  |  |                 receive() | 
					
						
							|  |  |  |                 if alive_mode() then | 
					
						
							|  |  |  |                     local was_dead = is_dead | 
					
						
							|  |  |  |                     is_dead = 0 | 
					
						
							|  |  |  |                     for index, dragonStateAddr in pairs(DragonState) do | 
					
						
							|  |  |  |                         local dragonstateval = memory.read_u8(dragonStateAddr, "System Bus") | 
					
						
							|  |  |  |                         if ( dragonstateval == 2) then | 
					
						
							|  |  |  |                             is_dead = index | 
					
						
							|  |  |  |                         end | 
					
						
							|  |  |  |                     end | 
					
						
							|  |  |  |                     if was_dead ~= 0 and is_dead == 0 then | 
					
						
							|  |  |  |                         TryFreeincarnate() | 
					
						
							|  |  |  |                     end | 
					
						
							|  |  |  |                     if deathlink_rec == true and is_dead == 0 then | 
					
						
							|  |  |  |                         print("setting dead from deathlink") | 
					
						
							|  |  |  |                         deathlink_rec = false | 
					
						
							|  |  |  |                         deathlink_sent = true | 
					
						
							|  |  |  |                         is_dead = 1 | 
					
						
							|  |  |  |                         memory.write_u8(carryAddress, nullObjectId, "System Bus") | 
					
						
							|  |  |  |                         memory.write_u8(DragonState[1], 2, "System Bus") | 
					
						
							|  |  |  |                     end | 
					
						
							|  |  |  |                     if (is_dead > 0 and deathlink_send == 0 and not deathlink_sent) then | 
					
						
							|  |  |  |                         deathlink_send = is_dead | 
					
						
							|  |  |  |                         print("setting deathlink_send to "..tostring(is_dead)) | 
					
						
							|  |  |  |                     elseif (is_dead == 0) then | 
					
						
							|  |  |  |                         deathlink_send = 0 | 
					
						
							|  |  |  |                         deathlink_sent = false | 
					
						
							|  |  |  |                     end | 
					
						
							|  |  |  |                     if ItemsReceived ~= nil and ItemsReceived[ItemIndex + 1] ~= nil then | 
					
						
							|  |  |  |                         while ItemsReceived[ItemIndex + 1] ~= nil and skip_inventory_items[ItemsReceived[ItemIndex + 1]] ~= nil do | 
					
						
							|  |  |  |                             print("skip") | 
					
						
							|  |  |  |                             ItemIndex = ItemIndex + 1 | 
					
						
							|  |  |  |                         end | 
					
						
							|  |  |  |                         local static_id = ItemsReceived[ItemIndex + 1] | 
					
						
							|  |  |  |                         if static_id ~= nil then | 
					
						
							|  |  |  |                             inventory[static_id] = 1 | 
					
						
							|  |  |  |                             if next_inventory_item == nil then | 
					
						
							|  |  |  |                                 next_inventory_item = static_id | 
					
						
							|  |  |  |                             end | 
					
						
							|  |  |  |                         end | 
					
						
							|  |  |  |                     end | 
					
						
							|  |  |  |                 end | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  |         elseif (curstate == STATE_UNINITIALIZED) then | 
					
						
							|  |  |  |             if  (frame % 60 == 0) then | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 print("Waiting for client.") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 emu.frameadvance() | 
					
						
							|  |  |  |                 server:settimeout(2) | 
					
						
							|  |  |  |                 print("Attempting to connect") | 
					
						
							|  |  |  |                 local client, timeout = server:accept() | 
					
						
							|  |  |  |                 if timeout == nil then | 
					
						
							|  |  |  |                     print("Initial connection made") | 
					
						
							|  |  |  |                     curstate = STATE_INITIAL_CONNECTION_MADE | 
					
						
							|  |  |  |                     atariSocket = client | 
					
						
							|  |  |  |                     atariSocket:settimeout(0) | 
					
						
							|  |  |  |                 end | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |         emu.frameadvance() | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | main() |