diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..83fabae --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +build +build/* +factorio_mods diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e0f7493 --- /dev/null +++ b/LICENSE @@ -0,0 +1,13 @@ +Copyright (c) 2016, Afforess + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e6277ce --- /dev/null +++ b/Makefile @@ -0,0 +1,42 @@ +PACKAGE_NAME := Big_Brother +VERSION_STRING := 0.1.0 + +OUTPUT_NAME := $(PACKAGE_NAME)_$(VERSION_STRING) +OUTPUT_DIR := build/$(OUTPUT_NAME) + +PKG_COPY := $(wildcard *.md) graphics locale + +SED_FILES := $(shell find . -iname '*.json' -type f -not -path "./build/*") $(shell find . -iname '*.lua' -type f -not -path "./build/*") +OUT_FILES := $(SED_FILES:%=$(OUTPUT_DIR)/%) + +SED_EXPRS := -e 's/{{MOD_NAME}}/$(PACKAGE_NAME)/g' +SED_EXPRS += -e 's/{{VERSION}}/$(VERSION_STRING)/g' + +all: clean package install_mod + +package-copy: $(PKG_DIRS) $(PKG_FILES) + mkdir -p $(OUTPUT_DIR) +ifneq ($(PKG_COPY),) + cp -r $(PKG_COPY) build/$(OUTPUT_NAME) +endif + +$(OUTPUT_DIR)/%.lua: %.lua + @mkdir -p $(@D) + @sed $(SED_EXPRS) $< > $@ + luac -p $@ + +$(OUTPUT_DIR)/%: % + mkdir -p $(@D) + sed $(SED_EXPRS) $< > $@ + +package: package-copy $(OUT_FILES) + cd build && zip -r $(OUTPUT_NAME).zip $(OUTPUT_NAME) + +clean: + rm -rf build/ + +install_mod: + if [ -L factorio_mods ] ; \ + then \ + cp -R build/$(OUTPUT_NAME) factorio_mods ; \ + fi; diff --git a/README.md b/README.md new file mode 100644 index 0000000..e93fbb1 --- /dev/null +++ b/README.md @@ -0,0 +1,12 @@ +Repository for the Factorio Concrete Logistics mod. + +Description +=========== + +Mod compatibility +================= +Requires color-coding factorio mod. + +Contributing +============ +Contributions are welcome. diff --git a/control.lua b/control.lua new file mode 100644 index 0000000..508385c --- /dev/null +++ b/control.lua @@ -0,0 +1,263 @@ +require 'defines' +require 'stdlib/string' +require 'stdlib/surface' +require 'stdlib/table' +require 'stdlib/event/event' +require 'stdlib/log/logger' +require 'stdlib/area/position' +require 'stdlib/entity/entity' + +LOGGER = Logger.new('Big_Brother', 'main', true) +MAX_SURVEILLANCE_DISTANCE = 25000 +MAX_SURVEILLANCE_DISTANCE_SQUARED = MAX_SURVEILLANCE_DISTANCE * MAX_SURVEILLANCE_DISTANCE + +Event.register({defines.events.on_built_entity, defines.events.on_robot_built_entity}, function(event) + local entity = event.created_entity + local name = entity.name + if name == 'radar' then + track_entity('radars', entity) + upgrade_radars(entity.force) + elseif name == 'big-electric-pole' then + track_entity('power_poles', entity) + if entity.force.technologies['surveillance-2'].researched then + update_surveillance(entity, false) + end + elseif entity.type == 'car' then + track_entity('vehicles', entity) + update_surveillance(entity, true) + elseif entity.type == 'locomotive' then + track_entity('trains', entity) + update_surveillance(entity, true) + elseif entity.name == 'big_brother-surveillance-center' then + entity.backer_name = '' + track_entity('surveillance_centers', entity) + if global.vehicles then + for _, vehicle in pairs(global.vehicles) do + update_surveillance(vehicle, true) + end + end + if global.trains then + for _, train in pairs(global.trains) do + update_surveillance(train, true) + end + end + end +end) + +-- Scan the map once if the mod has never been loaded (then deregister on_tick) +Event.register(defines.events.on_tick, function(event) + if not global.scanned_map then + if not global.map_scan_countdown then global.map_scan_countdown = 120 end + global.map_scan_countdown = global.map_scan_countdown - 1 + if global.map_scan_countdown <= 0 then + Event.remove(defines.events.on_tick, event._handler) + -- track all radars + local radars = Surface.find_all_entities({name = 'radar'}) + for i = 1, #radars do + track_entity('radars', radars[i]) + end + for _, force in pairs(game.forces) do + upgrade_radars(force) + end + + -- track all vehicles + local vehicles = Surface.find_all_entities({type = 'car'}) + for i = 1, #vehicles do + track_entity('vehicles', vehicles[i]) + end + + -- track all trains + local trains = Surface.find_all_entities({type = 'locomotive'}) + LOGGER.log("Locomotives found: " .. #trains) + for i = 1, #trains do + track_entity('trains', trains[i]) + end + + -- track all big-electric-poles + local power_poles = Surface.find_all_entities({name = 'big-electric-pole'}) + for i = 1, #power_poles do + track_entity('power_poles', power_poles[i]) + end + + global.map_scan_countdown = nil + global.scanned_map = true + end + end +end) + +Event.register(defines.events.on_research_finished, function(event) + local tech_name = event.research.name + if tech_name:starts_with('radar-amplifier') or tech_name:starts_with('radar-efficiency') then + -- update radars in 1 tick + local force = event.research.force + Event.register(defines.events.on_tick, function(event) + upgrade_radars(force) + + Event.remove(defines.events.on_tick, event._handler) + end) + elseif tech_name == 'surveillance-2' then + if global.power_poles and global.surveillance_centers then + local power_poles = global.power_poles + for i = #power_poles, 1, -1 do + local entity = power_poles[i] + if entity.valid then + update_surveillance(entity, false) + else + table.remove(power_poles, i) + end + end + end + end +end) + +Event.register(defines.events.on_sector_scanned, function(event) + if not global.following then return end + if event.radar.name == 'big_brother-surveillance-center' then + for i = #global.following, 1, -1 do + local entity = global.following[i] + if not entity.valid then + table.remove(global.following, i) + else + if entity.type == 'locomotive' then + local train = entity.train + local speed = train.speed + if math.abs(speed) > 0.05 then + chart_locomotive(entity, speed) + else + for _, wagon in pairs(train.cargo_wagons) do + entity.force.chart(entity.surface, Position.expand_to_area(wagon.position, 1)) + end + end + else + entity.force.chart(entity.surface, Position.expand_to_area(pos, 1)) + end + end + end + end +end) + +function chart_locomotive(entity, speed) + local pos = entity.position + + local x = pos.x + 16 * math.sin(2 * math.pi * entity.orientation) + local y = pos.y - 16 * math.cos(2 * math.pi * entity.orientation) + local area = {{x = x, y = y}, pos} + if pos.x < x then + area[1].x = pos.x + area[2].x = x + end + if pos.y < y then + area[1].y = pos.y + area[2].y = y + end + entity.force.chart(entity.surface, area) +end + +function upgrade_radars(force) + if not global.radars then return end + + local radar_efficiency_level = calculate_tech_level(force, 'radar-efficiency', 9) + local radar_amplifier_level = calculate_tech_level(force, 'radar-amplifier', 9) + local radar_name = 'big_brother-radar_ra-' .. radar_amplifier_level .. '_re-' .. radar_efficiency_level + LOGGER.log("Upgrading " .. force.name .. "'s radars to " .. radar_name) + for i = #global.radars, 1, -1 do + local radar = global.radars[i] + if not radar.valid then + table.remove(global.radars, i) + elseif radar.force == force then + local pos = radar.position + local direction = radar.direction + local health = radar.health + local surface = radar.surface + + LOGGER.log("Upgrading radar {" .. radar.name .. "} at " .. serpent.line(pos, {comment=false})) + + radar.destroy() + local new_radar = surface.create_entity({ name = radar_name, position = pos, direction = direction, force = force}) + new_radar.health = health + + global.radars[i] = new_radar + end + end +end + +function calculate_tech_level(force, tech_name, max_levels) + for i = max_levels, 1, -1 do + local full_tech_name = tech_name + if i > 1 then + full_tech_name = tech_name .. '-' .. i + end + + if force.technologies[full_tech_name].researched then + return i + end + end + return 0 +end + +function update_surveillance(entity, follow) + local surv_center = get_nearest_surveillance_center(entity.position, entity.surface, entity.force) + if surv_center then + local data = Entity.get_data(entity) + if not data then + if not follow then + local surveillance = entity.surface.create_entity({name = 'big_brother-surveillance-small', position = entity.position, force = entity.force}) + surveillance.destructible = false + surveillance.operable = false + surveillance.minable = false + data = { surveillance = surveillance } + Entity.set_data(entity, data) + else + track_entity('following', entity) + end + end + else + if follow then + if not global.following then return end + for i = #global.following, 1, -1 do + local data = global.following[i] + if data.entity == entity then + table.remove(global.following, i) + end + end + else + local data = Entity.get_data(entity) + if data and data.surveillance and data.surveillance.valid then + data.surveillance.destroy() + Entity.set_data(entity, nil) + end + end + end +end + +function get_nearest_surveillance_center(position, surface, force) + if global.surveillance_centers then + global.surveillance_centers = table.filter(global.surveillance_centers, Game.VALID_FILTER) + local list = table.filter(global.surveillance_centers, function(entity) + return entity.surface == surface and entity.force == force + end) + table.sort(list, function(a, b) + return Position.distance_squared(a.position, position) < Position.distance_squared(b.position, position) + end) + local nearest = table.first(list) + if nearest and Position.distance_squared(nearest.position, position) < MAX_SURVEILLANCE_DISTANCE_SQUARED then + return nearest + end + end +end + +function track_entity(category, entity) + if not global[category] then global[category] = {} end + local entity_list = global[category] + for i = #entity_list, 1, -1 do + local e = entity_list[i] + if not e.valid then + table.remove(entity_list, i) + elseif e == entity then + return false + end + end + + table.insert(entity_list, entity) + return true +end diff --git a/data-updates.lua b/data-updates.lua new file mode 100644 index 0000000..e69de29 diff --git a/data.lua b/data.lua new file mode 100755 index 0000000..f9fbb0e --- /dev/null +++ b/data.lua @@ -0,0 +1,5 @@ +require("prototypes.technology.radar") +require("prototypes.item.surveillance") +require("prototypes.recipe.surveillance") +require("prototypes.entity.radar") +require("prototypes.entity.surveillance") diff --git a/graphics/entity/radar/radar1.png b/graphics/entity/radar/radar1.png new file mode 100644 index 0000000..4fc5e96 Binary files /dev/null and b/graphics/entity/radar/radar1.png differ diff --git a/graphics/entity/radar/radar10.png b/graphics/entity/radar/radar10.png new file mode 100644 index 0000000..1046e4d Binary files /dev/null and b/graphics/entity/radar/radar10.png differ diff --git a/graphics/entity/radar/radar11.png b/graphics/entity/radar/radar11.png new file mode 100644 index 0000000..f5ab9b7 Binary files /dev/null and b/graphics/entity/radar/radar11.png differ diff --git a/graphics/entity/radar/radar12.png b/graphics/entity/radar/radar12.png new file mode 100644 index 0000000..966b757 Binary files /dev/null and b/graphics/entity/radar/radar12.png differ diff --git a/graphics/entity/radar/radar13.png b/graphics/entity/radar/radar13.png new file mode 100644 index 0000000..b347991 Binary files /dev/null and b/graphics/entity/radar/radar13.png differ diff --git a/graphics/entity/radar/radar14.png b/graphics/entity/radar/radar14.png new file mode 100644 index 0000000..7cf423a Binary files /dev/null and b/graphics/entity/radar/radar14.png differ diff --git a/graphics/entity/radar/radar15.png b/graphics/entity/radar/radar15.png new file mode 100644 index 0000000..734396a Binary files /dev/null and b/graphics/entity/radar/radar15.png differ diff --git a/graphics/entity/radar/radar16.png b/graphics/entity/radar/radar16.png new file mode 100644 index 0000000..2fe233a Binary files /dev/null and b/graphics/entity/radar/radar16.png differ diff --git a/graphics/entity/radar/radar2.png b/graphics/entity/radar/radar2.png new file mode 100644 index 0000000..1383ad0 Binary files /dev/null and b/graphics/entity/radar/radar2.png differ diff --git a/graphics/entity/radar/radar3.png b/graphics/entity/radar/radar3.png new file mode 100644 index 0000000..11a25f7 Binary files /dev/null and b/graphics/entity/radar/radar3.png differ diff --git a/graphics/entity/radar/radar4.png b/graphics/entity/radar/radar4.png new file mode 100644 index 0000000..8e68ed2 Binary files /dev/null and b/graphics/entity/radar/radar4.png differ diff --git a/graphics/entity/radar/radar5.png b/graphics/entity/radar/radar5.png new file mode 100644 index 0000000..ccaeb44 Binary files /dev/null and b/graphics/entity/radar/radar5.png differ diff --git a/graphics/entity/radar/radar6.png b/graphics/entity/radar/radar6.png new file mode 100644 index 0000000..4caf534 Binary files /dev/null and b/graphics/entity/radar/radar6.png differ diff --git a/graphics/entity/radar/radar7.png b/graphics/entity/radar/radar7.png new file mode 100644 index 0000000..36acbbd Binary files /dev/null and b/graphics/entity/radar/radar7.png differ diff --git a/graphics/entity/radar/radar8.png b/graphics/entity/radar/radar8.png new file mode 100644 index 0000000..25cd2fd Binary files /dev/null and b/graphics/entity/radar/radar8.png differ diff --git a/graphics/entity/radar/radar9.png b/graphics/entity/radar/radar9.png new file mode 100644 index 0000000..87b67b3 Binary files /dev/null and b/graphics/entity/radar/radar9.png differ diff --git a/graphics/entity/radar/split.sh b/graphics/entity/radar/split.sh new file mode 100755 index 0000000..de0bb38 --- /dev/null +++ b/graphics/entity/radar/split.sh @@ -0,0 +1,12 @@ +#!/bin/bash +files=(*.png) +count=64 +for ((i=${#files[@]}-1; i >= 0; i--)); do + convert -crop 306x262 "${files[$i]}" tile_%d.png + for j in {0..3}; do + mv "tile_$((3-${j})).png" "tile_${count}.png" + echo "Moving tile_$((3-${j})).png to tile_${count}.png" + count=$((count-1)) + done +done + diff --git a/graphics/entity/radar/tile_1.png b/graphics/entity/radar/tile_1.png new file mode 100644 index 0000000..3400469 Binary files /dev/null and b/graphics/entity/radar/tile_1.png differ diff --git a/graphics/entity/radar/tile_10.png b/graphics/entity/radar/tile_10.png new file mode 100644 index 0000000..a07f6f6 Binary files /dev/null and b/graphics/entity/radar/tile_10.png differ diff --git a/graphics/entity/radar/tile_11.png b/graphics/entity/radar/tile_11.png new file mode 100644 index 0000000..ed377dd Binary files /dev/null and b/graphics/entity/radar/tile_11.png differ diff --git a/graphics/entity/radar/tile_12.png b/graphics/entity/radar/tile_12.png new file mode 100644 index 0000000..4ff421e Binary files /dev/null and b/graphics/entity/radar/tile_12.png differ diff --git a/graphics/entity/radar/tile_13.png b/graphics/entity/radar/tile_13.png new file mode 100644 index 0000000..85b7de3 Binary files /dev/null and b/graphics/entity/radar/tile_13.png differ diff --git a/graphics/entity/radar/tile_14.png b/graphics/entity/radar/tile_14.png new file mode 100644 index 0000000..f5e3b13 Binary files /dev/null and b/graphics/entity/radar/tile_14.png differ diff --git a/graphics/entity/radar/tile_15.png b/graphics/entity/radar/tile_15.png new file mode 100644 index 0000000..cbae80d Binary files /dev/null and b/graphics/entity/radar/tile_15.png differ diff --git a/graphics/entity/radar/tile_16.png b/graphics/entity/radar/tile_16.png new file mode 100644 index 0000000..0ff8679 Binary files /dev/null and b/graphics/entity/radar/tile_16.png differ diff --git a/graphics/entity/radar/tile_17.png b/graphics/entity/radar/tile_17.png new file mode 100644 index 0000000..3750325 Binary files /dev/null and b/graphics/entity/radar/tile_17.png differ diff --git a/graphics/entity/radar/tile_18.png b/graphics/entity/radar/tile_18.png new file mode 100644 index 0000000..cd93394 Binary files /dev/null and b/graphics/entity/radar/tile_18.png differ diff --git a/graphics/entity/radar/tile_19.png b/graphics/entity/radar/tile_19.png new file mode 100644 index 0000000..839a502 Binary files /dev/null and b/graphics/entity/radar/tile_19.png differ diff --git a/graphics/entity/radar/tile_2.png b/graphics/entity/radar/tile_2.png new file mode 100644 index 0000000..fe9db96 Binary files /dev/null and b/graphics/entity/radar/tile_2.png differ diff --git a/graphics/entity/radar/tile_20.png b/graphics/entity/radar/tile_20.png new file mode 100644 index 0000000..6e84808 Binary files /dev/null and b/graphics/entity/radar/tile_20.png differ diff --git a/graphics/entity/radar/tile_21.png b/graphics/entity/radar/tile_21.png new file mode 100644 index 0000000..9a7feb9 Binary files /dev/null and b/graphics/entity/radar/tile_21.png differ diff --git a/graphics/entity/radar/tile_22.png b/graphics/entity/radar/tile_22.png new file mode 100644 index 0000000..c3a7d52 Binary files /dev/null and b/graphics/entity/radar/tile_22.png differ diff --git a/graphics/entity/radar/tile_23.png b/graphics/entity/radar/tile_23.png new file mode 100644 index 0000000..be5406f Binary files /dev/null and b/graphics/entity/radar/tile_23.png differ diff --git a/graphics/entity/radar/tile_24.png b/graphics/entity/radar/tile_24.png new file mode 100644 index 0000000..14f2ff1 Binary files /dev/null and b/graphics/entity/radar/tile_24.png differ diff --git a/graphics/entity/radar/tile_25.png b/graphics/entity/radar/tile_25.png new file mode 100644 index 0000000..7f938ba Binary files /dev/null and b/graphics/entity/radar/tile_25.png differ diff --git a/graphics/entity/radar/tile_26.png b/graphics/entity/radar/tile_26.png new file mode 100644 index 0000000..92dfef2 Binary files /dev/null and b/graphics/entity/radar/tile_26.png differ diff --git a/graphics/entity/radar/tile_27.png b/graphics/entity/radar/tile_27.png new file mode 100644 index 0000000..43760a4 Binary files /dev/null and b/graphics/entity/radar/tile_27.png differ diff --git a/graphics/entity/radar/tile_28.png b/graphics/entity/radar/tile_28.png new file mode 100644 index 0000000..3bbe00f Binary files /dev/null and b/graphics/entity/radar/tile_28.png differ diff --git a/graphics/entity/radar/tile_29.png b/graphics/entity/radar/tile_29.png new file mode 100644 index 0000000..3cb288b Binary files /dev/null and b/graphics/entity/radar/tile_29.png differ diff --git a/graphics/entity/radar/tile_3.png b/graphics/entity/radar/tile_3.png new file mode 100644 index 0000000..bb29771 Binary files /dev/null and b/graphics/entity/radar/tile_3.png differ diff --git a/graphics/entity/radar/tile_30.png b/graphics/entity/radar/tile_30.png new file mode 100644 index 0000000..520d9ce Binary files /dev/null and b/graphics/entity/radar/tile_30.png differ diff --git a/graphics/entity/radar/tile_31.png b/graphics/entity/radar/tile_31.png new file mode 100644 index 0000000..c8360a0 Binary files /dev/null and b/graphics/entity/radar/tile_31.png differ diff --git a/graphics/entity/radar/tile_32.png b/graphics/entity/radar/tile_32.png new file mode 100644 index 0000000..eed64ae Binary files /dev/null and b/graphics/entity/radar/tile_32.png differ diff --git a/graphics/entity/radar/tile_33.png b/graphics/entity/radar/tile_33.png new file mode 100644 index 0000000..3fca057 Binary files /dev/null and b/graphics/entity/radar/tile_33.png differ diff --git a/graphics/entity/radar/tile_34.png b/graphics/entity/radar/tile_34.png new file mode 100644 index 0000000..6ba9bc1 Binary files /dev/null and b/graphics/entity/radar/tile_34.png differ diff --git a/graphics/entity/radar/tile_35.png b/graphics/entity/radar/tile_35.png new file mode 100644 index 0000000..48878ad Binary files /dev/null and b/graphics/entity/radar/tile_35.png differ diff --git a/graphics/entity/radar/tile_36.png b/graphics/entity/radar/tile_36.png new file mode 100644 index 0000000..98f31c3 Binary files /dev/null and b/graphics/entity/radar/tile_36.png differ diff --git a/graphics/entity/radar/tile_37.png b/graphics/entity/radar/tile_37.png new file mode 100644 index 0000000..86b55af Binary files /dev/null and b/graphics/entity/radar/tile_37.png differ diff --git a/graphics/entity/radar/tile_38.png b/graphics/entity/radar/tile_38.png new file mode 100644 index 0000000..3f22da2 Binary files /dev/null and b/graphics/entity/radar/tile_38.png differ diff --git a/graphics/entity/radar/tile_39.png b/graphics/entity/radar/tile_39.png new file mode 100644 index 0000000..c221583 Binary files /dev/null and b/graphics/entity/radar/tile_39.png differ diff --git a/graphics/entity/radar/tile_4.png b/graphics/entity/radar/tile_4.png new file mode 100644 index 0000000..9b3530d Binary files /dev/null and b/graphics/entity/radar/tile_4.png differ diff --git a/graphics/entity/radar/tile_40.png b/graphics/entity/radar/tile_40.png new file mode 100644 index 0000000..a06e834 Binary files /dev/null and b/graphics/entity/radar/tile_40.png differ diff --git a/graphics/entity/radar/tile_41.png b/graphics/entity/radar/tile_41.png new file mode 100644 index 0000000..71ec14b Binary files /dev/null and b/graphics/entity/radar/tile_41.png differ diff --git a/graphics/entity/radar/tile_42.png b/graphics/entity/radar/tile_42.png new file mode 100644 index 0000000..91ac7e4 Binary files /dev/null and b/graphics/entity/radar/tile_42.png differ diff --git a/graphics/entity/radar/tile_43.png b/graphics/entity/radar/tile_43.png new file mode 100644 index 0000000..205b201 Binary files /dev/null and b/graphics/entity/radar/tile_43.png differ diff --git a/graphics/entity/radar/tile_44.png b/graphics/entity/radar/tile_44.png new file mode 100644 index 0000000..8df1d82 Binary files /dev/null and b/graphics/entity/radar/tile_44.png differ diff --git a/graphics/entity/radar/tile_45.png b/graphics/entity/radar/tile_45.png new file mode 100644 index 0000000..ddd0a45 Binary files /dev/null and b/graphics/entity/radar/tile_45.png differ diff --git a/graphics/entity/radar/tile_46.png b/graphics/entity/radar/tile_46.png new file mode 100644 index 0000000..21f9381 Binary files /dev/null and b/graphics/entity/radar/tile_46.png differ diff --git a/graphics/entity/radar/tile_47.png b/graphics/entity/radar/tile_47.png new file mode 100644 index 0000000..557568d Binary files /dev/null and b/graphics/entity/radar/tile_47.png differ diff --git a/graphics/entity/radar/tile_48.png b/graphics/entity/radar/tile_48.png new file mode 100644 index 0000000..a0b1c1b Binary files /dev/null and b/graphics/entity/radar/tile_48.png differ diff --git a/graphics/entity/radar/tile_49.png b/graphics/entity/radar/tile_49.png new file mode 100644 index 0000000..65a79d9 Binary files /dev/null and b/graphics/entity/radar/tile_49.png differ diff --git a/graphics/entity/radar/tile_5.png b/graphics/entity/radar/tile_5.png new file mode 100644 index 0000000..be59d42 Binary files /dev/null and b/graphics/entity/radar/tile_5.png differ diff --git a/graphics/entity/radar/tile_50.png b/graphics/entity/radar/tile_50.png new file mode 100644 index 0000000..853735b Binary files /dev/null and b/graphics/entity/radar/tile_50.png differ diff --git a/graphics/entity/radar/tile_51.png b/graphics/entity/radar/tile_51.png new file mode 100644 index 0000000..1712ad8 Binary files /dev/null and b/graphics/entity/radar/tile_51.png differ diff --git a/graphics/entity/radar/tile_52.png b/graphics/entity/radar/tile_52.png new file mode 100644 index 0000000..e3587cd Binary files /dev/null and b/graphics/entity/radar/tile_52.png differ diff --git a/graphics/entity/radar/tile_53.png b/graphics/entity/radar/tile_53.png new file mode 100644 index 0000000..e96b63f Binary files /dev/null and b/graphics/entity/radar/tile_53.png differ diff --git a/graphics/entity/radar/tile_54.png b/graphics/entity/radar/tile_54.png new file mode 100644 index 0000000..3f1fd52 Binary files /dev/null and b/graphics/entity/radar/tile_54.png differ diff --git a/graphics/entity/radar/tile_55.png b/graphics/entity/radar/tile_55.png new file mode 100644 index 0000000..105304c Binary files /dev/null and b/graphics/entity/radar/tile_55.png differ diff --git a/graphics/entity/radar/tile_56.png b/graphics/entity/radar/tile_56.png new file mode 100644 index 0000000..f1eb0c9 Binary files /dev/null and b/graphics/entity/radar/tile_56.png differ diff --git a/graphics/entity/radar/tile_57.png b/graphics/entity/radar/tile_57.png new file mode 100644 index 0000000..ade131e Binary files /dev/null and b/graphics/entity/radar/tile_57.png differ diff --git a/graphics/entity/radar/tile_58.png b/graphics/entity/radar/tile_58.png new file mode 100644 index 0000000..79a3e47 Binary files /dev/null and b/graphics/entity/radar/tile_58.png differ diff --git a/graphics/entity/radar/tile_59.png b/graphics/entity/radar/tile_59.png new file mode 100644 index 0000000..b92e5c8 Binary files /dev/null and b/graphics/entity/radar/tile_59.png differ diff --git a/graphics/entity/radar/tile_6.png b/graphics/entity/radar/tile_6.png new file mode 100644 index 0000000..95408ef Binary files /dev/null and b/graphics/entity/radar/tile_6.png differ diff --git a/graphics/entity/radar/tile_60.png b/graphics/entity/radar/tile_60.png new file mode 100644 index 0000000..960a72b Binary files /dev/null and b/graphics/entity/radar/tile_60.png differ diff --git a/graphics/entity/radar/tile_61.png b/graphics/entity/radar/tile_61.png new file mode 100644 index 0000000..1e409e3 Binary files /dev/null and b/graphics/entity/radar/tile_61.png differ diff --git a/graphics/entity/radar/tile_62.png b/graphics/entity/radar/tile_62.png new file mode 100644 index 0000000..5aba6ec Binary files /dev/null and b/graphics/entity/radar/tile_62.png differ diff --git a/graphics/entity/radar/tile_63.png b/graphics/entity/radar/tile_63.png new file mode 100644 index 0000000..db10ac0 Binary files /dev/null and b/graphics/entity/radar/tile_63.png differ diff --git a/graphics/entity/radar/tile_64.png b/graphics/entity/radar/tile_64.png new file mode 100644 index 0000000..1c478a6 Binary files /dev/null and b/graphics/entity/radar/tile_64.png differ diff --git a/graphics/entity/radar/tile_7.png b/graphics/entity/radar/tile_7.png new file mode 100644 index 0000000..2d8d0ad Binary files /dev/null and b/graphics/entity/radar/tile_7.png differ diff --git a/graphics/entity/radar/tile_8.png b/graphics/entity/radar/tile_8.png new file mode 100644 index 0000000..8deadb7 Binary files /dev/null and b/graphics/entity/radar/tile_8.png differ diff --git a/graphics/entity/radar/tile_9.png b/graphics/entity/radar/tile_9.png new file mode 100644 index 0000000..d0e0d81 Binary files /dev/null and b/graphics/entity/radar/tile_9.png differ diff --git a/graphics/entity/surveillance/surveillance.png b/graphics/entity/surveillance/surveillance.png new file mode 100644 index 0000000..8d6744d Binary files /dev/null and b/graphics/entity/surveillance/surveillance.png differ diff --git a/graphics/entity/surveillance/tile-0.png b/graphics/entity/surveillance/tile-0.png new file mode 100644 index 0000000..089ed39 Binary files /dev/null and b/graphics/entity/surveillance/tile-0.png differ diff --git a/graphics/entity/surveillance/tile-1.png b/graphics/entity/surveillance/tile-1.png new file mode 100644 index 0000000..6514c6e Binary files /dev/null and b/graphics/entity/surveillance/tile-1.png differ diff --git a/graphics/entity/surveillance/tile-10.png b/graphics/entity/surveillance/tile-10.png new file mode 100644 index 0000000..8da20ad Binary files /dev/null and b/graphics/entity/surveillance/tile-10.png differ diff --git a/graphics/entity/surveillance/tile-11.png b/graphics/entity/surveillance/tile-11.png new file mode 100644 index 0000000..2e4c10c Binary files /dev/null and b/graphics/entity/surveillance/tile-11.png differ diff --git a/graphics/entity/surveillance/tile-12.png b/graphics/entity/surveillance/tile-12.png new file mode 100644 index 0000000..8d65f96 Binary files /dev/null and b/graphics/entity/surveillance/tile-12.png differ diff --git a/graphics/entity/surveillance/tile-13.png b/graphics/entity/surveillance/tile-13.png new file mode 100644 index 0000000..d76cf75 Binary files /dev/null and b/graphics/entity/surveillance/tile-13.png differ diff --git a/graphics/entity/surveillance/tile-14.png b/graphics/entity/surveillance/tile-14.png new file mode 100644 index 0000000..ee2debb Binary files /dev/null and b/graphics/entity/surveillance/tile-14.png differ diff --git a/graphics/entity/surveillance/tile-15.png b/graphics/entity/surveillance/tile-15.png new file mode 100644 index 0000000..0ee5883 Binary files /dev/null and b/graphics/entity/surveillance/tile-15.png differ diff --git a/graphics/entity/surveillance/tile-16.png b/graphics/entity/surveillance/tile-16.png new file mode 100644 index 0000000..363e960 Binary files /dev/null and b/graphics/entity/surveillance/tile-16.png differ diff --git a/graphics/entity/surveillance/tile-17.png b/graphics/entity/surveillance/tile-17.png new file mode 100644 index 0000000..7452ce6 Binary files /dev/null and b/graphics/entity/surveillance/tile-17.png differ diff --git a/graphics/entity/surveillance/tile-18.png b/graphics/entity/surveillance/tile-18.png new file mode 100644 index 0000000..6f58dd2 Binary files /dev/null and b/graphics/entity/surveillance/tile-18.png differ diff --git a/graphics/entity/surveillance/tile-19.png b/graphics/entity/surveillance/tile-19.png new file mode 100644 index 0000000..5b65919 Binary files /dev/null and b/graphics/entity/surveillance/tile-19.png differ diff --git a/graphics/entity/surveillance/tile-2.png b/graphics/entity/surveillance/tile-2.png new file mode 100644 index 0000000..060f6f5 Binary files /dev/null and b/graphics/entity/surveillance/tile-2.png differ diff --git a/graphics/entity/surveillance/tile-20.png b/graphics/entity/surveillance/tile-20.png new file mode 100644 index 0000000..9a53b2c Binary files /dev/null and b/graphics/entity/surveillance/tile-20.png differ diff --git a/graphics/entity/surveillance/tile-21.png b/graphics/entity/surveillance/tile-21.png new file mode 100644 index 0000000..b4d8364 Binary files /dev/null and b/graphics/entity/surveillance/tile-21.png differ diff --git a/graphics/entity/surveillance/tile-22.png b/graphics/entity/surveillance/tile-22.png new file mode 100644 index 0000000..ebbbffc Binary files /dev/null and b/graphics/entity/surveillance/tile-22.png differ diff --git a/graphics/entity/surveillance/tile-23.png b/graphics/entity/surveillance/tile-23.png new file mode 100644 index 0000000..b0a4c7f Binary files /dev/null and b/graphics/entity/surveillance/tile-23.png differ diff --git a/graphics/entity/surveillance/tile-24.png b/graphics/entity/surveillance/tile-24.png new file mode 100644 index 0000000..6d93736 Binary files /dev/null and b/graphics/entity/surveillance/tile-24.png differ diff --git a/graphics/entity/surveillance/tile-25.png b/graphics/entity/surveillance/tile-25.png new file mode 100644 index 0000000..316e86c Binary files /dev/null and b/graphics/entity/surveillance/tile-25.png differ diff --git a/graphics/entity/surveillance/tile-26.png b/graphics/entity/surveillance/tile-26.png new file mode 100644 index 0000000..690c57e Binary files /dev/null and b/graphics/entity/surveillance/tile-26.png differ diff --git a/graphics/entity/surveillance/tile-27.png b/graphics/entity/surveillance/tile-27.png new file mode 100644 index 0000000..1265ed1 Binary files /dev/null and b/graphics/entity/surveillance/tile-27.png differ diff --git a/graphics/entity/surveillance/tile-28.png b/graphics/entity/surveillance/tile-28.png new file mode 100644 index 0000000..ffed3ee Binary files /dev/null and b/graphics/entity/surveillance/tile-28.png differ diff --git a/graphics/entity/surveillance/tile-29.png b/graphics/entity/surveillance/tile-29.png new file mode 100644 index 0000000..c0432c5 Binary files /dev/null and b/graphics/entity/surveillance/tile-29.png differ diff --git a/graphics/entity/surveillance/tile-3.png b/graphics/entity/surveillance/tile-3.png new file mode 100644 index 0000000..be2d34a Binary files /dev/null and b/graphics/entity/surveillance/tile-3.png differ diff --git a/graphics/entity/surveillance/tile-30.png b/graphics/entity/surveillance/tile-30.png new file mode 100644 index 0000000..d93bf23 Binary files /dev/null and b/graphics/entity/surveillance/tile-30.png differ diff --git a/graphics/entity/surveillance/tile-31.png b/graphics/entity/surveillance/tile-31.png new file mode 100644 index 0000000..f090293 Binary files /dev/null and b/graphics/entity/surveillance/tile-31.png differ diff --git a/graphics/entity/surveillance/tile-32.png b/graphics/entity/surveillance/tile-32.png new file mode 100644 index 0000000..5ac9de5 Binary files /dev/null and b/graphics/entity/surveillance/tile-32.png differ diff --git a/graphics/entity/surveillance/tile-33.png b/graphics/entity/surveillance/tile-33.png new file mode 100644 index 0000000..9d7e211 Binary files /dev/null and b/graphics/entity/surveillance/tile-33.png differ diff --git a/graphics/entity/surveillance/tile-34.png b/graphics/entity/surveillance/tile-34.png new file mode 100644 index 0000000..0c6a96a Binary files /dev/null and b/graphics/entity/surveillance/tile-34.png differ diff --git a/graphics/entity/surveillance/tile-35.png b/graphics/entity/surveillance/tile-35.png new file mode 100644 index 0000000..f1ee8ef Binary files /dev/null and b/graphics/entity/surveillance/tile-35.png differ diff --git a/graphics/entity/surveillance/tile-36.png b/graphics/entity/surveillance/tile-36.png new file mode 100644 index 0000000..e1147db Binary files /dev/null and b/graphics/entity/surveillance/tile-36.png differ diff --git a/graphics/entity/surveillance/tile-37.png b/graphics/entity/surveillance/tile-37.png new file mode 100644 index 0000000..c0702b3 Binary files /dev/null and b/graphics/entity/surveillance/tile-37.png differ diff --git a/graphics/entity/surveillance/tile-38.png b/graphics/entity/surveillance/tile-38.png new file mode 100644 index 0000000..91ef889 Binary files /dev/null and b/graphics/entity/surveillance/tile-38.png differ diff --git a/graphics/entity/surveillance/tile-39.png b/graphics/entity/surveillance/tile-39.png new file mode 100644 index 0000000..7e411fa Binary files /dev/null and b/graphics/entity/surveillance/tile-39.png differ diff --git a/graphics/entity/surveillance/tile-4.png b/graphics/entity/surveillance/tile-4.png new file mode 100644 index 0000000..fdeefa3 Binary files /dev/null and b/graphics/entity/surveillance/tile-4.png differ diff --git a/graphics/entity/surveillance/tile-40.png b/graphics/entity/surveillance/tile-40.png new file mode 100644 index 0000000..d1faa29 Binary files /dev/null and b/graphics/entity/surveillance/tile-40.png differ diff --git a/graphics/entity/surveillance/tile-41.png b/graphics/entity/surveillance/tile-41.png new file mode 100644 index 0000000..e5a1e48 Binary files /dev/null and b/graphics/entity/surveillance/tile-41.png differ diff --git a/graphics/entity/surveillance/tile-42.png b/graphics/entity/surveillance/tile-42.png new file mode 100644 index 0000000..60316e3 Binary files /dev/null and b/graphics/entity/surveillance/tile-42.png differ diff --git a/graphics/entity/surveillance/tile-43.png b/graphics/entity/surveillance/tile-43.png new file mode 100644 index 0000000..47a88b6 Binary files /dev/null and b/graphics/entity/surveillance/tile-43.png differ diff --git a/graphics/entity/surveillance/tile-44.png b/graphics/entity/surveillance/tile-44.png new file mode 100644 index 0000000..28cf3d6 Binary files /dev/null and b/graphics/entity/surveillance/tile-44.png differ diff --git a/graphics/entity/surveillance/tile-45.png b/graphics/entity/surveillance/tile-45.png new file mode 100644 index 0000000..d7e7d8c Binary files /dev/null and b/graphics/entity/surveillance/tile-45.png differ diff --git a/graphics/entity/surveillance/tile-46.png b/graphics/entity/surveillance/tile-46.png new file mode 100644 index 0000000..65758b6 Binary files /dev/null and b/graphics/entity/surveillance/tile-46.png differ diff --git a/graphics/entity/surveillance/tile-47.png b/graphics/entity/surveillance/tile-47.png new file mode 100644 index 0000000..38b423e Binary files /dev/null and b/graphics/entity/surveillance/tile-47.png differ diff --git a/graphics/entity/surveillance/tile-48.png b/graphics/entity/surveillance/tile-48.png new file mode 100644 index 0000000..6fb0cb0 Binary files /dev/null and b/graphics/entity/surveillance/tile-48.png differ diff --git a/graphics/entity/surveillance/tile-49.png b/graphics/entity/surveillance/tile-49.png new file mode 100644 index 0000000..a01b7eb Binary files /dev/null and b/graphics/entity/surveillance/tile-49.png differ diff --git a/graphics/entity/surveillance/tile-5.png b/graphics/entity/surveillance/tile-5.png new file mode 100644 index 0000000..ba393a8 Binary files /dev/null and b/graphics/entity/surveillance/tile-5.png differ diff --git a/graphics/entity/surveillance/tile-50.png b/graphics/entity/surveillance/tile-50.png new file mode 100644 index 0000000..cf7c955 Binary files /dev/null and b/graphics/entity/surveillance/tile-50.png differ diff --git a/graphics/entity/surveillance/tile-51.png b/graphics/entity/surveillance/tile-51.png new file mode 100644 index 0000000..1a3d11f Binary files /dev/null and b/graphics/entity/surveillance/tile-51.png differ diff --git a/graphics/entity/surveillance/tile-52.png b/graphics/entity/surveillance/tile-52.png new file mode 100644 index 0000000..a2935f6 Binary files /dev/null and b/graphics/entity/surveillance/tile-52.png differ diff --git a/graphics/entity/surveillance/tile-53.png b/graphics/entity/surveillance/tile-53.png new file mode 100644 index 0000000..5785fff Binary files /dev/null and b/graphics/entity/surveillance/tile-53.png differ diff --git a/graphics/entity/surveillance/tile-54.png b/graphics/entity/surveillance/tile-54.png new file mode 100644 index 0000000..b6517ad Binary files /dev/null and b/graphics/entity/surveillance/tile-54.png differ diff --git a/graphics/entity/surveillance/tile-55.png b/graphics/entity/surveillance/tile-55.png new file mode 100644 index 0000000..7b3f0b8 Binary files /dev/null and b/graphics/entity/surveillance/tile-55.png differ diff --git a/graphics/entity/surveillance/tile-56.png b/graphics/entity/surveillance/tile-56.png new file mode 100644 index 0000000..5b18158 Binary files /dev/null and b/graphics/entity/surveillance/tile-56.png differ diff --git a/graphics/entity/surveillance/tile-57.png b/graphics/entity/surveillance/tile-57.png new file mode 100644 index 0000000..b6fec8f Binary files /dev/null and b/graphics/entity/surveillance/tile-57.png differ diff --git a/graphics/entity/surveillance/tile-58.png b/graphics/entity/surveillance/tile-58.png new file mode 100644 index 0000000..51f88f9 Binary files /dev/null and b/graphics/entity/surveillance/tile-58.png differ diff --git a/graphics/entity/surveillance/tile-59.png b/graphics/entity/surveillance/tile-59.png new file mode 100644 index 0000000..b2293ca Binary files /dev/null and b/graphics/entity/surveillance/tile-59.png differ diff --git a/graphics/entity/surveillance/tile-6.png b/graphics/entity/surveillance/tile-6.png new file mode 100644 index 0000000..a385251 Binary files /dev/null and b/graphics/entity/surveillance/tile-6.png differ diff --git a/graphics/entity/surveillance/tile-60.png b/graphics/entity/surveillance/tile-60.png new file mode 100644 index 0000000..8aae2dc Binary files /dev/null and b/graphics/entity/surveillance/tile-60.png differ diff --git a/graphics/entity/surveillance/tile-61.png b/graphics/entity/surveillance/tile-61.png new file mode 100644 index 0000000..9b1f76f Binary files /dev/null and b/graphics/entity/surveillance/tile-61.png differ diff --git a/graphics/entity/surveillance/tile-62.png b/graphics/entity/surveillance/tile-62.png new file mode 100644 index 0000000..1b2dcb4 Binary files /dev/null and b/graphics/entity/surveillance/tile-62.png differ diff --git a/graphics/entity/surveillance/tile-63.png b/graphics/entity/surveillance/tile-63.png new file mode 100644 index 0000000..b1bbe55 Binary files /dev/null and b/graphics/entity/surveillance/tile-63.png differ diff --git a/graphics/entity/surveillance/tile-7.png b/graphics/entity/surveillance/tile-7.png new file mode 100644 index 0000000..8d678b9 Binary files /dev/null and b/graphics/entity/surveillance/tile-7.png differ diff --git a/graphics/entity/surveillance/tile-8.png b/graphics/entity/surveillance/tile-8.png new file mode 100644 index 0000000..68b2fb6 Binary files /dev/null and b/graphics/entity/surveillance/tile-8.png differ diff --git a/graphics/entity/surveillance/tile-9.png b/graphics/entity/surveillance/tile-9.png new file mode 100644 index 0000000..a0f344b Binary files /dev/null and b/graphics/entity/surveillance/tile-9.png differ diff --git a/graphics/icons/radar-amplifier.png b/graphics/icons/radar-amplifier.png new file mode 100644 index 0000000..1018225 Binary files /dev/null and b/graphics/icons/radar-amplifier.png differ diff --git a/graphics/icons/radar-efficiency.png b/graphics/icons/radar-efficiency.png new file mode 100644 index 0000000..1077188 Binary files /dev/null and b/graphics/icons/radar-efficiency.png differ diff --git a/graphics/icons/surveillance.png b/graphics/icons/surveillance.png new file mode 100644 index 0000000..4ad80a4 Binary files /dev/null and b/graphics/icons/surveillance.png differ diff --git a/graphics/icons/tech_surveillance.png b/graphics/icons/tech_surveillance.png new file mode 100644 index 0000000..571fa8e Binary files /dev/null and b/graphics/icons/tech_surveillance.png differ diff --git a/info.json b/info.json new file mode 100755 index 0000000..b115ce7 --- /dev/null +++ b/info.json @@ -0,0 +1,9 @@ +{ + "name": "Big_Brother", + "version": "{{VERSION}}", + "title": "Big Brother", + "author": "Afforess", + "homepage": "http://afforess.com", + "description": "Proudly building the perfect surveillance state", + "dependencies": ["base >= 0.12.31"] +} diff --git a/locale/en/big-brother.cfg b/locale/en/big-brother.cfg new file mode 100644 index 0000000..cf00a67 --- /dev/null +++ b/locale/en/big-brother.cfg @@ -0,0 +1,128 @@ + +[entity-name] +big_brother-radar_ra-0_re-0=Radar +big_brother-radar_ra-1_re-0=Radar +big_brother-radar_ra-2_re-0=Radar +big_brother-radar_ra-3_re-0=Radar +big_brother-radar_ra-4_re-0=Radar +big_brother-radar_ra-5_re-0=Radar +big_brother-radar_ra-6_re-0=Radar +big_brother-radar_ra-7_re-0=Radar +big_brother-radar_ra-8_re-0=Radar +big_brother-radar_ra-9_re-0=Radar + +big_brother-radar_ra-0_re-1=Radar +big_brother-radar_ra-1_re-1=Radar +big_brother-radar_ra-2_re-1=Radar +big_brother-radar_ra-3_re-1=Radar +big_brother-radar_ra-4_re-1=Radar +big_brother-radar_ra-5_re-1=Radar +big_brother-radar_ra-6_re-1=Radar +big_brother-radar_ra-7_re-1=Radar +big_brother-radar_ra-8_re-1=Radar +big_brother-radar_ra-9_re-1=Radar + +big_brother-radar_ra-0_re-2=Radar +big_brother-radar_ra-1_re-2=Radar +big_brother-radar_ra-2_re-2=Radar +big_brother-radar_ra-3_re-2=Radar +big_brother-radar_ra-4_re-2=Radar +big_brother-radar_ra-5_re-2=Radar +big_brother-radar_ra-6_re-2=Radar +big_brother-radar_ra-7_re-2=Radar +big_brother-radar_ra-8_re-2=Radar +big_brother-radar_ra-9_re-2=Radar + +big_brother-radar_ra-0_re-3=Radar +big_brother-radar_ra-1_re-3=Radar +big_brother-radar_ra-2_re-3=Radar +big_brother-radar_ra-3_re-3=Radar +big_brother-radar_ra-4_re-3=Radar +big_brother-radar_ra-5_re-3=Radar +big_brother-radar_ra-6_re-3=Radar +big_brother-radar_ra-7_re-3=Radar +big_brother-radar_ra-8_re-3=Radar +big_brother-radar_ra-9_re-3=Radar + +big_brother-radar_ra-0_re-4=Radar +big_brother-radar_ra-1_re-4=Radar +big_brother-radar_ra-2_re-4=Radar +big_brother-radar_ra-3_re-4=Radar +big_brother-radar_ra-4_re-4=Radar +big_brother-radar_ra-5_re-4=Radar +big_brother-radar_ra-6_re-4=Radar +big_brother-radar_ra-7_re-4=Radar +big_brother-radar_ra-8_re-4=Radar +big_brother-radar_ra-9_re-4=Radar + +big_brother-radar_ra-0_re-5=Radar +big_brother-radar_ra-1_re-5=Radar +big_brother-radar_ra-2_re-5=Radar +big_brother-radar_ra-3_re-5=Radar +big_brother-radar_ra-4_re-5=Radar +big_brother-radar_ra-5_re-5=Radar +big_brother-radar_ra-6_re-5=Radar +big_brother-radar_ra-7_re-5=Radar +big_brother-radar_ra-8_re-5=Radar +big_brother-radar_ra-9_re-5=Radar + +big_brother-radar_ra-0_re-6=Radar +big_brother-radar_ra-1_re-6=Radar +big_brother-radar_ra-2_re-6=Radar +big_brother-radar_ra-3_re-6=Radar +big_brother-radar_ra-4_re-6=Radar +big_brother-radar_ra-5_re-6=Radar +big_brother-radar_ra-6_re-6=Radar +big_brother-radar_ra-7_re-6=Radar +big_brother-radar_ra-8_re-6=Radar +big_brother-radar_ra-9_re-6=Radar + +big_brother-radar_ra-0_re-7=Radar +big_brother-radar_ra-1_re-7=Radar +big_brother-radar_ra-2_re-7=Radar +big_brother-radar_ra-3_re-7=Radar +big_brother-radar_ra-4_re-7=Radar +big_brother-radar_ra-5_re-7=Radar +big_brother-radar_ra-6_re-7=Radar +big_brother-radar_ra-7_re-7=Radar +big_brother-radar_ra-8_re-7=Radar +big_brother-radar_ra-9_re-7=Radar + +big_brother-radar_ra-0_re-8=Radar +big_brother-radar_ra-1_re-8=Radar +big_brother-radar_ra-2_re-8=Radar +big_brother-radar_ra-3_re-8=Radar +big_brother-radar_ra-4_re-8=Radar +big_brother-radar_ra-5_re-8=Radar +big_brother-radar_ra-6_re-8=Radar +big_brother-radar_ra-7_re-8=Radar +big_brother-radar_ra-8_re-8=Radar +big_brother-radar_ra-9_re-8=Radar + +big_brother-radar_ra-0_re-9=Radar +big_brother-radar_ra-1_re-9=Radar +big_brother-radar_ra-2_re-9=Radar +big_brother-radar_ra-3_re-9=Radar +big_brother-radar_ra-4_re-9=Radar +big_brother-radar_ra-5_re-9=Radar +big_brother-radar_ra-6_re-9=Radar +big_brother-radar_ra-7_re-9=Radar +big_brother-radar_ra-8_re-9=Radar +big_brother-radar_ra-9_re-9=Radar + +big_brother-surveillance-center=Surveillance center +big_brother-surveillance-small=Surveillance camera + +[item-name] +big_brother-surveillance-center=Surveillance center + +[technology-name] +radar-amplifier=Radar amplification +radar-efficiency=Radar efficiency +surveillance=Surveillance + +[technology-description] +radar-amplifier=Expands the Radar line of sight and scan range +radar-efficiency=Radars scan distant sectors more quickly +surveillance=Vehicles and Trains are always in the line of sight on the map +surveillance-2=Big electric poles are always in the line of sight on the map diff --git a/prototypes/entity/radar.lua b/prototypes/entity/radar.lua new file mode 100644 index 0000000..791d520 --- /dev/null +++ b/prototypes/entity/radar.lua @@ -0,0 +1,40 @@ +local radars = {} + +for radar_amplification_type = 0, 9 do + for radar_efficiency_type = 0, 9 do + local max_distance_of_sector_revealed = data.raw['radar']['radar'].max_distance_of_sector_revealed + radar_amplification_type * 3 + local max_distance_of_nearby_sector_revealed = data.raw['radar']['radar'].max_distance_of_nearby_sector_revealed + radar_amplification_type * 2 + local extra_energy_cost = 75 * radar_amplification_type + + -- base time to scan is ~40s + local energy_per_sector = (10000 + extra_energy_cost * 40) / (1 + math.pow(radar_efficiency_type, 1.5)) + + local radar = table.deepcopy(data.raw['radar']['radar']) + radar.name = 'big_brother-radar_ra-' .. radar_amplification_type .. '_re-' .. radar_efficiency_type + radar.max_distance_of_sector_revealed = max_distance_of_sector_revealed + radar.max_distance_of_nearby_sector_revealed = max_distance_of_nearby_sector_revealed + radar.energy_per_sector = energy_per_sector .. "KJ" + radar.energy_usage = (300 + extra_energy_cost) .. "kW" + radar.order ="d-c" + + local file_names = {} + for i = 1, 64 do + table.insert(file_names, "__Big_Brother__/graphics/entity/radar/tile_" .. i .. ".png") + end + radar.pictures = { + apply_projection = false, + direction_count = #file_names, + filenames = file_names, + height = 262, + line_length = 1, + lines_per_file = 1, + priority = "low", + scale = 0.5, + shift = {0.875, -0.34375}, + width = 306, + } + table.insert(radars, radar) + end +end + +data:extend(radars) diff --git a/prototypes/entity/surveillance.lua b/prototypes/entity/surveillance.lua new file mode 100644 index 0000000..f74ef49 --- /dev/null +++ b/prototypes/entity/surveillance.lua @@ -0,0 +1,77 @@ +local file_names = {} +for i = 0, 63 do + table.insert(file_names, "__Big_Brother__/graphics/entity/surveillance/tile-" .. i .. ".png") +end +data:extend({ + { + type = "radar", + name = "big_brother-surveillance-center", + icon = "__Big_Brother__/graphics/icons/surveillance.png", + flags = {"placeable-player", "player-creation"}, + minable = {hardness = 0.2, mining_time = 0.5, result = "big_brother-surveillance-center"}, + max_health = 400, + corpse = "big-remnants", + resistances = + { + { + type = "fire", + percent = 70 + } + }, + collision_box = {{-2.1, -2.1}, {2.1, 2.1}}, + selection_box = {{-2.25, -2.25}, {2.25, 2.25}}, + energy_per_sector = "400kJ", + max_distance_of_sector_revealed = 0, + max_distance_of_nearby_sector_revealed = 1, + energy_per_nearby_scan = "250kJ", + energy_source = + { + type = "electric", + usage_priority = "secondary-input" + }, + energy_usage = "1MW", + pictures = + { + direction_count = #file_names, + filenames = file_names, + priority = "low", + width = 338, + height = 280, + scale = 0.75, + axially_symmetrical = false, + apply_projection = false, + line_length = 1, + lines_per_file = 1, + shift = {1.55, 0.9} + } + }, + { + type = "radar", + name = "big_brother-surveillance-small", + icon = "__Big_Brother__/graphics/icons/surveillance.png", + order = 'd-f', + max_health = 100, + selectable_in_game = false, + energy_per_sector = "10KJ", + max_distance_of_sector_revealed = 0, + max_distance_of_nearby_sector_revealed = 1, + energy_per_nearby_scan = "10kJ", + energy_source = + { + type = "electric", + usage_priority = "secondary-input" + }, + energy_usage = "3kW", + pictures = + { + filename = "__base__/graphics/entity/radar/radar.png", + priority = "low", + width = 0, + height = 0, + apply_projection = false, + direction_count = 1, + line_length = 1, + shift = {0.0, 0.0} + } + }, +}) diff --git a/prototypes/item/surveillance.lua b/prototypes/item/surveillance.lua new file mode 100644 index 0000000..b2b4b53 --- /dev/null +++ b/prototypes/item/surveillance.lua @@ -0,0 +1,12 @@ +data:extend({ + { + type = "item", + name = "big_brother-surveillance-center", + icon = "__Big_Brother__/graphics/icons/surveillance.png", + flags = {"goes-to-main-inventory"}, + subgroup = "defensive-structure", + order = "d[radar]-a[surveillance]", + place_result = "big_brother-surveillance-center", + stack_size = 1 + } +}) diff --git a/prototypes/recipe/surveillance.lua b/prototypes/recipe/surveillance.lua new file mode 100644 index 0000000..b1d54c8 --- /dev/null +++ b/prototypes/recipe/surveillance.lua @@ -0,0 +1,15 @@ +data:extend( +{ + { + type = "recipe", + name = "big_brother-surveillance-center", + ingredients = + { + {"radar", 5}, + {"processing-unit", 5}, + {"steel-plate", 40}, + {"copper-cable", 40} + }, + result = "big_brother-surveillance-center" + } +}) diff --git a/prototypes/technology/radar.lua b/prototypes/technology/radar.lua new file mode 100644 index 0000000..b233ff7 --- /dev/null +++ b/prototypes/technology/radar.lua @@ -0,0 +1,384 @@ +data:extend( +{ + { + type = "technology", + name = "radar-amplifier", + icon = "__Big_Brother__/graphics/icons/radar-amplifier.png", + icon_size = 128, + effects = { }, + prerequisites = {"military", "optics"}, + unit = { + count = 25, + ingredients = { + {"science-pack-1", 1}, + }, + time = 15 + }, + order = "e-a-a" + }, + { + type = "technology", + name = "radar-amplifier-2", + icon = "__Big_Brother__/graphics/icons/radar-amplifier.png", + icon_size = 128, + effects = { }, + prerequisites = {"radar-amplifier"}, + unit = { + count = 25, + ingredients = { + {"science-pack-1", 2}, + {"science-pack-2", 1}, + }, + time = 20 + }, + upgrade = true, + order = "e-a-a" + }, + { + type = "technology", + name = "radar-amplifier-3", + icon = "__Big_Brother__/graphics/icons/radar-amplifier.png", + icon_size = 128, + effects = { }, + prerequisites = {"radar-amplifier-2", "circuit-network"}, + unit = { + count = 50, + ingredients = { + {"science-pack-1", 2}, + {"science-pack-2", 1}, + }, + time = 25 + }, + upgrade = true, + order = "e-a-a" + }, + { + type = "technology", + name = "radar-amplifier-4", + icon = "__Big_Brother__/graphics/icons/radar-amplifier.png", + icon_size = 128, + effects = { }, + prerequisites = {"radar-amplifier-3", "modules"}, + unit = { + count = 80, + ingredients = { + {"science-pack-1", 2}, + {"science-pack-2", 1}, + }, + time = 30 + }, + upgrade = true, + order = "e-a-a" + }, + { + type = "technology", + name = "radar-amplifier-5", + icon = "__Big_Brother__/graphics/icons/radar-amplifier.png", + icon_size = 128, + effects = { }, + prerequisites = {"effect-transmission", "radar-amplifier-4"}, + unit = { + count = 125, + ingredients = { + {"science-pack-1", 2}, + {"science-pack-2", 1}, + {"science-pack-3", 1}, + }, + time = 35 + }, + upgrade = true, + order = "e-a-a" + }, + { + type = "technology", + name = "radar-amplifier-6", + icon = "__Big_Brother__/graphics/icons/radar-amplifier.png", + icon_size = 128, + effects = { }, + prerequisites = {"productivity-module-2", "radar-amplifier-5"}, + unit = { + count = 75, + ingredients = { + {"science-pack-1", 4}, + {"science-pack-2", 3}, + {"science-pack-3", 2}, + }, + time = 40 + }, + upgrade = true, + order = "e-a-a" + }, + { + type = "technology", + name = "radar-amplifier-7", + icon = "__Big_Brother__/graphics/icons/radar-amplifier.png", + icon_size = 128, + effects = { }, + prerequisites = {"productivity-module-3", "radar-amplifier-6"}, + unit = { + count = 100, + ingredients = { + {"science-pack-1", 4}, + {"science-pack-2", 3}, + {"science-pack-3", 1}, + {"alien-science-pack", 2}, + }, + time = 45 + }, + upgrade = true, + order = "e-a-a" + }, + { + type = "technology", + name = "radar-amplifier-8", + icon = "__Big_Brother__/graphics/icons/radar-amplifier.png", + icon_size = 128, + effects = { }, + prerequisites = {"radar-amplifier-7"}, + unit = { + count = 130, + ingredients = { + {"science-pack-1", 4}, + {"science-pack-2", 3}, + {"science-pack-3", 1}, + {"alien-science-pack", 2}, + }, + time = 50 + }, + upgrade = true, + order = "e-a-a" + }, + { + type = "technology", + name = "radar-amplifier-9", + icon = "__Big_Brother__/graphics/icons/radar-amplifier.png", + icon_size = 128, + effects = { }, + prerequisites = {"radar-amplifier-8"}, + unit = { + count = 150, + ingredients = { + {"science-pack-1", 4}, + {"science-pack-2", 3}, + {"science-pack-3", 1}, + {"alien-science-pack", 2}, + }, + time = 60 + }, + upgrade = true, + order = "e-a-a" + }, + + { + type = "technology", + name = "radar-efficiency", + icon = "__Big_Brother__/graphics/icons/radar-efficiency.png", + icon_size = 128, + effects = { }, + prerequisites = {"military", "optics"}, + unit = { + count = 25, + ingredients = { + {"science-pack-1", 1}, + }, + time = 20 + }, + order = "e-a-b" + }, + { + type = "technology", + name = "radar-efficiency-2", + icon = "__Big_Brother__/graphics/icons/radar-efficiency.png", + icon_size = 128, + effects = { }, + prerequisites = {"radar-efficiency"}, + unit = { + count = 30, + ingredients = { + {"science-pack-1", 2}, + {"science-pack-2", 1}, + }, + time = 25 + }, + upgrade = true, + order = "e-a-b" + }, + { + type = "technology", + name = "radar-efficiency-3", + icon = "__Big_Brother__/graphics/icons/radar-efficiency.png", + icon_size = 128, + effects = { }, + prerequisites = {"radar-efficiency-2", "advanced-electronics"}, + unit = { + count = 100, + ingredients = { + {"science-pack-1", 2}, + {"science-pack-2", 1}, + }, + time = 30 + }, + upgrade = true, + order = "e-a-b" + }, + { + type = "technology", + name = "radar-efficiency-4", + icon = "__Big_Brother__/graphics/icons/radar-efficiency.png", + icon_size = 128, + effects = { }, + prerequisites = {"radar-efficiency-3", "laser"}, + unit = { + count = 75, + ingredients = { + {"science-pack-1", 4}, + {"science-pack-2", 2}, + }, + time = 35 + }, + upgrade = true, + order = "e-a-b" + }, + { + type = "technology", + name = "radar-efficiency-5", + icon = "__Big_Brother__/graphics/icons/radar-efficiency.png", + icon_size = 128, + effects = { }, + prerequisites = {"radar-efficiency-4", "advanced-electronics-2"}, + unit = { + count = 100, + ingredients = { + {"science-pack-1", 2}, + {"science-pack-2", 1}, + {"science-pack-3", 1}, + }, + time = 40 + }, + upgrade = true, + order = "e-a-b" + }, + { + type = "technology", + name = "radar-efficiency-6", + icon = "__Big_Brother__/graphics/icons/radar-efficiency.png", + icon_size = 128, + effects = { }, + prerequisites = {"radar-efficiency-5", "effectivity-module-2"}, + unit = { + count = 75, + ingredients = { + {"science-pack-1", 4}, + {"science-pack-2", 3}, + {"science-pack-3", 2}, + }, + time = 45 + }, + upgrade = true, + order = "e-a-b" + }, + { + type = "technology", + name = "radar-efficiency-7", + icon = "__Big_Brother__/graphics/icons/radar-efficiency.png", + icon_size = 128, + effects = { }, + prerequisites = {"radar-efficiency-6", "effectivity-module-3"}, + unit = { + count = 100, + ingredients = { + {"science-pack-1", 4}, + {"science-pack-2", 3}, + {"science-pack-3", 1}, + {"alien-science-pack", 2}, + }, + time = 50 + }, + upgrade = true, + order = "e-a-b" + }, + { + type = "technology", + name = "radar-efficiency-8", + icon = "__Big_Brother__/graphics/icons/radar-efficiency.png", + icon_size = 128, + effects = { }, + prerequisites = {"radar-efficiency-7"}, + unit = { + count = 150, + ingredients = { + {"science-pack-1", 4}, + {"science-pack-2", 3}, + {"science-pack-3", 1}, + {"alien-science-pack", 2}, + }, + time = 60 + }, + upgrade = true, + order = "e-a-b" + }, + { + type = "technology", + name = "radar-efficiency-9", + icon = "__Big_Brother__/graphics/icons/radar-efficiency.png", + icon_size = 128, + effects = { }, + prerequisites = {"radar-efficiency-8"}, + unit = { + count = 200, + ingredients = { + {"science-pack-1", 4}, + {"science-pack-2", 3}, + {"science-pack-3", 1}, + {"alien-science-pack", 2}, + }, + time = 70 + }, + upgrade = true, + order = "e-a-b" + }, + + { + type = "technology", + name = "surveillance", + icon = "__Big_Brother__/graphics/icons/tech_surveillance.png", + icon_size = 128, + effects = { + { + type = "unlock-recipe", + recipe = "big_brother-surveillance-center" + } + }, + prerequisites = {"radar-amplifier-4", "electric-energy-distribution-1"}, + unit = { + count = 80, + ingredients = { + {"science-pack-1", 2}, + {"science-pack-2", 1}, + {"science-pack-3", 1}, + }, + time = 60 + }, + order = "e-a-d" + }, + { + type = "technology", + name = "surveillance-2", + icon = "__Big_Brother__/graphics/icons/tech_surveillance.png", + icon_size = 128, + upgrade = true, + effects = { }, + prerequisites = {"radar-amplifier-5", "surveillance"}, + unit = { + count = 110, + ingredients = { + {"science-pack-1", 2}, + {"science-pack-2", 1}, + {"science-pack-3", 1}, + }, + time = 75 + }, + order = "e-a-e" + } +} +) diff --git a/stdlib/area/area.lua b/stdlib/area/area.lua new file mode 100644 index 0000000..6df71f8 --- /dev/null +++ b/stdlib/area/area.lua @@ -0,0 +1,114 @@ +--- Area module +-- @module area + +require 'stdlib/core' +require 'stdlib/area/position' + +Area = {} + +--- Tests if a position {x, y} is inside (inclusive) of area +-- @param area the area +-- @param pos the position to check +-- @return true if the position is inside of the area +function Area.inside(area, pos) + fail_if_missing(pos, "missing pos value") + fail_if_missing(area, "missing area value") + pos = Position.to_table(pos) + area = Area.to_table(area) + + local left_top = Position.to_table(area.left_top) + local right_bottom = Position.to_table(area.right_bottom) + return pos.x >= left_top.x and pos.y >= left_top.y and pos.x <= right_bottom.x and pos.y <= right_bottom.y +end + +--- Shrinks the size of an area by the given amount +-- @param area the area +-- @param amount to shrink each edge of the area inwards by +-- @return the shrunk area +function Area.shrink(area, amount) + fail_if_missing(area, "missing area value") + fail_if_missing(amount, "missing amount value") + if amount < 0 then error("Can not shrunk area by a negative amount (see Area.expand)!", 2) end + area = Area.to_table(area) + + local left_top = Position.to_table(area.left_top) + local right_bottom = Position.to_table(area.right_bottom) + return {left_top = {x = left_top.x + amount, y = left_top.y + amount}, right_bottom = {x = right_bottom.x - amount, y = right_bottom.y - amount}} +end + +--- Expands the size of an area by the given amount +-- @param area the area +-- @param amount to expand each edge of the area outwards by +-- @return the expanded area +function Area.expand(area, amount) + fail_if_missing(area, "missing area value") + fail_if_missing(amount, "missing amount value") + if amount < 0 then error("Can not expand area by a negative amount (see Area.shrink)!", 2) end + area = Area.to_table(area) + + local left_top = Position.to_table(area.left_top) + local right_bottom = Position.to_table(area.right_bottom) + return {left_top = {x = left_top.x - amount, y = left_top.y - amount}, right_bottom = {x = right_bottom.x + amount, y = right_bottom.y + amount}} +end + +--- Offsets the area by the {x, y} values +-- @param area the area +-- @param pos the {x, y} amount to offset the area +-- @return offset area by the position values +function Area.offset(area, pos) + fail_if_missing(area, "missing area value") + fail_if_missing(pos, "missing pos value") + area = Area.to_table(area) + + return {left_top = Position.add(area.left_top, pos), right_bottom = Position.add(area.right_bottom, pos)} +end + +--- Converts an area to the integer representation, by taking the floor of the left_top and the ceiling of the right_bottom +-- @param area the area +-- @return the rounded integer representation +function Area.round_to_integer(area) + fail_if_missing(area, "missing area value") + area = Area.to_table(area) + + local left_top = Position.to_table(area.left_top) + local right_bottom = Position.to_table(area.right_bottom) + return {left_top = {x = math.floor(left_top.x), y = math.floor(left_top.y)}, + right_bottom = {x = math.ceil(right_bottom.x), y = math.ceil(right_bottom.y)}} +end + +--- Iterates an area. Example: +--
+-- for x,y in Area.iterate({{0, -5}, {3, -3}}) do +-- ... +-- end+-- @param area the area +-- @return iterator +function Area.iterate(area) + fail_if_missing(area, "missing area value") + + local iterator = {idx = 0} + function iterator.iterate(area) + local rx = area.right_bottom.x - area.left_top.x + 1 + local dx = iterator.idx % rx + local dy = math.floor(iterator.idx / rx) + iterator.idx = iterator.idx + 1 + if (area.left_top.y + dy) > area.right_bottom.y then + return + end + return (area.left_top.x + dx), (area.left_top.y + dy) + end + return iterator.iterate, Area.to_table(area), 0 +end + +--- Converts an area in the array format to an array in the table format +-- @param area_arr the area to convert +-- @return a converted position, { x = pos_arr[1], y = pos_arr[2] } +function Area.to_table(area_arr) + fail_if_missing(area_arr, "missing area value") + if #area_arr == 2 then + return { left_top = Position.to_table(area_arr[1]), right_bottom = Position.to_table(area_arr[2]) } + end + return area_arr +end + +return Area diff --git a/stdlib/area/position.lua b/stdlib/area/position.lua new file mode 100644 index 0000000..9ce0fa2 --- /dev/null +++ b/stdlib/area/position.lua @@ -0,0 +1,159 @@ +--- Position module +-- @module position + +Position = {} + +require 'stdlib/core' + +--- Creates a position that is offset by x,y coordinate pair +-- @param pos the position to offset +-- @param x the amount to offset the position in the x direction +-- @param y the amount to offset the position in the y direction +-- @return a new position, offset by the x,y coordinates +function Position.offset(pos, x, y) + fail_if_missing(pos, "missing position argument") + fail_if_missing(x, "missing x-coordinate value") + fail_if_missing(y, "missing y-coordinate value") + + if #pos == 2 then + return { x = pos[1] + x, y = pos[2] + y } + else + return { x = pos.x + x, y = pos.y + y } + end +end + +--- Adds 2 positions +-- @param pos1 the first position +-- @param pos2 the second position +-- @return a new position +function Position.add(pos1, pos2) + fail_if_missing(pos1, "missing first position argument") + fail_if_missing(pos2, "missing second position argument") + + pos1 = Position.to_table(pos1) + pos2 = Position.to_table(pos2) + return { x = pos1.x + pos2.x, y = pos1.y + pos2.y} +end + +--- Subtracts 2 positions +-- @param pos1 the first position +-- @param pos2 the second position +-- @return a new position +function Position.subtract(pos1, pos2) + fail_if_missing(pos1, "missing first position argument") + fail_if_missing(pos2, "missing second position argument") + + pos1 = Position.to_table(pos1) + pos2 = Position.to_table(pos2) + return { x = pos1.x - pos2.x, y = pos1.y - pos2.y } +end + +--- Translates a position in the given direction +-- @param pos the position to translate +-- @param direction in which direction to translate (see defines.direction) +-- @param distance distance of the translation +-- @return the translated position +function Position.translate(pos, direction, distance) + fail_if_missing(pos, "missing position argument") + fail_if_missing(direction, "missing direction argument") + fail_if_missing(distance, "missing distance argument") + + pos = Position.to_table(pos) + + if direction == defines.direction.north then + return { x = pos.x, y = pos.y - distance } + elseif direction == defines.direction.northeast then + return { x = pos.x + distance, y = pos.y - distance } + elseif direction == defines.direction.east then + return { x = pos.x + distance, y = pos.y } + elseif direction == defines.direction.southeast then + return { x = pos.x + distance, y = pos.y + distance } + elseif direction == defines.direction.south then + return { x = pos.x, y = pos.y + distance } + elseif direction == defines.direction.southwest then + return { x = pos.x - distance, y = pos.y + distance } + elseif direction == defines.direction.west then + return { x = pos.x - distance, y = pos.y } + elseif direction == defines.direction.northwest then + return { x = pos.x - distance, y = pos.y - distance } + end +end + +--- Expands a position to a square area +-- @param pos the position to expand into an area +-- @param radius half the side length of the area +-- @return a bounding box +function Position.expand_to_area(pos, radius) + fail_if_missing(pos, "missing position argument") + fail_if_missing(radius, "missing radius argument") + + if #pos == 2 then + return { left_top = { x = pos[1] - radius, y = pos[2] - radius }, right_bottom = { x = pos[1] + radius, y = pos[2] + radius } } + end + return { left_top = { x = pos.x - radius, y = pos.y - radius}, right_bottom = { x = pos.x + radius, y = pos.y + radius } } +end + +--- Calculates the Euclidean distance squared between two positions, useful when sqrt is not needed +-- @param pos1 the first position +-- @param pos2 the second position +-- @return the square of the Euclidean distance +function Position.distance_squared(pos1, pos2) + fail_if_missing(pos1, "missing first position argument") + fail_if_missing(pos2, "missing second position argument") + + pos1 = Position.to_table(pos1) + pos2 = Position.to_table(pos2) + local axbx = pos1.x - pos2.x + local ayby = pos1.y - pos2.y + return axbx * axbx + ayby * ayby +end + +--- Calculates the Euclidean distance between two positions +-- @param pos1 the first position +-- @param pos2 the second position +-- @return the square of the Euclidean distance +function Position.distance(pos1, pos2) + fail_if_missing(pos1, "missing first position argument") + fail_if_missing(pos2, "missing second position argument") + + return math.sqrt(Position.distance_squared(pos1, pos2)) +end + +--- Calculates the manhatten distance between two positions +-- @param pos1 the first position +-- @param pos2 the second position +-- @return the square of the Euclidean distance +function Position.manhattan_distance(pos1, pos2) + fail_if_missing(pos1, "missing first position argument") + fail_if_missing(pos2, "missing second position argument") + pos1 = Position.to_table(pos1) + pos2 = Position.to_table(pos2) + + return math.abs(pos2.x - pos1.x) + math.abs(pos2.y - pos1.y) +end + +--- Converts a position in the array format to a position in the table format +-- @param pos_arr the position to convert +-- @return a converted position, { x = pos_arr[1], y = pos_arr[2] } +function Position.to_table(pos_arr) + fail_if_missing(pos_arr, "missing position argument") + + if #pos_arr == 2 then + return { x = pos_arr[1], y = pos_arr[2] } + end + return pos_arr +end + +--- Converts a position to a string +-- @param pos the position to convert +-- @return string representation of pos +function Position.tostring(pos) + fail_if_missing(pos, "missing position argument") + if #pos == 2 then + return "Position {x = " .. pos[1] .. ", y = " .. pos[2] .. "}" + else + return "Position {x = " .. pos.x .. ", y = " .. pos.y .. "}" + end +end + +return Position diff --git a/stdlib/core.lua b/stdlib/core.lua new file mode 100644 index 0000000..c2e784d --- /dev/null +++ b/stdlib/core.lua @@ -0,0 +1,16 @@ +--- Core module +-- @module core + +--- Errors if the variable evaluates to false, with an optional msg +-- @param var variable to evaluate +-- @param msg (optional) message +function fail_if_missing(var, msg) + if not var then + if msg then + error(msg, 3) + else + error("Missing value", 3) + end + end + return false +end diff --git a/stdlib/entity/entity.lua b/stdlib/entity/entity.lua new file mode 100644 index 0000000..06bf5de --- /dev/null +++ b/stdlib/entity/entity.lua @@ -0,0 +1,100 @@ +--- Entity module +-- @module entity + +require 'stdlib/core' +require 'stdlib/surface' +require 'stdlib/area/area' + +Entity = {} + +--- Converts an entity and its selection_box to the area around it +-- @param entity to convert to an area +-- @return area that entity selection_box is valid for +function Entity.to_selection_area(entity) + fail_if_missing(entity, "missing entity argument") + + local pos = entity.position + local bb = entity.prototype.selection_box + return Area.offset(bb, pos) +end + +--- Converts an entity and its selection_box to the area around it +-- @param entity to convert to an area +-- @return area that entity selection_box is valid for +function Entity.to_collision_area(entity) + fail_if_missing(entity, "missing entity argument") + + local pos = entity.position + local bb = entity.prototype.collision_box + return Area.offset(bb, pos) +end + +--- Tests whether an entity has access to the field +-- @param entity to test field access +-- @param field_name that should be tested for +-- @return true if the entity has access to the field, false if the entity threw an exception accessing the field +function Entity.has(entity, field_name) + fail_if_missing(entity, "missing entity argument") + fail_if_missing(field_name, "missing field name argument") + + local status = pcall(function() return entity[field_name]; end) + return status +end + +--- Gets user data from the entity, stored in a mod's global data. +---
The data will persist between loads, and will be removed for an entity when it becomes invalid
+-- @param the entity to look up data for +-- @return the data, or nil if no data exists for the entity +function Entity.get_data(entity) + fail_if_missing(entity, "missing entity argument") + if not global._entity_data then return nil end + + local entity_name = entity.name + if not global._entity_data[entity_name] then return nil end + local entity_category = global._entity_data[entity_name] + for _, entity_data in pairs(entity_category) do + if entity_data.entity == entity then + return entity_data.data + end + end + return nil +end + +--- Sets user data on the entity, stored in a mod's global data. +---The data will persist between loads, and will be removed for an entity when it becomes invalid
+-- @param the entity to set data for +-- @param the data to set, or nil to delete the data associated with the entity +-- @return the previous data associated with the entity, or nil if the entity had no previous data +function Entity.set_data(entity, data) + fail_if_missing(entity, "missing entity argument") + + if not global._entity_data then global._entity_data = {} end + + local entity_name = entity.name + if not global._entity_data[entity_name] then + global._entity_data[entity_name] = { pos_data = {}, data = {} } + end + + local entity_category = global._entity_data[entity_name] + + for i = #entity_category, 1, -1 do + local entity_data = entity_category[i] + if not entity_data.entity.valid then + table.remove(entity_category, i) + end + if entity_data.entity == entity then + local prev = entity_data.data + if data then + entity_data.data = data + else + table.remove(entity_category, i) + end + return prev + end + end + + table.insert(entity_category, { entity = entity, data = data }) + return nil +end + +return Entity diff --git a/stdlib/entity/inventory.lua b/stdlib/entity/inventory.lua new file mode 100644 index 0000000..71ed231 --- /dev/null +++ b/stdlib/entity/inventory.lua @@ -0,0 +1,28 @@ +--- Inventory module +-- @module inventory + +Inventory = {} + +require 'stdlib/core' + +--- Copies an inventory contents to a destination inventory +-- @param src source inventory to copy from +-- @param dest destination inventory, to copy to +-- @return an array of SimpleItemStacks of left over items that could not be copied. +function Inventory.copy_inventory(src, dest) + fail_if_missing(src, "missing source inventory") + fail_if_missing(dest, "missing destination inventory") + + local contents = src.get_contents() + local left_over = {} + for n, c in pairs(contents) do + local inserted = dest.insert({name=n, count=c}) + local amt_not_inserted = c - inserted + if amt_not_inserted > 0 then + table.insert(left_over, { name = n, count = amt_not_inserted }) + end + end + return left_over +end + +return Inventory diff --git a/stdlib/event/event.lua b/stdlib/event/event.lua new file mode 100644 index 0000000..02d2e2b --- /dev/null +++ b/stdlib/event/event.lua @@ -0,0 +1,86 @@ +--- Event module +-- @module Event + +require 'stdlib/core' +require 'stdlib/game' + +Event = {_registry = {}} + +--- Registers a function for a given event +-- @param event or array containing events to register +-- @param handler Function to call when event is triggered +-- @return #Event +function Event.register(event, handler) + fail_if_missing(event, "missing event argument") + + if type(event) == "number" then + event = {event} + end + + for _, event_id in pairs(event) do + fail_if_missing(event_id, "missing event id") + if handler == nil then + Event._registry[event_id] = nil + script.on_event(event_id, nil) + else + if not Event._registry[event_id] then + Event._registry[event_id] = {} + script.on_event(event_id, Event.dispatch) + end + table.insert(Event._registry[event_id], handler) + end + end + return Event +end + +--- Calls the registerd handlers +-- @param event LuaEvent as created by game.raise_event +function Event.dispatch(event) + fail_if_missing(event, "missing event argument") + + if Event._registry[event.name] then + for _, handler in pairs(Event._registry[event.name]) do + local metatbl = { __index = function(tbl, key) if key == '_handler' then return handler else return rawget(tbl, key) end end } + setmetatable(event, metatbl) + local success, err = pcall(handler, event) + if not success then + Game.print_all(err) + return + end + if err then + return + end + end + end +end + +--- Removes the handler from the event +-- @param event event or array containing events to remove the handler +-- @param handler to remove +-- @return #Event +function Event.remove(event, handler) + fail_if_missing(event, "missing event argument") + fail_if_missing(handler, "missing handler argument") + + if type(event) == "number" then + event = {event} + end + + for _, event_id in pairs(event) do + fail_if_missing(event_id, "missing event id") + if Event._registry[event_id] then + for i=#Event._registry[event_id], 1, -1 do + if Event._registry[event_id][i] == handler then + table.remove(Event._registry[event_id], i) + end + end + if #Event._registry[event_id] == 0 then + Event._registry[event_id] = nil + script.on_event(event_id, nil) + end + end + end + return Event +end + +return Event diff --git a/stdlib/game.lua b/stdlib/game.lua new file mode 100644 index 0000000..3a1bf06 --- /dev/null +++ b/stdlib/game.lua @@ -0,0 +1,58 @@ +--- Game module +-- @module game + +Game = {} +Game.VALID_FILTER = function(v) + return v.valid +end + +--- Messages all players currently connected to the game +-- @param msg message to send to players +-- @param condition (optional) optional condition to be true for the player to be messaged +-- @return the number of players who received the message +function Game.print_all(msg, condition) + local num = 0 + for _, player in ipairs(game.players) do + if player.valid and player.connected then + if condition == nil or select(2, pcall(condition, player)) then + player.print(msg) + num = num + 1 + end + end + end + return num +end + +--- Messages all players with the given force connected to the game +-- @param force (may be force name string, or force object) the players with the given force to message +-- @param msg message to send to players +-- @return the number of players who received the message +function Game.print_force(force, msg) + local force_name + if type(force) == "string" then + force_name = force + else + force_name = force.name + end + return Game.print_all(msg, function(player) + return player.force.name == force_name + end) +end + +--- Messages all players with the given surface connected to the game +-- @param surface the players with the given surface to message +-- @param msg message to send to players +-- @return the number of players who received the message +function Game.print_surface(surface, msg) + local surface_name + if type(surface) == "string" then + surface_name = surface + else + surface_name = surface.name + end + return Game.print_all(msg, function(player) + return player.surface.name == surface_name + end) +end + +return Game diff --git a/stdlib/log/logger.lua b/stdlib/log/logger.lua new file mode 100644 index 0000000..b575aab --- /dev/null +++ b/stdlib/log/logger.lua @@ -0,0 +1,59 @@ +--- Logger module +-- @module log + +Logger = {} + +--- Creates a new logger object +-- @param mod_name [required] the name of the mod to create the logger for +-- @param log_name (optional, default: 'main') the name of the logger +-- @param debug_mode (optional, default: false) toggles the debug state of logger. +-- In debug mode, the logger writes immediately. Otherwise it buffers lines. +-- Logger flushes after 60 seconds has elapsed since the last message. +-- @return the logger instance +function Logger.new(mod_name, log_name, debug_mode) + if not mod_name then + error("Logger must be given a mod_name as the first argument") + end + if not log_name then + log_name = "main" + end + local Logger = {mod_name = mod_name, log_name = log_name, debug_mode = debug_mode, buffer = {}, last_written = 0, ever_written = false} + + --- Logs a message + -- @param msg a string, the message to log + -- @return true if the message was written, false if it was queued for a later write + function Logger.log(msg) + if _G["game"] then + local time_s = math.floor(game.tick/60) + local time_minutes = math.floor(time_s/60) + local time_hours = math.floor(time_minutes/60) + table.insert(Logger.buffer, string.format("%02d:%02d:%02d: %s\n", time_hours, time_minutes % 60, time_s % 60, msg)) + + -- write the log every minute + if (Logger.debug_mode or (game.tick - Logger.last_written) > 216000) then + return Logger.write() + end + else + table.insert(Logger.buffer, string.format("00:00:00: %s\n", msg)) + end + return false + end + + --- Writes out all buffered messages immediately + -- @return true if there any messages were written, false if not + function Logger.write() + if _G["game"] then + Logger.last_written = game.tick + local file_name = "logs/" .. Logger.mod_name .. "/" .. Logger.log_name .. ".log" + game.write_file(file_name, table.concat(Logger.buffer), Logger.ever_written) + Logger.buffer = {} + Logger.ever_written = true + return true + end + return false + end + + return Logger +end + +return Logger diff --git a/stdlib/string.lua b/stdlib/string.lua new file mode 100644 index 0000000..0992428 --- /dev/null +++ b/stdlib/string.lua @@ -0,0 +1,25 @@ +--- String module +-- @module string + +--- Returns a copy of the string with any leading or trailing whitespace from the string removed. +-- @param s the string to remove leading or trailing whitespace from +-- @return a copy of the string without leading or trailing whitespace +function string.trim(s) + return (s:gsub("^%s*(.-)%s*$", "%1")) +end + +--- Tests if a string starts with a given substring +-- @param s the string to check for the start substring +-- @param start the substring to test for +-- @return true if the start substring was found in the string +function string.starts_with(s, start) + return string.find(s, start, 1, true) == 1 +end + +--- Tests if a string ends with a given substring +-- @param s the string to check for the end substring +-- @param ends the substring to test for +-- @return true if the end substring was found in the string +function string.ends_with(s, ends) + return #s >= #ends and string.find(s, ends, #s - #ends + 1, true) and true or false +end diff --git a/stdlib/surface.lua b/stdlib/surface.lua new file mode 100644 index 0000000..6cd3a3e --- /dev/null +++ b/stdlib/surface.lua @@ -0,0 +1,79 @@ +--- Surface module +-- @module surface + +require 'stdlib/core' + +Surface = {} + +--- Flexible, safe lookup function for surfaces.+-- May be given a string, the name of a surface, or may be given a table with surface names, +-- may be given the a surface object, or may be given a table of surface objects, or +-- may be given nil.
+-- Returns an array of surface objects of all valid, existing surfaces +-- If a surface does not exist for the surface, it is ignored, if no surfaces +-- are given, an empty array is returned. +-- @param surface to lookup +-- @return the list of surfaces looked up +function Surface.lookup(surface) + if not surface then + return {} + end + if type(surface) == 'string' then + if game.surfaces[surface] then + return {game.surfaces[surface]} + end + return {} + end + local result = {} + for _, surface_item in pairs(surface) do + if type(surface_item) == 'string' then + if game.surfaces[surface_item] then + table.insert(result, game.surfaces[surface_item]) + end + elseif type(surface_item) == 'table' and surface_item['__self'] then + table.insert(result, surface_item) + end + end + return result +end + +--- Given search criteria, a table that contains a name or type of entity to search for, +-- and optionally surface or force, searches all loaded chunks for the entities that +-- match the critera. +--
Ex:
+-- Surface.final_all_entities({ type = 'unit', surface = 'nauvis' })
+-- Will return all units on the nauvis surface. +-- @param search_criteria a table of criteria. Must contain either the name or type or force of an entity. May contain surface or force. +-- @return an array of all entities that matched the criteria +function Surface.find_all_entities(search_criteria) + fail_if_missing(search_criteria, "missing search_criteria argument") + if search_criteria.name == nil and search_criteria.type == nil and search_criteria.force == nil then + error("Missing search criteria field: name or type or force of entity", 2) + end + + local surface_list = Surface.lookup(search_criteria.surface) + if search_criteria.surface == nil then + surface_list = game.surfaces + end + + local result = {} + + for _, surface in pairs(surface_list) do + for chunk in surface.get_chunks() do + local entities = surface.find_entities_filtered( + { + area = { left_top = { x = chunk.x * 32, y = chunk.y * 32 }, right_bottom = {x = (chunk.x + 1) * 32, y = (chunk.y + 1) * 32}}, + name = search_criteria.name, + type = search_criteria.type, + force = search_criteria.force + }) + for _, entity in ipairs(entities) do + table.insert(result, entity) + end + end + end + + return result +end + +return Surface diff --git a/stdlib/table.lua b/stdlib/table.lua new file mode 100644 index 0000000..6bb8b4d --- /dev/null +++ b/stdlib/table.lua @@ -0,0 +1,67 @@ +--- Table module +-- @module table + +--- Given a mapping function, creates a transformed copy of the table +--- by calling the function for each element in the table, and using +--- the result as the new value for the key. +---
Ex:
+---table.map({ 1, 2, 3, 4, 5}, function(v) return v * 10 end) +--- produces: { 10, 20, 30, 40, 50 }+-- @param tbl to be mapped to the transform +-- @param func to transform values +-- @result a new table containing the keys and mapped values +function table.map(tbl, func) + local newtbl = {} + for i, v in pairs(tbl) do + newtbl[i] = func(v) + end + return newtbl +end + +--- Given a filter function, creates a filtered copy of the table +--- by calling the function for each element in the table, and +--- filtering out any key-value pairs for non-true results +---
Ex:
+---table.filter({ 1, 2, 3, 4, 5}, function(v) return v % 2 == 0 end) +--- produces: { 2, 4 }+-- @param tbl to be filtered +-- @param func to filter values +-- @return a new table containing the filtered key-value pairs +function table.filter(tbl, func) + local newtbl = {} + local insert = #tbl > 0 + for k, v in pairs(tbl) do + if func(v) then + if insert then table.insert(newtbl, v) + else newtbl[k] = v end + end + end + return newtbl +end + +--- Given a function, apply it to each element in the table +-- @param tbl to be iterated +-- @param func to apply to values +-- @return the given table +function table.each(tbl, func) + for _, v in pairs(tbl) do + func(v) + end + return tbl +end + +--- Given an array, returns the first element or nil if no element exists +-- @param tbl the array +-- @return the first element +function table.first(tbl) + return tbl[1] +end + +--- Given an array, returns the last element or nil if no elements exist +-- @param tbl the array +-- @return the last element +function table.last(tbl) + local size = #tbl + if size == 0 then return nil end + return tbl[size] +end