Project

Profile

Help

HostedRedmine.com has moved to the Planio platform. All logins and passwords remained the same. All users will be able to login and use Redmine just as before. Read more...

Feature #913055 » 0001-Detailed-combat-info-from-server-message.patch

Charlie Galik, 2021-01-08 07:33 AM

View differences:

common/combat.c
return NULL;
}
/**************************************************************************
Returns if the attack is going to be a tired attack
**************************************************************************/
bool is_tired_attack(int moves_left)
{
return game.info.tired_attack && moves_left < SINGLE_MOVE;
}
/**************************************************************************
Convenience wrapper for base_get_attack_power.
**************************************************************************/
......
power = punittype->attack_strength * POWER_FACTOR
* vlevel->power_fact / 100;
if (game.info.tired_attack && moves_left < SINGLE_MOVE) {
if (is_tired_attack(moves_left)) {
power = (power * moves_left) / SINGLE_MOVE;
}
common/combat.h
bool unit_really_ignores_citywalls(const struct unit *punit);
struct city *sdi_try_defend(const struct player *owner,
const struct tile *ptile);
bool is_tired_attack(int moves_left);
int get_attack_power(const struct unit *punit);
int base_get_attack_power(const struct unit_type *punittype,
common/featured_text.c
return buf;
}
/**************************************************************************
Get a text of a unit's vet level.
N.B.: The returned string is static, so every call to this function
overwrites the previous.
**************************************************************************/
const char *unit_veteran_level_string(const struct unit *punit)
{
static char buf[MAX_LEN_LINK];
const struct veteran_level *vlevel;
if (!punit) {
/* If no unit, return empty string */
fc_snprintf(buf, sizeof(buf), "");
return buf;
}
vlevel = utype_veteran_level(unit_type_get(punit), punit->veteran);
fc_snprintf(buf, sizeof(buf), "%s", name_translation_get(&vlevel->name));
return buf;
}
/**************************************************************************
Get string of when unit gets upgraded to new veteran level.
N.B.: The returned string is static, so every call to this function
overwrites the previous.
**************************************************************************/
const char *unit_achieved_rank_string(const struct unit *punit)
{
static char buf[MAX_LEN_LINK];
fc_snprintf(buf, sizeof(buf),
/* TRANS: " and achieved the rank of <veteran level>";
* preserve leading space */
" and achieved the rank of %s",
unit_veteran_level_string(punit));
return buf;
}
/**************************************************************************
Get string of unit's attack would be a tired attack or not.
N.B.: The returned string is static, so every call to this function
overwrites the previous.
**************************************************************************/
const char *unit_tired_attack_string(const struct unit *punit)
{
static char buf[MAX_LEN_LINK];
if (is_tired_attack(punit->moves_left)) {
fc_snprintf(buf, sizeof(buf),
/* TRANS: tired; note trailing space */
_("tired "));
} else {
fc_snprintf(buf, sizeof(buf), "");
}
return buf;
}
/**************************************************************************
Get string of unit's firepower text, i.e. "FP:2 "
If firepower is equal to one, then an empty string is returned
so as to shorten the text output.
N.B.: The returned string is static, so every call to this function
overwrites the previous.
**************************************************************************/
const char *unit_firepower_if_not_one(int firepower)
{
static char buf[MAX_LEN_LINK];
if (firepower == 1) {
fc_snprintf(buf, sizeof(buf), "");
} else {
fc_snprintf(buf, sizeof(buf),
/* TRANS: FP = Firepower of a unit; note trailing space */
_("FP:%d "),
firepower);
}
return buf;
}
/**************************************************************************
Get a text link to an unit.
N.B.: The returned string is static, so every call to this function
common/featured_text.h
const char *tile_link(const struct tile *ptile);
const char *unit_link(const struct unit *punit);
const char *unit_tile_link(const struct unit *punit);
const char *unit_veteran_level_string(const struct unit *punit);
const char *unit_achieved_rank_string(const struct unit *punit);
const char *unit_tired_attack_string(const struct unit *punit);
const char *unit_firepower_if_not_one(int firepower);
#ifdef __cplusplus
}
server/unithand.c
#include "city.h"
#include "combat.h"
#include "events.h"
#include "featured_text.h"
#include "game.h"
#include "log.h"
#include "map.h"
......
static void unit_attack_handling(struct unit *punit, struct unit *pdefender)
{
char loser_link[MAX_LEN_LINK], winner_link[MAX_LEN_LINK];
char attacker_link[MAX_LEN_LINK], defender_link[MAX_LEN_LINK];
char attacker_vet[MAX_LEN_LINK], defender_vet[MAX_LEN_LINK];
char attacker_fp[MAX_LEN_LINK], defender_fp[MAX_LEN_LINK];
char combat_msg_att[MAX_LEN_MSG], combat_msg_def[MAX_LEN_MSG];
struct unit *ploser, *pwinner;
struct city *pcity;
int moves_used, def_moves_used;
......
bool adj;
enum direction8 facing;
int att_hp, def_hp;
int att_hp_start = punit->hp;
int def_hp_start = pdefender->hp;
int def_power = get_total_defense_power(punit, pdefender);
int att_power = get_total_attack_power(punit, pdefender);
int att_fp, def_fp;
get_modified_firepower(punit, pdefender, &att_fp, &def_fp);
log_debug("Start attack: %s %s against %s %s.",
nation_rule_name(nation_of_player(pplayer)),
......
old_unit_vet = punit->veteran;
old_defender_vet = pdefender->veteran;
/* N.B.: unit_link always returns the same pointer. */
sz_strlcpy(attacker_link, unit_tile_link(punit));
sz_strlcpy(defender_link, unit_tile_link(pdefender));
/* N.B.: unit_veteran_level_string always returns the same pointer. */
sz_strlcpy(attacker_vet, unit_veteran_level_string(punit));
sz_strlcpy(defender_vet, unit_veteran_level_string(pdefender));
/* N.B.: unit_firepower_if_not_one always returns the same pointer. */
sz_strlcpy(attacker_fp, unit_firepower_if_not_one(att_fp));
sz_strlcpy(defender_fp, unit_firepower_if_not_one(def_fp));
fc_snprintf(combat_msg_att, sizeof(combat_msg_att),
/* TRANS: "Combat: Your veteran Cannon [id:100 ...
* attack:6.1 ... HP:20] has a 55.69% attacking the Polish
* green Phalanx [id:99 defense:3.5 ... HP:10]." */
_("Combat: Your %s %s [id:%d %sattack:%.1f %sHP:%d] has "
"a %.4g%% chance attacking the %s %s %s [id:%d defense:%.1f"
" %sHP:%d]."),
attacker_vet,
attacker_link,
punit->id,
unit_tired_attack_string(punit),
(float)att_power/POWER_FACTOR,
attacker_fp,
att_hp_start,
unit_win_chance(punit, pdefender)*100,
nation_adjective_for_player(unit_owner(pdefender)),
defender_vet,
defender_link,
pdefender->id,
(float)def_power/POWER_FACTOR,
defender_fp,
def_hp_start);
fc_snprintf(combat_msg_def, sizeof(combat_msg_def),
/* TRANS: "Combat: German veteran Cannon [id:100 ...
* attack:6.1 ... HP:20] has a 55.69% attacking your
* green Phalanx [id:99 defense:3.5 ... HP:10]." */
_("Combat: %s %s %s [id:%d %sattack:%.1f %sHP:%d] has "
"a %.4g%% chance against your %s %s [id:%d defense:%.1f"
" %sHP:%d]."),
nation_adjective_for_player(unit_owner(punit)),
attacker_vet,
attacker_link,
punit->id,
unit_tired_attack_string(punit),
(float)att_power/POWER_FACTOR,
attacker_fp,
att_hp_start,
unit_win_chance(punit, pdefender)*100,
defender_vet,
defender_link,
pdefender->id,
(float)def_power/POWER_FACTOR,
defender_fp,
def_hp_start);
unit_versus_unit(punit, pdefender, FALSE, &att_hp, &def_hp);
/* Now can send correct notification for lost/won */
notify_player(unit_owner(punit), unit_tile(punit),
(punit->hp > 0) ? E_UNIT_WIN_ATT : E_UNIT_LOST_ATT,
ftc_server, "%s", combat_msg_att);
notify_player(unit_owner(pdefender), unit_tile(pdefender),
(punit->hp > 0) ? E_UNIT_LOST_DEF : E_UNIT_WIN,
ftc_server, "%s", combat_msg_def);
if ((att_hp <= 0 || uclass_has_flag(unit_class_get(punit), UCF_MISSILE))
&& unit_transported(punit)) {
/* Dying attacker must be first unloaded so it doesn't die insider transport */
......
nation_rule_name(nation_of_unit(pdefender)),
unit_rule_name(pdefender));
notify_player(unit_owner(pwinner), unit_tile(pwinner),
E_UNIT_WIN, ftc_server,
/* TRANS: "Your Cannon ... the Polish Destroyer." */
_("Your %s survived the pathetic attack from the %s %s."),
winner_link,
nation_adjective_for_player(unit_owner(ploser)),
loser_link);
if (vet) {
notify_unit_experience(pwinner);
}
notify_player(unit_owner(ploser), def_tile,
E_UNIT_LOST_ATT, ftc_server,
/* TRANS: "... Cannon ... the Polish Destroyer." */
_("Your attacking %s failed against the %s %s!"),
loser_link,
nation_adjective_for_player(unit_owner(pwinner)),
winner_link);
notify_player(unit_owner(punit), unit_tile(punit), E_UNIT_LOST_ATT,
ftc_server,
/* TRANS: "Combat result: Cannon attack failed
* against the Polish Destroyer [lost 27 HP, 3 HP
* remaining...]."
*/
_("Combat result: Your %s attack failed against the %s %s"
" [lost %d HP, %d HP remaining%s]."),
attacker_link,
nation_adjective_for_player(unit_owner(pdefender)),
defender_link,
def_hp_start - pdefender->hp,
pdefender->hp,
vet ? unit_achieved_rank_string(pdefender) : "");
notify_player(unit_owner(pdefender), unit_tile(pdefender), E_UNIT_WIN,
ftc_server,
/* TRANS: "Combat result: German Cannon attack failed
* against the your Destroyer [lost 27 HP, 3 HP
* remaining...]."
*/
_("Combat result: %s %s attack failed against the your %s"
" [lost %d HP, %d HP remaining%s]."),
nation_adjective_for_player(unit_owner(punit)),
attacker_link,
defender_link,
def_hp_start - pdefender->hp,
pdefender->hp,
vet ? unit_achieved_rank_string(pdefender) : "");
wipe_unit(ploser, ULR_KILLED, unit_owner(pwinner));
} else {
/* The defender lost, the attacker punit lives! */
......
nation_rule_name(nation_of_unit(pdefender)),
unit_rule_name(pdefender));
notify_player(unit_owner(punit), unit_tile(punit),
E_UNIT_WIN_ATT, ftc_server,
/* TRANS: "Combat result: Your Cannon attack succeeded
* against the Polish Destroyer. Your Cannon lost 19 HP,
* 1 HP remaining...]." */
_("Combat result: Your %s attack succeeded against the %s "
"%s. Your %s lost %d HP, has %d HP remaining%s."),
winner_link,
nation_adjective_for_player(unit_owner(pdefender)),
loser_link,
winner_link,
att_hp_start - pwinner->hp,
pwinner->hp,
vet ? unit_achieved_rank_string(punit) : "");
notify_player(unit_owner(pdefender), unit_tile(pdefender),
E_UNIT_LOST_DEF, ftc_server,
/* TRANS: "Combat result: German Cannon attack succeeded
* against your Destroyer. German Cannon lost 19 HP,
* 1 HP remaining...]." */
_("Combat result: %s %s attack succeeded against your "
"%s. %s %s lost %d HP, has %d HP remaining%s."),
nation_adjective_for_player(unit_owner(punit)),
winner_link,
loser_link,
nation_adjective_for_player(unit_owner(punit)),
winner_link,
att_hp_start - pwinner->hp,
pwinner->hp,
vet ? unit_achieved_rank_string(punit) : "");
punit->moved = TRUE; /* We moved */
kill_unit(pwinner, ploser,
vet && !uclass_has_flag(unit_class_get(punit), UCF_MISSILE));
server/unittools.c
}
if (!is_stack_vulnerable(unit_tile(punit)) || unitcount == 1) {
notify_player(pvictor, unit_tile(pkiller), E_UNIT_WIN_ATT, ftc_server,
/* TRANS: "... Cannon ... the Polish Destroyer." */
_("Your attacking %s succeeded against the %s %s!"),
pkiller_link,
nation_adjective_for_player(pvictim),
punit_link);
if (vet) {
notify_unit_experience(pkiller);
}
notify_player(pvictim, unit_tile(punit), E_UNIT_LOST_DEF, ftc_server,
/* TRANS: "Cannon ... the Polish Destroyer." */
_("%s lost to an attack by the %s %s."),
punit_link,
nation_adjective_for_player(pvictor),
pkiller_link);
wipe_unit(punit, ULR_KILLED, pvictor);
} else { /* unitcount > 1 */
int i;
......
}
} unit_list_iterate_end;
/* Inform the destroyer: lots of different cases here! */
notify_player(pvictor, unit_tile(pkiller), E_UNIT_WIN_ATT, ftc_server,
/* TRANS: "... Cannon ... the Polish Destroyer ...." */
PL_("Your attacking %s succeeded against the %s %s "
"(and %d other unit)!",
"Your attacking %s succeeded against the %s %s "
"(and %d other units)!", unitcount - 1),
pkiller_link,
nation_adjective_for_player(pvictim),
punit_link,
unitcount - 1);
if (vet) {
notify_unit_experience(pkiller);
/* Inform the destroyer again if more than one unit was killed */
if (unitcount > 1) {
notify_player(pvictor, unit_tile(pkiller), E_UNIT_WIN_ATT, ftc_server,
/* TRANS: "... Cannon ... the Polish Destroyer ...." */
PL_("Your attacking %s succeeded against the %s %s "
"(and %d other unit)!",
"Your attacking %s succeeded against the %s %s "
"(and %d other units)!", unitcount - 1),
pkiller_link,
nation_adjective_for_player(pvictim),
punit_link,
unitcount - 1);
}
/* inform the owners: this only tells about owned units that were killed.
(2-2/12)