build_request: type: task debug: false definitions: schematic|pasteloc|npc|build_delay|finishfunction|finishvars1|finishvars2|npcstart script: # active_builds is used to restart builds when the servers goes down - if : - flag server active_builds: - if <[npc].exists.not> or <[npc].equals[0]>: - define npc # the builder - else: - define npc ]> - if <[npcstart].exists.not>: - define npcstart <[npc].location> - if <[build_delay].exists.not>: - define build_delay 3s # The schematic must include the file extention - if ].not>: - determine false - define schem <[schematic].split[.].get[1]> - if ].not>: - ~schematic load name:<[schem]> delayed # buildkey is just a refrence point for use with the active_builds flag - define buildkey <[schematic]><[pasteloc]> - if ].not>: - flag server active_builds:].as[;pasteloc=<[pasteloc]>;npc=<[npc].id>;build_delay=<[build_delay]>;finishfunction=<[finishfunction]>;finishvars1=<[finishvars1]>;finishvars2=<[finishvars2]>;npcstart=<[npcstart]>]>]> # All this stuff below is just because the schematic as it read Z->Y->X for vertical placement and this all changes it to Z->X->Y for horizontal placement. - define pastecuboid ].cuboid[<[pasteloc]>]> - define schem_x ].width> - define schem_y ].length> - define schem_z ].height> - define start <[pastecuboid].corners.first> - define starty <[start].y> - define startx <[start].x> - define startxsave <[startx]> - define pasteblocks <[pastecuboid].blocks> - define counter_x 0 - define counter_y 0 - define counter_z 0 # walk the NPC to the job site. Mind NPCs max pathing range. - walk <[npc]> <[pastecuboid].corners.first> auto_range - wait 1s system - while <[npc].is_navigating>: - wait 3s system - repeat <[schem_y]>: - repeat <[schem_x]>: - foreach <[pasteblocks]> as:worldloc: - if <[worldloc].y.equals[<[starty]>]>: - if <[worldloc].x.equals[<[startx]>]>: - define block ].block[<[counter_x]>,<[counter_y]>,<[counter_z]>]> # if the schematic block and world block are not the same then change it - if <[block].name.equals[<[worldloc].material.name>].not>: # if Wait time is in ticks, then just skip all the fanfair we are probably testing. - if <[build_delay].contains_text[t].not>: - walk <[npc]> <[worldloc]> auto_range - wait 1t - while <[npc].is_navigating>: - wait 1t - equip <[npc]> hand:<[block].name> - define currentmat <[worldloc].material.name> - if <[currentmat].equals[air].not>: # ~break <[worldloc]> <[npc]> # I would sometimes have issues where the NPC would ignore the break command and since it was awaited it would freeze the entire script so... added below to try and move it along. Im not sure if its hard rule but I found NPC break time was about 1.6 * block strength if > 2 seconds. - define waittime_breakblock <[worldloc].material.block_strength.mul[1.6].add[1]> - break <[worldloc]> <[npc]> - if <[waittime_breakblock].is_less_than[2.5]>: - define waittime_breakblock 2.5 # one of the few waits where we don't want it on system time, we want the wait to lag with the server if its lagging... # this wait really shouldnt be an issue.. unless you have another script meessing with the block too... - wait <[waittime_breakblock]>s # if whats there now is still what was there before then remove it and move on. - if <[worldloc].material.name.equals[<[currentmat]>]>: - adjust <[worldloc]> block_type:air - else: - adjust <[worldloc]> block_type:air - wait <[build_delay]> system - animate <[npc]> animation:arm_swing - adjust <[worldloc]> block_type:<[block]> - playsound <[worldloc]> sound:<[block].block_sound_data.get[place_sound]> pitch:1 volume:1 # for debugging /ex flag server stop:true duration:10s - if : - narrate "Stopped builder script" targets: - if ]>: - flag server active_builds:]> - stop - define counter_z:++ - define counter_z 0 - define startx:++ - define counter_x:++ - define startx:<[startxsave]> - define counter_x 0 - define starty:++ - define counter_y:++ # build complete so walk away from the build - equip <[npc]> hand:air - walk <[npc]> <[start].sub[0,0,10]> auto_range # run a function after done building - if <[finishfunction].exists> and <[finishfunction].equals[0].not>: - if <[finishvars1].exists> and <[finishvars1].equals[0].not>: - if <[finishvars2].exists> and <[finishvars2].equals[0].not>: - run <[finishfunction]> def:<[finishvars1]>|<[finishvars2]> - else: - run <[finishfunction]> def:<[finishvars1]> - else: - run <[finishfunction]> # remove the build from the list for server restarts. - if ]>: - flag server active_builds:]> # NPC is no longer building - if <[npc].has_flag[building]>: - flag <[npc]> building:! - wait 10s # walk the NPC back where it came from. Make sure to mind NPC pathing range (Like 20 by default) - walk <[npc]> <[npcstart]> auto_range restart_handler: type: world debug: true events: after server start: - foreach as:NPC: # remove the building flag from all NPCs, the server just started so none of them are building anymore. - flag <[npc]> building:! # active_builds is a server flag with all ongoing builds in it. - if and : # just holding off on builds till the server has a moment to finish booting up - wait 10s system - define wait_on_npcs - while <[wait_on_npcs].size.is_more_than[0]>: - foreach <[wait_on_npcs]> as:build: # if the NPC is building something skip it and see if there are other jobs for other NPCs - if <[build].get[npc].as[npc].has_flag[building]>: - foreach next # remove if needed, I just like to remove extra processing automatically when the servers lagging. - while : - wait 10s system - flag <[build].get[npc].as[npc]> building:true - run build_request def.schematic:<[build].get[schematic]> def.pasteloc:<[build].get[pasteloc]> def.npc:<[build].get[npc]> def.build_delay:<[build].get[build_delay]> def.finishfunction:<[build].get[finishfunction]> def.finishvars1:<[build].get[finishvars1]> def.finishvars2:<[build].get[finishvars2]> def.npcstart:<[build].get[npcstart]> # this NPC was not busy and the build request was sent so lets cross it off the list to keep checking in the top while loop above. - if <[wait_on_npcs].size.equals[1]>: - define wait_on_npcs - else: - define wait_on_npcs:<-:<[key]> # wait before assigning each build. abit of a anti lang thing. - wait 10s system # After cycling through all builds if there is still builds left (npcs are busy building) then wait 30 seconds and see if they are done building. Their flag gets cleared at the end of build_request - wait 30s system