From bd9fbca9954990020898b9646631162f89f5e861 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Sat, 14 May 2016 19:53:02 +0200 Subject: [PATCH] fire: Fix damage and ammunition use of return fire quiet_bigdef() runs for each attacker. It lets each eligible defender fire at most once. The first time a defender is eligible, it fires and is saved in the list of defenders, along with its firing damage. If it's eligible again for a later attacker, it's found in the list of defenders, and the damage is reused. The list of defenders searched with search_flist(). Unfortunately, search_flist() compares only uid, not type, and therefore can return a previously found defender of another type. If there are multiple attackers and multiple defenders with the same uid, total damage can be off, damage can be spread to attackers out of range, and defenders may not be charged shells. Abuse is possible, but complicated to set up, and probably not worth the trouble. Broken in commit f89edc7, v4.3.12. Fix by comparing the type as well. Signed-off-by: Markus Armbruster --- src/lib/commands/mfir.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/lib/commands/mfir.c b/src/lib/commands/mfir.c index 1983010f..29d27cba 100644 --- a/src/lib/commands/mfir.c +++ b/src/lib/commands/mfir.c @@ -28,7 +28,7 @@ * * Known contributors to this file: * Steve McClure, 2000 - * Markus Armbruster, 2004-2015 + * Markus Armbruster, 2004-2016 */ #include @@ -660,13 +660,16 @@ free_flist(struct emp_qelem *list) } static int -uid_eq(struct emp_qelem *elem, void *key) +flist_eq(struct emp_qelem *elem, void *key) { - return ((struct flist *)elem)->uid == ((struct empobj *)key)->uid; + struct flist *e = (struct flist *)elem; + struct flist *k = key; + + return e->type == k->type && e->uid == k->uid; } static struct flist * search_flist(struct emp_qelem *list, struct empobj *gp) { - return (struct flist *)emp_searchque(list, gp, uid_eq); + return (struct flist *)emp_searchque(list, gp, flist_eq); }