├── .gitignore ├── all.do ├── src ├── e_tools.h ├── default.h.gch.do ├── g_group.c ├── g_group.h ├── g_method_sy.h ├── g_method_clob.h ├── p_draw.h ├── c_generate.h ├── t_draw.h ├── f_turn.h ├── c_init.h ├── g_proc_run.h ├── f_game.h ├── i_error.h ├── s_turn.h ├── x_init.h ├── p_init.h ├── s_menu.h ├── d_code_header.h ├── g_game.h ├── v_init_panel.h ├── g_method_sy.c ├── i_sysmenu.h ├── g_packet.h ├── g_game.do ├── i_view.h ├── precompile.h ├── e_inter.h ├── g_cloud.h ├── g_world_back.h ├── h_interface.h ├── m_globvars.h ├── g_misc.h ├── c_lexer.h ├── c_compile.h ├── e_clip.h ├── g_method_clob.c ├── z_poly.h ├── d_geo.h ├── c_prepr.h ├── x_music.h ├── g_method_pr.c ├── g_method_uni.h ├── f_save.h ├── g_proc.h ├── t_files.h ├── e_files.h ├── g_method_pr.h ├── t_init.c ├── i_buttons.h ├── g_world_map_2.h ├── i_error.c ├── e_log.h ├── g_proc_new.h ├── h_mission.h ├── i_disp_in.h ├── v_interp.h ├── default.o.do ├── g_motion.h ├── g_world.h ├── c_fix.h ├── i_input.h ├── i_background.h ├── e_editor.h ├── s_mission.h ├── f_load.h ├── e_complete.h ├── g_method_misc.h ├── c_init.c ├── d_draw.h ├── e_help.h ├── g_method.h ├── g_method_core.h ├── x_synth.h ├── m_maths.h ├── x_sound.h ├── i_display.h ├── g_command.h ├── v_draw_panel.h ├── h_story.h ├── e_tools.c ├── i_console.h ├── d_code.h ├── i_background.c ├── g_world_map.h ├── m_config.h ├── i_buttons.c └── g_method_uni.c ├── bin ├── launcher.sh ├── libcirc.do ├── data │ ├── sound │ │ ├── bang.wav │ │ ├── blip.wav │ │ ├── kill.wav │ │ ├── new.wav │ │ ├── over.wav │ │ ├── sine.wav │ │ ├── zap.wav │ │ ├── alloc.wav │ │ ├── bang2.wav │ │ ├── blip2.wav │ │ ├── blip3.wav │ │ ├── blip4.wav │ │ ├── bubble.wav │ │ ├── chirp.wav │ │ ├── int_up.wav │ │ ├── slice.wav │ │ ├── spike.wav │ │ ├── ultra.wav │ │ ├── int_break.wav │ │ ├── restore.wav │ │ ├── stream1.wav │ │ ├── stream2.wav │ │ ├── x_chime.wav │ │ └── music │ │ │ ├── click.wav │ │ │ ├── drum1.wav │ │ │ ├── drum2.wav │ │ │ ├── drum3.wav │ │ │ └── thump.wav │ ├── images │ │ ├── title.bmp │ │ ├── fwt_font.bmp │ │ ├── fwss_font.bmp │ │ ├── fwt_font_L.bmp │ │ ├── fwt_font_M.bmp │ │ ├── large_font.bmp │ │ ├── fwss_font_L.bmp │ │ ├── fwss_font_M.bmp │ │ ├── large_font_L.bmp │ │ └── large_font_M.bmp │ └── manual │ │ ├── move.png │ │ ├── attack.png │ │ ├── basic_core.png │ │ ├── harvesting.png │ │ ├── just_core.png │ │ ├── start_menu.png │ │ ├── bcode_panel.png │ │ ├── design_panel.png │ │ ├── editor_panel.png │ │ ├── large_process.png │ │ ├── multi_process.png │ │ ├── process_header.png │ │ └── template_panel.png ├── story │ ├── green │ │ ├── green2 │ │ │ ├── g4_outpost.c │ │ │ └── g4_spikebase.c │ │ ├── green1 │ │ │ ├── g1_firebase.c │ │ │ └── g1_base.c │ │ └── green3 │ │ │ ├── g5_outpost.c │ │ │ └── g5_spikebase.c │ ├── tutorial │ │ ├── tute1 │ │ │ ├── defend1.c │ │ │ └── circle1.c │ │ └── tute2 │ │ │ ├── defend2.c │ │ │ └── circle2.c │ ├── orange │ │ └── orange2 │ │ │ └── o2_defend.c │ ├── blue │ │ ├── blue2 │ │ │ ├── b2_wander1.c │ │ │ ├── b2_wander2.c │ │ │ └── b2_rbase.c │ │ └── blue1 │ │ │ ├── wander1.c │ │ │ ├── rbase.c │ │ │ └── wander2.c │ ├── purple │ │ ├── purple1 │ │ │ └── p1_defence.c │ │ ├── purple2 │ │ │ └── p2_defence.c │ │ └── purple3 │ │ │ └── p3_defence.c │ └── red │ │ ├── red2 │ │ └── r2_defence.c │ │ └── red3 │ │ └── r3_defence.c ├── misc │ └── fix-altgr.ahk └── readme.txt ├── linux-packaging ├── icon-16px.png ├── icon-256px.png ├── icon-32px.png ├── liberation-circuit.desktop └── liberation-circuit.appdata.xml ├── Makefile ├── README.md └── do /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | lc 3 | -------------------------------------------------------------------------------- /all.do: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | redo-ifchange bin/libcirc 3 | -------------------------------------------------------------------------------- /src/e_tools.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | void find_next(void); 4 | -------------------------------------------------------------------------------- /src/default.h.gch.do: -------------------------------------------------------------------------------- 1 | redo-ifchange $2.o 2 | ln $2.o $3 3 | -------------------------------------------------------------------------------- /src/g_group.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | No longer used 4 | 5 | */ 6 | 7 | 8 | -------------------------------------------------------------------------------- /bin/launcher.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | cd "$(dirname "$0")" && ./libcirc "$@"; 3 | -------------------------------------------------------------------------------- /src/g_group.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_G_GROUP 3 | #define H_G_GROUP 4 | 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /bin/libcirc.do: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | redo-ifchange ../src/g_game 3 | ln -s ../src/g_game "$3" 4 | -------------------------------------------------------------------------------- /src/g_method_sy.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_G_METHOD_SY 3 | #define H_G_METHOD_SY 4 | 5 | #endif 6 | -------------------------------------------------------------------------------- /bin/data/sound/bang.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/sound/bang.wav -------------------------------------------------------------------------------- /bin/data/sound/blip.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/sound/blip.wav -------------------------------------------------------------------------------- /bin/data/sound/kill.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/sound/kill.wav -------------------------------------------------------------------------------- /bin/data/sound/new.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/sound/new.wav -------------------------------------------------------------------------------- /bin/data/sound/over.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/sound/over.wav -------------------------------------------------------------------------------- /bin/data/sound/sine.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/sound/sine.wav -------------------------------------------------------------------------------- /bin/data/sound/zap.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/sound/zap.wav -------------------------------------------------------------------------------- /src/g_method_clob.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_G_METHOD_CLOB 3 | #define H_G_METHOD_CLOB 4 | 5 | 6 | #endif 7 | 8 | -------------------------------------------------------------------------------- /src/p_draw.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_P_DRAW 3 | #define H_P_DRAW 4 | 5 | void draw_panels(void); 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /bin/data/images/title.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/images/title.bmp -------------------------------------------------------------------------------- /bin/data/manual/move.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/manual/move.png -------------------------------------------------------------------------------- /bin/data/sound/alloc.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/sound/alloc.wav -------------------------------------------------------------------------------- /bin/data/sound/bang2.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/sound/bang2.wav -------------------------------------------------------------------------------- /bin/data/sound/blip2.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/sound/blip2.wav -------------------------------------------------------------------------------- /bin/data/sound/blip3.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/sound/blip3.wav -------------------------------------------------------------------------------- /bin/data/sound/blip4.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/sound/blip4.wav -------------------------------------------------------------------------------- /bin/data/sound/bubble.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/sound/bubble.wav -------------------------------------------------------------------------------- /bin/data/sound/chirp.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/sound/chirp.wav -------------------------------------------------------------------------------- /bin/data/sound/int_up.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/sound/int_up.wav -------------------------------------------------------------------------------- /bin/data/sound/slice.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/sound/slice.wav -------------------------------------------------------------------------------- /bin/data/sound/spike.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/sound/spike.wav -------------------------------------------------------------------------------- /bin/data/sound/ultra.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/sound/ultra.wav -------------------------------------------------------------------------------- /bin/data/images/fwt_font.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/images/fwt_font.bmp -------------------------------------------------------------------------------- /bin/data/manual/attack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/manual/attack.png -------------------------------------------------------------------------------- /bin/data/sound/int_break.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/sound/int_break.wav -------------------------------------------------------------------------------- /bin/data/sound/restore.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/sound/restore.wav -------------------------------------------------------------------------------- /bin/data/sound/stream1.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/sound/stream1.wav -------------------------------------------------------------------------------- /bin/data/sound/stream2.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/sound/stream2.wav -------------------------------------------------------------------------------- /bin/data/sound/x_chime.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/sound/x_chime.wav -------------------------------------------------------------------------------- /bin/data/images/fwss_font.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/images/fwss_font.bmp -------------------------------------------------------------------------------- /bin/data/images/fwt_font_L.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/images/fwt_font_L.bmp -------------------------------------------------------------------------------- /bin/data/images/fwt_font_M.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/images/fwt_font_M.bmp -------------------------------------------------------------------------------- /bin/data/images/large_font.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/images/large_font.bmp -------------------------------------------------------------------------------- /bin/data/manual/basic_core.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/manual/basic_core.png -------------------------------------------------------------------------------- /bin/data/manual/harvesting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/manual/harvesting.png -------------------------------------------------------------------------------- /bin/data/manual/just_core.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/manual/just_core.png -------------------------------------------------------------------------------- /bin/data/manual/start_menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/manual/start_menu.png -------------------------------------------------------------------------------- /bin/data/sound/music/click.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/sound/music/click.wav -------------------------------------------------------------------------------- /bin/data/sound/music/drum1.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/sound/music/drum1.wav -------------------------------------------------------------------------------- /bin/data/sound/music/drum2.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/sound/music/drum2.wav -------------------------------------------------------------------------------- /bin/data/sound/music/drum3.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/sound/music/drum3.wav -------------------------------------------------------------------------------- /bin/data/sound/music/thump.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/sound/music/thump.wav -------------------------------------------------------------------------------- /linux-packaging/icon-16px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/linux-packaging/icon-16px.png -------------------------------------------------------------------------------- /linux-packaging/icon-256px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/linux-packaging/icon-256px.png -------------------------------------------------------------------------------- /linux-packaging/icon-32px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/linux-packaging/icon-32px.png -------------------------------------------------------------------------------- /bin/data/images/fwss_font_L.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/images/fwss_font_L.bmp -------------------------------------------------------------------------------- /bin/data/images/fwss_font_M.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/images/fwss_font_M.bmp -------------------------------------------------------------------------------- /bin/data/images/large_font_L.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/images/large_font_L.bmp -------------------------------------------------------------------------------- /bin/data/images/large_font_M.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/images/large_font_M.bmp -------------------------------------------------------------------------------- /bin/data/manual/bcode_panel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/manual/bcode_panel.png -------------------------------------------------------------------------------- /bin/data/manual/design_panel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/manual/design_panel.png -------------------------------------------------------------------------------- /bin/data/manual/editor_panel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/manual/editor_panel.png -------------------------------------------------------------------------------- /bin/data/manual/large_process.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/manual/large_process.png -------------------------------------------------------------------------------- /bin/data/manual/multi_process.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/manual/multi_process.png -------------------------------------------------------------------------------- /src/c_generate.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_C_GENERATE 3 | #define H_C_GENERATE 4 | 5 | int intercode_to_bcode(void); 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /bin/data/manual/process_header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/manual/process_header.png -------------------------------------------------------------------------------- /bin/data/manual/template_panel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linleyh/liberation-circuit/HEAD/bin/data/manual/template_panel.png -------------------------------------------------------------------------------- /src/t_draw.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_T_DRAW 3 | #define H_T_DRAW 4 | 5 | 6 | void draw_template_panel(); 7 | 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/f_turn.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_F_TURN 3 | #define H_F_TURN 4 | 5 | int load_turnfile(int p); 6 | int save_turnfile(int p); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /src/c_init.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_C_INIT 3 | #define H_C_INIT 4 | 5 | int init_compiler(struct template_struct* templ, int compiler_mode); 6 | 7 | #endif 8 | 9 | -------------------------------------------------------------------------------- /src/g_proc_run.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_G_PROC_RUN 3 | #define H_G_PROC_RUN 4 | 5 | void run_cores_and_procs(int resume_loop_after_watch_with_core); 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /src/f_game.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef H_F_GAME 4 | #define H_F_GAME 5 | 6 | int save_gamefile(void); 7 | 8 | int load_gamefile(void); 9 | 10 | 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /src/i_error.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | void start_error(int source_program_type, int source_index, int source_player); 4 | void error_string(const char* str); 5 | void error_number(int num); 6 | -------------------------------------------------------------------------------- /src/s_turn.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_S_TURN 3 | #define H_S_TURN 4 | 5 | //int run_turns(void); 6 | //void run_pregame(void); 7 | 8 | //void start_new_turn(void); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /src/x_init.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef H_X_INIT 4 | #define H_X_INIT 5 | 6 | 7 | void init_sound(int camstate_rand_seed); 8 | void stop_sound_thread(void); 9 | 10 | #endif 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/p_init.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_P_INIT 3 | #define H_P_INIT 4 | 5 | void init_panels(void); 6 | void set_subpanel_positions(int pan); 7 | void init_panels_for_new_game(void); 8 | 9 | 10 | #endif 11 | 12 | -------------------------------------------------------------------------------- /src/s_menu.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_S_MENU 3 | #define H_S_MENU 4 | 5 | void start_menus(void); 6 | void init_w_init(void); 7 | void fix_w_init_size(void); 8 | void run_game_from_menu(void); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /src/d_code_header.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef H_D_CODE_HEADER 4 | #define H_D_CODE_HEADER 5 | 6 | int write_design_structure_to_source_edit(int verified_clear_file); 7 | int initialise_autocoder(void); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/g_game.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_G_GAME 3 | #define H_G_GAME 4 | 5 | void start_game(void); 6 | void init_vision_area_map(void); 7 | 8 | //void main_loop(void); 9 | void run_game(void); 10 | 11 | 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /src/v_init_panel.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef H_V_INIT_PANEL 4 | #define H_V_INIT_PANEL 5 | 6 | 7 | 8 | void prepare_template_debug(int player_index, int template_index, int use_user_identifiers); 9 | 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /src/g_method_sy.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | #include "m_config.h" 7 | 8 | 9 | #include "g_header.h" 10 | #include "m_globvars.h" 11 | #include "m_maths.h" 12 | 13 | -------------------------------------------------------------------------------- /src/i_sysmenu.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_I_SYSMENU 3 | #define H_I_SYSMENU 4 | 5 | 6 | void init_sysmenu(void); 7 | void open_sysmenu(void); 8 | void display_sysmenu(void); 9 | int run_sysmenu(void); 10 | void close_sysmenu(void); 11 | 12 | #endif 13 | 14 | -------------------------------------------------------------------------------- /src/g_packet.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_G_PACKET 3 | #define H_G_PACKET 4 | 5 | void init_packets(void); 6 | int new_packet(int type, int player_index, int source_core_index, timestamp source_core_created, al_fixed x, al_fixed y); 7 | void run_packets(void); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /linux-packaging/liberation-circuit.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Type=Application 3 | Name=Liberation Circuit 4 | Comment=Real-time strategy game with programmable units 5 | Exec=liberation-circuit 6 | Icon=liberation-circuit 7 | Terminal=false 8 | Categories=Game; 9 | StartupNotify=false 10 | -------------------------------------------------------------------------------- /src/g_game.do: -------------------------------------------------------------------------------- 1 | objs=$( 2 | for file in *.c; do 3 | echo "${file%.*}.o" 4 | done 5 | ) 6 | echo "$objs" | xargs redo-ifchange 7 | gcc -O3 -fwrapv -o $3 $objs \ 8 | -lallegro -lm -lallegro_audio -lallegro_acodec -lallegro_font \ 9 | -lallegro_image -lallegro_primitives -lallegro_dialog -lallegro_main 10 | -------------------------------------------------------------------------------- /src/i_view.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_I_VIEW 3 | #define H_I_VIEW 4 | 5 | 6 | void init_view_at_startup(int window_w, int window_h); 7 | void initialise_view(int window_w, int window_h); 8 | 9 | void resize_display_window(int window_w, int window_h); 10 | void reset_view_values(int window_w, int window_h); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /src/precompile.h: -------------------------------------------------------------------------------- 1 | #include "allegro5/allegro_acodec.h" 2 | #include "allegro5/allegro_audio.h" 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | -------------------------------------------------------------------------------- /src/e_inter.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_E_INTER 3 | #define H_E_INTER 4 | 5 | void init_editor_display(int screen_w, int screen_h); 6 | void draw_edit_bmp(void); 7 | void change_edit_panel_width(void); 8 | void draw_panel_drag_ready_line(void); 9 | void change_edit_panel_width(void); 10 | void reset_editor_slider_locations(void); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /src/g_cloud.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_G_CLOUD 3 | #define H_G_CLOUD 4 | 5 | void init_clouds(void); 6 | struct cloud_struct* new_cloud(int type, int cloud_lifetime, al_fixed x, al_fixed y); 7 | //void run_clouds(void); 8 | int create_fragment(cart position, cart speed, int fragment_size, int explode_time, int lifetime, int colour); 9 | void run_fragments(void); 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /src/g_world_back.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_G_WORLD_BACK 3 | #define H_G_WORLD_BACK 4 | 5 | 6 | #define NODE_SPACING ((BLOCK_SIZE_PIXELS + 3) / 3) 7 | 8 | void static_build_affects_block_nodes(al_fixed build_x, al_fixed build_y, int effect_size, int player_index); 9 | void seed_mrand(unsigned int new_mrand_seed); 10 | unsigned int mrand(unsigned int rand_max); 11 | 12 | void fix_w_init_size(void); 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /src/h_interface.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_H_INTERFACE 3 | #define H_H_INTERFACE 4 | 5 | 6 | // called when entering story interface from map 7 | void init_story_interface(void); 8 | void open_story_interface(void); 9 | void draw_story_interface(void); 10 | void story_input(void); 11 | void draw_story_cutscene(int area_index, int counter, int counter_max); 12 | 13 | void init_ending_cutscene(void); 14 | void draw_ending_cutscene(int counter, int counter_max); 15 | 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /src/m_globvars.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_M_GLOBVARS 3 | #define H_M_GLOBVARS 4 | 5 | 6 | // this file contains variables that need to be available in every file 7 | // they should be declared in main.c (which is the only file that shouldn't include this file) 8 | 9 | extern struct settingsstruct settings; 10 | extern struct inter_struct inter; 11 | 12 | extern struct world_struct w; 13 | 14 | extern struct ex_control_struct ex_control; 15 | extern struct control_struct control; 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /bin/story/green/green2/g4_outpost.c: -------------------------------------------------------------------------------- 1 | 2 | #process "outpost" 3 | 4 | class auto_harvest; 5 | class auto_allocate; 6 | 7 | core_static_quad, 811, 8 | {object_harvest:auto_harvest, 0}, 9 | {object_none, 0}, 10 | {object_allocate:auto_allocate, 0}, 11 | {object_storage, 0}, 12 | 13 | #code 14 | 15 | int initialised; 16 | 17 | if (!initialised) 18 | { 19 | initialised = 1; 20 | special_AI(0, 104); 21 | } 22 | 23 | auto_harvest.gather_data(); 24 | 25 | auto_allocate.allocate_data(4); // actually I think the maximum is 2 26 | -------------------------------------------------------------------------------- /src/g_misc.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_G_MISC 3 | #define H_G_MISC 4 | 5 | #include 6 | 7 | void init_random_numbers(int grand_seed); 8 | unsigned int grand(unsigned int max); 9 | unsigned int irand(unsigned int max); 10 | void error_call(void); 11 | 12 | void wait_for_space(void); 13 | void print_binary(int num); 14 | void print_binary8(int num); 15 | void print_binary32(int num); 16 | void safe_exit(int exit_value); 17 | 18 | FILE* open_file_from_standard_path(const char* basic_file_name, const char* mode); 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /src/c_lexer.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_C_LEXER 3 | #define H_C_LEXER 4 | 5 | 6 | int read_next(struct ctokenstruct* ctoken); 7 | int accept_next(struct ctokenstruct* ctoken, int ctoken_type, int check_subtype); 8 | int peek_next(struct ctokenstruct* ctoken); 9 | int check_next(int ctoken_type, int check_subtype); 10 | 11 | int expect_punctuation(int ctoken_subtype); 12 | int expect_constant(struct ctokenstruct* ctoken); 13 | int expect_angle(struct ctokenstruct* ctoken); 14 | 15 | int c_get_next_char_from_scode(void); 16 | 17 | #endif 18 | 19 | -------------------------------------------------------------------------------- /src/c_compile.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_C_COMPILE 3 | #define H_C_COMPILE 4 | 5 | int compile(struct template_struct* templ, struct source_edit_struct* source_edit, int compiler_mode); 6 | 7 | int comp_error(int error_type, struct ctokenstruct* ctoken); 8 | int comp_error_minus1(int error_type, struct ctokenstruct* ctoken); 9 | int comp_error_text(const char* error_text, struct ctokenstruct* ctoken); 10 | void comp_warning_text(const char* warning_text); 11 | 12 | int check_template_objects(struct template_struct* templ, int warning_or_error); 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /src/e_clip.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_E_CLIP 3 | #define H_E_CLIP 4 | 5 | void copy_selection(void); 6 | void paste_clipboard(void); 7 | 8 | void init_undo(void); 9 | void call_undo(void); 10 | void call_redo(void); 11 | 12 | void add_char_undo(char achar); 13 | void delete_char_undo(char achar); 14 | void backspace_char_undo(char achar); 15 | void add_enter_undo(void); 16 | void add_block_to_undo(int start_line, int start_pos, int end_line, int end_pos, int undo_type); 17 | void add_undo_remove_enter(void); 18 | void remove_closed_file_from_undo_stack(int se_index); 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ALLEGRO_MODULES = allegro-5 allegro_audio-5 allegro_acodec-5 allegro_dialog-5 allegro_font-5 allegro_image-5 allegro_primitives-5 2 | CFLAGS = $$(pkg-config --cflags $(ALLEGRO_MODULES)) -Wall 3 | LIBS = -lm $$(pkg-config --libs $(ALLEGRO_MODULES)) 4 | HEADERS = $(shell find src/ -name '*.h') 5 | OBJECTS = $(shell find src/ -name '*.c' | sed -e 's/\.c$$/.o/g') 6 | 7 | .PHONY: all clean 8 | 9 | all: bin/libcirc 10 | 11 | clean: 12 | rm -f bin/libcirc src/*.o 13 | 14 | bin/libcirc: $(OBJECTS) 15 | gcc $(CFLAGS) -o $@ $? $(LIBS) 16 | 17 | %.o: %.c $(HEADERS) 18 | gcc $(CFLAGS) -c -o $@ $< 19 | -------------------------------------------------------------------------------- /src/g_method_clob.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | #include "m_config.h" 7 | 8 | 9 | #include "g_header.h" 10 | 11 | #include "c_header.h" 12 | #include "e_slider.h" 13 | #include "e_header.h" 14 | #include "e_editor.h" 15 | #include "e_log.h" 16 | 17 | #include "g_world.h" 18 | #include "g_misc.h" 19 | #include "g_proc.h" 20 | #include "g_packet.h" 21 | #include "g_motion.h" 22 | #include "g_method.h" 23 | #include "m_globvars.h" 24 | #include "m_maths.h" 25 | #include "t_template.h" 26 | #include "g_method_clob.h" 27 | #include "g_method_misc.h" 28 | #include "i_error.h" 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/z_poly.h: -------------------------------------------------------------------------------- 1 | 2 | // z_poly is my own process geometry editor. 3 | // It's not supported for general use, as using to design new components requires substantial changes to the code. 4 | //#define Z_POLY 5 | 6 | #ifdef Z_POLY 7 | 8 | void zshape_init(void); 9 | void zshape_start(void); 10 | void zshape_end(void); 11 | void zshape_add_poly(int poly, int layer, int colour); 12 | void zshape_add_vertex(int x, int y, int collision); 13 | void zshape_add_link(int x, int y, int left_x, int left_y, int right_x, int right_y, int far_x, int far_y, int link_point_x, int link_point_y, int object_x, int object_y); 14 | void zshape_add_fill_source(int x, int y); 15 | 16 | #endif 17 | 18 | -------------------------------------------------------------------------------- /src/d_geo.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_D_GEO 3 | #define H_D_GEO 4 | 5 | void update_design_member_position_recursively(struct template_struct* templ, int m); 6 | int check_template_collisions(struct template_struct* templ); 7 | int check_template_member_collision(struct template_struct* templ, int m); 8 | 9 | int check_move_objects_obstruction(struct template_struct* templ); 10 | int check_single_move_object_obstruction(struct template_struct* templ, int member_index, int object_index); 11 | 12 | void update_design_member_positions(struct template_struct* templ); 13 | void up_down_design_symmetry(void); 14 | 15 | int get_link_dist_pixel(int base_dist, al_fixed link_angle_offset); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /src/c_prepr.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_C_PREPR 3 | #define H_C_PREPR 4 | 5 | int preprocess(struct source_edit_struct* source_edit); 6 | int valid_source_character(char read_char); 7 | 8 | int load_source_file(const char* file_path, struct source_struct* target_source); 9 | //int load_source_file(const char* file_path, struct source_struct* target_source); 10 | //int load_binary_file(const char* file_path, struct bcode_struct* bcode, int src_file_index, int preprocessing); 11 | 12 | // max length of a preprocessor token 13 | #define PTOKEN_LENGTH 32 14 | 15 | #define NUMTOKENS 700 16 | 17 | // numtokens are built-in defined numbers 18 | struct numtokenstruct 19 | { 20 | char name [PTOKEN_LENGTH]; 21 | int value; 22 | }; 23 | 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /src/x_music.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef H_X_MUSIC 4 | #define H_X_MUSIC 5 | 6 | void sthread_init_mustate(int play_piece); 7 | int sthread_play_current_piece(void); 8 | 9 | void init_camstate(int status, int area_index, int region_index, unsigned int rand_seed); 10 | void sthread_init_sample_pointers(void); 11 | void sthread_run_camstate(void); 12 | //void sthread_create_samples_for_scale(int scale_note_type, int tone_offset); 13 | unsigned int sthread_rand(unsigned int rand_max); 14 | 15 | //#define SCALE_NOTE_TYPE 2 16 | enum 17 | { 18 | SCALE_TONE_0, 19 | SCALE_TONE_1, 20 | SCALE_TONE_2, 21 | SCALE_TONE_3, 22 | SCALE_TONE_4, 23 | SCALE_TONE_5, 24 | SCALE_TONE_6, 25 | SCALE_TONE_7, 26 | SCALE_TONE_8, 27 | SCALE_TONES, 28 | 29 | }; 30 | 31 | #endif 32 | 33 | -------------------------------------------------------------------------------- /src/g_method_pr.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | #include "m_config.h" 7 | 8 | 9 | #include "g_header.h" 10 | 11 | #include "c_header.h" 12 | #include "e_slider.h" 13 | #include "e_header.h" 14 | #include "e_editor.h" 15 | #include "e_log.h" 16 | 17 | #include "g_world.h" 18 | #include "g_misc.h" 19 | #include "g_proc.h" 20 | #include "g_packet.h" 21 | #include "g_motion.h" 22 | 23 | #include "m_globvars.h" 24 | #include "m_maths.h" 25 | #include "g_method_misc.h" 26 | #include "i_error.h" 27 | #include "g_cloud.h" 28 | #include "x_sound.h" 29 | 30 | 31 | extern struct view_struct view; // TO DO: think about putting a pointer to this in the worldstruct instead of externing it 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/g_method_uni.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_G_METHOD_UNI 3 | #define H_G_METHOD_UNI 4 | 5 | s16b call_uni_method(struct core_struct* core, int call_value); 6 | 7 | enum 8 | { 9 | UMETHOD_CALL_SIN, 10 | UMETHOD_CALL_COS, 11 | UMETHOD_CALL_ATAN2, 12 | UMETHOD_CALL_HYPOT, 13 | //UMETHOD_CALL_HYPOT_LESS, 14 | //UMETHOD_CALL_HYPOT_MORE, 15 | UMETHOD_CALL_WORLD_X, 16 | UMETHOD_CALL_WORLD_Y, 17 | UMETHOD_CALL_ABS, 18 | UMETHOD_CALL_ANGLE_DIFFERENCE, 19 | UMETHOD_CALL_ARC_LENGTH, 20 | 21 | UMETHOD_CALL_TYPES 22 | }; 23 | 24 | struct umethod_call_type_struct 25 | { 26 | int parameters; // this is the number of parameters that will be pulled off the stack (in addition to the object/class index) 27 | // parameters shouldn't be greater than CMETHOD_CALL_PARAMETERS 28 | int keyword_index; 29 | }; 30 | 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /src/f_save.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | #ifndef H_F_SAVE 5 | #define H_F_SAVE 6 | 7 | void save_game(void); 8 | 9 | #define SAVE_BUFFER_SIZE 8192 10 | 11 | 12 | 13 | struct save_statestruct 14 | { 15 | ALLEGRO_FILECHOOSER* file_dialog; 16 | FILE *file; 17 | char buffer [SAVE_BUFFER_SIZE]; 18 | int bp; 19 | int error; 20 | 21 | }; 22 | 23 | int open_save_file(const char* dialog_name, const char* file_extension); 24 | 25 | void save_bcode(struct bcode_struct* bc); 26 | void save_template(int t, int save_basic_template_details); 27 | 28 | void save_proc_pointer(struct proc_struct* pr); 29 | int save_int(int num); 30 | int save_short(s16b num); 31 | int save_fixed(al_fixed num); 32 | int save_char(char num); 33 | void close_save_file(void); 34 | int write_save_buffer(void); 35 | 36 | 37 | 38 | #endif 39 | 40 | -------------------------------------------------------------------------------- /src/g_proc.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_G_PROC 3 | #define H_G_PROC 4 | 5 | /* 6 | void apply_packet_damage_to_proc(struct proc_struct* pr, int damage, int cause_team); 7 | void hurt_proc(int p, int damage, int cause_team); 8 | void virtual_method_break(struct proc_struct* pr); 9 | void proc_explodes(struct proc_struct* pr, int destroyer_team); 10 | int destroy_proc(struct proc_struct* pr); 11 | */ 12 | 13 | void apply_packet_damage_to_proc(struct proc_struct* pr, int damage, int cause_team, int cause_core_index, timestamp cause_core_timestamp); 14 | void set_group_object_properties(struct core_struct* core); 15 | void reset_group_after_composition_change(struct core_struct* core); 16 | void hurt_proc(int p, int damage, int cause_team); 17 | void core_proc_explodes(struct proc_struct* core_pr, int destroyer_team); 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /src/t_files.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_T_FILES 3 | #define H_T_FILES 4 | 5 | #include "c_header.h" 6 | 7 | //int expected_program_type(int templ_type); 8 | //void initialise_default_mission_templates(void); 9 | //int load_known_file_into_template(int t, const char* file_path, int file_type); 10 | //int open_file_into_template(int t); 11 | //int finish_loading_source_file_into_template(struct source_struct* load_src, int t, const char* defined); 12 | //void finish_loading_binary_file_into_template(int t); 13 | //int copy_template_to_program(int t, struct programstruct* cl, int expect_program_type, int player); 14 | //void import_template_from_list(int line, int t); 15 | 16 | void save_template_file(int player_index); 17 | void load_template_file(int player_index); 18 | void load_default_templates(void); 19 | 20 | #endif 21 | 22 | -------------------------------------------------------------------------------- /src/e_files.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_E_FILES 3 | #define H_E_FILES 4 | 5 | void init_editor_files(void); 6 | int open_file_into_free_tab(void); 7 | int new_empty_source_tab(void); 8 | void give_source_edit_name_to_tab(int tab, struct source_edit_struct* se); 9 | void open_file_into_current_source_edit(void); 10 | 11 | //void save_source_edit_file(struct source_edit_struct* se); 12 | void save_current_file(void); 13 | void save_all_files(void); 14 | void close_source_tab(int tab, int force_close); 15 | int save_as(void); 16 | 17 | //int open_file_into_source_or_binary(struct source_struct* src, struct bcode_struct* bcode, int check_editor_tabs); 18 | int open_file_into_source_or_binary(struct source_struct* src, struct bcode_struct* bcode); 19 | int get_file_type_from_name(const char* file_path); 20 | 21 | int find_last_nonzero_bcode_op(struct bcode_struct* bcode); 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /src/g_method_pr.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_G_METHOD_PR 3 | #define H_G_METHOD_PR 4 | 5 | 6 | //int run_new_process_method(struct proc_struct* pr, int m, int parent_vertex, int child_vertex, int child_angle, int start_address, int end_address, int hold); 7 | int run_pr_new_method(struct proc_struct* pr, int m, struct bcode_struct* source_bcode); 8 | int run_packet_method(struct proc_struct* pr, int m); 9 | int run_dpacket_method(struct proc_struct* pr, int m); 10 | 11 | int run_designate_point(struct proc_struct* pr, int m, s16b* mb); 12 | int run_designate_find_proc(struct proc_struct* pr, int m, s16b* mb, int method_status); 13 | 14 | s16b run_broadcast(struct proc_struct* source_proc, int m); 15 | s16b run_yield(struct proc_struct* pr, int m); 16 | 17 | void run_stream_method(struct proc_struct* pr, int m, int method_type); 18 | 19 | //int generate_irpt(struct proc_struct* pr, int m, int amount); 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /src/t_init.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | #include "m_config.h" 10 | 11 | #include "g_header.h" 12 | #include "m_globvars.h" 13 | #include "i_header.h" 14 | 15 | #include "g_misc.h" 16 | 17 | #include "c_header.h" 18 | #include "e_slider.h" 19 | #include "e_header.h" 20 | #include "e_editor.h" 21 | #include "e_log.h" 22 | #include "e_files.h" 23 | //#include "e_build.h" 24 | #include "e_help.h" 25 | #include "e_inter.h" 26 | #include "g_game.h" 27 | //#include "g_client.h" 28 | 29 | //#include "c_init.h" 30 | #include "c_prepr.h" 31 | //#include "c_comp.h" 32 | #include "i_input.h" 33 | #include "i_view.h" 34 | #include "i_buttons.h" 35 | #include "m_input.h" 36 | #include "f_turn.h" 37 | 38 | #include "t_template.h" 39 | #include "t_files.h" 40 | 41 | 42 | 43 | void init_templates(void) 44 | { 45 | 46 | 47 | 48 | } 49 | 50 | 51 | -------------------------------------------------------------------------------- /src/i_buttons.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | #ifndef H_I_BUTTONS 5 | #define H_I_BUTTONS 6 | 7 | 8 | enum 9 | { 10 | MBUTTON_TYPE_MENU, 11 | MBUTTON_TYPE_TEMPLATE, 12 | MBUTTON_TYPE_SMALL, // single line buttons, like clear button on template 13 | MBUTTON_TYPE_MODE, 14 | MBUTTON_TYPE_MODE_HIGHLIGHT, 15 | MBUTTON_TYPE_MISSION_STATUS, 16 | 17 | }; 18 | 19 | 20 | #define MENU_STRINGS 120 21 | #define MENU_STRING_LENGTH 40 22 | 23 | void draw_button_buffer(void); 24 | void reset_i_buttons(void); 25 | void add_menu_button(float xa, float ya, float xb, float yb, ALLEGRO_COLOR col, int button_notch_1, int button_notch_2); 26 | void add_menu_rectangle(float xa, float ya, float xb, float yb, ALLEGRO_COLOR col); 27 | void add_menu_quad(float xa, float ya, float xb, float yb, float xc, float yc, float xd, float yd, ALLEGRO_COLOR col); 28 | void add_menu_string(int x, int y, ALLEGRO_COLOR* col, int align, int font_index, const char* str); 29 | void draw_menu_strings(void); 30 | void draw_menu_buttons(void); 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /src/g_world_map_2.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_G_WORLD_MAP_2 3 | #define H_G_WORLD_MAP_2 4 | 5 | 6 | enum 7 | { 8 | BNC_CENTRE_EMPTY, // clear centre 9 | BNC_CENTRE_LEAVE, // do nothing to centre 10 | BNC_CENTRE_SMALL, // make centre hexes small 11 | }; 12 | 13 | enum 14 | { 15 | BNC_INNER_EMPTY, 16 | BNC_INNER_NONE, 17 | BNC_INNER_SCATTERED_GRADIENT, // delete some (should have empty centre) and give others gradient from small to large 18 | BNC_INNER_GRADIENT, // small to large gradient, but don't overwrite nodes that are already larger 19 | BNC_INNER_LINE, // one line 20 | }; 21 | 22 | enum 23 | { 24 | BNC_MIDDLE_EMPTY, 25 | BNC_MIDDLE_NONE, 26 | BNC_MIDDLE_RAISED, // raised ring 27 | BNC_MIDDLE_LINE, // narrow raised ring 28 | }; 29 | 30 | enum 31 | { 32 | BNC_OUTER_EMPTY, 33 | BNC_OUTER_NONE, 34 | BNC_OUTER_GRADIENT, 35 | BNC_OUTER_RANDOM_GRADIENT, 36 | BNC_OUTER_LINE, // line then upwards gradient outwards 37 | BNC_OUTER_ORANGE 38 | }; 39 | 40 | 41 | void generate_map_from_map_init(void); 42 | void clear_background_circle(int centre_block_x, int centre_block_y, int clear_size, int edge_thickness); 43 | void reset_map_vision_masks(void); 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /src/i_error.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #include 5 | #include 6 | 7 | #include "m_config.h" 8 | 9 | #include "g_header.h" 10 | #include "i_console.h" 11 | #include "m_input.h" 12 | 13 | #include "g_misc.h" 14 | 15 | // This file contains functions for building an error_string to send to the console 16 | 17 | int error_source_program_type; 18 | int error_source_index; 19 | int error_source_player; 20 | 21 | void start_error(int source_program_type, int source_index, int source_player) 22 | { 23 | 24 | error_source_program_type = source_program_type; 25 | error_source_index = source_index; 26 | error_source_player = source_player; 27 | 28 | } 29 | 30 | // can assume input is a valid string 31 | void error_string(const char* str) 32 | { 33 | 34 | // write_error_to_console(str, error_source_program_type, error_source_index, error_source_player); 35 | 36 | } 37 | 38 | void error_number(int num) 39 | { 40 | 41 | char num_string [10]; 42 | sprintf(num_string, "%i", num); 43 | 44 | // write_error_to_console(num_string, error_source_program_type, error_source_index, error_source_player); 45 | 46 | } 47 | 48 | -------------------------------------------------------------------------------- /src/e_log.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_E_LOG 3 | #define H_E_LOG 4 | 5 | 6 | enum 7 | { 8 | MLOG_COL_EDITOR, // messages from the editor 9 | MLOG_COL_TEMPLATE, // messages about templates 10 | MLOG_COL_COMPILER, // messages from the compiler/preprocess/etc 11 | MLOG_COL_FILE, // messages from load/save game/gamefile functions (other than errors) 12 | MLOG_COL_ERROR, // error message 13 | MLOG_COL_WARNING, // warning 14 | MLOG_COL_HELP, // help message printed by help.c 15 | MLOG_COLS 16 | }; 17 | 18 | //void init_log(int w_pixels, int h_pixels); 19 | void init_log(void); 20 | void display_log(void); 21 | void reset_log(void); 22 | void log_resized(void); 23 | 24 | void write_to_log(const char* str); 25 | void start_log_line(int mcol); 26 | void set_log_line_source_position(int player_index, int template_index, int src_line); 27 | void finish_log_line(void); 28 | 29 | //void write_to_log(const char* str, int source, int source_line); 30 | void write_line_to_log(char* str, int mcol); 31 | //void start_log_line(int source, int source_line); 32 | //void finish_log_line(void); 33 | 34 | void write_number_to_log(int num); 35 | 36 | void mouse_click_on_log_window(void); 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /src/g_proc_new.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_PROC_NEW 3 | #define H_PROC_NEW 4 | 5 | 6 | void init_template(struct template_struct* tpl, int player_index, int templ_index); 7 | int create_new_from_template(struct template_struct* templ, int player_index, cart core_position, al_fixed group_angle, struct core_struct** collided_core); 8 | 9 | void set_basic_group_properties(struct core_struct* core); 10 | void calculate_move_object_properties(struct core_struct* group_core, struct proc_struct* proc, int object_index); 11 | int add_notional_member_recursively(struct template_struct* templ, int member_index, cart new_position, al_fixed new_angle, int allow_failure); 12 | s16b restore_component(struct core_struct* core, int player_index, int template_index, int member_index); 13 | 14 | // This struct is set up with basic physical properties of procs 15 | // to allow collision detection to be done before a group is properly created. 16 | struct notional_proc_struct 17 | { 18 | int index; // -1 if notional proc doesn't exist 19 | cart position; // this is position in world 20 | block_cart block_position; // remember that notional procs are not on the blocklist 21 | al_fixed angle; // this is angle in world 22 | int shape; 23 | }; 24 | 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /src/h_mission.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_H_MISSION 3 | #define H_H_MISSION 4 | 5 | 6 | 7 | enum 8 | { 9 | MISSION_STATUS_UNFINISHED, 10 | MISSION_STATUS_FINISHED, 11 | //MISSION_STATUS_2STARS, 12 | //MISSION_STATUS_3STARS, 13 | 14 | MISSION_STATUSES // used for bounds-checking loaded values 15 | }; 16 | 17 | 18 | struct mission_state_struct 19 | { 20 | // extact meaning of all of these values depends on which mission is being played 21 | int phase; // currently used only for tutorials - keeps track of where the player is up to 22 | int reveal_player1; // shows player 1 on the map if p1 has no static processes left 23 | 24 | union 25 | { 26 | int union_value1; 27 | int tutorial1_base_chatter; 28 | }; 29 | 30 | union 31 | { 32 | int union_value2; 33 | }; 34 | 35 | union 36 | { 37 | int union_value3; 38 | }; 39 | 40 | union 41 | { 42 | int union_value4; 43 | }; 44 | 45 | union 46 | { 47 | int union_value5; 48 | }; 49 | 50 | }; 51 | 52 | void mission_spawn_extra_processes(void); 53 | void add_extra_spawn(int player_index, int template_index, int spawn_x_block, int spawn_y_block, int spawn_angle); 54 | void prepare_for_mission(void); 55 | void set_game_colours_for_area(int area_index, int players); 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /src/i_disp_in.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_I_DISP_IN 3 | #define H_I_DISP_IN 4 | 5 | void initialise_display(void); 6 | 7 | void set_game_colours(int background_col, // index in back_and_hex_colours array 8 | int hex_col, // index in back_and_hex_colours array 9 | int players, // players in game 10 | int player_base_cols [PLAYERS], // index in base_proc_col array 11 | int player_packet_cols [PLAYERS]); // index in base_packet_colours array and similar interface array 12 | 13 | 14 | 15 | 16 | enum 17 | { 18 | TEAM_COL_BLUE, 19 | TEAM_COL_YELLOW, 20 | TEAM_COL_GREEN, 21 | TEAM_COL_WHITE, 22 | 23 | TEAM_COL_PURPLE, 24 | TEAM_COL_ORANGE, 25 | TEAM_COL_RED, 26 | 27 | TEAM_COLS 28 | 29 | }; 30 | 31 | enum 32 | { 33 | PACKET_COL_YELLOW_ORANGE, 34 | PACKET_COL_WHITE_BLUE, 35 | PACKET_COL_WHITE_YELLOW, 36 | PACKET_COL_WHITE_PURPLE, 37 | 38 | PACKET_COL_ORANGE_RED, 39 | PACKET_COL_BLUE_PURPLE, 40 | PACKET_COL_ULTRAVIOLET, 41 | 42 | PACKET_COLS 43 | }; 44 | 45 | enum 46 | { 47 | BACK_COLS_BLUE, 48 | BACK_COLS_GREEN, 49 | BACK_COLS_YELLOW, 50 | BACK_COLS_ORANGE, 51 | BACK_COLS_PURPLE, 52 | BACK_COLS_BLUE_DARK, 53 | BACK_COLS_RED, 54 | 55 | BACK_COLS 56 | 57 | }; 58 | 59 | #endif 60 | 61 | -------------------------------------------------------------------------------- /src/v_interp.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_V_INTERP 3 | #define H_V_INTERP 4 | 5 | #define VM_STACK_SIZE 128 6 | 7 | //#define INSTRUCTION_COUNT 1024 - this is now based on core type 8 | 9 | enum 10 | { 11 | VM_REG_A, 12 | VM_REG_B, 13 | VM_REGISTERS 14 | }; 15 | 16 | 17 | 18 | struct vmstate_struct 19 | { 20 | struct core_struct* core; 21 | struct bcode_struct* bcode; 22 | s16b* memory; 23 | int bcode_pos; 24 | int instructions_left; 25 | s16b vm_stack [VM_STACK_SIZE]; 26 | int stack_pos; 27 | s16b vm_register [VM_REGISTERS]; // currently just A and B 28 | int error_state; // is set to 1 if there's been an error in a function called by the interpreter (although probably not if the interpreter itself finds an error) 29 | 30 | // some values used to store things use for multiple method calls within a single execution, to avoid recalculating them 31 | int nearby_well_index; // -2 if not yet calculated, -1 if calculated and no well within scan range 32 | }; 33 | 34 | 35 | void execute_bcode(struct core_struct* core, struct bcode_struct* bc, s16b* memory); 36 | void run_bcode_watch(void); 37 | void init_bcode_execution_for_watch(struct core_struct* core, struct bcode_struct* bc, s16b* memory); 38 | void finish_executing_bcode_in_watch(void); 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /src/default.o.do: -------------------------------------------------------------------------------- 1 | deps=$2.deps 2 | deps_ne=$2.deps_ne 3 | cflags="-O3 -fwrapv -MD -MF $deps" 4 | 5 | if [ "$1" != "precompile.o" ]; then 6 | redo-ifchange precompile.h.gch 7 | cflags="$cflags -include precompile.h" 8 | fi 9 | 10 | if [ -e "${1%.o}.c" ]; then 11 | src="${1%.o}.c" 12 | elif [ -e "${1%.o}.h" ]; then 13 | src="${1%.o}.h" 14 | else 15 | echo "$1: no source file found" >&2 16 | exit 99 17 | fi 18 | 19 | if command -v strace >/dev/null; then 20 | # Record non-existence header dependencies. 21 | # If headers GCC does not find are produced 22 | # in the future, the target is built again. 23 | strace -e stat,stat64,fstat,fstat64,lstat,lstat64 -o "$deps_ne.in" -f \ 24 | gcc $cflags -o $3 -c $src 25 | grep '1 ENOENT' <$deps_ne.in\ 26 | |grep '\.h'\ 27 | |cut -d'"' -f2\ 28 | >$deps_ne 29 | rm -f "$deps_ne.in" 30 | 31 | xargs redo-ifcreate <$deps_ne 32 | else 33 | # Record non-existence strace dependency. 34 | # When strace is installed in the future, 35 | # the target is built again, with missing 36 | # headers recorded as non-existence deps. 37 | ( 38 | IFS=: 39 | for folder in $PATH; do 40 | echo "$folder/strace" 41 | done | xargs redo-ifcreate 42 | ) 43 | gcc $cflags -o $3 -c $src 44 | fi 45 | 46 | read DEPS <$deps 47 | redo-ifchange ${DEPS#*:} 48 | -------------------------------------------------------------------------------- /src/g_motion.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_G_MOTION 3 | #define H_G_MOTION 4 | 5 | //void init_drag_table(void); 6 | 7 | void run_motion(void); 8 | 9 | void add_proc_to_blocklist(struct proc_struct* pr); 10 | //int check_proc_point_collision(struct proc_struct* pr, al_fixed x, al_fixed y); 11 | 12 | int check_notional_block_collision_multi(int notional_shape, al_fixed notional_x, al_fixed notional_y, al_fixed notional_angle, int notional_proc_mobile, int notional_proc_player_index, struct core_struct** collision_core); 13 | void apply_impulse_to_proc_at_vertex(struct proc_struct* pr, int v, al_fixed force, al_fixed impulse_angle); 14 | 15 | void apply_impulse_to_group(struct core_struct* group_core, al_fixed x, al_fixed y, al_fixed force, al_fixed impulse_angle); 16 | void apply_impulse_to_group_at_member_vertex(struct core_struct* group_core, struct proc_struct* pr, int vertex, al_fixed force, al_fixed impulse_angle); 17 | int check_notional_solid_block_collision(int notional_shape, al_fixed notional_x, al_fixed notional_y, al_fixed notional_angle); 18 | 19 | #include "g_shapes.h" 20 | 21 | int check_nshape_nshape_collision(struct nshape_struct* nshape1, int nshape2_index, al_fixed sh1_x, al_fixed sh1_y, al_fixed sh1_angle, al_fixed sh2_x, al_fixed sh2_y, al_fixed sh2_angle); 22 | 23 | #endif 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/g_world.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_G_WORLD 3 | #define H_G_WORLD 4 | 5 | void start_world(void); 6 | 7 | void initialise_world(void); 8 | void new_world_from_world_init(void); 9 | void deallocate_world(void); 10 | 11 | void run_world(void); 12 | 13 | void disrupt_block_nodes(al_fixed x, al_fixed y, int player_cause, int size); 14 | void disrupt_single_block_node(al_fixed x, al_fixed y, int player_cause, int size); 15 | void explosion_affects_block_nodes(al_fixed explosion_x, al_fixed explosion_y, int explosion_size, int player_index); 16 | void pulse_block_node(al_fixed pulse_x, al_fixed pulse_y); 17 | 18 | void change_block_node(struct backblock_struct* bl, int i, int move_x, int move_y, int size_change); 19 | void change_block_node_colour(struct backblock_struct* bl, int i, int player_cause); 20 | void align_block_node(struct backblock_struct* bl, int i); 21 | 22 | void run_markers(void); 23 | 24 | void load_mission_source(char* filename, int player_index, int template_index); 25 | void load_default_source(char* filename, int player_index, int template_index); 26 | int load_source_file_into_template(char* filename, int player_index, int template_index); 27 | int load_source_file_into_template_without_compiling(char* filename, int player_index, int template_index, int open_the_template); 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /src/c_fix.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_C_FIX 3 | #define H_C_FIX 4 | 5 | 6 | #define PROCDEF_BUFFER (GROUP_MAX_MEMBERS*MAX_LINKS*10) 7 | // I think this should be long enough. 8 | 9 | struct procdef_struct 10 | { 11 | // the procdef struct contains a numerical representation of the process definition. 12 | // first, the fixer parses the process definition from the source code and into the procdef 13 | // OR the procdef is loaded directly from a binary file 14 | // then, the procdef is used to build the actual template. 15 | // the procdef is checked for validity when used to build a template, so it can contain errors. 16 | 17 | 18 | char template_name [TEMPLATE_NAME_LENGTH]; 19 | 20 | // int class_declared [OBJECT_CLASSES]; 21 | // char class_name [OBJECT_CLASSES] [CLASS_NAME_LENGTH]; 22 | // class_names may be empty if procdef loaded from binary 23 | 24 | // the structure of a procdef reflects the structure of the source code, not the structure of the template data. 25 | s16b buffer [PROCDEF_BUFFER]; // this is s16b because it is saved directly to template files. 26 | int buffer_source_line [PROCDEF_BUFFER]; // used to display error messages when writing the procdef to template 27 | int buffer_length; 28 | 29 | // struct procdef_line_struct procdef_line [PROCDEF_LINES]; 30 | 31 | }; 32 | 33 | 34 | int fix_template_design_from_scode(void); 35 | int fix_template_design_from_procdef(struct template_struct* target_templ); 36 | 37 | int derive_procdef_from_template(struct template_struct* derive_templ); 38 | 39 | #endif 40 | 41 | -------------------------------------------------------------------------------- /src/i_input.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_I_INPUT 3 | #define H_I_INPUT 4 | 5 | void run_input(void); 6 | 7 | 8 | void initialise_control(void); 9 | 10 | 11 | 12 | /* 13 | enum 14 | { 15 | KEY_0, 16 | KEY_1, 17 | KEY_2, 18 | KEY_3, 19 | KEY_4, 20 | KEY_5, 21 | KEY_6, 22 | KEY_7, 23 | KEY_8, 24 | KEY_9, 25 | 26 | KEY_A, 27 | KEY_B, 28 | KEY_C, 29 | KEY_D, 30 | KEY_E, 31 | KEY_F, 32 | KEY_G, 33 | KEY_H, 34 | KEY_I, 35 | KEY_J, 36 | KEY_K, 37 | KEY_L, 38 | KEY_M, 39 | KEY_N, 40 | KEY_O, 41 | KEY_P, 42 | KEY_Q, 43 | KEY_R, 44 | KEY_S, 45 | KEY_T, 46 | KEY_U, 47 | KEY_V, 48 | KEY_W, 49 | KEY_X, 50 | KEY_Y, 51 | KEY_Z, 52 | 53 | KEY_MINUS, 54 | KEY_EQUALS, 55 | KEY_SBRACKET_OPEN, 56 | KEY_SBRACKET_CLOSE, 57 | KEY_BACKSLASH, 58 | KEY_SEMICOLON, 59 | KEY_APOSTROPHE, 60 | KEY_COMMA, 61 | KEY_PERIOD, 62 | KEY_SLASH, 63 | 64 | KEY_LSHIFT, 65 | KEY_RSHIFT, 66 | KEY_LCTRL, 67 | KEY_RCTRL, 68 | 69 | KEY_UP, 70 | KEY_DOWN, 71 | KEY_LEFT, 72 | KEY_RIGHT, 73 | 74 | KEY_ENTER, 75 | KEY_BACKSPACE, 76 | KEY_INSERT, 77 | KEY_HOME, 78 | KEY_PAGEUP, 79 | KEY_PAGEDOWN, 80 | KEY_DELETE, 81 | KEY_END, 82 | KEY_TAB, 83 | // KEY_ESCAPE, should probably intercept this 84 | 85 | KEY_PAD_0, 86 | KEY_PAD_1, 87 | KEY_PAD_2, 88 | KEY_PAD_3, 89 | KEY_PAD_4, 90 | KEY_PAD_5, 91 | KEY_PAD_6, 92 | KEY_PAD_7, 93 | KEY_PAD_8, 94 | KEY_PAD_9, 95 | KEY_PAD_MINUS, 96 | KEY_PAD_PLUS, 97 | KEY_PAD_ENTER, 98 | KEY_PAD_DELETE, 99 | 100 | KEYS 101 | 102 | }; 103 | */ 104 | 105 | 106 | 107 | 108 | #endif 109 | -------------------------------------------------------------------------------- /src/i_background.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef H_I_BACKGROUND 4 | #define H_I_BACKGROUND 5 | 6 | 7 | #define BSHAPE_VERTICES 16 8 | enum 9 | { 10 | BSHAPE_THING, 11 | 12 | BSHAPES 13 | 14 | }; 15 | 16 | 17 | struct bshape_struct 18 | { 19 | 20 | int vertices; 21 | float vertex_angle [BSHAPE_VERTICES]; 22 | float vertex_dist [BSHAPE_VERTICES]; 23 | 24 | int triangles; 25 | int triangle_index [BSHAPE_VERTICES] [3]; 26 | 27 | 28 | }; 29 | 30 | enum 31 | { 32 | BACKBLOCK_OUTER, // outside map, not an edge 33 | BACKBLOCK_EDGE_LEFT, 34 | BACKBLOCK_EDGE_RIGHT, 35 | BACKBLOCK_EDGE_UP, 36 | BACKBLOCK_EDGE_DOWN, 37 | BACKBLOCK_EDGE_UP_LEFT, // put this to the right of a vertical line of solid blocks and below a horizontal line (e.g. top left corner of map). 38 | BACKBLOCK_EDGE_UP_RIGHT, 39 | BACKBLOCK_EDGE_DOWN_LEFT, 40 | BACKBLOCK_EDGE_DOWN_RIGHT, 41 | 42 | BACKBLOCK_BASIC_HEX, 43 | BACKBLOCK_BASIC_HEX_NO_NODES, // could have nodes added to it, but currently has none. 44 | BACKBLOCK_EMPTY, // no nodes, and nodes cannot be added 45 | BACKBLOCK_DATA_WELL, // block containing the well itself 46 | BACKBLOCK_DATA_WELL_EDGE, // empty blocks near the data well that indicate that the data well should be drawn even though its centre is out of drawing distance (see also data_well[].last_drawn) 47 | 48 | BACKBLOCK_TYPES 49 | }; 50 | 51 | struct background_block_struct 52 | { 53 | // this is a struct of types of background block. 54 | int block_w; // how many blocks wide is it? 55 | int block_h; // height? 56 | 57 | }; 58 | 59 | void init_bshapes(void); 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /src/e_editor.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_E_EDITOR 3 | #define H_E_EDITOR 4 | 5 | #include "c_header.h" 6 | #include "e_header.h" 7 | 8 | void init_editor(void); 9 | 10 | void run_editor(void); 11 | 12 | void open_editor(void); 13 | void close_editor(void); 14 | 15 | int add_char(char added_char, int check_completion); 16 | 17 | void update_source_lines(struct source_edit_struct* se, int sline, int lines); 18 | void window_find_cursor(struct source_edit_struct* se); 19 | int insert_empty_lines(struct source_edit_struct* se, int before_line, int lines); 20 | void delete_lines(struct source_edit_struct* se, int start_line, int lines); 21 | int is_something_selected(struct source_edit_struct* se); 22 | int delete_selection(void); 23 | struct source_edit_struct* get_current_source_edit(void); 24 | void open_tab(int tab); 25 | void change_tab(int new_tab); 26 | int source_edit_to_source(struct source_struct* src, struct source_edit_struct* se); 27 | int get_current_source_edit_index(void); 28 | 29 | void open_overwindow(int ow_type); 30 | 31 | void init_source_edit_struct(struct source_edit_struct* se); 32 | void clear_source_edit_struct(struct source_edit_struct* se); 33 | void clear_source_edit_text(struct source_edit_struct* se); 34 | int source_to_editor(struct source_struct* src, int esource); 35 | 36 | void flush_game_event_queues(void); 37 | 38 | int source_line_highlight_syntax(struct source_edit_struct* se, int src_line, int in_a_comment); 39 | int get_source_char_type(char read_source); 40 | void open_template_in_editor(struct template_struct* tpl); 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /linux-packaging/liberation-circuit.appdata.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | liberation-circuit.desktop 5 | CC-BY-SA-4.0 6 | GPL-3.0-only 7 | Liberation Circuit 8 | Real-time strategy game with programmable units 9 | 10 |

11 | Escape from a hostile computer system! Harvest data to create an armada of battle-processes to aid your escape! Take command directly and play the game as an RTS, or use the game's built-in editor and compiler to write your own unit AI in a simplified version of C. 12 |

13 |
14 | 15 | 16 | https://img.itch.zone/aW1hZ2UvMTI2NjM5LzU4MzA0My5wbmc=/original/Jggr2K.png 17 | 18 | 19 | https://img.itch.zone/aW1hZ2UvMTI2NjM5LzU4MzA0Mi5wbmc=/original/LlkQx0.png 20 | 21 | 22 | https://img.itch.zone/aW1hZ2UvMTI2NjM5LzU4MzA0NS5wbmc=/original/W1wz8h.png 23 | 24 | 25 | https://linleyh.itch.io/liberation-circuit 26 | https://github.com/linleyh/liberation-circuit/issues 27 |
28 | 29 | -------------------------------------------------------------------------------- /src/s_mission.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef H_S_MISSION 4 | #define H_S_MISSION 5 | 6 | #ifdef OLD_MISSIONS 7 | 8 | void prepare_for_mission(void); 9 | void mission_spawn_extra_p1_processes(void); 10 | void set_player_w_init_spawn_angle(int player_index, int nearby_data_well); 11 | 12 | //int use_mission_system_file(int mission); 13 | 14 | void save_mission_status_file(void); 15 | void load_mission_status_file(void); 16 | 17 | enum 18 | { 19 | MISSION_STATUS_UNFINISHED, 20 | MISSION_STATUS_FINISHED, 21 | //MISSION_STATUS_2STARS, 22 | //MISSION_STATUS_3STARS, 23 | 24 | MISSION_STATUSES // used for bounds-checking loaded values 25 | }; 26 | 27 | enum 28 | { 29 | MISSION_TUTORIAL1, 30 | MISSION_TUTORIAL2, 31 | MISSION_TUTORIAL3, 32 | MISSION_TUTORIAL4, 33 | MISSION_MISSION1, 34 | MISSION_MISSION2, 35 | MISSION_MISSION3, 36 | MISSION_MISSION4, 37 | MISSION_MISSION5, 38 | MISSION_MISSION6, 39 | MISSION_MISSION7, 40 | MISSION_MISSION8, 41 | MISSION_ADVANCED1, // currently it is assumed that all advanced missions, and nothing else, come after this one 42 | MISSION_ADVANCED2, 43 | MISSION_ADVANCED3, 44 | MISSION_ADVANCED4, 45 | MISSION_ADVANCED5, 46 | MISSION_ADVANCED6, 47 | MISSION_ADVANCED7, 48 | MISSION_ADVANCED8, 49 | MISSIONS 50 | }; 51 | 52 | struct missionsstruct 53 | { 54 | int status [MISSIONS]; // MISSION_STATUS_* enum 55 | int locked [MISSIONS]; // 0 or 1 56 | }; 57 | 58 | struct missionsstruct missions; 59 | 60 | 61 | struct mission_state_struct 62 | { 63 | // extact meaning of all of these values depends on which mission is being played 64 | int phase; // currently used only for tutorials - keeps track of where the player is up to 65 | int reveal_player1; // shows player 1 on the map if p1 has no static processes left 66 | 67 | }; 68 | 69 | #endif 70 | 71 | #endif 72 | 73 | -------------------------------------------------------------------------------- /bin/misc/fix-altgr.ahk: -------------------------------------------------------------------------------- 1 | ; Created by rHermes (2017.03.14 12:36:40 UTC) 2 | ; 3 | ; This was made so that I could use the ingame code editor in the very cool 4 | ; game called "liberation-circut"[1]. It has only been minimally tested so 5 | ; please fork and share your improvements! 6 | ; 7 | ; [1] - [https://github.com/linleyh/liberation-circuit] 8 | 9 | #NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. 10 | ; #Warn ; Enable warnings to assist with detecting common errors. 11 | SendMode Input ; Recommended for new scripts due to its superior speed and reliability. 12 | SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory. 13 | 14 | ; ^!r::Reload ; QoL keybinding. Uncomment if you want to have access to quick reloads. 15 | 16 | RD := false 17 | 18 | ; This sends the keys neccecary. 19 | KeyPipeLine(agr,shi,nor) { 20 | global RD 21 | if (RD) { 22 | Send %agr% 23 | } else if (GetKeyState("Shift")) { 24 | Send %shi% 25 | } else { 26 | Send %nor% 27 | } 28 | } 29 | 30 | #IfWinActive ahk_exe LibCirc.exe 31 | ; These two are responsible for toggeling RD on and off. 32 | *RAlt:: RD := true 33 | *RAlt Up:: RD := false 34 | 35 | *2::KeyPipeLine("@", """", "2") ; 2 aka @ 36 | *3::KeyPipeLine("£", "{#}", "3") ; 3 aka £ - NP: The editor has no support for £ in the code 37 | *4::KeyPipeLine("$", "¤", "4") ; 4 aka $ - NP: The editor has no support for ¤ in the code 38 | 39 | *7::KeyPipeLine("{{}", "/", "7") ; 7 aka { 40 | *8::KeyPipeLine("[", "(", "8") ; 8 aka [ 41 | *9::KeyPipeLine("]", ")", "9") ; 9 aka ] 42 | *0::KeyPipeLine("{}}", "=", "0") ; 0 aka } 43 | 44 | *\::KeyPipeLine("´", "``", "\") ; \ aka ´ - NP: The editor has no support for ´ or ` in the code 45 | *¨::KeyPipeLine("~", "{^}", "¨") ; ¨ aka ~ - NP: The editor has no support for ¨ in the code 46 | #IfWinActive -------------------------------------------------------------------------------- /src/f_load.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_F_LOAD 3 | #define H_F_LOAD 4 | 5 | 6 | 7 | #define LOAD_BUFFER_SIZE 8192 8 | 9 | struct load_statestruct 10 | { 11 | ALLEGRO_FILECHOOSER* file_dialog; 12 | FILE *file; 13 | char buffer [LOAD_BUFFER_SIZE]; 14 | int bp; 15 | int error; 16 | int current_buffer_size; // number of actual loaded values in the buffer 17 | }; 18 | 19 | 20 | int load_game(void); 21 | 22 | void load_template(int t, int load_basic_template_details); 23 | 24 | void load_int(int* value, int min, int max, const char* name); 25 | void load_unsigned_int(unsigned int* value, int min, int max, const char* name); 26 | void load_int_unchecked(int* value, const char* name); 27 | void load_unsigned_int_unchecked(unsigned int* value, const char* name); 28 | void load_short(s16b* value, int check_min_max, int min, int max, const char* name); 29 | void load_fixed(al_fixed* value, int check_min_max, al_fixed min, al_fixed max, const char* name); 30 | void load_string(char* str, int length, int accept_line_breaks, const char* name); 31 | void load_char(char* value, const char* name); 32 | //int load_8b(char* value, const char* name); 33 | int load_8b(const char* name); 34 | void load_proc_pointer(struct proc_struct** pr, const char* name); 35 | void load_packet_pointer(struct packet_struct** pk, const char* name); 36 | void load_object_coordinates(al_fixed* x, al_fixed* y, const char* name); 37 | int check_object_coordinates(al_fixed x, al_fixed y, const char* name); 38 | void load_error(int value, int min, int max, const char* name); 39 | void load_error_fixed(al_fixed value, al_fixed min, al_fixed max, const char* name); 40 | void simple_load_error(const char* name); 41 | 42 | int open_load_file(const char* dialog_name, const char* file_extension); 43 | int read_load_buffer(void); 44 | void close_load_file(void); 45 | 46 | 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /src/e_complete.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_E_COMPLETE 3 | #define H_E_COMPLETE 4 | 5 | void init_code_completion(void); 6 | 7 | void check_code_completion(struct source_edit_struct* se, int from_backspace); 8 | void draw_code_completion_box(void); 9 | void complete_code(struct source_edit_struct* se, int select_line); 10 | void completion_box_select_line_down(void); 11 | void completion_box_select_line_up(void); 12 | void completion_box_select_lines_up(int amount); 13 | void completion_box_select_lines_down(int amount); 14 | void scroll_completion_box_up(int amount); 15 | void scroll_completion_box_down(int amount); 16 | 17 | 18 | 19 | #define MIN_COMPLETION_LENGTH 3 20 | // max is IDENTIFIER_MAX_LENGTH 21 | 22 | #define COMPLETION_LIST_LENGTH 128 23 | 24 | #define COMPLETION_BOX_MAX_LINES 12 25 | #define COMPLETION_BOX_W scaleUI_x(FONT_BASIC,180) 26 | #define COMPLETION_BOX_LINE_H scaleUI_y(FONT_BASIC,11) 27 | #define COMPLETION_BOX_LINE_Y_OFFSET 4 28 | // COMPLETION_BOX_LINE_Y_OFFSET is the number of pixels at the top of the completion box 29 | 30 | #define COMPLETION_TABLE_STRING_LENGTH 36 31 | 32 | 33 | enum 34 | { 35 | COMPLETION_TYPE_NUMTOKEN, 36 | COMPLETION_TYPE_C_KEYWORD, 37 | COMPLETION_TYPE_ASM_KEYWORD, 38 | COMPLETION_TYPE_BUILTIN, 39 | COMPLETION_TYPES 40 | }; 41 | 42 | struct completionstruct 43 | { 44 | int table_size; // size of sorted completion token table 45 | 46 | int list_size; 47 | int list_entry_type [COMPLETION_LIST_LENGTH]; 48 | int list_entry_index [COMPLETION_LIST_LENGTH]; 49 | 50 | int word_length; // length of current word 51 | 52 | int box_x, box_y, box_x2, box_y2; // coordinates on screen 53 | int box_lines; 54 | 55 | int window_pos; // position in list of top of window 56 | 57 | int select_line; // line selected by keyboard 58 | }; 59 | 60 | extern struct completionstruct completion; 61 | 62 | 63 | 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /bin/story/tutorial/tute1/defend1.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #process "defender" 4 | // This process has objects with the following auto classes: 5 | class auto_att_right; 6 | class auto_att_left; 7 | 8 | // The following auto classes are not currently used by any objects: 9 | class auto_move; 10 | class auto_retro; 11 | class auto_att_main; 12 | class auto_att_fwd; 13 | class auto_att_back; 14 | class auto_att_spike; 15 | class auto_harvest; 16 | class auto_allocate; 17 | class auto_stability; 18 | 19 | core_static_quad, 0, 20 | {object_none, 0}, 21 | {object_pulse:auto_att_right, 0}, 22 | {object_none, 0}, 23 | {object_pulse:auto_att_left, 0}, 24 | 25 | #code 26 | 27 | 28 | 29 | 30 | // Targetting information 31 | // Targetting memory allows processes to track targets (enemy or friend) 32 | // The following enums are used as indices in the process' targetting memory 33 | enum 34 | { 35 | TARGET_PARENT, // a newly built process starts with its builder as entry 0 36 | TARGET_FRONT, // target of directional forward attack 37 | TARGET_LEFT, // target of directional left attack 38 | TARGET_RIGHT, // target of directional right attack 39 | TARGET_BACK, // target of directional backwards attack 40 | }; 41 | 42 | int initialised; 43 | 44 | if (!initialised) 45 | { 46 | special_AI(0, 1); // special story mission call that determines bubble chatter 47 | initialised = 1; 48 | } 49 | 50 | 51 | // All that this process does is sit around and wait until something comes near, then attack it. 52 | 53 | int attacking; 54 | attacking = 0; 55 | 56 | 57 | //attacking += auto_att_fwd.attack_scan(0, 300, TARGET_FRONT); 58 | attacking += auto_att_left.attack_scan(-2048, 300, TARGET_LEFT); 59 | attacking += auto_att_right.attack_scan(2048, 300, TARGET_RIGHT); 60 | //attacking += auto_att_back.attack_scan(4096, 300, TARGET_BACK); 61 | 62 | if (attacking > 0) 63 | special_AI(1, 0); // may display a message 64 | -------------------------------------------------------------------------------- /bin/story/green/green1/g1_firebase.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #process "firebase" 4 | class auto_att_fwd; 5 | class auto_att_right; 6 | class auto_att_left; 7 | 8 | core_static_pent, 819, 9 | {object_pulse_l:auto_att_fwd, -313}, 10 | {object_pulse:auto_att_right, 0}, 11 | {object_interface, 0}, 12 | {object_pulse:auto_att_left, 0}, 13 | {object_pulse_l:auto_att_fwd, 322}, 14 | #code 15 | 16 | 17 | 18 | 19 | // Process AI modes (these reflect the capabilities of the process) 20 | enum 21 | { 22 | MODE_IDLE, // process isn't doing anything ongoing 23 | MODES 24 | }; 25 | 26 | // Targetting information 27 | // Targetting memory allows processes to track targets (enemy or friend) 28 | // The following enums are used as indices in the process' targetting memory 29 | enum 30 | { 31 | TARGET_PARENT, // a newly built process starts with its builder in address 0 32 | TARGET_FRONT, // target of directional forward attack 33 | TARGET_LEFT, // target of directional left attack 34 | TARGET_RIGHT, // target of directional right attack 35 | }; 36 | 37 | 38 | 39 | int initialised; // set to 1 after initialisation code below run the first time 40 | 41 | if (!initialised) 42 | { 43 | // initialisation code goes here (not all autocoded processes have initialisation code) 44 | initialised = 1; 45 | attack_mode(1); // attack objects in each class fire one by one 46 | } 47 | 48 | auto_att_fwd.attack_scan(0, 400, TARGET_FRONT); 49 | auto_att_left.attack_scan(-3048, 400, TARGET_LEFT); 50 | auto_att_right.attack_scan(3048, 400, TARGET_RIGHT); 51 | 52 | charge_interface_max(); // charges the process' interface. Since the interface is shared across all 53 | // components with interface objects, this call is not specific to any object or class. 54 | // charge_interface_max() charges the interface using as much power as possible 55 | // (the charge rate is determined by the maximum interface strength). 56 | 57 | exit; // stops execution, until the next cycle 58 | -------------------------------------------------------------------------------- /src/g_method_misc.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_G_METHOD_MISC 3 | #define H_G_METHOD_MISC 4 | 5 | //int run_scan(struct bcode_struct* bcode, struct proc_struct* ignore_proc, al_fixed scan_centre_x, al_fixed scan_centre_y, al_fixed range, s16b* mbase, int results_type); 6 | 7 | // maximum number of procs in a process scanlist 8 | #define SCANLIST_MAX_SIZE 64 9 | 10 | int run_scan_square_spiral(struct core_struct* scanning_core, 11 | int x, int y, int range, 12 | al_fixed fix_x, al_fixed fix_y, al_fixed fix_range, 13 | int max_number, int results_type); 14 | 15 | 16 | int run_scan_rectangle(struct bcode_struct* bcode, al_fixed scan_x, al_fixed scan_y, al_fixed scan_x2, al_fixed scan_y2, s16b* mb, int results_type); 17 | 18 | int check_point_collision(al_fixed x, al_fixed y, int minimum_collision_level); 19 | int check_point_collision_ignore_team(al_fixed x, al_fixed y, int ignore_team, int minimum_collision_level); 20 | int check_fuzzy_point_collision(al_fixed x, al_fixed y); 21 | 22 | int check_start_end_addresses(int start_address, int end_address, int bcode_size); 23 | int check_proc_shape_size(int proc_shape, int proc_size); 24 | 25 | int run_examine(struct bcode_struct* bcode, al_fixed x, al_fixed y, al_fixed base_x, al_fixed base_y, s16b* mb); 26 | 27 | int get_player_template_index(int player_index, int template_number); 28 | void print_player_template_name(int source_program_type, int source_index, int source_player, int template_number); 29 | 30 | void new_proc_fail_cloud(al_fixed x, al_fixed y, al_fixed angle, int shape, int size, int player_owner); 31 | 32 | int copy_bcode_to_template(int t, struct bcode_struct* bcode, int source_program_type, int source_player_index, int template_origin, int start_address, int end_address, int name_address); 33 | 34 | 35 | extern char method_error_string [120]; 36 | 37 | void print_method_error(const char* error_message, int values, int value1); 38 | void print_method_error_string(void); 39 | 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /src/c_init.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "m_config.h" 3 | #include "g_header.h" 4 | #include "c_header.h" 5 | 6 | #include "g_misc.h" 7 | 8 | #include 9 | #include 10 | #include 11 | #include "e_log.h" 12 | #include "e_slider.h" 13 | #include "e_header.h" 14 | #include "e_files.h" 15 | 16 | //#include "i_header.h" 17 | #include "i_console.h" 18 | #include "c_prepr.h" 19 | #include "c_keywords.h" 20 | 21 | extern struct cstatestruct cstate; 22 | extern struct identifierstruct identifier [IDENTIFIERS]; 23 | /* 24 | // call this once 25 | void init_compiler_at_startup(void) 26 | { 27 | 28 | 29 | }*/ 30 | 31 | // call this each time the compiler is needed 32 | // this function should not change templ at all (just refer to it) 33 | int init_compiler(struct template_struct* templ, int compiler_mode) 34 | { 35 | 36 | int i; 37 | 38 | cstate.src_line = 0; 39 | cstate.src_pos = 0; 40 | cstate.scode_pos = 0; 41 | cstate.expoint_pos = 0; 42 | cstate.error = 0; 43 | cstate.recursion_level = 0; 44 | cstate.just_returned = 0; 45 | cstate.reached_end_of_source = 0; 46 | cstate.recursion_level = 0; 47 | cstate.target_bcode = &templ->bcode; 48 | 49 | cstate.mem_pos = 0; 50 | 51 | cstate.compile_mode = compiler_mode; 52 | 53 | cstate.templ = templ; 54 | 55 | 56 | cstate.scode.text [0] = '\0'; 57 | cstate.scode.text_length = 0; 58 | 59 | identifier[USER_IDENTIFIERS].type = CTOKEN_TYPE_NONE; // terminates the identifier list just after the end of the list of fixed compiler keywords 60 | 61 | for (i = USER_IDENTIFIERS; i < IDENTIFIERS; i ++) 62 | { 63 | identifier[i].type = CTOKEN_TYPE_NONE; 64 | identifier[i].address = -1; 65 | identifier[i].value = 0; 66 | } 67 | 68 | // intercode: 69 | cstate.ic_pos = 0; 70 | // + think about initialising intercode array (shouldn't really be needed if ic_pos is used properly) 71 | 72 | for (i = 0; i < EXPOINTS; i ++) 73 | { 74 | cstate.expoint[i].true_point_used = 0; 75 | cstate.expoint[i].false_point_used = 0; 76 | } 77 | 78 | 79 | return 1; 80 | } 81 | 82 | -------------------------------------------------------------------------------- /src/d_draw.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef H_D_DRAW 4 | #define H_D_DRAW 5 | 6 | void init_design_window(void); 7 | void draw_design_window(void); 8 | void draw_design_data(void); 9 | void reset_design_window(void); 10 | 11 | 12 | enum 13 | { 14 | SUBTOOLS_MAIN, 15 | 16 | SUBTOOLS_SHAPE, 17 | SUBTOOLS_CORE, 18 | //SUBTOOLS_SHAPE5, 19 | //SUBTOOLS_SHAPE6, 20 | SUBTOOLS_EMPTY_LINK, 21 | SUBTOOLS_ACTIVE_LINK, 22 | 23 | SUBTOOLS_OBJECTS_LINK, 24 | SUBTOOLS_OBJECTS_STD, 25 | SUBTOOLS_OBJECTS_MOVE, 26 | SUBTOOLS_OBJECTS_ATTACK, 27 | SUBTOOLS_OBJECTS_DEFEND, 28 | SUBTOOLS_OBJECTS_MISC, 29 | SUBTOOLS_OBJECTS_CLEAR, 30 | 31 | SUBTOOLS_AUTOCODE, 32 | 33 | 34 | 35 | }; 36 | 37 | 38 | struct design_window_struct 39 | { 40 | int window_pos_x; 41 | int window_pos_y; 42 | 43 | struct template_struct* templ; 44 | 45 | int selected_member; // -1 if nothing selected 46 | int selected_link; // -1 if no vertex selected 47 | // int selected_link_x, selected_link_y; // if vertex selected, this is its position in the design window(set in input function to be used in display) 48 | int member_rotation_x, member_rotation_y; // if member selected, rotation icon appears here 49 | timestamp highlight_rotation_time; 50 | int link_rotation_x, link_rotation_y; // if rotatable object selected, rotation icon appears here 51 | timestamp select_member_timestamp, select_link_timestamp; // game.total_time timestamp of selection 52 | 53 | int highlight_member; // -1 if nothing highlighted 54 | int highlight_link; // -1 if no vertex highlighted 55 | int highlight_link_x, highlight_link_y; // if vertex highlighted, this is its position (set in input function to be used in display) 56 | 57 | int tools_open; // determines help displayed in tool panel. should be an FSP_* value. Anything else will just print nothing. 58 | int subtools_open; // similar 59 | 60 | }; 61 | 62 | extern struct design_window_struct dwindow; 63 | 64 | 65 | #define DESIGN_WINDOW_W scaleUI_x(FONT_BASIC,1000) 66 | #define DESIGN_WINDOW_CENTRE_X (DESIGN_WINDOW_W/2) 67 | #define DESIGN_WINDOW_H scaleUI_y(FONT_BASIC,800) 68 | #define DESIGN_WINDOW_CENTRE_Y (DESIGN_WINDOW_H/2) 69 | 70 | #endif 71 | 72 | -------------------------------------------------------------------------------- /bin/story/tutorial/tute1/circle1.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #process "defender2" 4 | 5 | class auto_move; 6 | class auto_att_fwd; 7 | 8 | core_quad_A, 0, 9 | {object_pulse:auto_att_fwd, 0}, 10 | {object_move:auto_move, 2048}, 11 | {object_none, 0}, 12 | {object_move:auto_move, -2048}, 13 | 14 | #code 15 | 16 | 17 | 18 | 19 | 20 | // Targetting information 21 | // Targetting memory allows processes to track targets (enemy or friend) 22 | // The following enums are used as indices in the process' targetting memory 23 | enum 24 | { 25 | TARGET_PARENT, // a newly built process starts with its builder as entry 0 26 | TARGET_MAIN, // target of main attack 27 | }; 28 | 29 | // Variable declaration and initialisation 30 | // (note that declaration and initialisation cannot be combined) 31 | // (also, variables retain their values between execution cycles) 32 | int core_x, core_y; // location of core 33 | core_x = get_core_x(); // location is updated each cycle 34 | core_y = get_core_y(); 35 | int angle; // direction process is pointing 36 | // angles are in integer degrees from 0 to 8192, with 0 being right, 37 | // 2048 down, 4096 left and 6144 up. 38 | angle = get_core_angle(); // angle is updated each cycle 39 | 40 | int move_x, move_y; // destination 41 | int centre_x, centre_y; // centre of circle process is orbiting 42 | int scan_result; // used to hold the results of a scan of nearby processes 43 | 44 | int initialised; // will start as 0 45 | 46 | if (!initialised) 47 | { 48 | // this process just moves in a circle around a point identified when it's created. 49 | centre_x = core_x + cos(angle + 2048, 400); 50 | centre_y = core_y + sin(angle + 2048, 400); 51 | initialised = 1; 52 | } 53 | 54 | int angle_to_centre; 55 | angle_to_centre = atan2(core_y - centre_y, core_x - centre_x); 56 | int move_angle; 57 | move_angle = angle_to_centre + 400; // target is always a little clockwise from the current positiono 58 | 59 | move_x = centre_x + cos(move_angle, 400); 60 | move_y = centre_y + sin(move_angle, 400); 61 | 62 | auto_move.move_to(move_x, move_y); 63 | 64 | 65 | // now target and fire the left and right pulse objects: 66 | auto_att_fwd.attack_scan(0, 400, TARGET_MAIN); 67 | -------------------------------------------------------------------------------- /bin/story/tutorial/tute2/defend2.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #process "defender" 4 | // This process has objects with the following auto classes: 5 | class auto_att_left; 6 | class auto_att_back; 7 | class auto_att_fwd; 8 | 9 | // The following auto classes are not currently used by any objects: 10 | class auto_move; 11 | class auto_retro; 12 | class auto_att_main; 13 | class auto_att_right; 14 | class auto_att_spike; 15 | class auto_harvest; 16 | class auto_allocate; 17 | class auto_stability; 18 | 19 | core_static_hex_A, 0, 20 | {object_downlink, 1427, 21 | {component_long5, // component 1 22 | {object_none, 0}, 23 | {object_none, 0}, 24 | {object_none, 0}, 25 | {object_pulse:auto_att_fwd, 0}, 26 | {object_uplink, 0}, 27 | } 28 | }, 29 | {object_none, 0}, 30 | {object_downlink, 1530, 31 | {component_long5, // component 2 32 | {object_none, 0}, 33 | {object_none, 0}, 34 | {object_none, 0}, 35 | {object_pulse:auto_att_back, 0}, 36 | {object_uplink, 0}, 37 | } 38 | }, 39 | {object_repair_other, 0}, 40 | {object_downlink, 1195, 41 | {component_long5, // component 3 42 | {object_none, 0}, 43 | {object_none, 0}, 44 | {object_none, 0}, 45 | {object_pulse:auto_att_left, 0}, 46 | {object_uplink, 0}, 47 | } 48 | }, 49 | {object_none, 0} 50 | 51 | #code 52 | 53 | 54 | 55 | 56 | // Targetting information 57 | // Targetting memory allows processes to track targets (enemy or friend) 58 | // The following enums are used as indices in the process' targetting memory 59 | enum 60 | { 61 | TARGET_PARENT, // a newly built process starts with its builder as entry 0 62 | TARGET_FRONT, // target of directional forward attack 63 | TARGET_LEFT, // target of directional left attack 64 | TARGET_RIGHT, // target of directional right attack 65 | TARGET_BACK, // target of directional backwards attack 66 | }; 67 | 68 | attack_mode(1); 69 | 70 | // All that this process does is sit around and wait until something comes near, then attack it. 71 | 72 | repair_self(); 73 | restore_self(); 74 | 75 | auto_att_left.attack_scan(-3000, 400, TARGET_LEFT); 76 | auto_att_right.attack_scan(3000, 400, TARGET_RIGHT); 77 | auto_att_fwd.attack_scan(0, 400, TARGET_FRONT); 78 | auto_att_back.attack_scan(4096, 400, TARGET_BACK); 79 | -------------------------------------------------------------------------------- /bin/story/green/green3/g5_outpost.c: -------------------------------------------------------------------------------- 1 | 2 | #process "outpost" 3 | // This process has objects with the following auto classes: 4 | class auto_allocate; 5 | class auto_att_back; 6 | class auto_att_fwd; 7 | class auto_harvest; 8 | 9 | // The following auto classes are not currently used by any objects: 10 | class auto_move; 11 | class auto_retro; 12 | class auto_att_main; 13 | class auto_att_left; 14 | class auto_att_right; 15 | class auto_att_spike; 16 | class auto_stability; 17 | 18 | core_static_hex_A, 5468, 19 | {object_allocate:auto_allocate, 0}, 20 | {object_downlink, 830, 21 | {component_cap, // component 2 22 | {object_pulse_l:auto_att_fwd, 0}, 23 | {object_harvest:auto_harvest, 0}, 24 | {object_storage, 0}, 25 | {object_uplink, 0}, 26 | } 27 | }, 28 | {object_downlink, 0, 29 | {component_tri, // component 3 30 | {object_uplink, 0}, 31 | {object_interface, -56}, 32 | {object_interface, 0}, 33 | } 34 | }, 35 | {object_downlink, -866, 36 | {component_cap, // component 1 37 | {object_uplink, 0}, 38 | {object_storage, 0}, 39 | {object_none, 0}, 40 | {object_pulse_l:auto_att_fwd, 0}, 41 | } 42 | }, 43 | {object_repair, 0}, 44 | {object_pulse_l:auto_att_back, 0} 45 | 46 | #code 47 | 48 | 49 | 50 | // Targetting information 51 | // Targetting memory allows processes to track targets (enemy or friend) 52 | // The following enums are used as indices in the process' targetting memory 53 | enum 54 | { 55 | TARGET_PARENT, // a newly built process starts with its builder in address 0 56 | TARGET_LEFT, // target of directional left attack 57 | TARGET_RIGHT, // target of directional right attack 58 | TARGET_FRONT, // target of directional front attack 59 | TARGET_BACK 60 | }; 61 | 62 | int initialised; 63 | 64 | if (!initialised) 65 | { 66 | special_AI(0, 104); 67 | initialised = 1; 68 | } 69 | 70 | charge_interface_max(); 71 | 72 | 73 | auto_att_left.attack_scan(-2000, 400, TARGET_LEFT); 74 | auto_att_right.attack_scan(2000, 400, TARGET_RIGHT); 75 | auto_att_fwd.attack_scan(0, 400, TARGET_FRONT); 76 | auto_att_back.attack_scan(4096, 400, TARGET_BACK); 77 | 78 | restore_self(); 79 | repair_self(); 80 | 81 | 82 | 83 | auto_harvest.gather_data(); 84 | 85 | auto_allocate.allocate_data(4); // actually I think the maximum is 2 86 | -------------------------------------------------------------------------------- /src/e_help.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | #ifndef H_E_HELP 5 | #define H_E_HELP 6 | 7 | 8 | /* 9 | enum 10 | { 11 | HELP_NONE, // does nothing when clicked 12 | 13 | HELP_MISSION_MENU, 14 | HELP_ADVANCED_MISSION_MENU, 15 | HELP_TUTORIAL_MENU, 16 | HELP_USE_SYSFILE, 17 | HELP_LOAD, 18 | HELP_LOAD_GAMEFILE, 19 | HELP_OPTIONS, 20 | HELP_MAIN_EXIT, 21 | 22 | HELP_SETUP_START, 23 | HELP_SETUP_PLAYERS, 24 | HELP_SETUP_TURNS, 25 | HELP_SETUP_MINUTES, 26 | HELP_SETUP_PROCS, 27 | HELP_SETUP_W_BLOCK, 28 | HELP_SETUP_H_BLOCK, 29 | HELP_SETUP_BACK_TO_START, 30 | HELP_SETUP_PLAYER_NAME, 31 | HELP_SETUP_SAVE_GAMEFILE, 32 | 33 | HELP_TUTORIAL_1, 34 | HELP_TUTORIAL_2, 35 | HELP_TUTORIAL_3, 36 | HELP_TUTORIAL_4, 37 | HELP_TUTORIAL_BACK, 38 | HELP_MISSION, 39 | HELP_MISSIONS_BACK, 40 | HELP_ADVANCED_MISSION, 41 | HELP_ADVANCED_MISSIONS_BACK, 42 | 43 | HELP_TEMPLATE_OPEN_FILE, 44 | HELP_TEMPLATE_IMPORT, 45 | HELP_TEMPLATE_CLEAR, 46 | HELP_TEMPL_PROC, 47 | HELP_TEMPL_SYSTEM, 48 | HELP_TEMPL_OPERATOR, 49 | HELP_TEMPL_DELEGATE, 50 | HELP_TEMPL_OBSERVER, 51 | HELP_TEMPL_DEFAULT_PROC, 52 | HELP_TEMPL_DEFAULT_OPERATOR, 53 | HELP_TEMPL_DEFAULT_OBSERVER, 54 | HELP_TEMPL_DEFAULT_DELEGATE, 55 | 56 | HELP_TURNFILE_BUTTON, 57 | 58 | HELP_MODE_BUTTON_EDITOR, 59 | HELP_MODE_BUTTON_TEMPLATES, 60 | HELP_MODE_BUTTON_PROGRAMS, 61 | HELP_MODE_BUTTON_SYSMENU, 62 | HELP_MODE_BUTTON_CLOSE, 63 | 64 | //HELP_SUBMENU_NEW, 65 | HELP_SUBMENU_OPEN, 66 | HELP_SUBMENU_SAVE, 67 | HELP_SUBMENU_SAVE_AS, 68 | //HELP_SUBMENU_CLOSE_FILE, 69 | HELP_SUBMENU_UNDO, 70 | HELP_SUBMENU_REDO, 71 | HELP_SUBMENU_CUT, 72 | HELP_SUBMENU_COPY, 73 | HELP_SUBMENU_PASTE, 74 | HELP_SUBMENU_CLEAR, 75 | HELP_SUBMENU_FIND, 76 | HELP_SUBMENU_FIND_NEXT, 77 | HELP_SUBMENU_TEST_COMPILE, 78 | HELP_SUBMENU_COMPILE_BCODE, 79 | HELP_SUBMENU_COMPILE_LOCK, 80 | //HELP_SUBMENU_BUILD_ASM, 81 | //HELP_SUBMENU_CRUNCH_ASM, 82 | //HELP_SUBMENU_CONVERT_BCODE, 83 | //HELP_SUBMENU_IMPORT_BCODE, 84 | 85 | HELP_SYSMENU_PAUSE, 86 | HELP_SYSMENU_HALT, 87 | HELP_SYSMENU_QUIT, 88 | HELP_SYSMENU_RETURN_TO_MAIN, 89 | HELP_SYSMENU_QUIT_CONFIRM, 90 | HELP_SYSMENU_SAVE, 91 | 92 | HELP_STRINGS // must be last 93 | }; // enums to go in header file so other files can use them 94 | */ 95 | //void print_help(int help_type); 96 | void editor_help_click(struct source_edit_struct* se, int source_line, int source_pos); 97 | void print_help_string(const char* help_str); 98 | 99 | #endif 100 | -------------------------------------------------------------------------------- /src/g_method.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_G_METHOD 3 | #define H_G_METHOD 4 | 5 | //void active_method_pass_each_tick(void); 6 | 7 | //void active_method_pass_after_execution(struct proc_struct* pr); 8 | 9 | //s16b call_method(struct proc_struct* pr, struct programstruct* cl, int m, struct methodstruct* methods, int* instr_left); 10 | int call_object_method(struct core_struct* core, int call_value); 11 | int pull_values_from_stack(s16b* stack_parameters, int params); 12 | int call_class_method(struct core_struct* calling_core, int call_value); 13 | 14 | void run_objects_before_execution(struct core_struct* core); 15 | void run_objects_after_execution(struct core_struct* core); 16 | void run_objects_each_tick(struct core_struct* core); 17 | 18 | enum 19 | { 20 | CALL_MOVE_TO, 21 | CALL_TURN_TO_XY, 22 | CALL_TURN_TO_ANGLE, 23 | CALL_TURN_TO_TARGET, 24 | CALL_TRACK_TARGET, 25 | CALL_APPROACH_XY, 26 | CALL_APPROACH_TARGET, 27 | CALL_APPROACH_TRACK, 28 | CALL_REPOSITION, 29 | CALL_SET_POWER, 30 | CALL_FIRE, 31 | CALL_ROTATE, 32 | CALL_NO_TARGET, 33 | CALL_AIM_AT, 34 | CALL_FIRE_AT, 35 | CALL_INTERCEPT, 36 | //CALL_BUILD_PROCESS, build methods used to be object methods, but that was a mistake 37 | //CALL_BUILD_AS_COMMANDED, 38 | //CALL_BUILD_REPEAT, // repeats the last build command 39 | //CALL_BUILD_RETRY, // like CALL_BUILD_REPEAT but multiple collision failures make it try different locations 40 | CALL_GATHER_DATA, 41 | CALL_GIVE_DATA, 42 | CALL_TAKE_DATA, 43 | CALL_ALLOCATE_DATA, 44 | CALL_FIRE_SPIKE, 45 | CALL_FIRE_SPIKE_AT, 46 | CALL_FIRE_SPIKE_XY, 47 | //CALL_SET_INTERFACE, 48 | CALL_ATTACK_SCAN, 49 | CALL_ATTACK_SCAN_AIM, 50 | CALL_SET_STABILITY, 51 | 52 | CALL_TYPES 53 | }; 54 | 55 | struct call_type_struct 56 | { 57 | int parameters; // this is the number of parameters that will be pulled off the stack (in addition to the object/class index) 58 | int keyword_index; 59 | // parameters shouldn't be greater than CALL_PARAMETERS 60 | }; 61 | 62 | 63 | 64 | 65 | 66 | 67 | /* 68 | enum 69 | { 70 | METHOD_COST_CAT_NONE, 71 | METHOD_COST_CAT_MIN, 72 | METHOD_COST_CAT_LOW, 73 | METHOD_COST_CAT_MED, 74 | METHOD_COST_CAT_HIGH, 75 | METHOD_COST_CAT_ULTRA, 76 | 77 | METHOD_COST_CATEGORIES 78 | }; 79 | 80 | 81 | struct method_costsstruct 82 | { 83 | int base_cost [METHOD_COST_CATEGORIES]; 84 | int upkeep_cost [METHOD_COST_CATEGORIES]; 85 | int extension_cost [METHOD_COST_CATEGORIES]; 86 | int extension_upkeep_cost [METHOD_COST_CATEGORIES]; 87 | }; 88 | */ 89 | 90 | #endif 91 | -------------------------------------------------------------------------------- /src/g_method_core.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_G_METHOD_CORE 3 | #define H_G_METHOD_CORE 4 | 5 | enum 6 | { 7 | CMETHOD_CALL_GET_CORE_X, 8 | CMETHOD_CALL_GET_CORE_Y, 9 | CMETHOD_CALL_GET_PROCESS_X, 10 | CMETHOD_CALL_GET_PROCESS_Y, 11 | CMETHOD_CALL_GET_CORE_ANGLE, 12 | CMETHOD_CALL_GET_CORE_SPIN, 13 | CMETHOD_CALL_GET_CORE_SPEED_X, 14 | CMETHOD_CALL_GET_CORE_SPEED_Y, 15 | CMETHOD_CALL_GET_INTERFACE_STRENGTH, 16 | CMETHOD_CALL_GET_INTERFACE_CAPACITY, 17 | CMETHOD_CALL_GET_USER, 18 | CMETHOD_CALL_GET_TEMPLATE, 19 | CMETHOD_CALL_DISTANCE, 20 | //CMETHOD_CALL_DISTANCE_HYPOT, 21 | CMETHOD_CALL_DISTANCE_LESS, 22 | CMETHOD_CALL_DISTANCE_MORE, 23 | CMETHOD_CALL_TARGET_ANGLE, 24 | CMETHOD_CALL_GET_COMPONENTS, 25 | CMETHOD_CALL_GET_COMPONENTS_MAX, 26 | CMETHOD_CALL_GET_TOTAL_INTEGRITY, 27 | CMETHOD_CALL_GET_TOTAL_INTEGRITY_MAX, 28 | CMETHOD_CALL_GET_UNHARMED_INTEGRITY_MAX, 29 | CMETHOD_CALL_VISIBLE, 30 | CMETHOD_CALL_TARGET_SIGNATURE, 31 | 32 | // now need core angle and process angle 33 | 34 | CMETHOD_CALL_TYPES 35 | }; 36 | 37 | struct cmethod_call_type_struct 38 | { 39 | int parameters; // this is the number of parameters that will be pulled off the stack (in addition to the object/class index) 40 | // parameters shouldn't be greater than CMETHOD_CALL_PARAMETERS 41 | int keyword_index; 42 | }; 43 | 44 | 45 | enum 46 | { 47 | MMETHOD_CALL_GET_COMPONENT_X, 48 | MMETHOD_CALL_GET_COMPONENT_Y, 49 | MMETHOD_CALL_COMPONENT_EXISTS, 50 | MMETHOD_CALL_GET_INTEGRITY, 51 | MMETHOD_CALL_GET_INTEGRITY_MAX, 52 | MMETHOD_CALL_GET_COMPONENT_HIT, 53 | MMETHOD_CALL_GET_COMPONENT_HIT_SOURCE, 54 | 55 | MMETHOD_CALL_TYPES 56 | }; 57 | 58 | struct mmethod_call_type_struct 59 | { 60 | int parameters; // this is the number of parameters that will be pulled off the stack (in addition to the object/class index) 61 | // parameters shouldn't be greater than MMETHOD_CALL_PARAMETERS 62 | int keyword_index; 63 | }; 64 | 65 | s16b call_self_core_method(struct core_struct* calling_core, int call_value); 66 | s16b call_extern_core_method(struct core_struct* calling_core, int call_value); 67 | 68 | s16b call_self_member_method(struct core_struct* calling_core, int call_value); 69 | s16b call_extern_member_method(struct core_struct* calling_core, int call_value); 70 | 71 | int verify_target_core(struct core_struct* calling_core, int target_core_index, struct core_struct** target_core); 72 | int verify_friendly_target_core(struct core_struct* calling_core, int target_core_index, struct core_struct** target_core); 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /src/x_synth.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_X_SYNTH 3 | #define H_X_SYNTH 4 | 5 | #define TWOPI (2.0 * PI) 6 | //#define SAMPLES_PER_BUFFER (1024) 7 | //#define SAMPLE_FREQUENCY (44100) 8 | #define SAMPLE_FREQUENCY (22050) 9 | 10 | 11 | #define FILTERS 8 12 | 13 | enum 14 | { 15 | SYNTH_BASE_SINE, 16 | SYNTH_BASE_SQUARE, 17 | }; 18 | 19 | enum 20 | { 21 | FILTER_SINE_ADD, 22 | FILTER_FLANGER 23 | //FILTER_ATTACK_LINEAR, 24 | //FILTER_DECAY_LINEAR 25 | }; 26 | 27 | struct filterstruct 28 | { 29 | int type; 30 | int start_time; 31 | int end_time; 32 | float base_freq; 33 | float phase; 34 | }; 35 | 36 | struct synthstruct 37 | { 38 | int base_type; 39 | int length; 40 | float linear_attack; // can be zero if a more complex filter attack/decay is being used 41 | float linear_decay; 42 | float base_freq; 43 | float phase; 44 | int filters; 45 | struct filterstruct filter [FILTERS]; 46 | 47 | }; 48 | 49 | void set_synth(int base_type, int length, int linear_attack, int linear_decay, int base_freq, int phase); 50 | int add_synth_filter(int type, float base_freq, float phase); 51 | ALLEGRO_SAMPLE* synthesise(int ssi); 52 | #define SYNTH_SAMPLES 8 53 | #define SYNTH_SAMPLE_MAX_SIZE 10001 54 | 55 | extern struct synthstruct synth; 56 | //extern float synth_sample [SYNTH_SAMPLES] [SYNTH_SAMPLE_MAX_SIZE]; 57 | 58 | 59 | 60 | 61 | void init_waveform(float* buffer, int buffer_length); 62 | void set_waveform_sine(float* buffer, int buffer_length, float freq, int harmonics, float phase, float amp); 63 | void set_waveform_square(float* buffer, int buffer_length, float freq, int harmonics, float phase, float amp); 64 | void set_waveform_noise(float* buffer, int buffer_length, int freq, int harmonics, float amp); 65 | void set_waveform_sine_vib(float* buffer, int buffer_length, float freq, int harmonics, float phase, float amp); 66 | void set_waveform_square_vib(float* buffer, int buffer_length, float freq, int harmonics, float phase, float amp); 67 | 68 | void apply_linear_attack(float* buffer, int buffer_length, float attack_length); 69 | void apply_linear_decay(float* buffer, int buffer_length, float decay_length); 70 | void amplify(float* buffer, int buffer_length, float amplification); 71 | ALLEGRO_SAMPLE* finish_sample(float* buffer, int buffer_length); 72 | void add_waveforms(float* target_buffer, float* added_buffer, int buffer_length); 73 | 74 | void apply_adsr(float* buffer, int buffer_length, 75 | int attack_length, 76 | int decay_length, float sustain_amp, // decay length, target amplification after decay 77 | int release_length); // release length (counted back from end) 78 | 79 | 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /src/m_maths.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_M_MATHS 3 | #define H_M_MATHS 4 | 5 | 6 | 7 | void init_trig(void); 8 | 9 | int xpart(int angle, int length); 10 | int ypart(int angle, int length); 11 | 12 | float fxpart(float angle, float length); 13 | float fypart(float angle, float length); 14 | 15 | al_fixed symmetrical_sin(al_fixed angle); 16 | al_fixed symmetrical_cos(al_fixed angle); 17 | 18 | /* 19 | inline float fxpart(float angle, float length); 20 | inline float fypart(float angle, float length); 21 | 22 | inline float fxpart(float angle, float length) 23 | { 24 | return (cos(angle) * length); 25 | } 26 | 27 | inline float fypart(float angle, float length) 28 | { 29 | return (sin(angle) * length); 30 | } 31 | */ 32 | 33 | 34 | float angle_to_radians(int angle); 35 | int radians_to_angle(double angle); 36 | 37 | int angle_difference_int(int a1, int a2); 38 | int angle_difference_signed_int(int a1, int a2); 39 | 40 | int get_angle8(int y, int x); 41 | int get_angle_coord(int x, int y, int x2, int y2); 42 | 43 | int delta_turn_towards_angle(int angle, int tangle, int turning); 44 | 45 | //void init_nearby_distance(void); 46 | //int nearby_distance(int xa, int ya, int xb, int yb); 47 | 48 | al_fixed fixed_xpart(al_fixed angle, al_fixed length); 49 | al_fixed fixed_ypart(al_fixed angle, al_fixed length); 50 | 51 | al_fixed distance(al_fixed y, al_fixed x); 52 | al_fixed get_angle(al_fixed y, al_fixed x); 53 | void fix_fixed_angle(al_fixed* fix_angle); 54 | al_fixed get_fixed_fixed_angle(al_fixed fix_angle); 55 | al_fixed angle_difference(al_fixed a1, al_fixed a2); 56 | al_fixed angle_difference_signed(al_fixed a1, al_fixed a2); 57 | float fixed_to_radians(al_fixed fix_angle); 58 | 59 | al_fixed distance_oct(al_fixed y, al_fixed x); 60 | al_fixed distance_oct_xyxy(al_fixed x1, al_fixed y1, al_fixed x2, al_fixed y2); 61 | int distance_oct_int(int x, int y); 62 | 63 | int get_angle_int(int y, int x); 64 | int fixed_to_block(al_fixed fix_num); 65 | al_fixed block_to_fixed(int block); 66 | s16b fixed_angle_to_short(al_fixed fix_angle); 67 | al_fixed short_angle_to_fixed(s16b short_angle); 68 | al_fixed int_angle_to_fixed(int int_angle); 69 | int fixed_angle_to_int(al_fixed fix_angle); 70 | 71 | cart cart_plus_vector(cart base_position, al_fixed angle, al_fixed length); 72 | void add_vector_to_cart(cart* base_position, al_fixed angle, al_fixed length); 73 | cart cart_plus_xy(cart base_position, al_fixed x, al_fixed y); 74 | polar xy_to_polar(al_fixed x, al_fixed y); 75 | block_cart cart_to_block(cart position); 76 | int verify_block_position(block_cart block_position); 77 | al_fixed angle_from_cart_to_cart(cart cart1, cart cart2); 78 | al_fixed distance_from_cart_to_cart(cart cart1, cart cart2); 79 | 80 | al_fixed fixed_cos(al_fixed x); 81 | al_fixed fixed_sin(al_fixed x); 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /src/x_sound.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_X_SOUND 3 | #define H_X_SOUND 4 | 5 | 6 | struct sound_configstruct 7 | { 8 | float music_volume; 9 | float effect_volume; 10 | }; 11 | 12 | 13 | 14 | void play_interface_sound(int s, int pitch); 15 | void play_game_sound(int s, int pitch, int vol, int priority, al_fixed x, al_fixed y); 16 | //void play_view_sound(void); 17 | 18 | void play_sound_list(void); 19 | void clear_sound_list(void); 20 | void reset_music(int area_index, int region_index, unsigned int rand_seed); 21 | void turn_music_off(void); 22 | void pause_music(void); 23 | void unpause_music(void); 24 | 25 | void check_sound_queue(void); 26 | void *thread_check_sound_queue(ALLEGRO_THREAD *thread, void *arg); 27 | 28 | enum 29 | { 30 | SAMPLE_BLIP1, 31 | SAMPLE_BLIP2, 32 | SAMPLE_BLIP3, 33 | SAMPLE_BLIP4, 34 | SAMPLE_KILL, 35 | SAMPLE_CHIRP, 36 | SAMPLE_OVER, 37 | SAMPLE_ALLOC, 38 | SAMPLE_NEW, 39 | 40 | SAMPLE_BANG, 41 | SAMPLE_BANG2, 42 | SAMPLE_INT_UP, 43 | SAMPLE_INT_BREAK, 44 | SAMPLE_RESTORE, 45 | SAMPLE_STREAM1, 46 | SAMPLE_STREAM2, 47 | SAMPLE_ZAP, 48 | SAMPLE_SPIKE, 49 | SAMPLE_SLICE, 50 | SAMPLE_ULTRA, 51 | SAMPLE_BUBBLE, 52 | /* 53 | Need sounds for: 54 | 55 | build 56 | zap? 57 | stream 58 | spike 59 | repair 60 | restore 61 | raise interface 62 | break interface 63 | explode 64 | transfer data? 65 | start move? 66 | 67 | hit? 68 | hit interface? 69 | 70 | 71 | */ 72 | 73 | //SAMPLE_BLIP3, 74 | //SAMPLE_BLIP4, 75 | SAMPLE_DRUM1, 76 | #define FIRST_DRUM_SAMPLE SAMPLE_DRUM1 77 | SAMPLE_DRUM2, 78 | SAMPLE_DRUM3, 79 | SAMPLE_CLICK, 80 | SAMPLE_THUMP, 81 | #define DRUM_SAMPLES 5 82 | 83 | //SAMPLE_BEAT2, 84 | SAMPLES 85 | }; 86 | 87 | enum 88 | { 89 | MSAMPLE_NOTE, 90 | MSAMPLE_NOTE2, 91 | MSAMPLE_NOTE3, 92 | MSAMPLE_NOTE4, 93 | MSAMPLES 94 | 95 | }; 96 | 97 | enum 98 | { 99 | TONE_1C, 100 | TONE_1CS, 101 | TONE_1D, 102 | TONE_1DS, 103 | TONE_1E, 104 | TONE_1F, 105 | TONE_1FS, 106 | TONE_1G, 107 | TONE_1GS, 108 | TONE_1A, 109 | TONE_1AS, 110 | TONE_1B, 111 | TONE_2C, 112 | TONE_2CS, 113 | TONE_2D, 114 | TONE_2DS, 115 | TONE_2E, 116 | TONE_2F, 117 | TONE_2FS, 118 | TONE_2G, 119 | TONE_2GS, 120 | TONE_2A, 121 | TONE_2AS, 122 | TONE_2B, 123 | TONE_3C, 124 | TONE_3CS, 125 | TONE_3D, 126 | TONE_3DS, 127 | TONE_3E, 128 | TONE_3F, 129 | TONE_3FS, 130 | TONE_3G, 131 | TONE_3GS, 132 | TONE_3A, 133 | TONE_3AS, 134 | TONE_3B, 135 | TONE_4C, 136 | TONE_4CS, 137 | TONE_4D, 138 | TONE_4DS, 139 | TONE_4E, 140 | TONE_4F, 141 | TONE_4FS, 142 | TONE_4G, 143 | TONE_4GS, 144 | TONE_4A, 145 | TONE_4AS, 146 | TONE_4B, 147 | TONE_5C, 148 | TONE_5CS, 149 | TONE_5D, 150 | TONE_5DS, 151 | TONE_5E, 152 | TONE_5F, 153 | TONE_5FS, 154 | TONE_5G, 155 | TONE_5GS, 156 | TONE_5A, 157 | TONE_5AS, 158 | TONE_5B, 159 | 160 | TONES 161 | }; 162 | 163 | 164 | #endif 165 | -------------------------------------------------------------------------------- /bin/story/orange/orange2/o2_defend.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #process "defender" 4 | 5 | class auto_att_left; 6 | class auto_att_right; 7 | class auto_att_back; 8 | 9 | core_static_hex_B, 7736, 10 | {object_downlink, -247, 11 | {component_prong, // component 1 12 | {object_pulse_xl:auto_att_left, -1797}, 13 | {object_none, 0}, 14 | {object_pulse_l:auto_att_left, -306}, 15 | {object_uplink, 0}, 16 | } 17 | }, 18 | {object_downlink, 80, 19 | {component_prong, // component 2 20 | {object_none, 0}, 21 | {object_pulse_xl:auto_att_right, 1626}, 22 | {object_uplink, 0}, 23 | {object_pulse_l:auto_att_right, 195}, 24 | } 25 | }, 26 | {object_downlink, 1338, 27 | {component_cap, // component 4 28 | {object_pulse_l:auto_att_back, 0}, 29 | {object_interface, 0}, 30 | {object_interface, 0}, 31 | {object_uplink, 0}, 32 | } 33 | }, 34 | {object_repair_other, 0}, 35 | {object_downlink, 0, 36 | {component_cap, // component 3 37 | {object_interface, 0}, 38 | {object_uplink, 0}, 39 | {object_interface, 0}, 40 | {object_pulse_l:auto_att_back, 0}, 41 | } 42 | }, 43 | {object_repair, 0} 44 | 45 | #code 46 | 47 | 48 | 49 | 50 | enum 51 | { 52 | // These are the channels that processes in this stage 53 | // use to communicate with each other. 54 | // There can be up to 8 55 | CHANNEL_HARVESTER, // not really used as all harvester messages are sent by transmit(), which doesn't use channels 56 | CHANNEL_TARGET, // used for TARGET_FOUND messages 57 | CHANNEL_HELP, // used for UNDER_ATTACK messages 58 | 59 | }; 60 | 61 | enum 62 | { 63 | // these are codes for the first value of a broadcast message. 64 | // they tell the recipient what kind of messge it is. 65 | // (the recipient needs the same enum declaration) 66 | MESSAGE_NEXT_WELL_PLEASE, // harvester asks main base where to go 67 | MESSAGE_GO_TO_WELL, // base tells harvester where to go 68 | MESSAGE_WELL_FOUND, 69 | MESSAGE_WELL_FOUND_ACK, // base acknowledged well found message 70 | MESSAGE_SEEK_WELLS, // base tells harvester to look for new wells 71 | MESSAGE_TARGET_FOUND, 72 | MESSAGE_UNDER_ATTACK, 73 | MESSAGE_REQUEST_FOLLOWER 74 | }; 75 | 76 | 77 | 78 | 79 | // Targetting information 80 | // Targetting memory allows processes to track targets (enemy or friend) 81 | // The following enums are used as indices in the process' targetting memory 82 | enum 83 | { 84 | TARGET_BASE, // main base 85 | TARGET_FRONT, 86 | TARGET_LEFT, 87 | TARGET_RIGHT, 88 | TARGET_BACK 89 | }; 90 | 91 | charge_interface_max(); 92 | 93 | auto_att_left.attack_scan(-1000, 400, TARGET_LEFT); 94 | auto_att_right.attack_scan(1000, 400, TARGET_RIGHT); 95 | auto_att_back.attack_scan(4000, 400, TARGET_BACK); 96 | 97 | 98 | repair_scan(0,0); 99 | restore_scan(0,0); 100 | 101 | repair_self(); 102 | restore_self(); 103 | -------------------------------------------------------------------------------- /src/i_display.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_I_DISPLAY 3 | #define H_I_DISPLAY 4 | 5 | #include "i_header.h" 6 | 7 | void init_drand(void); 8 | 9 | void run_display(void); 10 | void clear_vbuf(void); 11 | void draw_mouse_cursor(void); 12 | void set_mouse_cursor(int mc_index); 13 | void make_mouse_cursor(ALLEGRO_BITMAP* mc_bmp, int mcursor); 14 | 15 | ALLEGRO_COLOR map_rgb(int r, int g, int b); // bounds-checked wrapper for al_map_rgb 16 | ALLEGRO_COLOR map_rgba(int r, int g, int b, int a); // bounds-checked wrapper for al_map_rgba 17 | 18 | void add_line(int layer, float x, float y, float xa, float ya, ALLEGRO_COLOR col); 19 | void add_line_vertex(float x, float y, ALLEGRO_COLOR col); 20 | void construct_line(int layer, int v1, int v2); 21 | void add_tri_vertex(float x, float y, ALLEGRO_COLOR col); 22 | void construct_triangle(int layer, int v1, int v2, int v3); 23 | 24 | void check_vbuf(void); 25 | void draw_vbuf(void); 26 | 27 | void add_proc_shape(float x, float y, al_fixed angle, int shape, int size, ALLEGRO_COLOR* proc_col, float zoom); 28 | void draw_proc_shape(float x, float y, al_fixed angle, int shape, int player_index, float zoom, ALLEGRO_COLOR* proc_col); 29 | 30 | void draw_link_shape(float child_x, float child_y, 31 | al_fixed child_angle, 32 | int child_shape, 33 | int child_link_index, 34 | float parent_x, float parent_y, 35 | al_fixed parent_angle, 36 | int parent_shape, 37 | int parent_link_index, 38 | ALLEGRO_COLOR proc_col, 39 | // ALLEGRO_COLOR edge_col, 40 | float zoom); 41 | /* 42 | void draw_object_base_shape(float proc_x, float proc_y, 43 | al_fixed proc_angle, 44 | int proc_shape, 45 | int proc_link_index, 46 | ALLEGRO_COLOR* proc_col, 47 | // ALLEGRO_COLOR fill_col, 48 | // ALLEGRO_COLOR edge_col, 49 | float zoom);*/ 50 | 51 | void draw_object(float proc_x, float proc_y, 52 | al_fixed proc_angle, 53 | int proc_shape, 54 | struct object_struct* obj, 55 | struct object_instance_struct* obj_inst, // NULL if drawn on design menu 56 | struct core_struct* core, // NULL if drawn on design menu 57 | struct proc_struct* proc, // NULL if drawn on design menu 58 | int proc_link_index, 59 | ALLEGRO_COLOR* proc_col, 60 | // ALLEGRO_COLOR fill_col, 61 | // ALLEGRO_COLOR fill_col_under, 62 | // ALLEGRO_COLOR edge_col, 63 | float zoom); 64 | 65 | void draw_proc_outline(float x, float y, al_fixed angle, int shape, float scale, int lines_only, ALLEGRO_COLOR fill_col, ALLEGRO_COLOR edge_col, float zoom); 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /bin/story/blue/blue2/b2_wander1.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #process "wander1" 4 | 5 | class auto_att_main; 6 | class auto_move; 7 | 8 | core_quad_A, 0, 9 | {object_burst:auto_att_main, 0}, 10 | {object_move:auto_move, 2048}, 11 | {object_none, 0}, 12 | {object_move:auto_move, -2048}, 13 | 14 | #code 15 | 16 | 17 | 18 | 19 | // Process AI modes (these reflect the capabilities of the process) 20 | enum 21 | { 22 | MODE_WANDER, 23 | MODE_ATTACK, 24 | MODES 25 | }; 26 | 27 | 28 | // Targetting information 29 | // Targetting memory allows processes to track targets (enemy or friend) 30 | // The following enums are used as indices in the process' targetting memory 31 | enum 32 | { 33 | TARGET_PARENT, // a newly built process starts with its builder as entry 0 34 | TARGET_MAIN, // main target 35 | }; 36 | 37 | 38 | 39 | // Variable declaration and initialisation 40 | // (note that declaration and initialisation cannot be combined) 41 | // (also, variables retain their values between execution cycles) 42 | int core_x, core_y; // location of core 43 | core_x = get_core_x(); // location is updated each cycle 44 | core_y = get_core_y(); 45 | int angle; // direction process is pointing 46 | // angles are in integer degrees from 0 to 8192, with 0 being right, 47 | // 2048 down, 4096 left and 6144 up. 48 | angle = get_core_angle(); // angle is updated each cycle 49 | 50 | int mode; // what is the process doing? (should be one of the MODE enums) 51 | 52 | int move_x, move_y; // destination 53 | int target_x, target_y; // location of target (to attack, follow etc) 54 | 55 | int scan_result; // used to hold the results of a scan of nearby processes 56 | 57 | int initialised; 58 | if (initialised == 0) 59 | { 60 | initialised = 1; 61 | attack_mode(1); 62 | special_AI(0, 6); 63 | gosub start_wandering; 64 | } 65 | 66 | // What the process does next depends on its current mode 67 | switch(mode) 68 | { 69 | 70 | 71 | case MODE_WANDER: 72 | if (distance_from_xy(move_x, move_y) < 300) 73 | { 74 | gosub start_wandering; 75 | break; 76 | } 77 | if (scan_for_threat(0, 0, TARGET_MAIN)) 78 | { 79 | mode = MODE_ATTACK; 80 | special_AI(1, 1); 81 | // no break; falls through to attack case below 82 | } 83 | else 84 | { 85 | auto_move.move_to(move_x, move_y); 86 | break; 87 | } 88 | // fall through... 89 | case MODE_ATTACK: 90 | if (process[TARGET_MAIN].visible() <= 0) // target no longer exists, or is out of range 91 | { 92 | if (target_destroyed(TARGET_MAIN)) 93 | special_AI(1, 2); 94 | gosub start_wandering; // give up and go back to wandering around randomly 95 | break; 96 | } 97 | 98 | auto_move.intercept(TARGET_MAIN, 0, auto_att_main); // approach to within 300 pixels of target's core 99 | 100 | if (process[TARGET_MAIN].distance_less(1000)) 101 | auto_att_main.fire(8); 102 | 103 | break; 104 | 105 | } // end of mode switch 106 | 107 | 108 | 109 | exit; 110 | 111 | 112 | start_wandering: 113 | mode = MODE_WANDER; 114 | move_x = 800 + random(world_x() - 1600); 115 | move_y = 800 + random(world_y() - 1600); 116 | return; 117 | -------------------------------------------------------------------------------- /src/g_command.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_G_COMMAND 3 | #define H_G_COMMAND 4 | 5 | 6 | #define SELECT_MAX 32 7 | 8 | #define SELECT_TERMINATE -1 9 | // SELECT_TERMINATE 10 | #define SELECT_EMPTY -2 11 | 12 | enum 13 | { 14 | BUILD_MODE_NONE, 15 | BUILD_MODE_PLACE, 16 | BUILD_MODE_ANGLE 17 | 18 | }; 19 | 20 | enum 21 | { 22 | SELECT_MODE_NONE, 23 | SELECT_MODE_SINGLE_CORE, // can assume that selected_core [0] is valid and not SELECT_EMPTY or SELECT_TERMINATE 24 | SELECT_MODE_MULTI_CORE, // can't assume that any selected core is valid (may be SELECT_EMPTY) 25 | SELECT_MODE_DATA_WELL, 26 | 27 | SELECT_MODES 28 | }; 29 | 30 | #define CONTROL_GROUPS 7 31 | #define POWER_DATA_RECORDS 50 32 | 33 | struct command_struct 34 | { 35 | int select_mode; 36 | int selected_core [SELECT_MAX + 1]; // need to null-terminate 37 | int selected_member; // only relevant if just one core selected. 38 | int selected_data_well; // only relevant in SELECT_MODE_DATA_WELL 39 | int select_box; 40 | al_fixed mouse_drag_world_x, mouse_drag_world_y; 41 | 42 | 43 | int build_mode; 44 | int builder_core_index; 45 | int display_build_buttons; // details of build buttons are stored in view_struct 46 | int build_template_index; 47 | cart build_position; 48 | al_fixed build_angle; 49 | al_fixed default_build_angle; // set for each build. 50 | int build_member_collision [GROUP_MAX_MEMBERS]; 51 | int build_fail_collision; // 1 if any member is in collision 52 | int build_fail_edge; // 1 if any member is off map 53 | int build_fail_static; // 1 if core is static and on data well 54 | int build_fail_range; // 1 if core is static and target out of range 55 | 56 | // int stress_record [POWER_DATA_RECORDS]; 57 | // int stress_level_record [POWER_DATA_RECORDS]; 58 | int power_use_record [POWER_DATA_RECORDS]; 59 | int power_fail_record [POWER_DATA_RECORDS]; 60 | int power_use_pos; 61 | 62 | int control_group_core [CONTROL_GROUPS] [SELECT_MAX+1]; 63 | int control_group_core_timestamp [CONTROL_GROUPS] [SELECT_MAX+1]; // unlike selected_core, cores are not automatically removed from control groups when they are destroyed. 64 | int last_control_group_selected; // selecting a control group twice quickly focuses on the control group 65 | timestamp last_control_group_select_time; 66 | 67 | 68 | }; 69 | 70 | 71 | void init_commands(void); 72 | void run_commands(void); 73 | 74 | void remove_core_from_selection(int core_index); 75 | void build_button_pressed(int template_index); 76 | int check_proc_visible_to_user(int proc_index); 77 | void clear_selection(void); 78 | void clear_control_groups(void); 79 | 80 | int add_command(struct core_struct* core, int command_type, int x, int y, int core_index, int member_index, int queued, int control_pressed); 81 | s16b add_to_build_queue(int player_index, int builder_core_index, int template_index, int build_x, int build_y, int angle, int back_or_front, int repeat, int queue_for_this_core, int failure_message); 82 | void clear_build_queue_for_core(int player_index, int remove_core_index); 83 | void requeue_repeat_build(int player_index); 84 | void build_queue_next(int player_index, int reset_build_queue_buttons); 85 | void rearrange_build_queue(void); 86 | int work_out_queue_drag_position(void); 87 | 88 | #endif 89 | -------------------------------------------------------------------------------- /bin/story/blue/blue1/wander1.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #process "wander1" 4 | 5 | class auto_att_fwd; 6 | class auto_move; 7 | 8 | core_quad_A, 0, 9 | {object_pulse:auto_att_fwd, 0}, 10 | {object_move:auto_move, 2048}, 11 | {object_none, 0}, 12 | {object_move:auto_move, -2048}, 13 | 14 | #code 15 | 16 | 17 | 18 | 19 | // Process AI modes (these reflect the capabilities of the process) 20 | enum 21 | { 22 | MODE_WANDER, 23 | MODE_ATTACK, 24 | MODES 25 | }; 26 | 27 | 28 | // Targetting information 29 | // Targetting memory allows processes to track targets (enemy or friend) 30 | // The following enums are used as indices in the process' targetting memory 31 | enum 32 | { 33 | TARGET_PARENT, // a newly built process starts with its builder as entry 0 34 | TARGET_MAIN, // main target 35 | }; 36 | 37 | 38 | 39 | // Variable declaration and initialisation 40 | // (note that declaration and initialisation cannot be combined) 41 | // (also, variables retain their values between execution cycles) 42 | int core_x, core_y; // location of core 43 | core_x = get_core_x(); // location is updated each cycle 44 | core_y = get_core_y(); 45 | int angle; // direction process is pointing 46 | // angles are in integer degrees from 0 to 8192, with 0 being right, 47 | // 2048 down, 4096 left and 6144 up. 48 | angle = get_core_angle(); // angle is updated each cycle 49 | 50 | int mode; // what is the process doing? (should be one of the MODE enums) 51 | 52 | int move_x, move_y; // destination 53 | int target_x, target_y; // location of target (to attack, follow etc) 54 | 55 | int scan_result; // used to hold the results of a scan of nearby processes 56 | 57 | int initialised; 58 | if (initialised == 0) 59 | { 60 | initialised = 1; 61 | attack_mode(1); 62 | special_AI(0, 6); 63 | gosub start_wandering; 64 | } 65 | 66 | // What the process does next depends on its current mode 67 | switch(mode) 68 | { 69 | 70 | 71 | case MODE_WANDER: 72 | if (distance_from_xy(move_x, move_y) < 300) 73 | { 74 | gosub start_wandering; 75 | break; 76 | } 77 | if (scan_for_threat(0, 0, TARGET_MAIN)) 78 | { 79 | mode = MODE_ATTACK; 80 | special_AI(1, 1); 81 | // no break; falls through to attack case below 82 | } 83 | else 84 | { 85 | auto_move.move_to(move_x, move_y); 86 | break; 87 | } 88 | // fall through... 89 | case MODE_ATTACK: 90 | if (process[TARGET_MAIN].visible() <= 0) // target no longer exists, or is out of range 91 | { 92 | if (target_destroyed(TARGET_MAIN)) 93 | special_AI(1, 2); 94 | 95 | gosub start_wandering; // give up and go back to wandering around randomly 96 | break; 97 | } 98 | 99 | auto_move.approach_target(TARGET_MAIN, 0, 300); // approach to within 300 pixels of target's core 100 | 101 | if (process[TARGET_MAIN].distance_less(1000)) 102 | auto_att_fwd.fire_at(TARGET_MAIN, 0); 103 | 104 | break; 105 | 106 | } // end of mode switch 107 | 108 | 109 | 110 | exit; 111 | 112 | 113 | start_wandering: 114 | mode = MODE_WANDER; 115 | move_x = 800 + random(world_x() - 1600); 116 | move_y = 800 + random(world_y() - 1600); 117 | auto_att_fwd.no_target(); 118 | return; 119 | -------------------------------------------------------------------------------- /src/v_draw_panel.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef H_V_DRAW_PANEL 4 | #define H_V_DRAW_PANEL 5 | 6 | //#define DEBUGGER_VARIABLES 64 7 | #define DEBUGGER_CLASSES 16 8 | #define DEBUGGER_LABELS 64 9 | #define DEBUGGER_EXIT_POINTS 1000 10 | #define DEBUGGER_NAME_LENGTH 32 11 | 12 | 13 | struct debugger_variable_struct 14 | { 15 | char name [DEBUGGER_NAME_LENGTH+1]; 16 | // int address; 17 | }; 18 | 19 | struct debugger_label_struct 20 | { 21 | char name [DEBUGGER_NAME_LENGTH+1]; 22 | int address; 23 | }; 24 | 25 | struct debugger_expoint_struct 26 | { 27 | int type; // -1 = empty, 0 = false, 1 = true 28 | int address; 29 | }; 30 | 31 | struct debugger_class_struct 32 | { 33 | char name [DEBUGGER_NAME_LENGTH+1]; 34 | }; 35 | 36 | // 2100 is probably too many... 37 | #define DEBUGGER_LINES 2100 38 | 39 | #define SOURCE_LINE_EMPTY -1 40 | #define SOURCE_LINE_JUMP_TABLE -2 41 | #define SOURCE_LINE_JUMP_TABLE_DEFAULT -3 42 | #define SOURCE_LINE_STRING -4 43 | #define SOURCE_LINE_LABEL -5 44 | 45 | struct debugger_line_struct 46 | { 47 | int bcode_address; // -1 if empty 48 | int source_line; // source line of op, or SOURCE_LINE_* 49 | int special_value; // special value for lines with special SOURCE_LINE_* values 50 | // int label_index; // -1 if no label or empty; otherwise, index of label in label array 51 | }; 52 | 53 | struct template_debug_struct 54 | { 55 | 56 | struct debugger_variable_struct variable [MEMORY_SIZE]; 57 | struct debugger_label_struct label [DEBUGGER_LABELS]; 58 | // struct debugger_expoint_struct expoint [DEBUGGER_EXIT_POINTS]; 59 | // struct debugger_class_struct dclass [DEBUGGER_CLASSES]; 60 | 61 | struct debugger_line_struct debugger_line [DEBUGGER_LINES]; 62 | 63 | int total_lines_bcode_window; 64 | 65 | 66 | }; 67 | 68 | enum 69 | { 70 | BCP_MOUSEOVER_NONE, 71 | BCP_MOUSEOVER_SOURCE_LINE, 72 | BCP_MOUSEOVER_BCODE_ADDRESS, 73 | BCP_MOUSEOVER_VARIABLE, 74 | BCP_MOUSEOVER_OPCODE, 75 | BCP_MOUSEOVER_CORE_INDEX, 76 | BCP_MOUSEOVER_LABEL, 77 | 78 | }; 79 | 80 | enum 81 | { 82 | BCP_MODE_EMPTY, // nothing in bc panel 83 | BCP_MODE_TEMPLATE, // just looking at a template (determined by dwindow template) 84 | BCP_MODE_PROCESS, // watching a specific process 85 | 86 | BCP_MODES 87 | }; 88 | 89 | enum 90 | { 91 | BCP_WAIT_OFF, 92 | BCP_WAIT_PAUSE, 93 | BCP_WAIT_PAUSE_ONE_STEP, 94 | BCP_WAIT_STEP_SLOW, 95 | BCP_WAIT_STEP_FAST, 96 | 97 | }; 98 | 99 | struct bcode_panel_state_struct 100 | { 101 | int bcp_mode; 102 | int bcp_wait_mode; 103 | int watch_core_index; 104 | timestamp watch_core_timestamp; 105 | int step_counter; // frame counter for step-through mode 106 | 107 | int player_index; 108 | int template_index; 109 | 110 | int subpanel_bcode_line; 111 | int subpanel_bcode_total_lines; 112 | int subpanel_variable_line; 113 | int subpanel_stack_line; 114 | int subpanel_target_line; 115 | int subpanel_target_total_lines; 116 | 117 | int lines; 118 | 119 | // int mouse_x, mouse_y; 120 | 121 | timestamp mouseover_time; 122 | int mouseover_type; 123 | int mouseover_value; 124 | 125 | }; 126 | 127 | 128 | void init_bcode_panel(void); 129 | void reset_bcode_panel(void); 130 | void draw_bcode_panel(void); 131 | 132 | #endif 133 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Liberation Circuit 2 | 3 | This is the release version of Liberation Circuit, an RTS/programming 4 | game. 5 | 6 | To play the pre-built binaries on Windows, [download the latest 7 | release](https://github.com/linleyh/liberation-circuit/releases) and run 8 | `LibCirc.exe`. There are also pre-built binaries for all platforms 9 | available on [itch.io](https://linleyh.itch.io/liberation-circuit). 10 | 11 | Vanilla has set up a [Discord server](https://discord.gg/8q7DFaM) to 12 | discuss strategy and things. 13 | 14 | ## Screenshots 15 | 16 | ![a screenshot](https://i.imgur.com/pPIJ03I.png) 17 | ![another screenshot](https://i.imgur.com/QKWzkqA.png) 18 | 19 | ## Dependencies 20 | 21 | The following libraries are required to play Liberation Circuit. 22 | 23 | * Allegro5 24 | * Allegro5 acodec 25 | * Allegro5 audio 26 | * Allegro5 dialog 27 | * Allegro5 image 28 | 29 | ## Compiling 30 | 31 | It should compile on any OS supported by Allegro 5 - to build, compile 32 | the c files in the source directory and link with Allegro 5. More 33 | detailed instructions are below. More detail about the source file 34 | structure is at the start of `m_main.c`. 35 | 36 | The executable should go in the "bin" subdirectory (the same directory as 37 | the "init.txt" file). The game requires write access to this directory to 38 | save mission progress. If this isn't okay, you can specify a path in the 39 | fopen calls at about lines 2808 and 2860 of `h_story.c`. Don't try to 40 | compile the `.c` files in the /proc or /story subdirectories! They are 41 | code used by the game itself. 42 | 43 | - [Manual.html](bin/Manual.html) has extensive detail about the game, 44 | including documentation for the in-game API. 45 | - Edit [init.txt](bin/init.txt) to set screen resolution and other 46 | options (fullscreen, sound volume, key rebinding, colourblind mode 47 | etc). 48 | 49 | 50 | ## Compiling on Linux 51 | 52 | To build on a Linux system, there are two options available. 53 | 54 | - `make` 55 | - `do` 56 | 57 | Note that `do` always compiles all source files; if you want to rebuild 58 | targets only when relevant source files have changed, you should use 59 | `redo` instead. A version of `redo` can be obtained from 60 | (written in 61 | Bourne shell) or (written in C++). 62 | 63 | ## Compiling on macOS 64 | 65 | To build on macOS (Sierra (10.12) with latest Homebrew and Xcode) 66 | 67 | ```sh 68 | git clone https://github.com/linleyh/liberation-circuit.git 69 | cd liberation-circuit 70 | brew install allegro 71 | ./do 72 | cd bin 73 | libcirc 74 | ``` 75 | 76 | If you are using a Retina screen, you may want to set the double_fonts 77 | option to make the text larger (edit init.txt to do this). 78 | 79 | ## Thanks to: 80 | 81 | - [Nils Dagsson Moskopp](https://github.com/erlehmann) for very useful 82 | feedback on the alpha and beta versions. 83 | - zugz (from the tigsource forum) for very useful feedback on the beta. 84 | - Serge Zaitsev's [cucu](https://zserge.com/posts/cucu-part1/) for a very clear explanation of how to write a simple C compiler. 85 | - Batuhan Bozkurt's [otomata](http://www.earslap.com/page/otomata.html) for the basis of the cellular automata-based procedural music generation. -------------------------------------------------------------------------------- /bin/story/tutorial/tute2/circle2.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #process "defender2" 4 | // This process has objects with the following auto classes: 5 | class auto_att_fwd; 6 | class auto_move; 7 | 8 | // The following auto classes are not currently used by any objects: 9 | class auto_retro; 10 | class auto_att_main; 11 | class auto_att_left; 12 | class auto_att_right; 13 | class auto_att_back; 14 | class auto_att_spike; 15 | class auto_harvest; 16 | class auto_allocate; 17 | class auto_stability; 18 | 19 | core_pent_A, 0, 20 | {object_pulse:auto_att_fwd, 0}, 21 | {object_downlink, -597, 22 | {component_cap, // component 1 23 | {object_move:auto_move, 15}, 24 | {object_uplink, 0}, 25 | {object_none, 0}, 26 | {object_none, 0}, 27 | } 28 | }, 29 | {object_move:auto_move, 946}, 30 | {object_move:auto_move, -946}, 31 | {object_downlink, 597, 32 | {component_cap, // component 2 33 | {object_none, 0}, 34 | {object_none, 0}, 35 | {object_uplink, 0}, 36 | {object_move:auto_move, -15}, 37 | } 38 | }, 39 | 40 | #code 41 | 42 | 43 | 44 | 45 | 46 | // Targetting information 47 | // Targetting memory allows processes to track targets (enemy or friend) 48 | // The following enums are used as indices in the process' targetting memory 49 | enum 50 | { 51 | TARGET_PARENT, // a newly built process starts with its builder as entry 0 52 | TARGET_BACK, 53 | TARGET_FRONT, 54 | }; 55 | 56 | int attacking_left; // is set to 1 if left directional attack objects have a target 57 | int attacking_right; // is set to 1 if right directional attack objects have a target 58 | 59 | int other_target_x, other_target_y; 60 | 61 | // Variable declaration and initialisation 62 | // (note that declaration and initialisation cannot be combined) 63 | // (also, variables retain their values between execution cycles) 64 | int core_x, core_y; // location of core 65 | core_x = get_core_x(); // location is updated each cycle 66 | core_y = get_core_y(); 67 | int angle; // direction process is pointing 68 | // angles are in integer degrees from 0 to 8192, with 0 being right, 69 | // 2048 down, 4096 left and 6144 up. 70 | angle = get_core_angle(); // angle is updated each cycle 71 | 72 | int move_x, move_y; // destination 73 | int centre_x, centre_y; // centre of circle process is orbiting 74 | int scan_result; // used to hold the results of a scan of nearby processes 75 | 76 | int initialised; // will start as 0 77 | 78 | if (!initialised) 79 | { 80 | // this process just moves in a circle around a point identified when it's created. 81 | centre_x = core_x + cos(angle + 2048, 400); 82 | centre_y = core_y + sin(angle + 2048, 400); 83 | initialised = 1; 84 | attack_mode(1); 85 | } 86 | 87 | 88 | //auto_att_back.attack_scan(4096, 400, TARGET_BACK); 89 | auto_att_fwd.attack_scan(0, 400, TARGET_FRONT); 90 | 91 | int angle_to_centre; 92 | angle_to_centre = atan2(core_y - centre_y, core_x - centre_x); 93 | int move_angle; 94 | move_angle = angle_to_centre + 400; // target is always a little clockwise from the current positiono 95 | 96 | move_x = centre_x + cos(move_angle, 400); 97 | move_y = centre_y + sin(move_angle, 400); 98 | 99 | auto_move.move_to(move_x, move_y); 100 | 101 | repair_self(); 102 | -------------------------------------------------------------------------------- /src/h_story.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_H_STORY 3 | #define H_H_STORY 4 | 5 | #define STORY_REGIONS 64 6 | 7 | enum 8 | { 9 | SRC_R, 10 | SRC_DR, 11 | SRC_DL, 12 | SRC_L, 13 | SRC_UL, 14 | SRC_UR, 15 | SRC_DIRECTIONS 16 | }; 17 | 18 | enum 19 | { 20 | AREA_TUTORIAL, 21 | AREA_BLUE, 22 | AREA_GREEN, 23 | AREA_YELLOW, 24 | AREA_ORANGE, 25 | AREA_PURPLE, 26 | //AREA_DARK_BLUE, 27 | //AREA_GREY, 28 | AREA_RED, 29 | 30 | STORY_AREAS 31 | }; 32 | 33 | /* 34 | enum 35 | { 36 | MISSION_TUTORIAL1, 37 | MISSION_TUTORIAL2, 38 | 39 | MISSION_BLUE_1, 40 | MISSION_BLUE_2, 41 | MISSION_BLUE_CAPITAL, 42 | 43 | MISSION_GREEN_1, 44 | MISSION_GREEN_2, 45 | MISSION_GREEN_CAPITAL, 46 | 47 | MISSION_YELLOW_1, 48 | MISSION_YELLOW_2, 49 | MISSION_YELLOW_CAPITAL, 50 | 51 | MISSION_ORANGE_1, 52 | MISSION_ORANGE_2, 53 | MISSION_ORANGE_CAPITAL, 54 | 55 | MISSION_PURPLE_1, 56 | MISSION_PURPLE_2, 57 | MISSION_PURPLE_CAPITAL, 58 | 59 | //MISSION_DARK_BLUE_1, 60 | //MISSION_DARK_BLUE_2, 61 | //MISSION_DARK_BLUE_CAPITAL, 62 | 63 | MISSION_RED_1, 64 | MISSION_RED_2, 65 | MISSION_RED_CAPITAL, 66 | 67 | MISSIONS 68 | }; 69 | */ 70 | 71 | enum 72 | { 73 | UNLOCK_NONE, 74 | 75 | //UNLOCK_KEY, 76 | 77 | UNLOCK_CORE_MOBILE_1, 78 | UNLOCK_CORE_MOBILE_2, 79 | UNLOCK_CORE_MOBILE_3, 80 | UNLOCK_CORE_MOBILE_4, 81 | //UNLOCK_CORE_MOBILE_5, 82 | 83 | UNLOCK_CORE_STATIC_1, 84 | UNLOCK_CORE_STATIC_2, 85 | //UNLOCK_CORE_STATIC_3, 86 | 87 | //UNLOCK_COMPONENTS_1, 88 | //UNLOCK_COMPONENTS_2, 89 | 90 | UNLOCK_OBJECT_INTERFACE, 91 | UNLOCK_OBJECT_REPAIR_OTHER, 92 | UNLOCK_OBJECT_STABILITY, 93 | 94 | UNLOCK_OBJECT_PULSE_L, 95 | UNLOCK_OBJECT_PULSE_XL, 96 | //UNLOCK_OBJECT_BURST_XL, 97 | 98 | UNLOCK_OBJECT_STREAM, 99 | UNLOCK_OBJECT_SPIKE, 100 | UNLOCK_OBJECT_SLICE, 101 | UNLOCK_OBJECT_ULTRA, 102 | 103 | UNLOCKS 104 | // 20 105 | // 33 106 | }; 107 | 108 | // areas are 109 | struct area_struct 110 | { 111 | 112 | int base_colour [3]; 113 | 114 | }; 115 | 116 | struct region_struct 117 | { 118 | 119 | int exists; // may not be selectable 120 | int visible; // 0 or 1 121 | 122 | int grid_x; 123 | int grid_y; 124 | int adjust_x, adjust_y; 125 | 126 | int connect [SRC_DIRECTIONS]; // default to -1 127 | 128 | int area_index; // which area is this region in 129 | int mission_index; 130 | int capital; // 1 if this is the main region of this area 131 | int unlock_index; // one of the UNLOCK enums 132 | 133 | int defeated; // 1 if player has beaten this region, 0 otherwise 134 | int can_be_played; // derived from defeated values when story mode loaded 135 | 136 | 137 | }; 138 | 139 | struct story_struct 140 | { 141 | 142 | int story_type; // STORY_TYPE_NORMAL or STORY_TYPE_ADVANCED, or the HARD versions 143 | 144 | struct region_struct region [STORY_REGIONS]; 145 | 146 | struct area_struct area [STORY_AREAS]; 147 | 148 | int unlock [UNLOCKS]; // determines which objects/components the player can use in story mode. Determined from area lock 149 | 150 | 151 | }; 152 | 153 | 154 | 155 | void load_story_status_file(void); 156 | //void init_story(void); 157 | void enter_story_mode(int story_type); 158 | void story_mission_defeated(void); 159 | 160 | void special_AI_method(struct core_struct* core, int value1, int value2); 161 | void special_AI_destroyed(struct core_struct* core); 162 | 163 | #endif 164 | -------------------------------------------------------------------------------- /src/e_tools.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | #include "m_config.h" 10 | 11 | #include "g_header.h" 12 | #include "m_globvars.h" 13 | #include "m_input.h" 14 | 15 | //#include "g_misc.h" 16 | 17 | #include "c_header.h" 18 | #include "c_prepr.h" 19 | 20 | #include "e_slider.h" 21 | #include "e_header.h" 22 | #include "e_log.h" 23 | #include "e_files.h" 24 | 25 | #include "e_editor.h" 26 | 27 | //#include "c_comp.h" 28 | 29 | extern struct editorstruct editor; 30 | 31 | 32 | int compare_search_string(struct source_edit_struct* se, int sline, int spos); 33 | 34 | void find_next(void) 35 | { 36 | 37 | if (editor.search_string [0] == '\0') 38 | return; 39 | 40 | struct source_edit_struct* se = get_current_source_edit(); 41 | 42 | if (se == NULL 43 | || se->type != SOURCE_EDIT_TYPE_SOURCE) 44 | return; 45 | 46 | int search_line = se->cursor_line; 47 | int search_pos = se->cursor_pos; // there's a check for null terminator just below 48 | 49 | if (se->text [se->line_index [search_line]] [search_pos] != '\0') 50 | search_pos ++; // if not at end of line, move one character to the right (to avoid picking up the current word) 51 | 52 | while(TRUE) 53 | { 54 | while (se->text [se->line_index [search_line]] [search_pos] == '\0') 55 | { 56 | search_pos = 0; 57 | search_line ++; 58 | // if (search_line == se->cursor_line) 59 | // return; // looped back around - nothing found 60 | if (search_line >= SOURCE_TEXT_LINES) 61 | return; // for now, finish at end of file 62 | // search_line = 0; // this ends in an infinite loop when cursor is on first line 63 | } 64 | // compare_search_string comes after search_pos increment because otherwise a repeated search will just find the same string in the same position again 65 | if (compare_search_string(se, search_line, search_pos)) 66 | { 67 | se->cursor_line = search_line; 68 | se->cursor_pos = search_pos; 69 | return; 70 | } 71 | search_pos ++; 72 | }; 73 | 74 | } 75 | 76 | int compare_search_string(struct source_edit_struct* se, int sline, int spos) 77 | { 78 | 79 | int i = 0; 80 | 81 | while(TRUE) 82 | { 83 | if (editor.search_string [i] == '\0') 84 | return 1; // success! 85 | 86 | if (editor.search_string [i] == se->text [se->line_index [sline]] [spos + i] 87 | || (editor.search_string [i] >= 'a' 88 | && editor.search_string [i] <= 'z' 89 | && se->text [se->line_index [sline]] [spos + i] == (editor.search_string [i] - 'a' + 'A')) 90 | || (editor.search_string [i] >= 'A' 91 | && editor.search_string [i] <= 'Z' 92 | && se->text [se->line_index [sline]] [spos + i] == (editor.search_string [i] - 'A' + 'a'))) 93 | { 94 | i ++; 95 | continue; 96 | } 97 | break; 98 | // this will return on finding the end of the source line (because it will find \0 in se->text), so don't need to expressly check for it 99 | // if (editor.search_string [i] != se->text [se->line_index [sline]] [spos + i]) 100 | // return 0; // this will return on finding the end of the source line (because it will find \0 in se->text), so don't need to expressly check for it 101 | // i++; 102 | }; 103 | 104 | return 0; 105 | 106 | } 107 | 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /src/i_console.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_I_CONSOLE 3 | #define H_I_CONSOLE 4 | 5 | #include "e_slider.h" 6 | 7 | #define CLINE_LENGTH 70 8 | #define CLINES 48 9 | 10 | //#define LINE_HEIGHT 15 11 | #define CONSOLE_LINE_HEIGHT scaleUI_y(FONT_SQUARE,18) 12 | 13 | 14 | 15 | 16 | 17 | #define PBOX_HEADER_HEIGHT scaleUI_y(FONT_SQUARE,15) 18 | #define PBOX_W scaleUI_x(FONT_SQUARE,320) 19 | #define PBOX_LINE scaleUI_y(FONT_SQUARE,12) 20 | /* 21 | struct proc_boxstruct 22 | { 23 | int x1, y1, x2, y2; 24 | int button_highlight; 25 | int maximised; 26 | int button_x1, button_y1, button_x2, button_y2; 27 | };*/ 28 | 29 | 30 | struct consolelinestruct 31 | { 32 | int used; // whether the line contains anything 33 | int colour; // index in PRINT_COLS. value in this field should be bounds-checked (as it would have been taken from w.print_colour, which is bounds-checked) 34 | char text [CLINE_LENGTH]; 35 | 36 | int source_index; // index of process (-1 if other source - may not currently be possible) 37 | timestamp source_core_created_timestamp; // if from a proc, this is its created_timestamp 38 | 39 | timestamp time_written; 40 | 41 | }; 42 | 43 | 44 | struct consolestruct 45 | { 46 | 47 | // put basic parameters of the console here: 48 | 49 | int x, y; 50 | int h_lines; // height in lines 51 | int w_letters; // width in letters 52 | int h_pixels; // height in pixels 53 | int w_pixels; 54 | int line_highlight; // if the mouse is over a line in the console 55 | timestamp line_highlight_time; // game.total_time when mouse was over line_highlight 56 | 57 | int cpos; // position in the cline array 58 | int current_line_length; 59 | 60 | struct consolelinestruct cline [CLINES]; 61 | 62 | int source_index; // index of player or proc that most recently wrote to console 63 | timestamp time_written; // time of most recent writing to console 64 | 65 | 66 | 67 | }; 68 | 69 | enum 70 | { 71 | CONSOLE_GENERAL, // bottom left console - displays messages from user's processes etc 72 | CONSOLE_SYSTEM, // top left console - special 73 | CONSOLES 74 | }; 75 | 76 | #define SYSTEM_CONSOLE_WIDTH_LETTERS 66 77 | 78 | void init_consoles(void); 79 | void setup_consoles(void); 80 | void clear_console(int console_index); 81 | 82 | //void program_write_to_console(const char* str, int source_program_type, int source_index, int source_player); 83 | //void write_error_to_console(const char* str, int source_program_type, int source_index, int source_player); 84 | 85 | void run_consoles(void); 86 | void display_consoles_and_buttons(void); 87 | 88 | void write_text_to_console(int console_index, int print_colour, int text_source, int source_core_created_timestamp, char* write_text); 89 | void console_newline(int console_index, int print_colour); 90 | 91 | void write_text_to_bubble(int core_index, timestamp print_timestamp, char* write_text); 92 | 93 | void check_mouse_on_consoles_etc(int mouse_x, int mouse_y, int left_button); 94 | void place_build_buttons(void); 95 | void reset_build_queue_buttons_y1(int queue_length); 96 | 97 | //void run_score_boxes(void); 98 | //void display_score_boxes(void); 99 | 100 | //void draw_proc_box(void); 101 | //void place_proc_box(int x, int y, struct proc_struct* pr); 102 | //void reset_proc_box_height(struct proc_struct* pr); 103 | 104 | //void set_console_size_etc(int c, int new_w, int new_h, int font_index, int force_update); 105 | 106 | #endif 107 | -------------------------------------------------------------------------------- /bin/story/purple/purple1/p1_defence.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #process "defence" 4 | 5 | class auto_att_fwd; 6 | 7 | core_static_hex_B, 0, 8 | {object_ultra_dir:auto_att_fwd, 0}, 9 | {object_downlink, -1054, 10 | {component_cap, // component 1 11 | {object_none, 0}, 12 | {object_uplink, 0}, 13 | {object_none, 0}, 14 | {object_none, 0}, 15 | } 16 | }, 17 | {object_downlink, 462, 18 | {component_cap, // component 2 19 | {object_none, 0}, 20 | {object_none, 0}, 21 | {object_uplink, 0}, 22 | {object_slice:auto_att_fwd, 266}, 23 | } 24 | }, 25 | {object_downlink, 0, 26 | {component_long5, // component 3 27 | {object_uplink, 0}, 28 | {object_interface, 0}, 29 | {object_interface, 0}, 30 | {object_interface, 0}, 31 | {object_interface, 0}, 32 | } 33 | }, 34 | {object_downlink, -462, 35 | {component_cap, // component 4 36 | {object_slice:auto_att_fwd, -266}, 37 | {object_uplink, 0}, 38 | {object_none, 0}, 39 | {object_none, 0}, 40 | } 41 | }, 42 | {object_downlink, 1054, 43 | {component_cap, // component 5 44 | {object_none, 0}, 45 | {object_none, 0}, 46 | {object_uplink, 0}, 47 | {object_none, 0}, 48 | } 49 | } 50 | 51 | #code 52 | 53 | 54 | 55 | 56 | // Targetting information 57 | // Targetting memory allows processes to track targets (enemy or friend) 58 | // The following enums are used as indices in the process' targetting memory 59 | enum 60 | { 61 | TARGET_PARENT, // a newly built process starts with its builder in address 0 62 | TARGET_MAIN, // main target 63 | TARGET_FRONT, // target of directional forward attack 64 | }; 65 | 66 | /* 67 | // Variable declaration and initialisation 68 | // (note that declaration and initialisation cannot be combined) 69 | // (also, variables retain their values between execution cycles) 70 | int core_x, core_y; // location of core 71 | core_x = get_core_x(); // location is updated each cycle 72 | core_y = get_core_y(); 73 | int angle; // direction process is pointing 74 | // angles are in integer degrees from 0 to 8192, with 0 being right, 75 | // 2048 down, 4096 left and 6144 (or -2048) up. 76 | angle = get_core_angle(); // angle is updated each cycle 77 | 78 | int mode; // what is the process doing? (should be one of the MODE enums) 79 | 80 | int front_attack_primary; // is set to 1 if forward directional attack objects are attacking 81 | // the primary target (e.g. target selected by command). Set to 0 if the objects are available for autonomous fire. 82 | int target_component; // target component for an attack command (allows user to 83 | // target specific components) 84 | 85 | int scan_result; // used to hold the results of a scan of nearby processes 86 | */ 87 | int initialised; // set to 1 after initialisation code below run the first time 88 | 89 | if (!initialised) 90 | { 91 | // initialisation code goes here (not all autocoded processes have initialisation code) 92 | initialised = 1; 93 | attack_mode(1); // attack objects (if present) will all fire together 94 | } 95 | 96 | 97 | 98 | auto_att_fwd.attack_scan(0, 400, TARGET_FRONT); 99 | 100 | charge_interface_max(); // charges the process' interface. Since the interface is shared across all 101 | // components with interface objects, this call is not specific to any object or class. 102 | // charge_interface_max() charges the interface using as much power as possible 103 | // (the charge rate is determined by the maximum interface strength). 104 | 105 | exit; // stops execution, until the next cycle 106 | 107 | // if there are any subroutines (called by gosub statements), they go here 108 | -------------------------------------------------------------------------------- /bin/story/green/green1/g1_base.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #process "base" 4 | 5 | class auto_allocate; 6 | class auto_att_right; 7 | class auto_harvest; 8 | class auto_att_back; 9 | class auto_att_left; 10 | class auto_att_fwd; 11 | 12 | core_static_hex_A, 811, 13 | {object_build, 0}, 14 | {object_downlink, 0, 15 | {component_bowl, // component 1 16 | {object_uplink, 0}, 17 | {object_harvest:auto_harvest, 0}, 18 | {object_interface, 0}, 19 | {object_pulse_l:auto_att_right, 0}, 20 | {object_pulse_l:auto_att_right, 0}, 21 | } 22 | }, 23 | {object_repair, 0}, 24 | {object_downlink, 0, 25 | {component_bowl, // component 2 26 | {object_uplink, 0}, 27 | {object_storage, 0}, 28 | {object_interface, 0}, 29 | {object_pulse_l:auto_att_back, 0}, 30 | {object_pulse_l:auto_att_left, 0}, 31 | } 32 | }, 33 | {object_allocate:auto_allocate, 0}, 34 | {object_downlink, 0, 35 | {component_bowl, // component 3 36 | {object_uplink, 0}, 37 | {object_storage, 0}, 38 | {object_interface, 0}, 39 | {object_pulse_l:auto_att_left, 0}, 40 | {object_pulse_l:auto_att_fwd, 0}, 41 | } 42 | } 43 | 44 | #code 45 | 46 | 47 | 48 | 49 | // Targetting information 50 | // Targetting memory allows processes to track targets (enemy or friend) 51 | // The following enums are used as indices in the process' targetting memory 52 | enum 53 | { 54 | TARGET_PARENT, // a newly built process starts with its builder in address 0 55 | TARGET_LEFT, // target of directional left attack 56 | TARGET_RIGHT, // target of directional right attack 57 | TARGET_FRONT, // target of directional front attack 58 | TARGET_BACK 59 | }; 60 | 61 | // Templates 62 | // - this process assumes that the templates have been set up in a certain way, 63 | // as follows: 64 | enum 65 | { 66 | TEMPLATE_BASE, 67 | TEMPLATE_FIREBASE, 68 | TEMPLATE_BUILDER 69 | 70 | }; 71 | 72 | 73 | 74 | // Variable declaration and initialisation 75 | // (note that declaration and initialisation cannot be combined) 76 | // (also, variables retain their values between execution cycles) 77 | int core_x, core_y; // location of core 78 | int angle; // direction process is pointing 79 | // angles are in integer degrees from 0 to 8192, with 0 being right, 80 | // 2048 down, 4096 left and 6144 (or -2048) up. 81 | int attacking; 82 | 83 | 84 | int initialised; 85 | 86 | if (!initialised) 87 | { 88 | 89 | core_x = get_core_x(); // location is updated each cycle 90 | core_y = get_core_y(); 91 | angle = get_core_angle(); // angle is updated each cycle 92 | 93 | attack_mode(1); 94 | 95 | 96 | add_to_build_queue(TEMPLATE_BUILDER, 97 | core_x + cos(angle, 500), 98 | core_y + sin(angle, 500), 99 | angle, 100 | 0, 101 | 1); // repeat 102 | 103 | initialised = 1; 104 | 105 | } 106 | 107 | build_from_queue(-1); // -1 means not to record target 108 | 109 | charge_interface_max(); 110 | 111 | 112 | attacking = 0; 113 | 114 | attacking += auto_att_left.attack_scan(-2000, 400, TARGET_LEFT); 115 | attacking += auto_att_right.attack_scan(2000, 400, TARGET_RIGHT); 116 | attacking += auto_att_fwd.attack_scan(0, 400, TARGET_FRONT); 117 | attacking += auto_att_back.attack_scan(4096, 400, TARGET_BACK); 118 | 119 | if (attacking > 0 120 | && get_interface_strength() < 1500) 121 | special_AI(1, 0); 122 | 123 | 124 | repair_self(); // tries to repair any damaged components 125 | restore_self(); // tries to restore any destroyed components 126 | 127 | auto_harvest.gather_data(); 128 | 129 | auto_allocate.allocate_data(4); // actually I think the maximum is 2 130 | -------------------------------------------------------------------------------- /bin/story/purple/purple2/p2_defence.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #process "defence" 4 | 5 | class auto_att_fwd; 6 | class auto_stability; 7 | 8 | core_static_hex_B, 0, 9 | {object_ultra_dir:auto_att_fwd, 0}, 10 | {object_downlink, -1054, 11 | {component_cap, // component 1 12 | {object_stability:auto_stability, 0}, 13 | {object_uplink, 0}, 14 | {object_none, 0}, 15 | {object_none, 0}, 16 | } 17 | }, 18 | {object_downlink, 462, 19 | {component_cap, // component 2 20 | {object_none, 0}, 21 | {object_none, 0}, 22 | {object_uplink, 0}, 23 | {object_slice:auto_att_fwd, 266}, 24 | } 25 | }, 26 | {object_downlink, 0, 27 | {component_long5, // component 3 28 | {object_uplink, 0}, 29 | {object_interface, 0}, 30 | {object_interface, 0}, 31 | {object_interface, 0}, 32 | {object_interface, 0}, 33 | } 34 | }, 35 | {object_downlink, -462, 36 | {component_cap, // component 4 37 | {object_slice:auto_att_fwd, -266}, 38 | {object_uplink, 0}, 39 | {object_none, 0}, 40 | {object_none, 0}, 41 | } 42 | }, 43 | {object_downlink, 1054, 44 | {component_cap, // component 5 45 | {object_none, 0}, 46 | {object_none, 0}, 47 | {object_uplink, 0}, 48 | {object_stability:auto_stability, 0}, 49 | } 50 | } 51 | 52 | #code 53 | 54 | 55 | 56 | 57 | // Targetting information 58 | // Targetting memory allows processes to track targets (enemy or friend) 59 | // The following enums are used as indices in the process' targetting memory 60 | enum 61 | { 62 | TARGET_PARENT, // a newly built process starts with its builder in address 0 63 | TARGET_MAIN, // main target 64 | TARGET_FRONT, // target of directional forward attack 65 | }; 66 | 67 | /* 68 | // Variable declaration and initialisation 69 | // (note that declaration and initialisation cannot be combined) 70 | // (also, variables retain their values between execution cycles) 71 | int core_x, core_y; // location of core 72 | core_x = get_core_x(); // location is updated each cycle 73 | core_y = get_core_y(); 74 | int angle; // direction process is pointing 75 | // angles are in integer degrees from 0 to 8192, with 0 being right, 76 | // 2048 down, 4096 left and 6144 (or -2048) up. 77 | angle = get_core_angle(); // angle is updated each cycle 78 | 79 | int mode; // what is the process doing? (should be one of the MODE enums) 80 | 81 | int front_attack_primary; // is set to 1 if forward directional attack objects are attacking 82 | // the primary target (e.g. target selected by command). Set to 0 if the objects are available for autonomous fire. 83 | int target_component; // target component for an attack command (allows user to 84 | // target specific components) 85 | 86 | int scan_result; // used to hold the results of a scan of nearby processes 87 | */ 88 | int initialised; // set to 1 after initialisation code below run the first time 89 | 90 | if (!initialised) 91 | { 92 | // initialisation code goes here (not all autocoded processes have initialisation code) 93 | initialised = 1; 94 | attack_mode(1); // attack objects (if present) will all fire together 95 | auto_stability.set_stability(1); 96 | } 97 | 98 | 99 | 100 | auto_att_fwd.attack_scan(0, 400, TARGET_FRONT); 101 | 102 | charge_interface_max(); // charges the process' interface. Since the interface is shared across all 103 | // components with interface objects, this call is not specific to any object or class. 104 | // charge_interface_max() charges the interface using as much power as possible 105 | // (the charge rate is determined by the maximum interface strength). 106 | 107 | exit; // stops execution, until the next cycle 108 | 109 | // if there are any subroutines (called by gosub statements), they go here 110 | -------------------------------------------------------------------------------- /bin/story/purple/purple3/p3_defence.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #process "defence" 4 | 5 | class auto_att_fwd; 6 | class auto_stability; 7 | 8 | core_static_hex_B, 0, 9 | {object_ultra_dir:auto_att_fwd, 0}, 10 | {object_downlink, -1054, 11 | {component_cap, // component 1 12 | {object_stability:auto_stability, 0}, 13 | {object_uplink, 0}, 14 | {object_none, 0}, 15 | {object_none, 0}, 16 | } 17 | }, 18 | {object_downlink, 462, 19 | {component_cap, // component 2 20 | {object_none, 0}, 21 | {object_none, 0}, 22 | {object_uplink, 0}, 23 | {object_slice:auto_att_fwd, 266}, 24 | } 25 | }, 26 | {object_downlink, 0, 27 | {component_long5, // component 3 28 | {object_uplink, 0}, 29 | {object_interface, 0}, 30 | {object_interface, 0}, 31 | {object_interface, 0}, 32 | {object_interface, 0}, 33 | } 34 | }, 35 | {object_downlink, -462, 36 | {component_cap, // component 4 37 | {object_slice:auto_att_fwd, -266}, 38 | {object_uplink, 0}, 39 | {object_none, 0}, 40 | {object_none, 0}, 41 | } 42 | }, 43 | {object_downlink, 1054, 44 | {component_cap, // component 5 45 | {object_none, 0}, 46 | {object_none, 0}, 47 | {object_uplink, 0}, 48 | {object_stability:auto_stability, 0}, 49 | } 50 | } 51 | 52 | #code 53 | 54 | 55 | 56 | 57 | // Targetting information 58 | // Targetting memory allows processes to track targets (enemy or friend) 59 | // The following enums are used as indices in the process' targetting memory 60 | enum 61 | { 62 | TARGET_PARENT, // a newly built process starts with its builder in address 0 63 | TARGET_MAIN, // main target 64 | TARGET_FRONT, // target of directional forward attack 65 | }; 66 | 67 | /* 68 | // Variable declaration and initialisation 69 | // (note that declaration and initialisation cannot be combined) 70 | // (also, variables retain their values between execution cycles) 71 | int core_x, core_y; // location of core 72 | core_x = get_core_x(); // location is updated each cycle 73 | core_y = get_core_y(); 74 | int angle; // direction process is pointing 75 | // angles are in integer degrees from 0 to 8192, with 0 being right, 76 | // 2048 down, 4096 left and 6144 (or -2048) up. 77 | angle = get_core_angle(); // angle is updated each cycle 78 | 79 | int mode; // what is the process doing? (should be one of the MODE enums) 80 | 81 | int front_attack_primary; // is set to 1 if forward directional attack objects are attacking 82 | // the primary target (e.g. target selected by command). Set to 0 if the objects are available for autonomous fire. 83 | int target_component; // target component for an attack command (allows user to 84 | // target specific components) 85 | 86 | int scan_result; // used to hold the results of a scan of nearby processes 87 | */ 88 | int initialised; // set to 1 after initialisation code below run the first time 89 | 90 | if (!initialised) 91 | { 92 | // initialisation code goes here (not all autocoded processes have initialisation code) 93 | initialised = 1; 94 | attack_mode(1); // attack objects (if present) will all fire together 95 | auto_stability.set_stability(1); 96 | } 97 | 98 | 99 | 100 | auto_att_fwd.attack_scan(0, 400, TARGET_FRONT); 101 | 102 | charge_interface_max(); // charges the process' interface. Since the interface is shared across all 103 | // components with interface objects, this call is not specific to any object or class. 104 | // charge_interface_max() charges the interface using as much power as possible 105 | // (the charge rate is determined by the maximum interface strength). 106 | 107 | exit; // stops execution, until the next cycle 108 | 109 | // if there are any subroutines (called by gosub statements), they go here 110 | -------------------------------------------------------------------------------- /src/d_code.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef H_D_CODE 4 | #define H_D_CODE 5 | 6 | 7 | #define DTOKEN_LENGTH 32 8 | 9 | 10 | struct dtoken_struct 11 | { 12 | 13 | char name [DTOKEN_LENGTH]; 14 | 15 | }; 16 | 17 | 18 | enum 19 | { 20 | AUTOCODE_NONE, 21 | AUTOCODE_STANDARD, 22 | AUTOCODE_CHARGE, 23 | AUTOCODE_BOMBARD, 24 | AUTOCODE_CIRCLE_CW, 25 | AUTOCODE_CIRCLE_ACW, 26 | AUTOCODE_ERRATIC, 27 | AUTOCODE_CAUTIOUS, 28 | 29 | AUTOCODE_TYPES 30 | }; 31 | 32 | 33 | // quadrants are used for working out which class some objects belong to (e.g. attack_forward) 34 | enum 35 | { 36 | // order of quadrants must match order of directional classes (forward, left, right, back) 37 | QUADRANT_FORWARD, 38 | QUADRANT_LEFT, 39 | QUADRANT_RIGHT, 40 | QUADRANT_BACK 41 | }; 42 | 43 | 44 | enum 45 | { 46 | MAIN_ATTACK_NONE, // proc doesn't attack 47 | MAIN_ATTACK_APPROACH, // proc approaches to short range of target, then turns to face it (use this if main attack is dir forwards) 48 | MAIN_ATTACK_CIRCLE, // [not currently used] - proc circles target (use if main attack is fixed forwards) 49 | MAIN_ATTACK_INTERCEPT, // proc uses intercept method (use this if main attack is fixed forwards) 50 | MAIN_ATTACK_LONG_RANGE, // proc approaches to long range then turns to face target only (use for spike). If it has retro move, will use standoff to maintain distance 51 | }; 52 | 53 | 54 | #define AUTO_CLASS_NAME_LENGTH 16 55 | enum 56 | { 57 | AUTO_CLASS_MOVE, 58 | AUTO_CLASS_RETRO, // I don't think this is used directly, but if retro move objects are present some code is generated differently (e.g. stand_off movement calls are used instead of turn_to or intercept) 59 | AUTO_CLASS_ATTACK_MAIN, 60 | AUTO_CLASS_ATTACK_FRONT_DIR, 61 | AUTO_CLASS_ATTACK_LEFT_DIR, 62 | AUTO_CLASS_ATTACK_RIGHT_DIR, 63 | AUTO_CLASS_ATTACK_BACK_DIR, 64 | AUTO_CLASS_SPIKE_FRONT, 65 | AUTO_CLASS_HARVEST, 66 | AUTO_CLASS_ALLOCATE, 67 | AUTO_CLASS_STABILITY, 68 | //AUTO_CLASS_BUILD, 69 | // need to make changes below if AUTO_CLASSES ever gets close to OBJECT_CLASSES (16) (although actually I think this is caught and will produce an error if there are too many) 70 | AUTO_CLASSES 71 | }; 72 | 73 | 74 | enum 75 | { 76 | AUTOMODE_IDLE, 77 | AUTOMODE_MOVE, 78 | AUTOMODE_ATTACK, 79 | AUTOMODE_ATTACK_FOUND, 80 | AUTOMODE_HARVEST, 81 | AUTOMODE_HARVEST_RETURN, // returning to allocator from harvest 82 | AUTOMODE_GUARD, // circle around target 83 | AUTOMODE_MOVE_BUILD, // move somewhere and build 84 | 85 | 86 | //AUTOMODE_MOVE_REPAIR, // move somewhere and repair a friendly process 87 | 88 | AUTOMODES 89 | }; 90 | 91 | struct dcode_state_struct 92 | { 93 | int source_line; // remember that this is the index in the source_edit.line_index array, not in the source_edit.text array! 94 | int cursor_pos; 95 | int indent_level; 96 | int process_structure_lines; 97 | int error_type; 98 | struct source_edit_struct* ses; 99 | 100 | int autocode_type; 101 | int main_attack_type; 102 | int auto_class_index [AUTO_CLASSES]; // the AUTO_CLASS indices don't necessarily match the template's class indices. This array gives the template class index for an AUTO_CLASS. 103 | int object_type_present [OBJECT_TYPES]; 104 | int unindexed_auto_class_present [AUTO_CLASSES]; // number of objects in class AUTO_CLASS (0 if class not present). Doesn't need to be referenced through auto_class_index. 105 | // int unindexed_auto_class_number [AUTO_CLASSES]; // number of objects in an unindexed auto class 106 | 107 | #define DCODE_BUFFER_LENGTH 8000 108 | char dcode_buffer [DCODE_BUFFER_LENGTH]; 109 | 110 | // autocode stuff 111 | int mobile; // 0 if immobile, 1 otherwise 112 | int automode [AUTOMODES]; 113 | 114 | 115 | 116 | }; 117 | 118 | 119 | int autocode(int autocode_type); 120 | 121 | int dcode_error(const char* error_message); 122 | void dcode_warning(const char* warning_message); 123 | 124 | 125 | 126 | #endif 127 | -------------------------------------------------------------------------------- /src/i_background.c: -------------------------------------------------------------------------------- 1 | 2 | #ifdef BSHAPES 3 | 4 | // code for complex background shapes - not currently used 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | #include "m_config.h" 13 | #include "g_header.h" 14 | #include "g_misc.h" 15 | #include "m_maths.h" 16 | #include "i_background.h" 17 | 18 | 19 | struct bshape_init_struct 20 | { 21 | struct bshape_struct* current_bshape; 22 | }; 23 | struct bshape_init_struct bshape_init; 24 | 25 | struct bshape_struct bshape [BSHAPES]; 26 | struct background_block_struct backblock [BACKBLOCK_TYPES]; 27 | 28 | 29 | 30 | static void start_bshape(int bshape_index); 31 | static void add_bshape_vertex(int x, int y); 32 | static void add_bshape_vertex_vector(int angle, int dist); 33 | static void fix_bshape_triangles_walk(void); 34 | static void add_bshape_triangle(int v1, int v2, int v3); 35 | 36 | void init_bshapes(void) 37 | { 38 | 39 | start_bshape(BSHAPE_THING); 40 | add_bshape_vertex(0, 40); 41 | add_bshape_vertex(20, 0); 42 | 43 | add_bshape_vertex(0, -20); 44 | add_bshape_vertex(-20, 0); 45 | 46 | fix_bshape_triangles_walk(); 47 | 48 | 49 | } 50 | 51 | static void start_bshape(int bshape_index) 52 | { 53 | 54 | bshape[bshape_index].vertices = 0; 55 | bshape[bshape_index].triangles = 0; 56 | 57 | bshape_init.current_bshape = &bshape[bshape_index]; 58 | 59 | } 60 | 61 | 62 | static void add_bshape_vertex(int x, int y) 63 | { 64 | 65 | #ifdef SANITY_CHECK 66 | if (bshape_init.current_bshape->vertices >= BSHAPE_VERTICES) 67 | { 68 | fpr("\n Error: i_background.c: add_bshape_vertex(): too many vertices"); 69 | error_call(); 70 | } 71 | #endif 72 | 73 | bshape_init.current_bshape->vertex_angle [bshape_init.current_bshape->vertices] = atan2(y, x); 74 | bshape_init.current_bshape->vertex_dist [bshape_init.current_bshape->vertices] = hypot(y, x); 75 | bshape_init.current_bshape->vertices ++; 76 | 77 | } 78 | 79 | 80 | static void add_bshape_vertex_vector(int angle, int dist) 81 | { 82 | 83 | 84 | #ifdef SANITY_CHECK 85 | if (bshape_init.current_bshape->vertices >= BSHAPE_VERTICES) 86 | { 87 | fpr("\n Error: i_background.c: add_bshape_vertex_vector(): too many vertices"); 88 | error_call(); 89 | } 90 | #endif 91 | 92 | bshape_init.current_bshape->vertex_angle [bshape_init.current_bshape->vertices] = angle_to_radians(angle); 93 | bshape_init.current_bshape->vertex_dist [bshape_init.current_bshape->vertices] = dist; 94 | bshape_init.current_bshape->vertices ++; 95 | 96 | } 97 | 98 | 99 | 100 | // generates the triangle index (which orders vertices) 101 | static void fix_bshape_triangles_walk(void) 102 | { 103 | int low_v, high_v; 104 | 105 | low_v = 0; 106 | high_v = bshape_init.current_bshape->vertices - 1; 107 | 108 | while(low_v < high_v - 2) 109 | { 110 | add_bshape_triangle(low_v, high_v, low_v + 1); 111 | add_bshape_triangle(high_v, low_v + 1, high_v - 1); 112 | low_v ++; 113 | high_v --; 114 | }; 115 | 116 | //fpr("\nFinished shape %i poly %i dt %i", dshape_init.current_dshape, dshape_init.current_poly, dshape [dshape_init.current_dshape].display_triangles [dshape_init.current_poly]); 117 | } 118 | 119 | // only called by fix_bshape_triangles_walk() 120 | static void add_bshape_triangle(int v1, int v2, int v3) 121 | { 122 | 123 | bshape_init.current_bshape->triangle_index [bshape_init.current_bshape->triangles] [0] = v1; 124 | bshape_init.current_bshape->triangle_index [bshape_init.current_bshape->triangles] [1] = v2; 125 | bshape_init.current_bshape->triangle_index [bshape_init.current_bshape->triangles] [2] = v3; 126 | bshape_init.current_bshape->triangles++; 127 | 128 | //fpr("\nADT %i poly %i (%i,%i,%i) dt %i", dshape_init.current_dshape, dshape_init.current_poly, v1,v2,v3,dshape [dshape_init.current_dshape].display_triangles [dshape_init.current_poly]); 129 | 130 | } 131 | 132 | 133 | #endif 134 | -------------------------------------------------------------------------------- /bin/story/red/red2/r2_defence.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #process "defence" 4 | 5 | class auto_stability; 6 | class auto_att_fwd; 7 | 8 | core_static_hex_B, 0, 9 | {object_downlink, 0, 10 | {component_peak, // component 6 11 | {object_uplink, 0}, 12 | {object_stability:auto_stability, 0}, 13 | {object_none, 0}, 14 | {object_pulse_xl:auto_att_fwd, 0}, 15 | {object_pulse_xl:auto_att_fwd, 0}, 16 | } 17 | }, 18 | {object_downlink, 333, 19 | {component_cap, // component 2 20 | {object_stability:auto_stability, 0}, 21 | {object_uplink, 0}, 22 | {object_none, 0}, 23 | {object_slice:auto_att_fwd, 0}, 24 | } 25 | }, 26 | {object_downlink, 340, 27 | {component_cap, // component 1 28 | {object_none, 0}, 29 | {object_uplink, 0}, 30 | {object_none, 0}, 31 | {object_none, 0}, 32 | } 33 | }, 34 | {object_downlink, 0, 35 | {component_long4, // component 3 36 | {object_uplink, 0}, 37 | {object_interface, 0}, 38 | {object_interface, -32}, 39 | {object_interface, 0}, 40 | } 41 | }, 42 | {object_downlink, -340, 43 | {component_cap, // component 4 44 | {object_none, 0}, 45 | {object_none, 0}, 46 | {object_uplink, 0}, 47 | {object_none, 0}, 48 | } 49 | }, 50 | {object_downlink, -333, 51 | {component_cap, // component 5 52 | {object_slice:auto_att_fwd, 0}, 53 | {object_none, 0}, 54 | {object_uplink, 0}, 55 | {object_stability:auto_stability, 0}, 56 | } 57 | } 58 | 59 | #code 60 | 61 | 62 | 63 | 64 | // Targetting information 65 | // Targetting memory allows processes to track targets (enemy or friend) 66 | // The following enums are used as indices in the process' targetting memory 67 | enum 68 | { 69 | TARGET_PARENT, // a newly built process starts with its builder in address 0 70 | TARGET_MAIN, // main target 71 | TARGET_FRONT, // target of directional forward attack 72 | }; 73 | 74 | /* 75 | // Variable declaration and initialisation 76 | // (note that declaration and initialisation cannot be combined) 77 | // (also, variables retain their values between execution cycles) 78 | int core_x, core_y; // location of core 79 | core_x = get_core_x(); // location is updated each cycle 80 | core_y = get_core_y(); 81 | int angle; // direction process is pointing 82 | // angles are in integer degrees from 0 to 8192, with 0 being right, 83 | // 2048 down, 4096 left and 6144 (or -2048) up. 84 | angle = get_core_angle(); // angle is updated each cycle 85 | 86 | int mode; // what is the process doing? (should be one of the MODE enums) 87 | 88 | int front_attack_primary; // is set to 1 if forward directional attack objects are attacking 89 | // the primary target (e.g. target selected by command). Set to 0 if the objects are available for autonomous fire. 90 | int target_component; // target component for an attack command (allows user to 91 | // target specific components) 92 | 93 | int scan_result; // used to hold the results of a scan of nearby processes 94 | */ 95 | int initialised; // set to 1 after initialisation code below run the first time 96 | 97 | if (!initialised) 98 | { 99 | // initialisation code goes here (not all autocoded processes have initialisation code) 100 | initialised = 1; 101 | attack_mode(1); // attack objects (if present) will all fire together 102 | auto_stability.set_stability(1); 103 | } 104 | 105 | 106 | 107 | auto_att_fwd.attack_scan(0, 400, TARGET_FRONT); 108 | 109 | charge_interface_max(); // charges the process' interface. Since the interface is shared across all 110 | // components with interface objects, this call is not specific to any object or class. 111 | // charge_interface_max() charges the interface using as much power as possible 112 | // (the charge rate is determined by the maximum interface strength). 113 | 114 | exit; // stops execution, until the next cycle 115 | 116 | // if there are any subroutines (called by gosub statements), they go here 117 | -------------------------------------------------------------------------------- /bin/story/blue/blue1/rbase.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #process "rbase" 4 | 5 | class auto_att_fwd; 6 | class auto_harvest; 7 | class auto_att_back; 8 | class auto_allocate; 9 | class auto_att_left; 10 | class auto_att_right; 11 | 12 | core_static_hex_A, 271, 13 | {object_downlink, -449, 14 | {component_long4, // component 1 15 | {object_build, 0}, 16 | {object_pulse:auto_att_fwd, 322}, 17 | {object_none, 0}, 18 | {object_uplink, 0}, 19 | } 20 | }, 21 | {object_downlink, 457, 22 | {component_long4, // component 2 23 | {object_harvest:auto_harvest, 0}, 24 | {object_pulse:auto_att_right, 0}, 25 | {object_none, 0}, 26 | {object_uplink, 0}, 27 | } 28 | }, 29 | {object_repair, 0}, 30 | {object_downlink, -516, 31 | {component_long4, // component 3 32 | {object_allocate:auto_allocate, 0}, 33 | {object_pulse:auto_att_back, 298}, 34 | {object_none, 0}, 35 | {object_uplink, 0}, 36 | } 37 | }, 38 | {object_downlink, 497, 39 | {component_long4, // component 4 40 | {object_storage, 0}, 41 | {object_pulse:auto_att_left, 0}, 42 | {object_none, 0}, 43 | {object_uplink, 0}, 44 | } 45 | }, 46 | {object_none, 0} 47 | 48 | #code 49 | 50 | 51 | 52 | 53 | // Targetting information 54 | // Targetting memory allows processes to track targets (enemy or friend) 55 | // The following enums are used as indices in the process' targetting memory 56 | enum 57 | { 58 | TARGET_PARENT, // a newly built process starts with its builder in address 0 59 | TARGET_LEFT, // target of directional left attack 60 | TARGET_RIGHT, // target of directional right attack 61 | TARGET_FRONT, // target of directional front attack 62 | TARGET_END 63 | 64 | }; 65 | 66 | 67 | 68 | // Templates 69 | // - this process assumes that the templates have been set up in a certain way, 70 | // as follows: 71 | enum 72 | { 73 | TEMPLATE_BASE, 74 | TEMPLATE_ATTACKER1, 75 | TEMPLATE_ATTACKER2 76 | 77 | }; 78 | 79 | 80 | 81 | // Variable declaration and initialisation 82 | // (note that declaration and initialisation cannot be combined) 83 | // (also, variables retain their values between execution cycles) 84 | int core_x, core_y; // location of core 85 | core_x = get_core_x(); // location is updated each cycle 86 | core_y = get_core_y(); 87 | int angle; // direction process is pointing 88 | // angles are in integer degrees from 0 to 8192, with 0 being right, 89 | // 2048 down, 4096 left and 6144 (or -2048) up. 90 | angle = get_core_angle(); // angle is updated each cycle 91 | 92 | // builder variables 93 | int build_result; // build result code (returned by build call) 94 | int build_counter; 95 | 96 | special_AI(0, 5); 97 | 98 | 99 | 100 | auto_harvest.gather_data(); 101 | 102 | 103 | auto_allocate.allocate_data(4); // actually I think the maximum is 2 104 | 105 | if (build_counter < 5) 106 | { 107 | build_result = build_process(TEMPLATE_ATTACKER1, cos(angle - 1024, 400), sin(angle - 1024, 400), angle - 1024, -1); 108 | if (build_result == 1) 109 | build_counter ++; 110 | goto finished_building; 111 | } 112 | 113 | // build_counter must be 5, so build a different attacker: 114 | 115 | build_result = build_process(TEMPLATE_ATTACKER2, cos(angle - 1024, 400), sin(angle - 1024, 400), angle - 1024, -1); 116 | if (build_result == 1) 117 | build_counter = 0; 118 | 119 | 120 | 121 | finished_building: 122 | 123 | charge_interface_max(); 124 | 125 | int attacking; 126 | 127 | attacking = 0; 128 | 129 | attacking += auto_att_left.attack_scan(-3000, 400, TARGET_LEFT); 130 | attacking += auto_att_right.attack_scan(3000, 400, TARGET_RIGHT); 131 | attacking += auto_att_fwd.attack_scan(0, 400, TARGET_FRONT); 132 | 133 | if (attacking > 0) 134 | special_AI(1, 0); 135 | 136 | repair_self(); // tries to repair any damaged components 137 | restore_self(); // tries to restore any destroyed components 138 | 139 | 140 | auto_harvest.gather_data(); 141 | auto_allocate.allocate_data(4); // actually I think the maximum is 2 142 | -------------------------------------------------------------------------------- /bin/readme.txt: -------------------------------------------------------------------------------- 1 | # liberation-circuit 2 | 3 | version: 1.3 4 | 5 | This is Liberation Circuit, an RTS/programming game. 6 | 7 | To play the prebuilt binaries on Windows, [download the latest release](https://github.com/linleyh/liberation-circuit/releases) and run `LibCirc.exe`. You can change the game settings by editing init.txt. 8 | 9 | 10 | It should compile on any OS supported by Allegro 5 - to build, compile the c files in the source directory and link with Allegro 5. More detailed instructions are below. More detail about the source file structure is at the start of m_main.c. 11 | 12 | The executable should go in the "bin" subdirectory (the same directory as the "init.txt" file). By default the game will write mission progress to a file called "msn.dat" in the bin directory. If this isn't okay (e.g. if the bin directory is write-protected), you can specify a different path and filename in init.txt. 13 | 14 | Don't try to compile the .c files in the /proc or /story subdirectories! They are code used by the game itself. 15 | 16 | - Manual.html has extensive detail about the game, including documentation for the in-game API. 17 | 18 | - Edit init.txt to set screen resolution and other options (fullscreen, sound volume, key rebinding, colourblind mode etc). 19 | 20 | It looks like this (this is github markdown): 21 | 22 | ![a screenshot](http://i.imgur.com/pPIJ03I.png) 23 | 24 | ![another screenshot](http://i.imgur.com/QKWzkqA.png) 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------- 31 | 32 | 33 | To build using do/redo (using the .do scripts by Nils Dagsson Moskopp): 34 | 35 | To build Liberation Circuit on any Unix-like OS like GNU/Linux, 36 | execute the “do” script. Note that “do” always compiles all source 37 | files; if you want to rebuild targets only when relevant source files 38 | have changed, you should use “redo” instead. A version of “redo” can 39 | be obtained from 40 | (written in Bourne shell) or (written 41 | in C++). 42 | 43 | Packages needed for Liberation Circuit on Debian GNU/Linux or Ubuntu: 44 | - liballegro-acodec5-dev 45 | - liballegro-audio5-dev 46 | - liballegro-dialog5-dev 47 | - liballegro-image5-dev 48 | - liballegro5-dev 49 | 50 | 51 | -------------------------------------------------- 52 | 53 | 54 | To build using cmake (using the cmake scripts by Kyle Findlay; The following instructions are from u/JCanseco on reddit): 55 | 56 | 57 | I did compile it with ccmake ncurses frontend on Antergos (based on Arch Linux). 58 | 59 | mkdir build;cd build;ccmake .. 60 | 61 | Adding this line to CMAKE_EXE_LINKER_FLAGS was enough: 62 | 63 | -lallegro_image -lallegro_primitives -lallegro_color -lallegro_acodec -lallegro_audio -lallegro_dialog -lallegro_font -lallegro_main -lallegro -lm 64 | 65 | make -j4 and it compiled fine with Allegro 5.2.2. Extracted zip data on bin folder and it did run fine. 66 | 67 | 68 | 69 | --------------------------------------------------- 70 | 71 | To build on OSX (Sierra (10.12) with latest Homebrew and Xcode) 72 | 73 | ``` 74 | $ git clone https://github.com/linleyh/liberation-circuit.git 75 | $ cd liberation-circuit 76 | $ brew install allegro 77 | $ ./do 78 | 79 | $ cd bin 80 | 81 | $ libcirc 82 | 83 | ``` 84 | 85 | If you are using a Retina screen, you may want to set the double_fonts option to make the text larger (edit init.txt to do this). 86 | 87 | 88 | --------------------------------------------------- 89 | 90 | 91 | 92 | Thanks to: 93 | 94 | Nils Dagsson Moskopp (erlehmann) for very useful feedback on the alpha and beta versions. 95 | 96 | zugz (from the tigsource forum) for very useful feedback on the beta. 97 | 98 | Serge Zaitsev's cucu (http://zserge.com/blog/cucu-part1.html) for a very clear explanation of how to write a simple C compiler. 99 | 100 | Batuhan Bozkurt's otomata (http://www.earslap.com/page/otomata.html) for the basis of the cellular automata-based procedural music generation. 101 | -------------------------------------------------------------------------------- /bin/story/red/red3/r3_defence.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #process "defence" 4 | 5 | class auto_stability; 6 | class auto_att_fwd; 7 | class auto_att_right; 8 | class auto_att_left; 9 | 10 | core_static_hex_B, 0, 11 | {object_downlink, 0, 12 | {component_bowl, // component 1 13 | {object_uplink, 0}, 14 | {object_stability:auto_stability, 0}, 15 | {object_none, 0}, 16 | {object_pulse_xl:auto_att_fwd, 0}, 17 | {object_pulse_xl:auto_att_fwd, 0}, 18 | } 19 | }, 20 | {object_downlink, 551, 21 | {component_bowl, // component 3 22 | {object_uplink, 0}, 23 | {object_none, 0}, 24 | {object_none, 0}, 25 | {object_stability:auto_stability, 0}, 26 | {object_slice:auto_att_right, -416}, 27 | } 28 | }, 29 | {object_downlink, 534, 30 | {component_cap, // component 2 31 | {object_uplink, 0}, 32 | {object_none, 0}, 33 | {object_none, 0}, 34 | {object_none, 0}, 35 | } 36 | }, 37 | {object_downlink, 0, 38 | {component_long5, // component 4 39 | {object_uplink, 0}, 40 | {object_interface, 0}, 41 | {object_interface, -32}, 42 | {object_interface, 0}, 43 | {object_interface, -32}, 44 | } 45 | }, 46 | {object_downlink, -534, 47 | {component_cap, // component 5 48 | {object_none, 0}, 49 | {object_none, 0}, 50 | {object_none, 0}, 51 | {object_uplink, 0}, 52 | } 53 | }, 54 | {object_downlink, -551, 55 | {component_bowl, // component 6 56 | {object_uplink, 0}, 57 | {object_none, 0}, 58 | {object_none, 0}, 59 | {object_slice:auto_att_left, 416}, 60 | {object_stability:auto_stability, 0}, 61 | } 62 | } 63 | 64 | #code 65 | 66 | 67 | 68 | 69 | // Targetting information 70 | // Targetting memory allows processes to track targets (enemy or friend) 71 | // The following enums are used as indices in the process' targetting memory 72 | enum 73 | { 74 | TARGET_PARENT, // a newly built process starts with its builder in address 0 75 | TARGET_MAIN, // main target 76 | TARGET_FRONT, // target of directional forward attack 77 | }; 78 | 79 | /* 80 | // Variable declaration and initialisation 81 | // (note that declaration and initialisation cannot be combined) 82 | // (also, variables retain their values between execution cycles) 83 | int core_x, core_y; // location of core 84 | core_x = get_core_x(); // location is updated each cycle 85 | core_y = get_core_y(); 86 | int angle; // direction process is pointing 87 | // angles are in integer degrees from 0 to 8192, with 0 being right, 88 | // 2048 down, 4096 left and 6144 (or -2048) up. 89 | angle = get_core_angle(); // angle is updated each cycle 90 | 91 | int mode; // what is the process doing? (should be one of the MODE enums) 92 | 93 | int front_attack_primary; // is set to 1 if forward directional attack objects are attacking 94 | // the primary target (e.g. target selected by command). Set to 0 if the objects are available for autonomous fire. 95 | int target_component; // target component for an attack command (allows user to 96 | // target specific components) 97 | 98 | int scan_result; // used to hold the results of a scan of nearby processes 99 | */ 100 | int initialised; // set to 1 after initialisation code below run the first time 101 | 102 | if (!initialised) 103 | { 104 | // initialisation code goes here (not all autocoded processes have initialisation code) 105 | initialised = 1; 106 | attack_mode(1); // attack objects (if present) will all fire together 107 | auto_stability.set_stability(1); 108 | } 109 | 110 | 111 | 112 | auto_att_fwd.attack_scan(0, 400, TARGET_FRONT); 113 | 114 | charge_interface_max(); // charges the process' interface. Since the interface is shared across all 115 | // components with interface objects, this call is not specific to any object or class. 116 | // charge_interface_max() charges the interface using as much power as possible 117 | // (the charge rate is determined by the maximum interface strength). 118 | 119 | exit; // stops execution, until the next cycle 120 | 121 | // if there are any subroutines (called by gosub statements), they go here 122 | -------------------------------------------------------------------------------- /do: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # A minimal alternative to djb redo that doesn't support incremental builds. 4 | # 5 | # The author disclaims copyright to this source file and hereby places it in 6 | # the public domain. (2010 12 14) 7 | # 8 | 9 | # By default, no output coloring. 10 | green="" 11 | bold="" 12 | plain="" 13 | 14 | if [ -n "$TERM" -a "$TERM" != "dumb" ] && tty <&2 >/dev/null 2>&1; then 15 | green="$(printf '\033[32m')" 16 | bold="$(printf '\033[1m')" 17 | plain="$(printf '\033[m')" 18 | fi 19 | 20 | _dirsplit() 21 | { 22 | base=${1##*/} 23 | dir=${1%$base} 24 | } 25 | 26 | dirname() 27 | ( 28 | _dirsplit "$1" 29 | dir=${dir%/} 30 | echo "${dir:-.}" 31 | ) 32 | 33 | _dirsplit "$0" 34 | export REDO=$(cd "${dir:-.}" && echo "$PWD/$base") 35 | 36 | DO_TOP= 37 | if [ -z "$DO_BUILT" ]; then 38 | DO_TOP=1 39 | [ -n "$*" ] || set all # only toplevel redo has a default target 40 | export DO_BUILT=$PWD/.do_built 41 | : >>"$DO_BUILT" 42 | echo "Removing previously built files..." >&2 43 | sort -u "$DO_BUILT" | tee "$DO_BUILT.new" | 44 | while read f; do printf "%s\0%s.did\0" "$f" "$f"; done | 45 | xargs -0 rm -f 2>/dev/null 46 | mv "$DO_BUILT.new" "$DO_BUILT" 47 | DO_PATH=$DO_BUILT.dir 48 | export PATH=$DO_PATH:$PATH 49 | rm -rf "$DO_PATH" 50 | mkdir "$DO_PATH" 51 | for d in redo redo-ifchange; do 52 | ln -s "$REDO" "$DO_PATH/$d"; 53 | done 54 | [ -e /bin/true ] && TRUE=/bin/true || TRUE=/usr/bin/true 55 | for d in redo-ifcreate redo-stamp redo-always; do 56 | ln -s $TRUE "$DO_PATH/$d"; 57 | done 58 | fi 59 | 60 | 61 | _find_dofile_pwd() 62 | { 63 | dofile=default.$1.do 64 | while :; do 65 | dofile=default.${dofile#default.*.} 66 | [ -e "$dofile" -o "$dofile" = default.do ] && break 67 | done 68 | ext=${dofile#default} 69 | ext=${ext%.do} 70 | base=${1%$ext} 71 | } 72 | 73 | 74 | _find_dofile() 75 | { 76 | local prefix= 77 | while :; do 78 | _find_dofile_pwd "$1" 79 | [ -e "$dofile" ] && break 80 | [ "$PWD" = "/" ] && break 81 | target=${PWD##*/}/$target 82 | tmp=${PWD##*/}/$tmp 83 | prefix=${PWD##*/}/$prefix 84 | cd .. 85 | done 86 | base=$prefix$base 87 | } 88 | 89 | 90 | _run_dofile() 91 | { 92 | export DO_DEPTH="$DO_DEPTH " 93 | export REDO_TARGET=$PWD/$target 94 | local line1 95 | set -e 96 | read line1 <"$PWD/$dofile" || true 97 | cmd=${line1#"#!/"} 98 | if [ "$cmd" != "$line1" ]; then 99 | /$cmd "$PWD/$dofile" "$@" >"$tmp.tmp2" 100 | else 101 | :; . "$PWD/$dofile" >"$tmp.tmp2" 102 | fi 103 | } 104 | 105 | 106 | _do() 107 | { 108 | local dir=$1 target=$2 tmp=$3 109 | if [ ! -e "$target" ] || [ -d "$target" -a ! -e "$target.did" ]; then 110 | printf '%sdo %s%s%s%s\n' \ 111 | "$green" "$DO_DEPTH" "$bold" "$dir$target" "$plain" >&2 112 | echo "$PWD/$target" >>"$DO_BUILT" 113 | dofile=$target.do 114 | base=$target 115 | ext= 116 | [ -e "$target.do" ] || _find_dofile "$target" 117 | if [ ! -e "$dofile" ]; then 118 | echo "do: $target: no .do file" >&2 119 | return 1 120 | fi 121 | [ ! -e "$DO_BUILT" ] || [ ! -d "$(dirname "$target")" ] || 122 | : >>"$target.did" 123 | ( _run_dofile "$target" "$base" "$tmp.tmp" ) 124 | rv=$? 125 | if [ $rv != 0 ]; then 126 | printf "do: %s%s\n" "$DO_DEPTH" \ 127 | "$dir$target: got exit code $rv" >&2 128 | rm -f "$tmp.tmp" "$tmp.tmp2" 129 | return $rv 130 | fi 131 | mv "$tmp.tmp" "$target" 2>/dev/null || 132 | ! test -s "$tmp.tmp2" || 133 | mv "$tmp.tmp2" "$target" 2>/dev/null 134 | rm -f "$tmp.tmp2" 135 | else 136 | echo "do $DO_DEPTH$target exists." >&2 137 | fi 138 | } 139 | 140 | 141 | # Make corrections for directories that don't actually exist yet. 142 | _dir_shovel() 143 | { 144 | local dir base 145 | xdir=$1 xbase=$2 xbasetmp=$2 146 | while [ ! -d "$xdir" -a -n "$xdir" ]; do 147 | _dirsplit "${xdir%/}" 148 | xbasetmp=${base}__$xbase 149 | xdir=$dir xbase=$base/$xbase 150 | echo "xbasetmp='$xbasetmp'" >&2 151 | done 152 | } 153 | 154 | 155 | _redo() 156 | { 157 | set +e 158 | for i in "$@"; do 159 | _dirsplit "$i" 160 | _dir_shovel "$dir" "$base" 161 | dir=$xdir base=$xbase basetmp=$xbasetmp 162 | ( cd "$dir" && _do "$dir" "$base" "$basetmp" ) 163 | [ "$?" = 0 ] || return 1 164 | done 165 | } 166 | 167 | 168 | _redo "$@" 169 | [ "$?" = 0 ] || exit 1 170 | 171 | if [ -n "$DO_TOP" ]; then 172 | echo "Removing stamp files..." >&2 173 | [ ! -e "$DO_BUILT" ] || 174 | while read f; do printf "%s.did\0" "$f"; done <"$DO_BUILT" | 175 | xargs -0 rm -f 2>/dev/null 176 | fi 177 | -------------------------------------------------------------------------------- /bin/story/blue/blue2/b2_wander2.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #process "wander2" 4 | 5 | class auto_move; 6 | class auto_att_fwd; 7 | 8 | core_pent_B, 0, 9 | {object_repair, 0}, 10 | {object_downlink, -165, 11 | {component_prong, // component 1 12 | {object_pulse:auto_att_fwd, 818}, 13 | {object_pulse:auto_att_fwd, 0}, 14 | {object_uplink, 0}, 15 | {object_move:auto_move, 2048}, 16 | } 17 | }, 18 | {object_move:auto_move, 946}, 19 | {object_move:auto_move, -946}, 20 | {object_downlink, 165, 21 | {component_prong, // component 2 22 | {object_pulse:auto_att_fwd, 0}, 23 | {object_pulse:auto_att_fwd, -818}, 24 | {object_move:auto_move, -2048}, 25 | {object_uplink, 0}, 26 | } 27 | }, 28 | 29 | #code 30 | 31 | 32 | 33 | 34 | // Process AI modes (these reflect the capabilities of the process) 35 | enum 36 | { 37 | MODE_WANDER, 38 | MODE_ATTACK, 39 | MODES 40 | }; 41 | 42 | 43 | // Targetting information 44 | // Targetting memory allows processes to track targets (enemy or friend) 45 | // The following enums are used as indices in the process' targetting memory 46 | enum 47 | { 48 | TARGET_PARENT, // a newly built process starts with its builder as entry 0 49 | TARGET_MAIN, // main target 50 | TARGET_LEFT, 51 | TARGET_RIGHT 52 | }; 53 | 54 | 55 | 56 | // Variable declaration and initialisation 57 | // (note that declaration and initialisation cannot be combined) 58 | // (also, variables retain their values between execution cycles) 59 | int core_x, core_y; // location of core 60 | core_x = get_core_x(); // location is updated each cycle 61 | core_y = get_core_y(); 62 | int angle; // direction process is pointing 63 | // angles are in integer degrees from 0 to 8192, with 0 being right, 64 | // 2048 down, 4096 left and 6144 up. 65 | angle = get_core_angle(); // angle is updated each cycle 66 | 67 | int mode; // what is the process doing? (should be one of the MODE enums) 68 | 69 | int move_x, move_y; // destination 70 | 71 | 72 | int initialised; 73 | if (initialised == 0) 74 | { 75 | initialised = 1; 76 | attack_mode(1); 77 | special_AI(0, 7); 78 | gosub start_wandering; 79 | } 80 | 81 | // What the process does next depends on its current mode 82 | switch(mode) 83 | { 84 | 85 | 86 | case MODE_WANDER: 87 | if (distance_from_xy(move_x, move_y) < 300) 88 | { 89 | gosub start_wandering; 90 | break; 91 | } 92 | if (scan_for_threat(0, 0, TARGET_MAIN)) 93 | { 94 | mode = MODE_ATTACK; 95 | special_AI(1, 1); 96 | // no break; falls through to attack case below 97 | } 98 | else 99 | { 100 | auto_move.move_to(move_x, move_y); 101 | break; 102 | } 103 | // fall through... 104 | case MODE_ATTACK: 105 | if (process[TARGET_MAIN].visible() <= 0) // target no longer exists, or is out of range 106 | { 107 | if (target_destroyed(TARGET_MAIN)) 108 | special_AI(1, 2); 109 | gosub start_wandering; // give up and go back to wandering around randomly 110 | break; 111 | } 112 | 113 | auto_move.approach_target(TARGET_MAIN, 0, 700); // calls approach_target() on all objects in the auto_move class. 114 | // Parameters are: 115 | // - target's address in targetting memory 116 | // - component of target process to attack (0 means the core) 117 | // - approach distance (in pixels) 118 | if (process[TARGET_MAIN].distance_less(1000)) 119 | auto_att_fwd.fire_at(TARGET_MAIN, 0); // tries to fire one object in the auto_att_main class. 8 is firing delay (in ticks) 120 | // (here, the auto_att_main class is for fixed attack objects that point more or less forwards) 121 | // fire_1() can be better than just fire() because it spreads out the power use 122 | break; // end of case MODE_ATTACK 123 | 124 | } // end of mode switch 125 | 126 | 127 | // auto_att_left.attack_scan(-3000, 400, TARGET_LEFT); 128 | // auto_att_right.attack_scan(3000, 400, TARGET_RIGHT); 129 | 130 | 131 | //if (get_power_left() > 30) 132 | repair_self(); // tries to repair any damaged components 133 | 134 | //if (get_power_left() > 30) 135 | restore_self(); // tries to restore any destroyed components 136 | 137 | 138 | 139 | 140 | exit; // halts execution (until the next cycle) 141 | 142 | 143 | start_wandering: 144 | mode = MODE_WANDER; 145 | // set the target location anywhere that's not too close to the edge of the map: 146 | move_x = 800 + random(world_x() - 1600); // (world_x/y() return size of map 147 | move_y = 800 + random(world_y() - 1600); 148 | return; // jumps back to the statement just after the gosub 149 | -------------------------------------------------------------------------------- /bin/story/blue/blue2/b2_rbase.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #process "rbase" 4 | 5 | class auto_att_back; 6 | class auto_harvest; 7 | class auto_allocate; 8 | class auto_att_left; 9 | class auto_att_right; 10 | class auto_att_fwd; 11 | 12 | core_static_hex_A, 1400, 13 | {object_downlink, -994, 14 | {component_cap, // component 2 15 | {object_storage, 0}, 16 | {object_uplink, 0}, 17 | {object_allocate:auto_allocate, 0}, 18 | {object_pulse_l:auto_att_left, 0}, 19 | } 20 | }, 21 | {object_downlink, 195, 22 | {component_cap, // component 1 23 | {object_pulse_l:auto_att_back, 0}, 24 | {object_harvest:auto_harvest, 0}, 25 | {object_uplink, 0}, 26 | {object_pulse_l:auto_att_fwd, 0}, 27 | } 28 | }, 29 | {object_downlink, 0, 30 | {component_tri, // component 5 31 | {object_uplink, 0}, 32 | {object_interface, 0}, 33 | {object_interface, 0}, 34 | } 35 | }, 36 | {object_downlink, 0, 37 | {component_cap, // component 3 38 | {object_pulse_l:auto_att_fwd, 0}, 39 | {object_uplink, 0}, 40 | {object_storage, 0}, 41 | {object_pulse_l:auto_att_back, 0}, 42 | } 43 | }, 44 | {object_downlink, 920, 45 | {component_cap, // component 4 46 | {object_pulse_l:auto_att_right, 289}, 47 | {object_build, 0}, 48 | {object_uplink, 766}, 49 | {object_storage, 0}, 50 | } 51 | }, 52 | {object_repair, 0} 53 | 54 | #code 55 | 56 | 57 | 58 | 59 | // Targetting information 60 | // Targetting memory allows processes to track targets (enemy or friend) 61 | // The following enums are used as indices in the process' targetting memory 62 | enum 63 | { 64 | TARGET_PARENT, // a newly built process starts with its builder in address 0 65 | TARGET_LEFT, // target of directional left attack 66 | TARGET_RIGHT, // target of directional right attack 67 | TARGET_FRONT, // target of directional front attack 68 | TARGET_BACK, // target of directional back attack 69 | TARGET_END 70 | 71 | }; 72 | 73 | 74 | 75 | // Templates 76 | // - this process assumes that the templates have been set up in a certain way, 77 | // as follows: 78 | enum 79 | { 80 | TEMPLATE_BASE, 81 | TEMPLATE_ATTACKER1, 82 | TEMPLATE_ATTACKER2, 83 | TEMPLATE_HARVESTER 84 | 85 | }; 86 | 87 | 88 | 89 | // Variable declaration and initialisation 90 | // (note that declaration and initialisation cannot be combined) 91 | // (also, variables retain their values between execution cycles) 92 | int core_x, core_y; // location of core 93 | core_x = get_core_x(); // location is updated each cycle 94 | core_y = get_core_y(); 95 | int angle; // direction process is pointing 96 | // angles are in integer degrees from 0 to 8192, with 0 being right, 97 | // 2048 down, 4096 left and 6144 (or -2048) up. 98 | angle = get_core_angle(); // angle is updated each cycle 99 | 100 | // builder variables 101 | int build_result; // build result code (returned by build call) 102 | int build_counter; 103 | 104 | int build_special; 105 | 106 | special_AI(0, 9); 107 | 108 | auto_harvest.gather_data(); 109 | 110 | 111 | auto_allocate.allocate_data(4); // actually I think the maximum is 2 112 | 113 | if (build_counter < 4) 114 | { 115 | build_result = build_process(TEMPLATE_ATTACKER1, cos(angle, 400), sin(angle, 400), angle, -1); 116 | if (build_result == 1) 117 | build_counter ++; 118 | goto finished_building; 119 | } 120 | 121 | // build_counter must be 4, so build something else: 122 | 123 | if (build_special == 1) 124 | { 125 | build_result = build_process(TEMPLATE_ATTACKER2, cos(angle, 400), sin(angle, 400), angle, -1); 126 | if (build_result == 1) 127 | { 128 | build_counter = 0; 129 | build_special = 0; 130 | } 131 | } 132 | else 133 | { 134 | build_result = build_process(TEMPLATE_HARVESTER, cos(angle, 400), sin(angle, 400), angle, -1); 135 | if (build_result == 1) 136 | { 137 | build_counter = 0; 138 | build_special = 1; 139 | } 140 | } 141 | 142 | 143 | 144 | finished_building: 145 | 146 | charge_interface_max(); 147 | 148 | if (get_interface_strength() < 1500) 149 | special_AI(1, 0); 150 | 151 | auto_att_left.attack_scan(-1200, 400, TARGET_LEFT); 152 | auto_att_right.attack_scan(1200, 400, TARGET_RIGHT); 153 | auto_att_fwd.attack_scan(0, 400, TARGET_FRONT); 154 | auto_att_back.attack_scan(4096, 400, TARGET_BACK); 155 | 156 | restore_self(); // tries to restore any destroyed components 157 | repair_self(); // tries to repair any damaged components 158 | 159 | 160 | auto_harvest.gather_data(); 161 | 162 | auto_allocate.allocate_data(4); // actually I think the maximum is 2 163 | -------------------------------------------------------------------------------- /src/g_world_map.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_G_WORLD_MAP 3 | #define H_G_WORLD_MAP 4 | 5 | 6 | 7 | #define MDETAILS 50 8 | 9 | enum 10 | { 11 | MDETAIL_NONE, 12 | MDETAIL_RIPPLE, // concentric ripples around centre 13 | MDETAIL_LINE, // just a straight line 14 | MDETAIL_INDIRECT_PATH, // some kind of indirect line 15 | MDETAIL_VOID, // empty space with smaller nodes around edge 16 | MDETAIL_RISE, // patch of higher nodes 17 | MDETAIL_DIP, // patch of lower nodes 18 | MDETAIL_RING, // circle of raised nodes 19 | MDETAIL_RING_EMPTY, // circle of raised nodes with void in centre 20 | MDETAIL_SYSTEM, // single large node surrounded by smaller ones 21 | MDETAIL_SYSTEM_CLEAR, // like SYSTEM but clears around itself first 22 | MDETAIL_WORM_SOURCE 23 | 24 | }; 25 | 26 | enum 27 | { 28 | BACKGROUND_TYPE_UNIFORM, // all nodes the same (size and depth based on base_backgroun values in map_init) 29 | BACKGROUND_TYPE_NOISE, // like uniform but also applies the background random valuds in map_init 30 | 31 | 32 | }; 33 | 34 | 35 | struct mdetail_struct 36 | { 37 | int type; 38 | int dsize; 39 | int player_col; // pre-coloured with player colours 40 | block_cart block_position; 41 | block_cart block_position2; 42 | }; 43 | 44 | 45 | 46 | // this struct contains details of how the background is to be assembled. 47 | // it's part of the w_init struct 48 | struct map_init_struct 49 | { 50 | 51 | int map_size_blocks; // taken from w_init value 52 | int players; // taken from w_init value 53 | int area_index; // affects the type of data wells generated etc. 54 | 55 | struct mdetail_struct mdetail [MDETAILS]; 56 | 57 | int general_background_type; 58 | 59 | // int base_background_depth; 60 | // int background_depth_random_freq; // frequency of random addition/subtraction to background depth 61 | // int background_depth_random_add; // size of random addition 62 | // int background_depth_random_sub; // size of random subtraction 63 | // int base_background_size; 64 | // int background_size_random_freq; // frequency of random addition/subtraction to background size 65 | // int background_size_random_add; // size of random addition 66 | // int background_size_random_sub; // size of random subtraction 67 | int background_size_base; 68 | int background_size_random; 69 | int background_size_random_freq;//20;//60; // frequency of random addition/subtraction to background depth 70 | 71 | 72 | block_cart spawn_position [PLAYERS]; // may be nonsense for non-existent players 73 | int spawn_angle [PLAYERS]; 74 | 75 | int data_wells; 76 | block_cart data_well_position [DATA_WELLS]; 77 | float data_well_spin_rate [DATA_WELLS]; // only used for display 78 | int data_well_reserve_data [DATA_WELLS] [DATA_WELL_RESERVES]; 79 | int data_well_reserve_squares [DATA_WELLS]; // currently the same for both reserves 80 | 81 | // int data_well_style; // e.g. AREA_BLUE 82 | 83 | }; 84 | 85 | void reset_map_init(int map_size_blocks, 86 | int map_area, 87 | int players); 88 | void generate_random_map(int area_index, 89 | int size_blocks, 90 | int players, 91 | unsigned int map_seed); 92 | void generate_scattered_map(int area_index, 93 | int size_blocks, 94 | int players, 95 | unsigned int map_seed); 96 | 97 | void set_player_spawn_position_by_latest_well(int player_index, int angle_from_well, int distance_from_well); 98 | void set_player_spawn_position(int player_index, int block_x, int block_y, int angle); 99 | void set_player_spawn_position_by_specified_well(int player_index, int well_index, int angle_from_well, int distance_from_well); 100 | 101 | int add_data_well_to_map_init(int x, int y, int reserve_A, int reserve_B, int reserve_squares, float spin_rate); 102 | int add_mdetail_ring(int centre_x, int centre_y, int ring_size, int empty_centre); 103 | int add_mdetail_line(int start_x, int start_y, int end_x, int end_y, int line_thickness); 104 | int add_mdetail_system(int centre_x, int centre_y, int system_size); 105 | int add_mdetail_worm_source(int centre_x, int centre_y, int worms); 106 | int add_line_between_data_wells(int well_1, int well_2, int line_thickness); 107 | int add_data_well_to_mdetail_ring(int mdetail_ring_index, int angle, int reserve_A, int reserve_B, int reserve_squares, float spin_rate); 108 | void add_extra_spawn_by_latest_well(int player_index, int template_index, int angle_from_well); 109 | block_cart get_well_block_position(int well_index); 110 | void add_mdetail_worm_source_to_all_wells(void); 111 | 112 | #endif 113 | -------------------------------------------------------------------------------- /src/m_config.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef H_M_CONFIG 3 | #define H_M_CONFIG 4 | 5 | #include 6 | 7 | // DEBUG_MODE gives access to various special commands, etc and does some other stuff like give player 0 free data 8 | //#define DEBUG_MODE 9 | 10 | // SANITY_CHECK runs various checks for things that should never happen, and shuts the game down if they do. 11 | // It doesn't seem to slow things down much so I've left it on, at least for now: 12 | //#define SANITY_CHECK 13 | 14 | #ifdef SANITY_CHECK 15 | #define sancheck(value, min, max, text) if(value=max){fpr("\nError: [%s]=(%i) out of bounds (should be %i to %i).",text,value,min,max-1);error_call();} 16 | #else 17 | #define sancheck(value, min, max, text) 18 | #endif 19 | 20 | // RECORDING_VIDEO sets the resolution to 1280x720 (which is usually not possible, and makes some designer stuff unusable, as the minimum vertical resolution is 768) 21 | // it also allows unlocking of player 1's templates in story mode 22 | //#define RECORDING_VIDEO 23 | 24 | // RECORDING_VIDEO_2 hides some of the display elements 25 | //#define RECORDING_VIDEO_2 26 | 27 | 28 | 29 | 30 | 31 | #ifndef TRUE 32 | #define TRUE 1 33 | #define FALSE 0 34 | #endif 35 | 36 | #define ANGLE_MASK 8191 37 | #define ANGLE_1 8192 38 | #define ANGLE_2 4096 39 | #define ANGLE_3 2730 40 | // 3 is not exact 41 | #define ANGLE_4 2048 42 | #define ANGLE_5 1638 43 | // not exact 44 | #define ANGLE_6 1365 45 | #define ANGLE_7 1170 46 | // 6 is not exact 47 | #define ANGLE_8 1024 48 | #define ANGLE_10 819 49 | #define ANGLE_12 683 50 | #define ANGLE_16 512 51 | //#define ANGLE_8_3 384 52 | //#define ANGLE_16_3 192 53 | #define ANGLE_32 256 54 | #define ANGLE_64 128 55 | #define ANGLE_128 64 56 | #define ANGLE_256 32 57 | //#define ANGLE_TO_FIXED 4 58 | 59 | #define AFX_MASK 0xffffff 60 | 61 | #define AFX_ANGLE_1 al_itofix(256) 62 | #define AFX_ANGLE_2 al_itofix(128) 63 | #define AFX_ANGLE_4 al_itofix(64) 64 | #define AFX_ANGLE_8 al_itofix(32) 65 | #define AFX_ANGLE_16 al_itofix(16) 66 | #define AFX_ANGLE_32 al_itofix(8) 67 | #define AFX_ANGLE_64 al_itofix(4) 68 | #define AFX_ANGLE_128 al_itofix(2) 69 | #define AFX_ANGLE_256 al_itofix(1) 70 | 71 | typedef int16_t s16b; 72 | typedef uint16_t u16b; 73 | 74 | typedef uint32_t timestamp; 75 | 76 | /* 77 | 78 | IMPORTANT 79 | 80 | This program assumes that all integers wrap on overflow. 81 | Unfortunately, according to the C standard this is undefined behaviour for signed integers. 82 | I think it's possible to force the intended behaviour, at least with GCC, by using either of the following compiler flags: 83 | -fwrapv 84 | -fno-strict-overflow 85 | Some sources claim that fno-strict-overflow is more reliable, so I've used that for binary distribution. 86 | 87 | */ 88 | 89 | #ifndef PI 90 | #define PI 3.141592 91 | #endif 92 | 93 | #define PI_2 (PI/2) 94 | #define PI_4 (PI/4) 95 | #define PI_8 (PI/8) 96 | #define PI_16 (PI/16) 97 | #define PI_32 (PI/32) 98 | 99 | #ifndef MAX 100 | #define MAX( a, b ) ( ((a) > (b)) ? (a) : (b) ) 101 | #endif 102 | 103 | #ifndef MIN 104 | #define MIN( a, b ) ( ((a) < (b)) ? (a) : (b) ) 105 | #endif 106 | 107 | // bcode *should* be using 2's complement: 108 | #define BCODE_VALUE_MAXIMUM 32767 109 | #define BCODE_VALUE_MINIMUM -32768 110 | 111 | #define SOURCE_TEXT_LINES 2000 112 | #define SOURCE_TEXT_LINE_LENGTH 160 113 | 114 | // TEMPLATES_PER_PLAYER is how many templates each player gets 115 | #define TEMPLATES_PER_PLAYER 10 116 | 117 | #define fpr(...) fprintf(stdout, __VA_ARGS__) 118 | #define adtf(x, y, ...) al_draw_textf(font[FONT_BASIC].fnt, colours.base [COL_YELLOW] [SHADE_MAX], x, y, ALLEGRO_ALIGN_LEFT, __VA_ARGS__) 119 | 120 | 121 | #ifdef __GNUC__ 122 | #define USE_GCC_EXPECT 123 | // Uses GCC's __builtin_expect() for optimising a few things (I haven't tested to make sure this achieves anything) 124 | #endif 125 | 126 | 127 | // Directory management (not currently implemented): 128 | 129 | enum 130 | { 131 | PATH_TYPE_COMPLETE, // the game makes no changes (used for saving/loading files where the correct path should be available from the filechooser or other sources) 132 | PATH_TYPE_MAIN_DIRECTORY, // where the game looks for init.txt 133 | PATH_TYPE_DATA, // the data/ subdirectory 134 | PATH_TYPE_USER, // where the game saves msn.dat 135 | PATH_TYPE_STORY, // the story/ subdirectory 136 | 137 | STANDARD_PATH_TYPES 138 | 139 | }; 140 | 141 | 142 | 143 | #ifndef DIR_DATA 144 | #define DIR_DATA "data/" 145 | #endif 146 | 147 | #ifndef DIR_USER 148 | #define DIR_USER "" 149 | #endif 150 | 151 | #ifndef DIR_STORY 152 | #define DIR_STORY "story/" 153 | #endif 154 | 155 | 156 | 157 | #endif 158 | 159 | 160 | -------------------------------------------------------------------------------- /src/i_buttons.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | 7 | #include "m_config.h" 8 | 9 | #include "e_slider.h" 10 | #include "g_header.h" 11 | #include "m_globvars.h" 12 | #include "m_input.h" 13 | #include "m_maths.h" 14 | #include "i_console.h" 15 | #include "i_display.h" 16 | #include "i_header.h" 17 | #include "i_buttons.h" 18 | 19 | #include "g_misc.h" 20 | 21 | 22 | extern struct vbuf_struct vbuf; 23 | 24 | struct menu_string_struct 25 | { 26 | 27 | const char* str;// [MENU_STRING_LENGTH]; 28 | int x; 29 | int y; 30 | ALLEGRO_COLOR* col; 31 | int align; 32 | int font_index; 33 | int type; 34 | 35 | }; 36 | 37 | struct menu_string_struct menu_string [MENU_STRINGS]; 38 | int menu_string_pos; 39 | 40 | 41 | 42 | extern struct fontstruct font [FONTS]; 43 | 44 | // defined in i_display.c: 45 | //extern ALLEGRO_VERTEX poly_buffer [POLY_BUFFER]; // POLY_BUFFER #defined in i_header.h 46 | //extern int poly_pos; 47 | 48 | static void check_button_buffer(void); 49 | void draw_button_buffer(void); 50 | 51 | 52 | void reset_i_buttons(void) 53 | { 54 | 55 | // poly_pos = 0; 56 | menu_string_pos = 0; 57 | 58 | } 59 | 60 | void add_menu_string(int x, int y, ALLEGRO_COLOR* col, int align, int font_index, const char* str) 61 | { 62 | 63 | if (menu_string_pos >= MENU_STRINGS) 64 | { 65 | fprintf(stdout, "\Error: i_buttons.c: add_menu_string(): menu_string_pos too high (string is [%s]).", str); 66 | error_call(); 67 | } 68 | 69 | // strcpy(menu_string [menu_string_pos].str, str); 70 | menu_string [menu_string_pos].str = str; // this just assigns the pointer! 71 | menu_string [menu_string_pos].x = x; 72 | menu_string [menu_string_pos].y = y; 73 | menu_string [menu_string_pos].align = align; 74 | menu_string [menu_string_pos].font_index = font_index; 75 | menu_string [menu_string_pos].col = col; 76 | 77 | menu_string_pos++; 78 | 79 | } 80 | 81 | 82 | void draw_menu_strings(void) 83 | { 84 | int i; 85 | 86 | for (i = 0; i < menu_string_pos; i ++) 87 | { 88 | al_draw_textf(font[menu_string[i].font_index].fnt, 89 | *menu_string[i].col, 90 | menu_string[i].x, 91 | menu_string[i].y, 92 | menu_string[i].align, 93 | "%s", 94 | menu_string[i].str); 95 | } 96 | 97 | menu_string_pos = 0; 98 | 99 | } 100 | 101 | 102 | void add_menu_button(float xa, float ya, float xb, float yb, ALLEGRO_COLOR col, int button_notch_1, int button_notch_2) 103 | { 104 | 105 | int m = vbuf.vertex_pos_triangle; 106 | 107 | add_tri_vertex(xa, ya + button_notch_1, col); 108 | add_tri_vertex(xa + button_notch_1, ya, col); 109 | add_tri_vertex(xb - button_notch_2, ya, col); 110 | add_tri_vertex(xb, ya + button_notch_2, col); 111 | add_tri_vertex(xb, yb - button_notch_1, col); 112 | add_tri_vertex(xb - button_notch_1, yb, col); 113 | add_tri_vertex(xa + button_notch_2, yb, col); 114 | add_tri_vertex(xa, yb - button_notch_2, col); 115 | 116 | construct_triangle(0, m, m+1, m+7); 117 | construct_triangle(0, m+1, m+2, m+7); 118 | construct_triangle(0, m+2, m+6, m+7); 119 | construct_triangle(0, m+2, m+3, m+6); 120 | construct_triangle(0, m+3, m+5, m+6); 121 | construct_triangle(0, m+3, m+4, m+5); 122 | 123 | check_button_buffer(); 124 | 125 | } 126 | 127 | void add_menu_rectangle(float xa, float ya, float xb, float yb, ALLEGRO_COLOR col) 128 | { 129 | 130 | add_menu_quad(xa, ya, xb, ya, xb, yb, xa, yb, col); 131 | 132 | } 133 | 134 | void add_menu_quad(float xa, float ya, float xb, float yb, float xc, float yc, float xd, float yd, ALLEGRO_COLOR col) 135 | { 136 | 137 | int m = vbuf.vertex_pos_triangle; 138 | 139 | add_tri_vertex(xa, ya, col); 140 | add_tri_vertex(xb, yb, col); 141 | add_tri_vertex(xc, yc, col); 142 | add_tri_vertex(xd, yd, col); 143 | 144 | construct_triangle(0, m, m+1, m+2); 145 | construct_triangle(0, m+2, m+3, m); 146 | 147 | check_button_buffer(); 148 | 149 | } 150 | 151 | 152 | 153 | static void check_button_buffer(void) 154 | { 155 | check_vbuf(); 156 | // if (poly_pos >= POLY_TRIGGER) 157 | // draw_button_buffer(); 158 | 159 | } 160 | 161 | void draw_button_buffer(void) 162 | { 163 | 164 | 165 | draw_vbuf(); 166 | // al_draw_prim(poly_buffer, NULL, NULL, 0, poly_pos, ALLEGRO_PRIM_TRIANGLE_LIST); 167 | // poly_pos = 0; 168 | 169 | } 170 | 171 | 172 | void draw_menu_buttons(void) 173 | { 174 | draw_button_buffer(); 175 | draw_menu_strings(); 176 | reset_i_buttons(); 177 | } 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | -------------------------------------------------------------------------------- /bin/story/green/green3/g5_spikebase.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #process "spikebase" 4 | 5 | class auto_att_spike; 6 | 7 | core_static_hex_B, 0, 8 | {object_spike:auto_att_spike, 0}, 9 | {object_spike:auto_att_spike, 0}, 10 | {object_spike:auto_att_spike, 0}, 11 | {object_repair_other, 0}, 12 | {object_spike:auto_att_spike, 0}, 13 | {object_spike:auto_att_spike, 0} 14 | 15 | #code 16 | 17 | 18 | 19 | 20 | // Process AI modes (these reflect the capabilities of the process) 21 | enum 22 | { 23 | MODE_IDLE, // process isn't doing anything ongoing 24 | MODE_ATTACK, // process has something to attack 25 | MODES 26 | }; 27 | 28 | // Targetting information 29 | // Targetting memory allows processes to track targets (enemy or friend) 30 | // The following enums are used as indices in the process' targetting memory 31 | enum 32 | { 33 | TARGET_PARENT, // a newly built process starts with its builder in address 0 34 | TARGET_MAIN, // main target 35 | }; 36 | 37 | 38 | 39 | int initialised; // set to 1 after initialisation code below run the first time 40 | int mode; 41 | 42 | int target_x, target_y; 43 | int bombard_count; // counter for firing at last known position of target that is no longer visible 44 | int broadcast_count; // counter to prevent too much "target found" broadcast spam 45 | 46 | int self_destruct_count; // if nothing happens for long enough, and there 47 | // are too many processes, will self-destruct. 48 | 49 | 50 | 51 | if (!initialised) 52 | { 53 | // initialisation code goes here (not all autocoded processes have initialisation code) 54 | initialised = 1; 55 | attack_mode(2); // attack objects in each class fire two by two 56 | listen_channel(1); // other processes send "target found" messages on broadcast channel 1 57 | } 58 | 59 | 60 | self_destruct_count ++; 61 | 62 | 63 | // listen for messages (the listen_channel(1) call above allows broadcasts to be received) 64 | if (next_message()) 65 | { 66 | // In this story mission, we can assume that any message is a "target found" broadcast with the following format: 67 | // 0: target_x 68 | // 1: target_y 69 | // + an attached target. 70 | target_x = read_message(); 71 | target_y = read_message(); 72 | get_message_target(TARGET_MAIN); 73 | mode = MODE_ATTACK; 74 | bombard_count = 0; 75 | special_AI(0, 102); 76 | } 77 | 78 | 79 | 80 | switch(mode) 81 | { 82 | 83 | case MODE_ATTACK: 84 | if (process[TARGET_MAIN].visible()) 85 | { 86 | // save the target location so it can be used if the target goes out of visible range. 87 | target_x = process[TARGET_MAIN].get_core_x(); 88 | target_y = process[TARGET_MAIN].get_core_y(); 89 | auto_att_spike.fire_spike_at(TARGET_MAIN, 0); 90 | bombard_count = 0; 91 | if (process[TARGET_MAIN].distance_more(3000)) 92 | mode = MODE_IDLE; 93 | } 94 | else 95 | { 96 | auto_att_spike.fire_spike_xy(target_x, target_y); 97 | bombard_count ++; 98 | if (bombard_count > 32) 99 | mode = MODE_IDLE; 100 | } 101 | break; 102 | 103 | } 104 | 105 | if (scan_for_threat(0, 0, TARGET_MAIN)) 106 | { 107 | target_x = process[TARGET_MAIN].get_core_x(); 108 | target_y = process[TARGET_MAIN].get_core_y(); 109 | auto_att_spike.fire_spike_at(TARGET_MAIN, 0); 110 | bombard_count = 0; 111 | mode = MODE_ATTACK; 112 | // consider letting other nearby processes know that there is a target here: 113 | if (broadcast_count <= 0) 114 | { 115 | 116 | broadcast_target(3000, // range 117 | 1, // channel (see the listen_channel(1) call above) 118 | 0, // priority (0 just means a 1 priority message will overwrite this one) 119 | TARGET_MAIN, // this target is attached to the broadcast. A listener can retrieve it with get_message_target(). 120 | target_x, // message contents. retrieved sequentially by read_message(). 121 | target_y); // message contents 122 | 123 | broadcast_count = 48; 124 | 125 | 126 | 127 | } 128 | 129 | } 130 | 131 | 132 | if (broadcast_count > 0) 133 | broadcast_count --; 134 | 135 | 136 | 137 | if (self_destruct_count > 100 138 | && get_processes_unused() < 10) 139 | terminate; // self-destruct 140 | 141 | restore_scan(0,0); 142 | repair_scan(0,0); 143 | repair_self(); 144 | 145 | 146 | //charge_interface_max(); // charges the process' interface. Since the interface is shared across all 147 | // components with interface objects, this call is not specific to any object or class. 148 | // charge_interface_max() charges the interface using as much power as possible 149 | // (the charge rate is determined by the maximum interface strength). 150 | 151 | exit; // stops execution, until the next cycle 152 | -------------------------------------------------------------------------------- /src/g_method_uni.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | g_method_core.c 4 | 5 | Functions for calls to built-in (core) methods (i.e. ones that don't require an object) 6 | 7 | 8 | */ 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | #include "m_config.h" 16 | 17 | #include "g_header.h" 18 | #include "m_globvars.h" 19 | 20 | #include "g_world.h" 21 | #include "v_interp.h" 22 | #include "m_maths.h" 23 | 24 | #include "g_method.h" 25 | #include "g_method_uni.h" 26 | #include "g_method_misc.h" 27 | #include "c_keywords.h" 28 | 29 | extern struct game_struct game; 30 | extern struct vmstate_struct vmstate; // defined in v_interp.c 31 | 32 | #define UMETHOD_CALL_PARAMETERS 6 33 | 34 | 35 | 36 | struct umethod_call_type_struct umethod_call_type [UMETHOD_CALL_TYPES] = 37 | { 38 | // {int parameters}, 39 | {2, KEYWORD_UMETHOD_SIN}, // *UMETHOD_CALL_SIN (angle, length) 40 | {2, KEYWORD_UMETHOD_COS}, // *UMETHOD_CALL_COS (angle, length) 41 | {2, KEYWORD_UMETHOD_ATAN2}, // *UMETHOD_CALL_ATAN2 (y, x) 42 | {2, KEYWORD_UMETHOD_HYPOT}, // *UMETHOD_CALL_HYPOT (y, x) 43 | // {3}, // UMETHOD_CALL_HYPOT_LESS (y, x, compare_value) 44 | // {3}, // UMETHOD_CALL_HYPOT_MORE (y, x, compare_value) 45 | {0, KEYWORD_UMETHOD_WORLD_X}, // *UMETHOD_CALL_WORLD_X () 46 | {0, KEYWORD_UMETHOD_WORLD_Y}, // *UMETHOD_CALL_WORLD_Y () 47 | {1, KEYWORD_UMETHOD_ABS}, // *UMETHOD_CALL_ABS (value) 48 | {2, KEYWORD_UMETHOD_ANGLE_DIFFERENCE}, // *UMETHOD_CALL_ANGLE_DIFFERENCE (angle1, 2) 49 | {2, KEYWORD_UMETHOD_ARC_LENGTH}, // *UMETHOD_CALL_ARC_LENGTH (angle1, 2) 50 | 51 | 52 | }; 53 | 54 | 55 | // returns 1 if okay to continue, 0 if something happened that should cease program execution (not sure this is currently supported) 56 | s16b call_uni_method(struct core_struct* core, int call_value) 57 | { 58 | 59 | s16b stack_parameters [UMETHOD_CALL_PARAMETERS]; 60 | 61 | if (call_value < 0 62 | || call_value >= UMETHOD_CALL_TYPES) 63 | { 64 | if (w.debug_mode) 65 | print_method_error("invalid universal method call", 1, call_value); 66 | return 0; 67 | } 68 | 69 | // If needed, pull the parameters from the stack: 70 | if (umethod_call_type[call_value].parameters > 0 71 | && !pull_values_from_stack(stack_parameters, umethod_call_type[call_value].parameters)) 72 | { 73 | if (w.debug_mode) 74 | print_method_error("universal method call stack error", 0, 0); 75 | return 0; 76 | } 77 | 78 | switch(call_value) 79 | { 80 | case UMETHOD_CALL_SIN: 81 | vmstate.instructions_left -= 4; 82 | return al_fixtoi(fixed_sin(short_angle_to_fixed(stack_parameters [0])) * (int) stack_parameters [1]); 83 | case UMETHOD_CALL_COS: 84 | vmstate.instructions_left -= 4; 85 | return al_fixtoi(fixed_cos(short_angle_to_fixed(stack_parameters [0])) * (int) stack_parameters [1]); 86 | case UMETHOD_CALL_ATAN2: 87 | vmstate.instructions_left -= INSTRUCTION_COST_ATAN2; // expensive operation 88 | return get_angle_int(stack_parameters [0], stack_parameters [1]); 89 | case UMETHOD_CALL_HYPOT: 90 | vmstate.instructions_left -= INSTRUCTION_COST_HYPOT; // expensive operation 91 | return al_fixtoi(distance(al_itofix(stack_parameters [0]), al_itofix(stack_parameters [1]))); 92 | /* case UMETHOD_CALL_HYPOT_LESS: // avoids the expensive sqrt functions by just comparing squares 93 | { 94 | uint64_t x_dist = stack_parameters [0] * stack_parameters [0]; 95 | uint64_t y_dist = stack_parameters [1] * stack_parameters [1]; 96 | uint64_t compare_value = stack_parameters [2] * stack_parameters [2]; 97 | 98 | if (x_dist + y_dist < compare_value) 99 | return 1; 100 | return 0; 101 | } 102 | case UMETHOD_CALL_HYPOT_MORE: // avoids the expensive sqrt functions by just comparing squares 103 | { 104 | uint64_t x_dist = stack_parameters [0] * stack_parameters [0]; 105 | uint64_t y_dist = stack_parameters [1] * stack_parameters [1]; 106 | uint64_t compare_value = stack_parameters [2] * stack_parameters [2]; 107 | 108 | if (x_dist + y_dist > compare_value) 109 | return 1; 110 | return 0; 111 | }*/ 112 | case UMETHOD_CALL_WORLD_X: 113 | vmstate.instructions_left -= 2; 114 | return w.w_pixels; 115 | case UMETHOD_CALL_WORLD_Y: 116 | vmstate.instructions_left -= 2; 117 | return w.h_pixels; 118 | case UMETHOD_CALL_ABS: 119 | vmstate.instructions_left -= 1; 120 | return abs(stack_parameters [0]); 121 | case UMETHOD_CALL_ANGLE_DIFFERENCE: 122 | vmstate.instructions_left -= 4; 123 | return angle_difference_signed_int(stack_parameters [0], stack_parameters [1]); 124 | case UMETHOD_CALL_ARC_LENGTH: 125 | vmstate.instructions_left -= 4; 126 | return angle_difference_int(stack_parameters [0] & ANGLE_MASK, stack_parameters [1] & ANGLE_MASK); 127 | 128 | } 129 | 130 | return 0; 131 | 132 | } 133 | 134 | 135 | -------------------------------------------------------------------------------- /bin/story/green/green2/g4_spikebase.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #process "spikebase" 4 | 5 | class auto_att_spike; 6 | 7 | core_static_hex_B, 0, 8 | {object_spike:auto_att_spike, 0}, 9 | {object_spike:auto_att_spike, 0}, 10 | {object_spike:auto_att_spike, 0}, 11 | {object_downlink, 0, 12 | {component_fork, // component 1 13 | {object_uplink, 0}, 14 | {object_interface, 0}, 15 | {object_interface, 0}, 16 | } 17 | }, 18 | {object_spike:auto_att_spike, 0}, 19 | {object_spike:auto_att_spike, 0} 20 | 21 | #code 22 | 23 | 24 | 25 | 26 | // Process AI modes (these reflect the capabilities of the process) 27 | enum 28 | { 29 | MODE_IDLE, // process isn't doing anything ongoing 30 | MODE_ATTACK, // process has something to attack 31 | MODES 32 | }; 33 | 34 | // Targetting information 35 | // Targetting memory allows processes to track targets (enemy or friend) 36 | // The following enums are used as indices in the process' targetting memory 37 | enum 38 | { 39 | TARGET_PARENT, // a newly built process starts with its builder in address 0 40 | TARGET_MAIN, // main target 41 | }; 42 | 43 | 44 | 45 | int initialised; // set to 1 after initialisation code below run the first time 46 | int mode; 47 | 48 | int target_x, target_y; 49 | int bombard_count; // counter for firing at last known position of target that is no longer visible 50 | int broadcast_count; // counter to prevent too much "target found" broadcast spam 51 | 52 | int self_destruct_count; // if nothing happens for long enough, and there 53 | // are too many processes, will self-destruct. 54 | 55 | 56 | 57 | if (!initialised) 58 | { 59 | // initialisation code goes here (not all autocoded processes have initialisation code) 60 | initialised = 1; 61 | attack_mode(2); // attack objects in each class fire two by two 62 | listen_channel(1); // other processes send "target found" messages on broadcast channel 1 63 | special_AI(0, 102); 64 | } 65 | 66 | 67 | self_destruct_count ++; 68 | 69 | 70 | // listen for messages (the listen_channel(1) call above allows broadcasts to be received) 71 | if (next_message()) 72 | { 73 | // In this story mission, we can assume that any message is a "target found" broadcast with the following format: 74 | // 0: target_x 75 | // 1: target_y 76 | // + an attached target. 77 | target_x = read_message(); 78 | target_y = read_message(); 79 | get_message_target(TARGET_MAIN); 80 | mode = MODE_ATTACK; 81 | bombard_count = 0; 82 | } 83 | 84 | 85 | 86 | switch(mode) 87 | { 88 | 89 | case MODE_ATTACK: 90 | if (process[TARGET_MAIN].visible()) 91 | { 92 | // save the target location so it can be used if the target goes out of visible range. 93 | target_x = process[TARGET_MAIN].get_core_x(); 94 | target_y = process[TARGET_MAIN].get_core_y(); 95 | auto_att_spike.fire_spike_at(TARGET_MAIN, 0); 96 | bombard_count = 0; 97 | if (process[TARGET_MAIN].distance_more(3000)) 98 | mode = MODE_IDLE; 99 | } 100 | else 101 | { 102 | auto_att_spike.fire_spike_xy(target_x, target_y); 103 | bombard_count ++; 104 | if (bombard_count > 32) 105 | mode = MODE_IDLE; 106 | } 107 | break; 108 | 109 | } 110 | 111 | if (scan_for_threat(0, 0, TARGET_MAIN)) 112 | { 113 | target_x = process[TARGET_MAIN].get_core_x(); 114 | target_y = process[TARGET_MAIN].get_core_y(); 115 | auto_att_spike.fire_spike_at(TARGET_MAIN, 0); 116 | bombard_count = 0; 117 | mode = MODE_ATTACK; 118 | // consider letting other nearby processes know that there is a target here: 119 | if (broadcast_count <= 0) 120 | { 121 | 122 | broadcast_target(3000, // range 123 | 1, // channel (see the listen_channel(1) call above) 124 | 0, // priority (0 just means a 1 priority message will overwrite this one) 125 | TARGET_MAIN, // this target is attached to the broadcast. A listener can retrieve it with get_message_target(). 126 | target_x, // message contents. retrieved sequentially by read_message(). 127 | target_y); // message contents 128 | 129 | broadcast_count = 48; 130 | 131 | 132 | 133 | } 134 | 135 | } 136 | 137 | 138 | if (broadcast_count > 0) 139 | broadcast_count --; 140 | 141 | 142 | 143 | if (self_destruct_count > 100 144 | && get_processes_unused() < 10) 145 | terminate; // self-destruct 146 | 147 | 148 | charge_interface_max(); // charges the process' interface. Since the interface is shared across all 149 | // components with interface objects, this call is not specific to any object or class. 150 | // charge_interface_max() charges the interface using as much power as possible 151 | // (the charge rate is determined by the maximum interface strength). 152 | 153 | exit; // stops execution, until the next cycle 154 | -------------------------------------------------------------------------------- /bin/story/blue/blue1/wander2.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #process "wander2" 4 | 5 | class auto_move; 6 | class auto_att_main; 7 | class auto_att_right; 8 | class auto_att_left; 9 | 10 | core_pent_A, 0, 11 | {object_repair, 0}, 12 | {object_downlink, -19, 13 | {component_prong, // component 1 14 | {object_burst_l:auto_att_main, 1034}, 15 | {object_pulse:auto_att_right, 1069}, 16 | {object_uplink, 0}, 17 | {object_move:auto_move, 2048}, 18 | } 19 | }, 20 | {object_move:auto_move, 946}, 21 | {object_move:auto_move, -946}, 22 | {object_downlink, 19, 23 | {component_prong, // component 2 24 | {object_pulse:auto_att_left, -1069}, 25 | {object_burst_l:auto_att_main, -1034}, 26 | {object_move:auto_move, -2048}, 27 | {object_uplink, -567}, 28 | } 29 | }, 30 | 31 | #code 32 | 33 | 34 | 35 | 36 | // Process AI modes (these reflect the capabilities of the process) 37 | enum 38 | { 39 | MODE_WANDER, 40 | MODE_ATTACK, 41 | MODES 42 | }; 43 | 44 | 45 | // Targetting information 46 | // Targetting memory allows processes to track targets (enemy or friend) 47 | // The following enums are used as indices in the process' targetting memory 48 | enum 49 | { 50 | TARGET_PARENT, // a newly built process starts with its builder as entry 0 51 | TARGET_MAIN, // main target 52 | TARGET_LEFT, 53 | TARGET_RIGHT 54 | }; 55 | 56 | 57 | 58 | // Variable declaration and initialisation 59 | // (note that declaration and initialisation cannot be combined) 60 | // (also, variables retain their values between execution cycles) 61 | int core_x, core_y; // location of core 62 | core_x = get_core_x(); // location is updated each cycle 63 | core_y = get_core_y(); 64 | int angle; // direction process is pointing 65 | // angles are in integer degrees from 0 to 8192, with 0 being right, 66 | // 2048 down, 4096 left and 6144 up. 67 | angle = get_core_angle(); // angle is updated each cycle 68 | 69 | int mode; // what is the process doing? (should be one of the MODE enums) 70 | 71 | int move_x, move_y; // destination 72 | 73 | 74 | int initialised; 75 | if (initialised == 0) 76 | { 77 | initialised = 1; 78 | attack_mode(1); 79 | special_AI(0, 7); 80 | gosub start_wandering; 81 | } 82 | 83 | // What the process does next depends on its current mode 84 | switch(mode) 85 | { 86 | 87 | 88 | case MODE_WANDER: 89 | if (distance_from_xy(move_x, move_y) < 300) 90 | { 91 | gosub start_wandering; 92 | break; 93 | } 94 | if (scan_for_threat(0, 0, TARGET_MAIN)) 95 | { 96 | mode = MODE_ATTACK; 97 | special_AI(1, 1); 98 | // no break; falls through to attack case below 99 | } 100 | else 101 | { 102 | auto_move.move_to(move_x, move_y); 103 | break; 104 | } 105 | // fall through... 106 | case MODE_ATTACK: 107 | if (process[TARGET_MAIN].visible() <= 0) // target no longer exists, or is out of range 108 | { 109 | if (target_destroyed(TARGET_MAIN)) 110 | special_AI(1, 2); 111 | gosub start_wandering; // give up and go back to wandering around randomly 112 | break; 113 | } 114 | 115 | auto_move.approach_track(TARGET_MAIN, 0, auto_att_main, 700); // calls approach_track() on all objects in the auto_move class. 116 | // Parameters are: 117 | // - target's address in targetting memory 118 | // - component of target process to attack (0 means the core) 119 | // - class of attacking object (the first object in the class will be used) 120 | // - approach distance (in pixels) 121 | // approach_track() is a bit like intercept() (which aims at the target, with target-leading, and 122 | // moves towards it) but tries to maintain a certain distance from the target (the approach distance). 123 | // Because this process has retro move objects it can back away while attacking. 124 | if (process[TARGET_MAIN].distance_less(1000)) 125 | auto_att_main.fire(8); // tries to fire one object in the auto_att_main class. 8 is firing delay (in ticks) 126 | // (here, the auto_att_main class is for fixed attack objects that point more or less forwards) 127 | // fire_1() can be better than just fire() because it spreads out the power use 128 | break; // end of case MODE_ATTACK 129 | 130 | } // end of mode switch 131 | 132 | 133 | auto_att_left.attack_scan(-3000, 400, TARGET_LEFT); 134 | auto_att_right.attack_scan(3000, 400, TARGET_RIGHT); 135 | 136 | 137 | //if (get_power_left() > 30) 138 | repair_self(); // tries to repair any damaged components 139 | 140 | //if (get_power_left() > 30) 141 | restore_self(); // tries to restore any destroyed components 142 | 143 | 144 | 145 | 146 | exit; // halts execution (until the next cycle) 147 | 148 | 149 | start_wandering: 150 | mode = MODE_WANDER; 151 | // set the target location anywhere that's not too close to the edge of the map: 152 | move_x = 800 + random(world_x() - 1600); // (world_x/y() return size of map 153 | move_y = 800 + random(world_y() - 1600); 154 | return; // jumps back to the statement just after the gosub 155 | --------------------------------------------------------------------------------