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 <armbru@pond.sub.org>
*
* Known contributors to this file:
* Steve McClure, 2000
- * Markus Armbruster, 2004-2015
+ * Markus Armbruster, 2004-2016
*/
#include <config.h>
}
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);
}