diff --git a/src/org/magiclib/bounty/MagicBountyIntel.java b/src/org/magiclib/bounty/MagicBountyIntel.java index 3e944d3b..8f2e6d0f 100644 --- a/src/org/magiclib/bounty/MagicBountyIntel.java +++ b/src/org/magiclib/bounty/MagicBountyIntel.java @@ -426,6 +426,13 @@ public void createSmallDescription(TooltipMakerAPI info, float width, float heig Misc.ucFirst(MagicBountyUtilsInternal.getPronoun(bounty.getCaptain())), bounty.getFleetSpawnLocation().getStarSystem().getNameWithLowercaseType()); break; + case Distance: + info.addPara(MagicTxt.getString("mb_distance"), + 10f, + Misc.getTextColor(), + Misc.getHighlightColor(), + Math.round(Misc.getDistanceLY(Global.getSector().getPlayerFleet(), bounty.getFleetSpawnLocation())) + ""); + break; default: info.addPara(MagicBountyUtilsInternal.createLocationEstimateText(bounty), 10f); break; @@ -459,8 +466,10 @@ public SectorEntityToken getMapLocation(SectorMapAPI map) { case Exact: case System: return hideoutLocation; -// case None: -// return null; NOPE, the icon should always be placed somewhere otherwise there is no way to get the location information again. + //case Vague: + case Distance: + case None: + return Global.getSector().getPlayerFleet(); default: // From PersonBountyIntel.getMapLocation Constellation c = hideoutLocation.getConstellation(); diff --git a/src/org/magiclib/bounty/intel/AssassinationMagicBountyInfo.kt b/src/org/magiclib/bounty/intel/AssassinationMagicBountyInfo.kt deleted file mode 100644 index c215da3d..00000000 --- a/src/org/magiclib/bounty/intel/AssassinationMagicBountyInfo.kt +++ /dev/null @@ -1,98 +0,0 @@ -package org.magiclib.bounty.intel - -import com.fs.starfarer.api.Global -import com.fs.starfarer.api.campaign.StarSystemAPI -import com.fs.starfarer.api.campaign.comm.IntelInfoPlugin -import com.fs.starfarer.api.impl.campaign.rulecmd.salvage.special.BreadcrumbSpecial -import com.fs.starfarer.api.ui.CustomPanelAPI -import com.fs.starfarer.api.ui.MapParams -import com.fs.starfarer.api.ui.TooltipMakerAPI -import com.fs.starfarer.api.util.Misc -import org.magiclib.bounty.MagicBountyLoader -import org.magiclib.bounty.MagicBountySpec -import org.magiclib.kotlin.ucFirst -import org.magiclib.util.MagicTxt -import java.awt.Color -import kotlin.math.roundToInt - -class AssassinationMagicBountyInfo(bountyKey: String, bountySpec: MagicBountySpec) : - MagicBountyInfo(bountyKey, bountySpec) { - override fun showTargetInfo(panel: CustomPanelAPI, width: Float, height: Float): TooltipMakerAPI { - val targetInfoTooltip = panel.createUIElement(width, height, true) - val childPanelWidth = width - 16f - val activeBountyLocal = activeBounty ?: return targetInfoTooltip - - if (bountySpec.job_show_captain) { - val portrait = targetInfoTooltip.beginImageWithText(getJobIcon(), 64f) - var displayName = activeBountyLocal.fleet.commander.nameString - val targetFirstName = activeBountyLocal.captain.name.first - val targetLastName = activeBountyLocal.captain.name.last - if (targetFirstName != null || targetLastName != null) { - displayName = "$targetFirstName $targetLastName" - if (targetFirstName == null || targetFirstName.isEmpty()) - displayName = targetLastName - else if (targetLastName == null || targetLastName.isEmpty()) - displayName = targetFirstName - } - portrait.addPara(displayName, activeBountyLocal.targetFactionTextColor, 0f) - portrait.addPara(activeBountyLocal.fleet.commander.rank.ucFirst(), 2f) - targetInfoTooltip.addImageWithText(0f) - } - - val location = getLocationIfBountyIsActive() - if (location is StarSystemAPI) { - val params = MapParams() - params.showSystem(location) - val w = targetInfoTooltip.widthSoFar - val h = (w / 1.6f).roundToInt().toFloat() - params.positionToShowAllMarkersAndSystems(false, w.coerceAtMost(h)) - params.filterData.fuel = true - params.arrows.add(IntelInfoPlugin.ArrowData(Global.getSector().playerFleet, location.center)) - - val map = targetInfoTooltip.createSectorMap(childPanelWidth, 200f, params, null) - targetInfoTooltip.addCustom(map, 4f) - - if (bountySpec.job_show_distance != MagicBountyLoader.ShowDistance.None) { - when (bountySpec.job_show_distance) { - MagicBountyLoader.ShowDistance.Exact -> targetInfoTooltip.addPara( - createLocationPreciseText(activeBounty!!), - 10f, - location.lightColor, - activeBounty!!.fleetSpawnLocation.starSystem.nameWithLowercaseType - ) - - MagicBountyLoader.ShowDistance.System -> targetInfoTooltip.addPara( - MagicTxt.getString("mb_distance_system"), - 10f, - arrayOf(Misc.getTextColor(), location.lightColor), - MagicTxt.getString("mb_distance_they"), - activeBounty!!.fleetSpawnLocation.starSystem.nameWithLowercaseType - ) - - else -> targetInfoTooltip.addPara( - createLocationEstimateText(activeBounty!!), - 10f, - location.lightColor, - BreadcrumbSpecial.getLocationDescription(activeBounty!!.fleetSpawnLocation, false) - ) - } - } - } else { - targetInfoTooltip.setButtonFontOrbitron20Bold() - targetInfoTooltip.addPara(MagicTxt.getString("mb_descLocationUnknown"), 3f, Color.RED).position.inTMid(2f) - } - - activeBounty?.let { - showFleet(targetInfoTooltip, childPanelWidth, it) - - if (it.spec.job_show_captain) { - targetInfoTooltip.addPara(MagicTxt.getString("mb_hvb_skillsHeader"), 8f) - targetInfoTooltip.addSkillPanel(it.captain, 2f) - } - } - - panel.addUIElement(targetInfoTooltip).inTL(0f, 0f) - - return targetInfoTooltip - } -} \ No newline at end of file diff --git a/src/org/magiclib/bounty/intel/MagicBountyBoardProvider.kt b/src/org/magiclib/bounty/intel/MagicBountyBoardProvider.kt index e3a1f90f..e479964a 100644 --- a/src/org/magiclib/bounty/intel/MagicBountyBoardProvider.kt +++ b/src/org/magiclib/bounty/intel/MagicBountyBoardProvider.kt @@ -9,9 +9,6 @@ class MagicBountyBoardProvider: BountyBoardProvider { .entries .distinctBy { it.key } .map { (key, spec) -> - if (spec.job_type == MagicBountyLoader.JobType.Assassination) - AssassinationMagicBountyInfo(key, spec) - else MagicBountyInfo(key, spec) } } diff --git a/src/org/magiclib/bounty/intel/MagicBountyInfo.kt b/src/org/magiclib/bounty/intel/MagicBountyInfo.kt index c5a4d29e..9ce8e30b 100644 --- a/src/org/magiclib/bounty/intel/MagicBountyInfo.kt +++ b/src/org/magiclib/bounty/intel/MagicBountyInfo.kt @@ -2,17 +2,16 @@ package org.magiclib.bounty.intel import com.fs.starfarer.api.Global import com.fs.starfarer.api.campaign.LocationAPI +import com.fs.starfarer.api.campaign.SectorEntityToken import com.fs.starfarer.api.campaign.StarSystemAPI import com.fs.starfarer.api.campaign.comm.IntelInfoPlugin -import com.fs.starfarer.api.campaign.rules.MemoryAPI import com.fs.starfarer.api.fleet.FleetMemberAPI import com.fs.starfarer.api.impl.campaign.ids.Factions +import com.fs.starfarer.api.impl.campaign.procgen.Constellation import com.fs.starfarer.api.impl.campaign.rulecmd.salvage.special.BreadcrumbSpecial -import com.fs.starfarer.api.ui.CustomPanelAPI -import com.fs.starfarer.api.ui.LabelAPI -import com.fs.starfarer.api.ui.MapParams -import com.fs.starfarer.api.ui.TooltipMakerAPI +import com.fs.starfarer.api.ui.* import com.fs.starfarer.api.util.Misc +import org.lwjgl.util.vector.Vector2f import org.magiclib.bounty.ActiveBounty import org.magiclib.bounty.MagicBountyCoordinator import org.magiclib.bounty.MagicBountyLoader.* @@ -20,11 +19,13 @@ import org.magiclib.bounty.MagicBountySpec import org.magiclib.bounty.MagicBountyUtilsInternal import org.magiclib.bounty.ui.InteractiveUIPanelPlugin import org.magiclib.kotlin.setAlpha +import org.magiclib.kotlin.ucFirst import org.magiclib.util.MagicCampaign import org.magiclib.util.MagicTxt import java.awt.Color import kotlin.math.ceil import kotlin.math.roundToInt +import kotlin.text.isEmpty open class MagicBountyInfo(val bountyKey: String, val bountySpec: MagicBountySpec) : BountyInfo { val activeBounty: ActiveBounty? @@ -278,13 +279,31 @@ open class MagicBountyInfo(val bountyKey: String, val bountySpec: MagicBountySpe BountyBoardIntelPlugin.refreshPanel(this) } } else if (activeBountyLocal.stage == ActiveBounty.Stage.Accepted) { - val courseButton = - actionTooltip.addButton(MagicTxt.getString("mb_plot_course"), null, rightPanelWidth, 24f, 0f) - rightPanelPlugin.addButton(courseButton) { - courseButton.isChecked = false - Global.getSector().layInCourseFor( - Misc.getDistressJumpPoint(activeBountyLocal.fleet.containingLocation as StarSystemAPI) - ) + + //Add plot course button if there is a clear destination + val dis = activeBountyLocal.spec.job_show_distance + if(dis != ShowDistance.Distance && dis != ShowDistance.None// && dis != ShowDistance.Vague + ) { + + var location: SectorEntityToken? = null + if(dis == ShowDistance.Exact || dis == ShowDistance.System) { + location = Misc.getDistressJumpPoint(activeBountyLocal.fleet.containingLocation as StarSystemAPI) + } else { + val constellation = activeBountyLocal.fleet.constellation + if(constellation != null) + location = createConstellationCenterToken(constellation) + } + + if(location != null) { + val courseButton = + actionTooltip.addButton(MagicTxt.getString("mb_plot_course"), null, rightPanelWidth, 24f, 0f) + rightPanelPlugin.addButton(courseButton) { + courseButton.isChecked = false + Global.getSector().layInCourseFor( + location + ) + } + } } } @@ -455,38 +474,115 @@ open class MagicBountyInfo(val bountyKey: String, val bountySpec: MagicBountySpe val targetInfoTooltip = panel.createUIElement(width, height, true) val childPanelWidth = width - 16f + val bounty = activeBounty!! + + if (bountySpec.job_type == JobType.Assassination && bountySpec.job_show_captain) { + val portrait = targetInfoTooltip.beginImageWithText(getJobIcon(), 64f) + var displayName = bounty.fleet.commander.nameString + val targetFirstName = bounty.captain.name.first + val targetLastName = bounty.captain.name.last + if (targetFirstName != null || targetLastName != null) { + displayName = "$targetFirstName $targetLastName" + if (targetFirstName == null || targetFirstName.isEmpty()) + displayName = targetLastName + else if (targetLastName == null || targetLastName.isEmpty()) + displayName = targetFirstName + } + portrait.addPara(displayName, bounty.targetFactionTextColor, 0f) + portrait.addPara(bounty.fleet.commander.rank.ucFirst(), 2f) + targetInfoTooltip.addImageWithText(0f) + } + val location = getLocationIfBountyIsActive() - if (location is StarSystemAPI) { + if (location is StarSystemAPI + && bountySpec.job_show_distance != ShowDistance.None) { + + fun setupSystemParams(params: MapParams, location: StarSystemAPI) { + params.showSystem(location) + params.arrows.add(IntelInfoPlugin.ArrowData(Global.getSector().playerFleet, location.center)) + } + val params = MapParams() - params.showSystem(location) val w = targetInfoTooltip.widthSoFar val h = (w / 1.6f).roundToInt().toFloat() - params.positionToShowAllMarkersAndSystems(false, w.coerceAtMost(h)) - params.filterData.fuel = true - params.arrows.add(IntelInfoPlugin.ArrowData(Global.getSector().playerFleet, location.center)) - val map = targetInfoTooltip.createSectorMap(childPanelWidth, 200f, params, null) - targetInfoTooltip.addCustom(map, 2f) + when (bountySpec.job_show_distance) { + ShowDistance.Exact -> { + setupSystemParams(params, location) - if (bountySpec.job_show_distance != ShowDistance.None) { - val bounty = activeBounty!! - when (bountySpec.job_show_distance) { - ShowDistance.Exact -> targetInfoTooltip.addPara( + targetInfoTooltip.addPara( createLocationPreciseText(bounty), 10f, location.lightColor, bounty.fleetSpawnLocation.starSystem.nameWithLowercaseType ) + } + + ShowDistance.System -> { + setupSystemParams(params, location) - ShowDistance.System -> targetInfoTooltip.addPara( + targetInfoTooltip.addPara( MagicTxt.getString("mb_distance_system"), 10f, arrayOf(Misc.getTextColor(), location.lightColor), MagicTxt.getString("mb_distance_they"), bounty.fleetSpawnLocation.starSystem.nameWithLowercaseType ) + } + + /*ShowDistance.Vague -> { + params.filterData.names = false + + val distance = bounty.fleetSpawnLocation.containingLocation.location.length() + var vague = MagicTxt.getString("mb_distance_core") + if (distance > MagicVariables.getSectorSize() * 0.6f) { + vague = MagicTxt.getString("mb_distance_far") + } else if (distance > MagicVariables.getSectorSize() * 0.33f) { + vague = MagicTxt.getString("mb_distance_close") + } + targetInfoTooltip.addPara( + MagicTxt.getString("mb_distance_vague"), + 10f, + Misc.getTextColor(), + Misc.getHighlightColor(), + vague + ) + }*///Commented out due to seeming to be a bad mechanic with the current implementation of the bounty board. Given pre-existing use of it in some mods (such as Seeker), enabling this on an update may cause issues for some users. - else -> targetInfoTooltip.addPara( + ShowDistance.Distance -> { + params.filterData.names = false + + val distanceLY = Misc.getDistanceLY(Global.getSector().playerFleet, bounty.fleetSpawnLocation).roundToInt() + targetInfoTooltip.addPara( + MagicTxt.getString("mb_distance"), + 10f, + Misc.getTextColor(), + Misc.getHighlightColor(), + distanceLY.toString() + ) + } + + else -> { + val constellation = location.constellation + if(constellation != null) { + //Show constellation + params.filterData.constellations = true + params.filterData.names = false + params.showConsellations = setOf(constellation) + params.smallConstellations = true + + //Point towards center of constellation + val token = createConstellationCenterToken(constellation) + if (token != null) { + params.arrows.add(IntelInfoPlugin.ArrowData(Global.getSector().playerFleet, token)) + params.markers = listOf(MarkerData(token.location, Global.getSector().hyperspace)) + } + + } else { + setupSystemParams(params, location) + } + + targetInfoTooltip.addPara( createLocationEstimateText(bounty), 10f, location.lightColor, @@ -494,6 +590,15 @@ open class MagicBountyInfo(val bountyKey: String, val bountySpec: MagicBountySpe ) } } + + params.positionToShowAllMarkersAndSystems(false, w.coerceAtMost(h)) + params.markers = null//Markers are purely for positioning the camera. Don't render them. + + params.filterData.fuel = true + + val map = targetInfoTooltip.createSectorMap(childPanelWidth, 200f, params, null) + targetInfoTooltip.addCustom(map, 2f) + } else { targetInfoTooltip.setButtonFontOrbitron20Bold() targetInfoTooltip.addPara(MagicTxt.getString("mb_descLocationUnknown"), 3f, Color.RED).position.inTMid(2f) @@ -793,4 +898,25 @@ fun ActiveBounty.calculateCreditReward(): Float? { MagicBountyCoordinator.getInstance().preScalingCreditRewardMultiplier, MagicBountyCoordinator.getInstance().postScalingCreditRewardMultiplier ) -} \ No newline at end of file +} + +fun getConstellationSystemsCenter(constellation: Constellation): Vector2f? { + val systems = constellation.systems + if (systems.isEmpty()) return null + + val total = Vector2f(0f, 0f) + for (system in systems) { + Vector2f.add(total, system.location, total) + } + + total.scale(1f / systems.size) + return total +} + +fun createConstellationCenterToken(constellation: Constellation): SectorEntityToken? { + val center = getConstellationSystemsCenter(constellation) ?: return null + val hyperspace = Global.getSector().hyperspace + + // Create a temporary token at the calculated position + return hyperspace.createToken(center.x, center.y) +}