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_S2_6.patch

Charlie Galik, 2021-01-21 11:33 PM

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_vet[MAX_LEN_LINK], defender_vet[MAX_LEN_LINK];
char attacker_fp[MAX_LEN_LINK], defender_fp[MAX_LEN_LINK];
char attacker_tired[MAX_LEN_LINK];
struct unit *ploser, *pwinner;
struct city *pcity;
int moves_used, def_moves_used;
......
struct player *pplayer = unit_owner(punit);
bool adj;
enum direction8 facing;
int att_hp, def_hp;
int att_hp, def_hp, att_fp, def_fp;
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);
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_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));
/* Record tired attack string before attack */
sz_strlcpy(attacker_tired, unit_tired_attack_string(punit));
unit_versus_unit(punit, pdefender, FALSE, &att_hp, &def_hp);
if ((att_hp <= 0 || uclass_has_flag(unit_class_get(punit), UCF_MISSILE))
......
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."),
/* TRANS: "Your green Legion [id:100 ...D:4.0 lost 1 HP,
* 9 HP remaining] survived the pathetic ...attack from the
* green Greek Warriors [id:90 ...A:1.0 HP:10]. */
_("Your %s %s [id:%d %sD:%.1f lost %d HP, %d HP remaining]"
" survived the pathetic %sattack from the %s %s %s "
"[id:%d %sA:%.1f HP:%d]."),
defender_vet,
winner_link,
pdefender->id,
defender_fp,
(float)def_power/POWER_FACTOR,
def_hp_start - pdefender->hp,
pdefender->hp,
attacker_tired,
nation_adjective_for_player(unit_owner(ploser)),
loser_link);
attacker_vet,
loser_link,
punit->id,
attacker_fp,
(float)att_power/POWER_FACTOR,
att_hp_start);
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);
/* TRANS: "Your attacking green Cannon [id:100 ...A:8.0
* failed against the Greek Polish Destroyer [id:200 lost
* 27 HP, 3 HP remaining%s]!";
* last %s is either "and ..." or empty string */
_("Your attacking %s %s [id:%d %sA:%.1f HP:%d] failed "
"against the %s %s %s [id:%d lost %d HP, %d HP "
"remaining%s]!"),
attacker_vet,
loser_link,
punit->id,
attacker_fp,
(float)att_power/POWER_FACTOR,
att_hp_start,
nation_adjective_for_player(unit_owner(pdefender)),
defender_vet,
winner_link,
pdefender->id,
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(pdefender), unit_tile(pdefender),
E_UNIT_LOST_DEF, ftc_server,
/* TRANS: "Your green Warriors [id:100 ...D:1.0 HP:10]
* lost to an attack by the Greek green Legion
* [id:200 ...A:4.0 lost 1 HP, has 9 HP remaining%s]."
* last %s is either "and ..." or empty string */
_("Your %s %s [id:%d %sD:%.1f HP:%d] lost to an attack by "
"the %s %s %s [id:%d %sA:%.1f lost %d HP, has %d HP "
"remaining%s]."),
defender_vet,
loser_link,
pdefender->id,
defender_fp,
(float)def_power/POWER_FACTOR,
def_hp_start,
nation_adjective_for_player(unit_owner(punit)),
attacker_vet,
winner_link,
punit->id,
attacker_fp,
(float)att_power/POWER_FACTOR,
att_hp_start - pwinner->hp,
pwinner->hp,
vet ? unit_achieved_rank_string(punit) : "");
notify_player(unit_owner(punit), unit_tile(punit),
E_UNIT_WIN_ATT, ftc_server,
/* TRANS: "Your attacking green Legion [id:200 ...A:4.0
* lost 1 HP, has 9 HP remaining] succeeded against the
* Greek green Warriors [id:100 HP:10]." */
_("Your attacking %s %s [id:%d %s%sA:%.1f lost %d HP, "
"has %d remaining] succeeded against the %s %s %s "
"[id:%d HP:%d]."),
attacker_vet,
winner_link,
punit->id,
attacker_fp,
attacker_tired,
(float)att_power/POWER_FACTOR,
att_hp_start - pwinner->hp,
pwinner->hp,
nation_adjective_for_player(unit_owner(pdefender)),
defender_vet,
loser_link,
pdefender->id,
def_hp_start);
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);
/* 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);
}
if (vet) {
notify_unit_experience(pkiller);
}
(7-7/12)