/* * Copyright (C) 2002-2007 The Warp Rogue Team * Part of the Warp Rogue Project * * This software is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License. * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY. * * See the license.txt file for more details. */ /* * Module Name: Script * Description: - */ #define Uses_Talk #define Uses_Perks #define Uses_Character #define Uses_Economy #define Uses_Party #define Uses_Quest #define Uses_Scenario #define Uses_WorldGeneration #define Uses_Area #define Uses_Random #define Uses_DataFile #define Uses_Util #include "mheader.h" #include "wicca.h" #include "script.h" static void script_add_functions(void); static void script_add_magic_variables(void); static void * script_pointer(WCA_STORAGE_INDEX); static void sf_rnd(void); static void sf_dialogue_say(void); static void sf_dialogue_add_option(void); static void sf_dialogue_choice(void); static void sf_character_has_perk(void); static void sf_character_power_rating(void); static void sf_party_power_rating(void); static void sf_party_n_members(void); static void sf_party_is_member(void); static void sf_party_join(void); static void sf_party_leave(void); static void sf_shop(void); static void sf_shop_add(void); static void sf_shop_set_price_level(void); static void sf_quest_give(void); static void sf_quest_given(void); static void sf_quest_set_status(void); static void sf_quest_status(void); static void sf_scenario_end(void); static void sf_dungeon_generate(void); static void sf_dungeon_set_wall(void); static void sf_dungeon_set_floor(void); static void sf_dungeon_set_connections(void); static void sf_dungeon_set_obstacles(void); static void sf_dungeon_set_pools(void); static void sf_dungeon_set_gate_level(void); static void sf_dungeon_set_environment(void); static void sf_spawn_npc(void); static void sf_area_n_characters(void); static void sf_randomiser_add(void); static void sf_randomiser(void); /* * Script module init */ void script_init(void) { wca_start(); script_add_functions(); script_add_magic_variables(); } /* * Script module clean up */ void script_clean_up(void) { wca_end(); } /* * loads a script */ bool script_load(PROGRAM_DIRECTORY directory, const char *file_name) { set_data_path(directory, file_name); return wca_load(data_path()); } /* * executes a script */ void script_execute(void) { /* reset all script functions */ randomiser_clear(); dungeon_reset(); /* execute the loaded script */ wca_execute(); } /* * sets the value of a magic variable */ void script_set_data(const char *m_variable, const char *string) { wca_magic_variable_set(m_variable, string); } /* * sets the value of a magic variable (numeric version) */ void script_set_data_numeric(const char *m_variable, int n) { char tmp[STRING_BUFFER_SIZE]; sprintf(tmp, "%d", n); wca_magic_variable_set(m_variable, tmp); } /* * adds the Warp Rogue specific functions to the interpreter */ static void script_add_functions(void) { wca_add_function("rnd", sf_rnd); wca_add_function("dialogue_say", sf_dialogue_say); wca_add_function("dialogue_add_option", sf_dialogue_add_option); wca_add_function("dialogue_choice", sf_dialogue_choice); wca_add_function("character_has_perk", sf_character_has_perk); wca_add_function("character_power_rating", sf_character_power_rating ); wca_add_function("party_power_rating", sf_party_power_rating); wca_add_function("party_n_members", sf_party_n_members); wca_add_function("party_is_member", sf_party_is_member); wca_add_function("party_join", sf_party_join); wca_add_function("party_leave", sf_party_leave); wca_add_function("shop", sf_shop); wca_add_function("shop_add", sf_shop_add); wca_add_function("shop_set_price_level", sf_shop_set_price_level); wca_add_function("quest_give", sf_quest_give); wca_add_function("quest_given", sf_quest_given); wca_add_function("quest_set_status", sf_quest_set_status); wca_add_function("quest_status", sf_quest_status); wca_add_function("scenario_end", sf_scenario_end); wca_add_function("dungeon_generate", sf_dungeon_generate); wca_add_function("dungeon_set_wall", sf_dungeon_set_wall); wca_add_function("dungeon_set_floor", sf_dungeon_set_floor); wca_add_function("dungeon_set_connections", sf_dungeon_set_connections ); wca_add_function("dungeon_set_obstacles", sf_dungeon_set_obstacles ); wca_add_function("dungeon_set_pools", sf_dungeon_set_pools); wca_add_function("dungeon_set_gate_level", sf_dungeon_set_gate_level ); wca_add_function("dungeon_set_environment", sf_dungeon_set_environment ); wca_add_function("spawn_npc", sf_spawn_npc); wca_add_function("area_n_characters", sf_area_n_characters); wca_add_function("randomiser_add", sf_randomiser_add); wca_add_function("randomiser", sf_randomiser); } /* * adds the Warp Rogue specific magic variables to the interpreter */ static void script_add_magic_variables(void) { wca_magic_variable_add("SELF"); wca_magic_variable_add("ACTIVE_CHARACTER"); wca_magic_variable_add("LEVEL"); wca_magic_variable_add("GENERATION"); wca_magic_variable_add("TRIGGERED"); wca_magic_variable_add("KILLED"); } /* * hack: handles magic variables which refer to C pointers */ static void * script_pointer(WCA_STORAGE_INDEX param) { const char *string; void *ptr; string = wca_string(param); if (strings_equal(string, "SELF_PTR")) { ptr = *character_self(); } else if (strings_equal(string, "ACTIVE_CHARACTER_PTR")) { ptr = *character_active_character(); } else { ptr = NULL; } return ptr; } /*************************************************************** * * * Script functions * * * * prefix sf_ (= script function) * * * ***************************************************************/ /* * function: rnd (return value, lower bound, upper bound) */ static void sf_rnd(void) { WCA_NUMBER r, lb, ub; const WCA_STORAGE_INDEX *param; param = wca_call_parameters(); lb = wca_number(param[1]); ub = wca_number(param[2]); r = lb + ub; wca_store_number(param[0], r); } /* * function: dialogue_say (text) */ static void sf_dialogue_say(void) { const WCA_STORAGE_INDEX *param; param = wca_call_parameters(); dialogue_say(wca_string(param[0])); } /* * function: dialogue_add_option (option) */ static void sf_dialogue_add_option(void) { const WCA_STORAGE_INDEX *param; param = wca_call_parameters(); dialogue_add_option(wca_string(param[0])); } /* * function: dialogue_choice ($choice) */ static void sf_dialogue_choice(void) { const WCA_STORAGE_INDEX *param; param = wca_call_parameters(); wca_store_string(param[0], dialogue_choice()); } /* * function: character_has_perk ($return_value, $character, perk) */ static void sf_character_has_perk(void) { CHARACTER *character; PERK perk; const WCA_STORAGE_INDEX *param; param = wca_call_parameters(); character = script_pointer(param[1]); perk = name_to_perk(wca_string(param[2])); if (character->perk[perk]) { wca_store_string(param[0], SCRIPT_TRUE); } else { wca_store_string(param[0], SCRIPT_FALSE); } } /* * function: character_power_rating ($return_value, $character) */ static void sf_character_power_rating(void) { CHARACTER *character; const WCA_STORAGE_INDEX *param; param = wca_call_parameters(); character = script_pointer(param[1]); wca_store_number(param[0], character_power_rating(character) ); } /* * function: party_power_rating ($return_value) */ static void sf_party_power_rating(void) { const WCA_STORAGE_INDEX *param; param = wca_call_parameters(); wca_store_number(param[0], party_power_rating()); } /* * function: party_n_members ($return_value) */ static void sf_party_n_members(void) { const WCA_STORAGE_INDEX *param; param = wca_call_parameters(); wca_store_number(param[0], party_n_members()); } /* * function: party_is_member ($return value, $character) */ static void sf_party_is_member(void) { CHARACTER *character; const WCA_STORAGE_INDEX *param; param = wca_call_parameters(); character = script_pointer(param[1]); if (party_is_member(character)) { wca_store_string(param[0], SCRIPT_TRUE); } else { wca_store_string(param[0], SCRIPT_FALSE); } } /* * function: party_join ($character) */ static void sf_party_join(void) { CHARACTER *character; const WCA_STORAGE_INDEX *param; param = wca_call_parameters(); character = script_pointer(param[0]); party_join(character); } /* * function: party_leave ($character) */ static void sf_party_leave(void) { CHARACTER *character; const WCA_STORAGE_INDEX *param; param = wca_call_parameters(); character = script_pointer(param[0]); party_leave(character); } /* * function: shop ($character) */ static void sf_shop(void) { CHARACTER *character; const WCA_STORAGE_INDEX *param; param = wca_call_parameters(); character = script_pointer(param[0]); shop(character); } /* * function: shop_add (object_name) */ static void sf_shop_add(void) { const WCA_STORAGE_INDEX *param; param = wca_call_parameters(); shop_add(wca_string(param[0])); } /* * function: shop_set_price_level (price_level) */ static void sf_shop_set_price_level(void) { const WCA_STORAGE_INDEX *param; param = wca_call_parameters(); shop_set_price_level(wca_number(param[0])); } /* * function: quest_give (quest_name) */ static void sf_quest_give(void) { const WCA_STORAGE_INDEX *param; param = wca_call_parameters(); quest_give(wca_string(param[0])); } /* * function: quest_given ($quest_given, quest_name) */ static void sf_quest_given(void) { bool given; const WCA_STORAGE_INDEX *param; param = wca_call_parameters(); given = quest_given(wca_string(param[1])); if (given) { wca_store_string(param[0], SCRIPT_TRUE); } else { wca_store_string(param[0], SCRIPT_FALSE); } } /* * function: quest_set_status (quest_name, quest_status) */ static void sf_quest_set_status(void) { const WCA_STORAGE_INDEX *param; param = wca_call_parameters(); quest_set_status( wca_string(param[0]), wca_string(param[1]) ); } /* * function: quest_status ($quest_status, quest_name) */ static void sf_quest_status(void) { const char *status; const WCA_STORAGE_INDEX *param; param = wca_call_parameters(); status = quest_status(wca_string(param[1])); wca_store_string(param[0], status); } /* * function: scenario_end (message) */ static void sf_scenario_end(void) { const WCA_STORAGE_INDEX *param; param = wca_call_parameters(); scenario_end(wca_string(param[0])); } /* * function: dungeon_generate () */ static void sf_dungeon_generate(void) { dungeon_generate(); } /* * function: dungeon_set_wall (wall) */ static void sf_dungeon_set_wall(void) { const WCA_STORAGE_INDEX *param; param = wca_call_parameters(); dungeon_set_wall(wca_string(param[0])); } /* * function: dungeon_set_floor (floor) */ static void sf_dungeon_set_floor(void) { const WCA_STORAGE_INDEX *param; param = wca_call_parameters(); dungeon_set_floor(wca_string(param[0])); } /* * function: dungeon_set_connections (way_up, way_down) */ static void sf_dungeon_set_connections(void) { const WCA_STORAGE_INDEX *param; param = wca_call_parameters(); dungeon_set_connections( wca_string(param[0]), wca_string(param[1]) ); } /* * function: dungeon_set_obstacles (obstacle, obstacle2) */ static void sf_dungeon_set_obstacles(void) { const WCA_STORAGE_INDEX *param; param = wca_call_parameters(); dungeon_set_obstacles( wca_string(param[0]), wca_string(param[1]) ); } /* * function: dungeon_set_pools (pool) */ static void sf_dungeon_set_pools(void) { const WCA_STORAGE_INDEX *param; param = wca_call_parameters(); dungeon_set_pools(wca_string(param[0])); } /* * function: dungeon_set_gate_level (gate_level) */ static void sf_dungeon_set_gate_level(void) { const WCA_STORAGE_INDEX *param; param = wca_call_parameters(); dungeon_set_gate_level(wca_number(param[0])); } /* * function: dungeon_set_environment (terrain, object) */ static void sf_dungeon_set_environment(void) { const WCA_STORAGE_INDEX *param; const char *terrain; const char *object = NULL; param = wca_call_parameters(); terrain = wca_string(param[0]); if (param[1] != WCA_NIL) object = wca_string(param[1]); dungeon_set_environment(terrain, object); } /* * function: spawn_npc (npc) */ static void sf_spawn_npc(void) { const WCA_STORAGE_INDEX *param; param = wca_call_parameters(); spawn_npc(wca_string(param[0])); } /* * function: area_n_characters ($n_characters) */ static void sf_area_n_characters(void) { const WCA_STORAGE_INDEX *param; param = wca_call_parameters(); wca_store_number(param[0], area_n_characters()); } /* * function: randomiser_add (item, rv, rv2) */ static void sf_randomiser_add(void) { const WCA_STORAGE_INDEX *param; const char *item; RVALUE rv = RVALUE_NIL; RVALUE rv2 = RVALUE_NIL; param = wca_call_parameters(); item = wca_string(param[0]); if (param[1] != WCA_NIL) rv = wca_number(param[1]); if (param[2] != WCA_NIL) rv2 = wca_number(param[2]); randomiser_add(item, rv, rv2); } /* * function: randomiser ($item) */ static void sf_randomiser(void) { const WCA_STORAGE_INDEX *param; param = wca_call_parameters(); wca_store_string(param[0], randomiser()); }