From d471d684be54bc6ce1f326ba00629b21882704e0 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Sat, 9 Jan 2010 13:26:16 +0100 Subject: [PATCH] Split up perform_mission() Move code out of perform_mission() into new perform_mission_land(), perform_mission_ship(), perform_mission_msl(), perform_mission_bomb(). --- src/lib/subs/mission.c | 361 +++++++++++++++++++++++------------------ 1 file changed, 202 insertions(+), 159 deletions(-) diff --git a/src/lib/subs/mission.c b/src/lib/subs/mission.c index cef5c47b8..395b170fe 100644 --- a/src/lib/subs/mission.c +++ b/src/lib/subs/mission.c @@ -73,6 +73,14 @@ static int find_airport(struct emp_qelem *, coord, coord); static void mission_pln_arm(struct emp_qelem *, coord, coord, int, int, struct ichrstr *); static void mission_pln_sel(struct emp_qelem *, int, int, int); +static int perform_mission_land(int, struct lndstr *, coord, coord, + natid, int, char *, int, int); +static int perform_mission_ship(int, struct shpstr *, coord, coord, + natid, int, char *, int, int); +static int perform_mission_msl(int, struct emp_qelem *, coord, coord, + natid, int); +static int perform_mission_bomb(int, struct emp_qelem *, coord, coord, + natid, int, char *, int, int); static int perform_mission(coord, coord, natid, struct emp_qelem *, int, char *, int); @@ -377,28 +385,20 @@ static int perform_mission(coord x, coord y, natid victim, struct emp_qelem *list, int mission, char *s, int hardtarget) { - struct emp_qelem *qp, missiles, bombers, escorts, airp, b, e; - struct emp_qelem *newqp; + struct emp_qelem *qp, missiles, bombers; struct genlist *glp; struct plist *plp; struct empobj *gp; - struct lndstr *lp; - struct shpstr *sp; struct sctstr sect; - struct mchrstr *mcp; struct plchrstr *pcp; - int dam = 0, dam2; - natid plane_owner = 0; - int md, range, air_dam, sublaunch; - double hitchance, vrange; + int dam = 0; + int md; int targeting_ships = *s == 's'; /* "subs" or "ships" FIXME gross! */ getsect(x, y, §); emp_initque(&missiles); emp_initque(&bombers); - emp_initque(&escorts); - emp_initque(&airp); for (qp = list->q_forw; qp != list; qp = qp->q_forw) { glp = (struct genlist *)qp; @@ -407,123 +407,13 @@ perform_mission(coord x, coord y, natid victim, struct emp_qelem *list, md = mapdist(x, y, gp->x, gp->y); if (glp->thing->ef_type == EF_LAND) { - lp = (struct lndstr *)glp->thing; - - if (mission == MI_SINTERDICT) - continue; - - if ((mission == MI_INTERDICT) && - (md > land_max_interdiction_range)) - continue; - - range = roundrange(lnd_fire_range(lp)); - if (md > range) - continue; - - dam2 = lnd_fire(lp); - putland(lp->lnd_uid, lp); - if (dam2 < 0) - continue; - - if (targeting_ships) { - if (chance(lnd_acc(lp) / 100.0)) - dam2 = ldround(dam2 / 2.0, 1); - } - dam += dam2; - if (targeting_ships) - nreport(lp->lnd_own, N_SHP_SHELL, victim, 1); - else - nreport(lp->lnd_own, N_SCT_SHELL, victim, 1); - wu(0, lp->lnd_own, - "%s fires at %s %s at %s\n", - prland(lp), cname(victim), s, xyas(x, y, lp->lnd_own)); - - mpr(victim, "%s %s fires at you at %s\n", - cname(lp->lnd_own), prland(lp), xyas(x, y, victim)); + dam = perform_mission_land(dam, (struct lndstr *)glp->thing, + x, y, victim, mission, s, + md, targeting_ships); } else if (glp->thing->ef_type == EF_SHIP) { - sp = (struct shpstr *)glp->thing; - mcp = glp->cp; - - if (((mission == MI_INTERDICT) || - (mission == MI_SINTERDICT)) && - (md > ship_max_interdiction_range)) - continue; - if (mission == MI_SINTERDICT) { - if (!(mcp->m_flags & M_SONAR)) - continue; - if (!(mcp->m_flags & M_DCH) && !(mcp->m_flags & M_SUBT)) - continue; - vrange = techfact(sp->shp_tech, mcp->m_vrnge); - vrange *= sp->shp_effic / 200.0; - if (md > vrange) - continue; - /* can't look all the time */ - if (chance(0.5)) - continue; - } - if (mcp->m_flags & M_SUB) { - if (!targeting_ships) - continue; /* subs interdict only ships */ - range = roundrange(torprange(sp)); - if (md > range) - continue; - if (!line_of_sight(NULL, x, y, gp->x, gp->y)) - continue; - dam2 = shp_torp(sp, 1); - putship(sp->shp_uid, sp); - if (dam2 < 0) - continue; - hitchance = shp_torp_hitchance(sp, md); - - wu(0, sp->shp_own, - "%s locking on %s %s in %s\n", - prship(sp), cname(victim), s, xyas(x, y, sp->shp_own)); - wu(0, sp->shp_own, - "\tEffective torpedo range is %d.0\n", range); - wu(0, sp->shp_own, - "\tWhooosh... Hitchance = %d%%\n", - (int)(hitchance * 100)); - - if (!chance(hitchance)) { - wu(0, sp->shp_own, "\tMissed\n"); - mpr(victim, - "Incoming torpedo sighted @ %s missed (whew)!\n", - xyas(x, y, victim)); - continue; - } - wu(0, sp->shp_own, "\tBOOM!...\n"); - dam += dam2; - nreport(victim, N_TORP_SHIP, 0, 1); - wu(0, sp->shp_own, - "\tTorpedo hit %s %s for %d damage\n", - cname(victim), s, dam2); - - mpr(victim, - "Incoming torpedo sighted @ %s hits and does %d damage!\n", - xyas(x, y, victim), dam2); - } else { - range = roundrange(shp_fire_range(sp)); - if (md > range) - continue; - if (mission == MI_SINTERDICT) - dam2 = shp_dchrg(sp); - else - dam2 = shp_fire(sp); - putship(sp->shp_uid, sp); - if (dam2 < 0) - continue; - dam += dam2; - if (targeting_ships) - nreport(sp->shp_own, N_SHP_SHELL, victim, 1); - else - nreport(sp->shp_own, N_SCT_SHELL, victim, 1); - wu(0, sp->shp_own, - "%s fires at %s %s at %s\n", - prship(sp), cname(victim), s, xyas(x, y, sp->shp_own)); - - mpr(victim, "%s %s fires at you at %s\n", - cname(sp->shp_own), prship(sp), xyas(x, y, victim)); - } + dam = perform_mission_ship(dam, (struct shpstr *)glp->thing, + x, y, victim, mission, s, + md, targeting_ships); } else if (glp->thing->ef_type == EF_PLANE) { pcp = glp->cp; if (pcp->pl_flags & P_M) @@ -541,20 +431,176 @@ perform_mission(coord x, coord y, natid victim, struct emp_qelem *list, emp_insque(&plp->queue, &missiles); else emp_insque(&plp->queue, &bombers); - plane_owner = plp->plane.pln_own; } else { CANT_REACH(); break; } } + dam = perform_mission_msl(dam, &missiles, x, y, victim, hardtarget); + dam = perform_mission_bomb(dam, &bombers, x, y, victim, mission, s, + hardtarget, targeting_ships); + + qp = list->q_forw; + while (qp != list) { + glp = (struct genlist *)qp; + qp = qp->q_forw; + + free(glp->thing); + free(glp); + } + + return dam; +} + +static int +perform_mission_land(int dam, struct lndstr *lp, coord x, coord y, + natid victim, int mission, char *s, int md, + int targeting_ships) +{ + int range, dam2; + + if (mission == MI_SINTERDICT) + return dam; + + if ((mission == MI_INTERDICT) && + (md > land_max_interdiction_range)) + return dam; + + range = roundrange(lnd_fire_range(lp)); + if (md > range) + return dam; + + dam2 = lnd_fire(lp); + putland(lp->lnd_uid, lp); + if (dam2 < 0) + return dam; + + if (targeting_ships) { + if (chance(lnd_acc(lp) / 100.0)) + dam2 = ldround(dam2 / 2.0, 1); + } + if (targeting_ships) + nreport(lp->lnd_own, N_SHP_SHELL, victim, 1); + else + nreport(lp->lnd_own, N_SCT_SHELL, victim, 1); + wu(0, lp->lnd_own, + "%s fires at %s %s at %s\n", + prland(lp), cname(victim), s, xyas(x, y, lp->lnd_own)); + + mpr(victim, "%s %s fires at you at %s\n", + cname(lp->lnd_own), prland(lp), xyas(x, y, victim)); + + return dam + dam2; +} + +static int +perform_mission_ship(int dam, struct shpstr *sp, coord x, coord y, + natid victim, int mission, char *s, int md, + int targeting_ships) +{ + struct mchrstr *mcp = &mchr[sp->shp_type]; + double vrange, hitchance; + int range, dam2; + + if (((mission == MI_INTERDICT) || + (mission == MI_SINTERDICT)) && + (md > ship_max_interdiction_range)) + return dam; + if (mission == MI_SINTERDICT) { + if (!(mcp->m_flags & M_SONAR)) + return dam; + if (!(mcp->m_flags & M_DCH) && !(mcp->m_flags & M_SUBT)) + return dam; + vrange = techfact(sp->shp_tech, mcp->m_vrnge); + vrange *= sp->shp_effic / 200.0; + if (md > vrange) + return dam; + /* can't look all the time */ + if (chance(0.5)) + return dam; + } + if (mcp->m_flags & M_SUB) { + if (!targeting_ships) + return dam; /* subs interdict only ships */ + range = roundrange(torprange(sp)); + if (md > range) + return dam; + if (!line_of_sight(NULL, x, y, sp->shp_x, sp->shp_y)) + return dam; + dam2 = shp_torp(sp, 1); + putship(sp->shp_uid, sp); + if (dam2 < 0) + return dam; + hitchance = shp_torp_hitchance(sp, md); + + wu(0, sp->shp_own, + "%s locking on %s %s in %s\n", + prship(sp), cname(victim), s, xyas(x, y, sp->shp_own)); + wu(0, sp->shp_own, + "\tEffective torpedo range is %d.0\n", range); + wu(0, sp->shp_own, + "\tWhooosh... Hitchance = %d%%\n", + (int)(hitchance * 100)); + + if (!chance(hitchance)) { + wu(0, sp->shp_own, "\tMissed\n"); + mpr(victim, + "Incoming torpedo sighted @ %s missed (whew)!\n", + xyas(x, y, victim)); + return dam; + } + wu(0, sp->shp_own, "\tBOOM!...\n"); + nreport(victim, N_TORP_SHIP, 0, 1); + wu(0, sp->shp_own, + "\tTorpedo hit %s %s for %d damage\n", + cname(victim), s, dam2); + + mpr(victim, + "Incoming torpedo sighted @ %s hits and does %d damage!\n", + xyas(x, y, victim), dam2); + } else { + range = roundrange(shp_fire_range(sp)); + if (md > range) + return dam; + if (mission == MI_SINTERDICT) + dam2 = shp_dchrg(sp); + else + dam2 = shp_fire(sp); + putship(sp->shp_uid, sp); + if (dam2 < 0) + return dam; + if (targeting_ships) + nreport(sp->shp_own, N_SHP_SHELL, victim, 1); + else + nreport(sp->shp_own, N_SCT_SHELL, victim, 1); + wu(0, sp->shp_own, + "%s fires at %s %s at %s\n", + prship(sp), cname(victim), s, xyas(x, y, sp->shp_own)); + + mpr(victim, "%s %s fires at you at %s\n", + cname(sp->shp_own), prship(sp), xyas(x, y, victim)); + } + + return dam + dam2; +} + +static int +perform_mission_msl(int dam, struct emp_qelem *missiles, coord x, coord y, + natid victim, int hardtarget) +{ + int air_dam; + struct emp_qelem *qp, *newqp; + struct plist *plp; + int sublaunch, dam2; + /* * Missiles, except for interdiction of ships or land units, * because that happens elsewhere, in shp_missile_interdiction() * and lnd_missile_interdiction(). */ air_dam = 0; - for (qp = missiles.q_back; qp != &missiles; qp = newqp) { + for (qp = missiles->q_back; qp != missiles; qp = newqp) { newqp = qp->q_back; plp = (struct plist *)qp; @@ -566,30 +612,38 @@ perform_mission(coord x, coord y, natid victim, struct emp_qelem *list, &sublaunch) < 0) goto use_up_msl; if (!msl_hit(&plp->plane, SECT_HARDTARGET, EF_SECTOR, - N_SCT_MISS, N_SCT_SMISS, sublaunch, victim)) + N_SCT_MISS, N_SCT_SMISS, sublaunch, victim)) CANT_REACH(); dam2 = pln_damage(&plp->plane, 'p', 1); air_dam += dam2; use_up_msl: plp->plane.pln_effic = 0; putplane(plp->plane.pln_uid, &plp->plane); - } + } emp_remque(qp); free(qp); } - dam += air_dam; + return dam + air_dam; +} + +static int +perform_mission_bomb(int dam, struct emp_qelem *bombers, coord x, coord y, + natid victim, int mission, char *s, int hardtarget, + int targeting_ships) +{ + struct emp_qelem *qp, *newqp, escorts, airp, b, e; + struct plist *plp; + int plane_owner, air_dam, md; - if (QEMPTY(&bombers)) { - qp = list->q_forw; - while (qp != list) { - glp = (struct genlist *)qp; - qp = qp->q_forw; + emp_initque(&escorts); + emp_initque(&airp); - free(glp->thing); - free(glp); - } + if (QEMPTY(bombers)) return dam; - } + + plp = (struct plist *)bombers->q_forw; + plane_owner = plp->plane.pln_own; + /* * If there are planes performing an * interdict or support mission, find @@ -599,13 +653,13 @@ perform_mission(coord x, coord y, natid victim, struct emp_qelem *list, find_escorts(x, y, plane_owner, &escorts); if (mission == MI_SINTERDICT) - mission_pln_sel(&bombers, P_T | P_A, 0, hardtarget); + mission_pln_sel(bombers, P_T | P_A, 0, hardtarget); else - mission_pln_sel(&bombers, P_T, P_A, SECT_HARDTARGET); + mission_pln_sel(bombers, P_T, P_A, SECT_HARDTARGET); mission_pln_sel(&escorts, P_ESC | P_F, 0, SECT_HARDTARGET); - for (qp = bombers.q_forw; qp != (&bombers); qp = qp->q_forw) { + for (qp = bombers->q_forw; qp != bombers; qp = qp->q_forw) { plp = (struct plist *)qp; if (!find_airport(&airp, plp->plane.pln_x, plp->plane.pln_y)) add_airport(&airp, plp->plane.pln_x, plp->plane.pln_y); @@ -624,7 +678,7 @@ perform_mission(coord x, coord y, natid victim, struct emp_qelem *list, emp_initque(&e); /* Split off the bombers at this base into b */ - divide(&bombers, &b, air->x, air->y); + divide(bombers, &b, air->x, air->y); /* Split off the escorts at this base into e */ divide(&escorts, &e, air->x, air->y); @@ -661,23 +715,12 @@ perform_mission(coord x, coord y, natid victim, struct emp_qelem *list, } if (air_dam > 0) { - dam += air_dam; if (targeting_ships) nreport(plane_owner, N_SHP_BOMB, victim, 1); else nreport(plane_owner, N_SCT_BOMB, victim, 1); } - /* free up all this memory */ - qp = list->q_forw; - while (qp != list) { - glp = (struct genlist *)qp; - qp = qp->q_forw; - - free(glp->thing); - free(glp); - } - qp = escorts.q_forw; while (qp != (&escorts)) { newqp = qp->q_forw; @@ -686,15 +729,15 @@ perform_mission(coord x, coord y, natid victim, struct emp_qelem *list, qp = newqp; } - qp = bombers.q_forw; - while (qp != (&bombers)) { + qp = bombers->q_forw; + while (qp != bombers) { newqp = qp->q_forw; emp_remque(qp); free(qp); qp = newqp; } - return dam; + return dam + air_dam; } int -- 2.43.0