Feature #1464 » lua-specialists.patch
common/scriptcore/api_game_effects.c | ||
---|---|---|
etype);
|
||
}
|
||
/***********************************************************************//**
|
||
Get effect bonus for specialist.
|
||
@param L Lua State to use
|
||
@param s Specialist to get the effect value for
|
||
@param d Optional: City or Player for which the effect
|
||
is calculated (if City, its owner becomes the player)
|
||
@param output_id Optional: Indetifier of the output related
|
||
to the effect (e.g. Output to harvest from s)
|
||
@param effect_type Effect to check
|
||
@return Effect bonus value
|
||
***************************************************************************/
|
||
int
|
||
api_effects_specialist_bonus(lua_State *L, Specialist *s, lua_Object d,
|
||
const char *output_id, const char *effect_type)
|
||
{
|
||
struct req_context ctx = {.specialist = s};
|
||
enum effect_type etype;
|
||
LUASCRIPT_CHECK_STATE(L, 0);
|
||
LUASCRIPT_CHECK_ARG_NIL(L, s, 2, Specialist, 0);
|
||
LUASCRIPT_CHECK_ARG_NIL(L, effect_type, 5, string, 0);
|
||
etype = effect_type_by_name(effect_type, fc_strcasecmp);
|
||
if (!effect_type_is_valid(etype)) {
|
||
return 0;
|
||
}
|
||
if (output_id != NULL) {
|
||
enum output_type_id id = output_type_by_identifier(output_id);
|
||
if (O_LAST == id){
|
||
char msg[255];
|
||
fc_snprintf(msg, sizeof(msg),
|
||
"Unknown output identifier \"%s\"", output_id);
|
||
LUASCRIPT_CHECK_ARG(L, id != O_LAST, 3, msg, 0); /* Fails */
|
||
}
|
||
ctx.output = get_output_type(id);
|
||
}
|
||
if (0 != d) {
|
||
tolua_Error e; /* ignored */
|
||
if (tolua_isusertype(L, d, "Player", 0, &e)) {
|
||
/* nil handled here */
|
||
ctx.player = (Player *) lua_touserdata(L, d);
|
||
} else if (tolua_isusertype(L, d, "City", 0, &e)) {
|
||
ctx.city = (City *) lua_touserdata(L, d);
|
||
if (ctx.city) {
|
||
ctx.player = city_owner(ctx.city);
|
||
}
|
||
} else {
|
||
char msg[255];
|
||
fc_snprintf(msg, sizeof(msg),
|
||
"got '%s', City or Player expected", tolua_typename(L, d));
|
||
LUASCRIPT_CHECK_ARG(L, FALSE, 2, msg, 0); /* Fails */
|
||
}
|
||
}
|
||
return get_target_bonus_effects(nullptr, &ctx, nullptr, etype);
|
||
}
|
||
/***********************************************************************//**
|
||
Returns the effect bonus at a tile and the specified unit.
|
||
Unlike effects.unit_bonus() the city the effect is evaluated against is
|
common/scriptcore/api_game_effects.h | ||
---|---|---|
const char *effect_type);
|
||
int api_effects_tile_bonus(lua_State *L, Tile *ptile, City *pcity,
|
||
const char *output_id, const char *effect_type);
|
||
int
|
||
api_effects_specialist_bonus(lua_State *L, Specialist *s, lua_Object d,
|
||
const char *output_id, const char *effect_type);
|
||
int api_effects_unit_vs_tile_bonus(lua_State *L, Unit *punit, Tile *ptile,
|
||
const char *effect_type);
|
||
common/scriptcore/api_game_methods.c | ||
---|---|---|
return citizens_nation_get(pcity, nationality->slot);
|
||
}
|
||
/**********************************************************************//**
|
||
Return number of specialists of type s working in pcity.
|
||
If no s is specified, return number of citizens employed as specialists.
|
||
**************************************************************************/
|
||
int api_methods_city_num_specialists(lua_State *L, City *pcity,
|
||
Specialist *s)
|
||
{
|
||
LUASCRIPT_CHECK_STATE(L, 0);
|
||
LUASCRIPT_CHECK_SELF(L, pcity, 0);
|
||
if (nullptr != s) {
|
||
return pcity->specialists[specialist_index(s)];
|
||
} else {
|
||
return city_specialists(pcity);
|
||
}
|
||
}
|
||
/**********************************************************************//**
|
||
Return if pcity agrees with reqs of specialist s
|
||
**************************************************************************/
|
||
bool api_methods_city_can_employ(lua_State *L, City *pcity, Specialist *s)
|
||
{
|
||
LUASCRIPT_CHECK_STATE(L, FALSE);
|
||
LUASCRIPT_CHECK_SELF(L, pcity, FALSE);
|
||
LUASCRIPT_CHECK_ARG_NIL(L, s, 3, Specialist, FALSE);
|
||
return city_can_use_specialist(pcity, specialist_index(s));
|
||
}
|
||
/**********************************************************************//**
|
||
Return rule name for Government
|
||
**************************************************************************/
|
||
... | ... | |
return can_player_build_improvement_direct(pplayer, itype);
|
||
}
|
||
/**********************************************************************//**
|
||
Return if pplayer agrees with Player+-ranged reqs of specialist s
|
||
**************************************************************************/
|
||
bool api_methods_player_can_employ(lua_State *L, Player *pplayer,
|
||
Specialist *s)
|
||
{
|
||
LUASCRIPT_CHECK_STATE(L, FALSE);
|
||
LUASCRIPT_CHECK_SELF(L, pplayer, FALSE);
|
||
LUASCRIPT_CHECK_ARG_NIL(L, s, 3, Specialist, FALSE);
|
||
return
|
||
are_reqs_active_ranges(REQ_RANGE_PLAYER, REQ_RANGE_WORLD,
|
||
&(const struct req_context) {
|
||
.player = pplayer,
|
||
}, nullptr, &s->reqs, RPT_POSSIBLE);
|
||
}
|
||
/**********************************************************************//**
|
||
Find player's primary capital, if known
|
||
**************************************************************************/
|
common/scriptcore/api_game_methods.h | ||
---|---|---|
bool api_methods_is_primary_capital(lua_State *L, City *pcity);
|
||
int api_methods_city_nationality_citizens(lua_State *L, City *pcity,
|
||
Player *nationality);
|
||
int api_methods_city_num_specialists(lua_State *L, City *pcity,
|
||
Specialist *s);
|
||
bool api_methods_city_can_employ(lua_State *L, City *pcity, Specialist *s);
|
||
/* Counter */
|
||
const char *api_methods_counter_rule_name(lua_State *L, Counter *c);
|
||
... | ... | |
Unit_Type *utype);
|
||
bool api_methods_player_can_build_impr_direct(lua_State *L, Player *pplayer,
|
||
Building_Type *itype);
|
||
bool api_methods_player_can_employ(lua_State *L, Player *pplayer,
|
||
Specialist *s);
|
||
City *api_methods_player_primary_capital(lua_State *L, Player *pplayer);
|
||
common/scriptcore/tolua_game.pkg | ||
---|---|---|
@ can_build_direct(lua_State *L, Player *pplayer, Building_Type *itype);
|
||
bool api_methods_player_can_build_unit_direct
|
||
@ can_build_direct(lua_State *L, Player *pplayer, Unit_Type *utype);
|
||
bool api_methods_player_can_employ
|
||
@ can_employ(lua_State *L, Player *pplayer, Specialist *s);
|
||
City *api_methods_player_primary_capital
|
||
@ primary_capital(lua_State *L, Player *pplayer);
|
||
... | ... | |
int api_methods_city_nationality_citizens
|
||
@ nationality_citizens(lua_State *L, City *self, Player *nationality);
|
||
bool api_methods_city_can_employ
|
||
@ can_employ(lua_State *L, City *pcity, Specialist *s);
|
||
int api_methods_city_num_specialists
|
||
@ num_specialists (lua_State *L, City *pcity, Specialist *s);
|
||
}
|
||
$[
|
||
... | ... | |
int api_effects_tile_bonus
|
||
@ tile_bonus(lua_State *L, Tile *ptile, City *pcity,
|
||
const char *output_id, const char *effect_type);
|
||
int api_effects_specialist_bonus
|
||
@ specialist_bonus (lua_State *L, Specialist *s, lua_Object d,
|
||
const char *output_id, const char *effect_type);
|
||
int api_effects_unit_vs_tile_bonus
|
||
@ unit_vs_tile_bonus(lua_State *L, Unit *punit, Tile *ptile,
|
||
const char *effect_type);
|
server/scripting/api_server_edit.c | ||
---|---|---|
}
|
||
}
|
||
/**********************************************************************//**
|
||
Reduce specialists of given type s in a way like toggling in the client.
|
||
Does not place workers on map, just switches to another specialist.
|
||
Does nothing if there is less than amount specialists s in pcity.
|
||
Return if given number could be repurposed.
|
||
**************************************************************************/
|
||
bool api_edit_city_reduce_specialists(lua_State *L, City *pcity,
|
||
Specialist *s, int amount)
|
||
{
|
||
Specialist_type_id from, to;
|
||
LUASCRIPT_CHECK_STATE(L, FALSE);
|
||
LUASCRIPT_CHECK_SELF(L, pcity, FALSE);
|
||
LUASCRIPT_CHECK_ARG_NIL(L, s, 2, Specialist, FALSE);
|
||
LUASCRIPT_CHECK_ARG(L, amount >= 0, 3, "must be non-negative", FALSE);
|
||
from = specialist_index(s);
|
||
if (pcity->specialists[from] < amount) {
|
||
return FALSE;
|
||
}
|
||
to = from;
|
||
do {
|
||
to = (to + 1) % specialist_count();
|
||
} while (to != from && !city_can_use_specialist(pcity, to));
|
||
if (to == from) {
|
||
/* We can use only the default specialist */
|
||
return FALSE;
|
||
} else {
|
||
/* City population must be correct */
|
||
fc_assert_ret_val_msg((int) pcity->specialists[to] + amount <= MAX_CITY_SIZE,
|
||
FALSE, "Wrong specialist number in %s",
|
||
city_name_get(pcity));
|
||
pcity->specialists[from] -= amount;
|
||
pcity->specialists[to] += amount;
|
||
city_refresh(pcity);
|
||
/* sanity_check_city(pcity); -- hopefully we don't break things here? */
|
||
send_city_info(city_owner(pcity), pcity);
|
||
return TRUE;
|
||
}
|
||
}
|
||
/**********************************************************************//**
|
||
Create a new player.
|
||
**************************************************************************/
|
server/scripting/api_server_edit.h | ||
---|---|---|
bool api_edit_transfer_city(lua_State *L, City *pcity, Player *new_owner);
|
||
void api_edit_create_building(lua_State *L, City *pcity, Building_Type *impr);
|
||
void api_edit_remove_building(lua_State *L, City *pcity, Building_Type *impr);
|
||
bool api_edit_city_reduce_specialists(lua_State *L, City *pcity,
|
||
Specialist *s, int amount);
|
||
Player *api_edit_create_player(lua_State *L, const char *username,
|
||
Nation_Type *pnation, const char *ai);
|
||
void api_edit_change_gold(lua_State *L, Player *pplayer, int amount);
|
server/scripting/tolua_server.pkg | ||
---|---|---|
@ create_building (lua_State *L, City *pcity, Building_Type *impr);
|
||
void api_edit_remove_building
|
||
@ remove_building (lua_State *L, City *pcity, Building_Type *impr);
|
||
bool api_edit_city_reduce_specialists
|
||
@ reduce_specialists (lua_State *L, City *pcity, Specialist *s,
|
||
int amount = 1);
|
||
void api_edit_create_owned_extra
|
||
@ create_owned_extra (lua_State *L, Tile *ptile,
|
||
const char *name, Player *pplayer);
|
||
... | ... | |
edit.remove_building(self, impr)
|
||
end
|
||
function City:reduce_specialists(spec, amount)
|
||
return edit.reduce_specialists(self, spec, amount)
|
||
end
|
||
function City:change_size(change, nationality)
|
||
edit.change_city_size(self, change, nationality)
|
||
end
|