<URL: http://bugs.freeciv.org/Ticket/Display.html?id=17187 >
Updated the patch to the latest revision trunk. The patch is almost ready but depends on #39450: Make rule names available in the scripting api; right now there is no way to tell the user "Your %s was killed by barbarians" Expanded the patch slightly by porting hut_get_barbarians to Lua, using a new method Tile:city_exists_within_city_radius and a new action barbarian_uprising(tile) Added a copyright header to the script.lua file since it now has a substantial amount of code; I hope that it is correct.
Index: server/scripting/api_actions.h =================================================================== --- server/scripting/api_actions.h (revision 13086) +++ server/scripting/api_actions.h (arbetskopia) @@ -16,6 +16,7 @@ #include "api_types.h" +bool api_unleash_barbarians(Tile *ptile); Unit *api_actions_create_unit(Player *pplayer, Tile *ptile, Unit_Type *ptype, int veteran_level, City *homecity, int moves_left); Index: server/scripting/api_methods.h =================================================================== --- server/scripting/api_methods.h (revision 13086) +++ server/scripting/api_methods.h (arbetskopia) @@ -16,12 +16,17 @@ #include "api_types.h" +bool api_methods_unit_city_can_be_built_here(Unit *punit); + int api_methods_player_num_cities(Player *pplayer); int api_methods_player_num_units(Player *pplayer); bool api_methods_unit_type_has_flag(Unit_Type *punit_type, const char *flag); bool api_methods_unit_type_has_role(Unit_Type *punit_type, const char *role); +bool api_methods_tile_city_exists_within_city_radius(Tile *ptile, + bool may_be_on_center); + bool api_methods_building_type_is_wonder(Building_Type *pbuilding); bool api_methods_building_type_is_great_wonder(Building_Type *pbuilding); bool api_methods_building_type_is_small_wonder(Building_Type *pbuilding); Index: server/scripting/api.pkg =================================================================== --- server/scripting/api.pkg (revision 13086) +++ server/scripting/api.pkg (arbetskopia) @@ -94,6 +94,7 @@ /* Class methods. */ + int api_methods_player_num_cities @ methods_player_num_cities (Player *pplayer); int api_methods_player_num_units @@ -103,7 +104,12 @@ @ methods_unit_type_has_flag (Unit_Type *punit_type, const char *flag); bool api_methods_unit_type_has_role @ methods_unit_type_has_role (Unit_Type *punit_type, const char *role); +bool api_methods_unit_city_can_be_built_here + @ methods_unit_city_can_be_built_here (Unit *punit); +bool api_methods_tile_city_exists_within_city_radius + @ methods_tile_city_exists_within_city_radius (Tile *ptile, bool center); + bool api_methods_building_type_is_wonder @ methods_building_type_is_wonder (Building_Type *pbuilding); bool api_methods_building_type_is_great_wonder @@ -133,6 +139,15 @@ return find.city(self.owner, self.homecity_id) end +function Unit:is_on_possible_city_tile() + return methods_unit_city_can_be_built_here(self) +end + +-- Tile methods +function Tile:city_exists_within_city_radius(center) + return methods_tile_city_exists_within_city_radius(self, center) +end + -- Building_Type methods. function Building_Type:build_shield_cost() return self.build_cost @@ -402,4 +417,4 @@ void api_actions_change_gold @ change_gold (Player *pplayer, int amount); Tech_Type *api_actions_give_technology @ give_technology (Player *pplayer, Tech_Type *ptech); - +bool api_unleash_barbarians @ unleash_barbarians (Tile *ptile); Index: server/scripting/api_actions.c =================================================================== --- server/scripting/api_actions.c (revision 13086) +++ server/scripting/api_actions.c (arbetskopia) @@ -15,6 +15,7 @@ #include <config.h> #endif +#include "barbarian.h" #include "plrhand.h" #include "citytools.h" #include "techtools.h" @@ -26,6 +27,14 @@ /************************************************************************** + Unleash barbarians on a tile, for example from a hut +**************************************************************************/ +bool api_unleash_barbarians(Tile *ptile) +{ + return unleash_barbarians(ptile); +} + +/************************************************************************** Create a new unit. **************************************************************************/ Unit *api_actions_create_unit(Player *pplayer, Tile *ptile, Unit_Type *ptype, Index: server/scripting/api_methods.c =================================================================== --- server/scripting/api_methods.c (revision 13086) +++ server/scripting/api_methods.c (arbetskopia) @@ -21,6 +21,14 @@ #include "script.h" /************************************************************************** + Can punit found a city on its tile? +**************************************************************************/ +bool api_methods_unit_city_can_be_built_here(Unit *punit) +{ + return city_can_be_built_here(punit->tile, punit); +} + +/************************************************************************** Return the number of cities pplayer has. **************************************************************************/ int api_methods_player_num_cities(Player *pplayer) @@ -67,6 +75,16 @@ } /************************************************************************** + Return TRUE there is a city inside city radius from ptile +**************************************************************************/ + +bool api_methods_tile_city_exists_within_city_radius(Tile *ptile, + bool may_be_on_center) +{ + return city_exists_within_city_radius(ptile, may_be_on_center); +} + +/************************************************************************** Return TRUE if pbuilding is a wonder. **************************************************************************/ bool api_methods_building_type_is_wonder(Building_Type *pbuilding) Index: server/barbarian.c =================================================================== --- server/barbarian.c (revision 13086) +++ server/barbarian.c (arbetskopia) @@ -57,14 +57,6 @@ #define BARBARIAN_INITIAL_VISION_RADIUS 3 #define BARBARIAN_INITIAL_VISION_RADIUS_SQ 9 -/* - IDEAS: - 1. Unrest factors configurable via rulesets (distance and gov factor) - 2. Separate nations for Sea Raiders and Land Barbarians - - - are these good ideas ?????? -*/ - /************************************************************************** Is player a land barbarian? **************************************************************************/ Index: server/barbarian.h =================================================================== --- server/barbarian.h (revision 13086) +++ server/barbarian.h (arbetskopia) @@ -32,5 +32,6 @@ bool unleash_barbarians(struct tile *ptile); void summon_barbarians(void); bool is_land_barbarian(struct player *pplayer); +bool hut_get_barbarians(struct unit *punit); #endif /* FC__BARBARIAN_H */ Index: server/unittools.c =================================================================== --- server/unittools.c (revision 13086) +++ server/unittools.c (arbetskopia) @@ -2242,119 +2242,6 @@ } /************************************************************************** - Get gold from entering a hut. -**************************************************************************/ -static void hut_get_gold(struct unit *punit, int cred) -{ - struct player *pplayer = unit_owner(punit); - notify_player(pplayer, punit->tile, E_HUT_GOLD, - _("You found %d gold."), cred); - pplayer->economic.gold += cred; -} - -/************************************************************************** - Get a tech from entering a hut. -**************************************************************************/ -static void hut_get_tech(struct unit *punit) -{ - struct player *pplayer = unit_owner(punit); - Tech_type_id new_tech; - const char* tech_name; - - new_tech = give_random_free_tech(pplayer); - - tech_name = advance_name_for_player(pplayer, new_tech); - notify_player(pplayer, punit->tile, E_HUT_TECH, - _("You found %s in ancient scrolls of wisdom."), - tech_name); - script_signal_emit("tech_researched", 3, - API_TYPE_TECH_TYPE, &advances[new_tech], - API_TYPE_PLAYER, pplayer, - API_TYPE_STRING, "hut"); - notify_embassies(pplayer, NULL, NULL, E_TECH_GAIN, - _("The %s have acquired %s" - " from ancient scrolls of wisdom."), - nation_plural_for_player(pplayer), - tech_name); -} - -/************************************************************************** - Get a mercenary unit from entering a hut. -**************************************************************************/ -static void hut_get_mercenaries(struct unit *punit) -{ - struct player *pplayer = unit_owner(punit); - - notify_player(pplayer, punit->tile, E_HUT_MERC, - _("A band of friendly mercenaries joins your cause.")); - (void) create_unit(pplayer, punit->tile, - find_a_unit_type(L_HUT, L_HUT_TECH), FALSE, - punit->homecity, -1); -} - -/************************************************************************** - Get barbarians from hut, unless close to a city. - Unit may die: returns 1 if unit is alive after, or 0 if it was killed. -**************************************************************************/ -static bool hut_get_barbarians(struct unit *punit) -{ - struct player *pplayer = unit_owner(punit); - bool ok = TRUE; - - if (city_exists_within_city_radius(punit->tile, TRUE) - || unit_has_type_flag(punit, F_GAMELOSS)) { - notify_player(pplayer, punit->tile, E_HUT_BARB_CITY_NEAR, - _("An abandoned village is here.")); - } else { - /* save coords and type in case unit dies */ - struct tile *unit_tile = punit->tile; - struct unit_type *type = unit_type(punit); - - ok = unleash_barbarians(unit_tile); - - if (ok) { - notify_player(pplayer, unit_tile, E_HUT_BARB, - _("You have unleashed a horde of barbarians!")); - } else { - notify_player(pplayer, unit_tile, E_HUT_BARB_KILLED, - _("Your %s has been killed by barbarians!"), - utype_name_translation(type)); - } - } - return ok; -} - -/************************************************************************** - Get new city from hut, or settlers (nomads) if terrain is poor. -**************************************************************************/ -static void hut_get_city(struct unit *punit) -{ - struct player *pplayer = unit_owner(punit); - - if (city_can_be_built_here(punit->tile, punit)) { - notify_player(pplayer, punit->tile, E_HUT_CITY, - _("You found a friendly city.")); - create_city(pplayer, punit->tile, - city_name_suggestion(pplayer, punit->tile)); - - if (unit_has_type_flag(punit, F_CITIES) || unit_has_type_flag(punit, F_SETTLERS)) { - /* In case city was found during autosettler activities */ - initialize_infrastructure_cache(pplayer); - } - - /* Init ai.choice. Handling ferryboats might use it. */ - init_choice(&punit->tile->city->ai.choice); - - } else { - notify_player(pplayer, punit->tile, E_HUT_SETTLER, - _("Friendly nomads are impressed by you," - " and join you.")); - (void) create_unit(pplayer, punit->tile, get_role_unit(F_CITIES,0), - 0, punit->homecity, -1); - } -} - -/************************************************************************** Return 1 if unit is alive, and 0 if it was killed **************************************************************************/ static bool unit_enter_hut(struct unit *punit) @@ -2386,34 +2273,6 @@ script_signal_emit("hut_enter", 1, API_TYPE_UNIT, punit); - switch (hut_chance) { - case 0: - hut_get_gold(punit, 25); - break; - case 1: case 2: case 3: - hut_get_gold(punit, 50); - break; - case 4: - hut_get_gold(punit, 100); - break; - case 5: case 6: case 7: - hut_get_tech(punit); - break; - case 8: case 9: - if (num_role_units(L_HUT) != 0) { - hut_get_mercenaries(punit); - } else { - hut_get_gold(punit, 25); - } - break; - case 10: - ok = hut_get_barbarians(punit); - break; - case 11: - hut_get_city(punit); - break; - } - send_player_info(pplayer, pplayer); /* eg, gold */ return ok; } Index: data/default/script.lua =================================================================== --- data/default/script.lua (revision 13086) +++ data/default/script.lua (arbetskopia) @@ -1,8 +1,116 @@ --- Callbacks +-- Freeciv - Copyright (C) 2007 - The Freeciv Project +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2, or (at your option) +-- any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. + +function hut_get_gold(unit, gold) + local owner = unit.owner + + notify.event(owner, unit.tile, E.HUT_GOLD, _("You found %d gold."), gold) + change_gold(owner, gold) +end + +function hut_get_tech(unit) + local owner = unit.owner + local tech = give_technology(owner, nil) + + if tech then + notify.event(owner, unit.tile, E.HUT_TECH, + _("You found %s in ancient scrolls of wisdom."), + tech.name) + notify.embassies(owner, unit.tile, E.HUT_TECH, + _("The %s have acquired %s from ancient scrolls of\ + wisdom."), + owner.nation.name_plural, tech.name) + return true + else + return false + end +end + +function hut_get_mercenaries(unit) + local type = find.unit_type('Legion') + + if type then + local owner = unit.owner + + notify.event(owner, unit.tile, E.HUT_MERC, + _("A band of friendly mercenaries joins your cause.")) + create_unit(owner, unit.tile, type, 0, unit:homecity(), -1) + return true + else + return false + end +end + +function hut_get_city(unit) + local owner = unit.owner + local settlers = find.unit_type('Settlers') + + if unit:is_on_possible_city_tile() then + create_city(owner, unit.tile, nil) + notify.event(owner, unit.tile, E.HUT_CITY, + _("You found a friendly city.")) + else + create_unit(owner, unit.tile, settlers, 0, unit:homecity(), -1) + notify.event(owner, unit.tile, E.HUT_SETTLER, + _("Friendly nomads are impressed by you, and join you.")) + end +end + +function hut_get_barbarians(unit) + local tile = unit.tile + local type = unit.utype + local owner = unit.owner + if unit.tile:city_exists_within_city_radius(true) + or type:has_flag('Gameloss') then + notify.event(owner, unit.tile, E.HUT_BARB_CITY_NEAR, + _("An abandoned village is here.")) + else + local alive = unleash_barbarians(tile) + if alive then + notify.event(owner, tile, E.HUT_BARB, + _("You have unleashed a horde of barbarians!")); + else + -- FIXME: no type.name available + notify.event(owner, tile, E.HUT_BARB_KILLED, + _("Your %s has been killed by barbarians!"), + type.name); + end + end + return alive +end + function hut_enter_callback(unit) - -- to be implemented + local chance = random(0, 11) + local alive = true + + if chance == 0 then + hut_get_gold(unit, 25) + elseif chance == 1 or chance == 2 or chance == 3 then + hut_get_gold(unit, 50) + elseif chance == 4 then + hut_get_gold(unit, 100) + elseif chance == 5 or chance == 6 or chance == 7 then + hut_get_tech(unit) + elseif chance == 8 or chance == 9 then + if not hut_get_mercenaries(unit) then + hut_get_gold(unit, 25) + end + elseif chance == 10 then + alive = hut_get_barbarians(unit) + elseif chance == 11 then + hut_get_city(unit) + end + + -- continue processing if unit is alive + return (not alive) end --- Main code signal.connect("hut_enter", "hut_enter_callback") -
_______________________________________________ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev