001package com.fs.starfarer.api.impl.campaign.terrain; 002 003import java.util.EnumSet; 004 005import org.json.JSONArray; 006import org.json.JSONException; 007import org.json.JSONObject; 008import org.lwjgl.util.vector.Vector2f; 009 010import com.fs.starfarer.api.Global; 011import com.fs.starfarer.api.campaign.CampaignEngineLayers; 012import com.fs.starfarer.api.campaign.CampaignFleetAPI; 013import com.fs.starfarer.api.campaign.SectorEntityToken; 014import com.fs.starfarer.api.combat.ViewportAPI; 015import com.fs.starfarer.api.util.Misc; 016 017public class RadioChatterTerrainPlugin extends BaseRingTerrain { 018 019 public static class RadioChatterParams extends RingParams { 020 public RadioChatterParams(float bandWidthInEngine, float middleRadius, SectorEntityToken relatedEntity) { 021 super(bandWidthInEngine, middleRadius, relatedEntity); 022 } 023 } 024 025 protected RadioChatterParams params; 026 027 028 public void init(String terrainId, SectorEntityToken entity, Object param) { 029 super.init(terrainId, entity, param); 030 this.params = (RadioChatterParams) param; 031 } 032 033 @Override 034 protected Object readResolve() { 035 super.readResolve(); 036 layers = EnumSet.noneOf(CampaignEngineLayers.class); 037 return this; 038 } 039 040 Object writeReplace() { 041 return this; 042 } 043 044 transient private EnumSet<CampaignEngineLayers> layers = EnumSet.noneOf(CampaignEngineLayers.class); 045 public EnumSet<CampaignEngineLayers> getActiveLayers() { 046 return layers; 047 } 048 049 050 051 public void render(CampaignEngineLayers layer, ViewportAPI viewport) { 052 053 } 054 055 protected transient float phase = 0f; 056 public void advance(float amount) { 057 super.advance(amount); 058 059 float period = (float)Math.PI * 2f; 060 phase += period/10f * amount; 061 } 062 @Override 063 public void applyEffect(SectorEntityToken entity, float days) { 064 if (!entity.isPlayerFleet()) return; 065 066 float prox = getProximitySoundFactor(); 067 float volumeMult = prox; 068 float suppressionMult = prox; 069 if (volumeMult <= 0) return; 070 volumeMult = (float) Math.sqrt(volumeMult); 071 //volumeMult = 1f; 072 073 Global.getSector().getCampaignUI().suppressMusic(getSpec().getMusicSuppression() * suppressionMult); 074 075 float dirToEntity = Misc.getAngleInDegrees(entity.getLocation(), this.entity.getLocation()); 076 Vector2f playbackLoc = Misc.getUnitVectorAtDegreeAngle(dirToEntity); 077 playbackLoc.scale(500f); 078 Vector2f.add(entity.getLocation(), playbackLoc, playbackLoc); 079 080 try { 081 JSONArray sounds = getSpec().getCustom().getJSONArray("chatter"); 082 float num = sounds.length(); 083 float period = (float)Math.PI * 2f; 084 085// float marketSize = 10f; 086// if (params.relatedEntity != null && params.relatedEntity.getMarket() != null) { 087// marketSize = params.relatedEntity.getMarket().getSize(); 088// } 089 090 //{"sound":"terrain_radio_chatter_1", "phaseMult":1, "threshold":-1}, 091 for (int i = 0; i < sounds.length(); i++) { 092 JSONObject sound = sounds.getJSONObject(i); 093 float threshold = (float) sound.getDouble("threshold"); 094 float phaseMult = (float) sound.getDouble("phaseMult"); 095 String soundId = sound.getString("sound"); 096 097// float thresholdRange = 1f - threshold; 098// float sizePenalty = Math.max(6f - marketSize, 0) / 6f * thresholdRange; 099// threshold += sizePenalty; 100 101 //phaseMult = 1f; 102 float offset = period / num * (float) i; 103 //float cos = (float) Math.cos((phase + offset) * ((float) i * 0.5f + 1f)); 104 float cos = (float) Math.cos(phase * phaseMult + offset); 105 106 float volume = 0f; 107 if (cos > threshold) { 108 volume = (cos - threshold) / (1f - threshold); 109 if (volume < 0) volume = 0; 110 if (volume > 1) volume = 1; 111 } 112 113 114 Global.getSoundPlayer().playLoop(soundId, params.relatedEntity, 115 //volume * 0.25f + 0.75f, volume * volumeMult, 116 1f, volume * volumeMult, 117 playbackLoc, Misc.ZERO); 118 } 119 120 121 } catch (JSONException e) { 122 } 123 } 124 125 126 @Override 127 public float getProximitySoundFactor() { 128 CampaignFleetAPI player = Global.getSector().getPlayerFleet(); 129 float dist = Misc.getDistance(player.getLocation(), entity.getLocation()); 130 float radSum = params.relatedEntity.getRadius() + player.getRadius(); 131 132 //if (dist < radSum) return 1f; 133 dist -= radSum; 134 135 float f = 1f - dist / Math.max(1, (params.bandWidthInEngine - params.relatedEntity.getRadius())); 136 if (f < 0) f = 0; 137 if (f > 1) f = 1; 138 return f; 139 } 140 141 @Override 142 protected float getExtraSoundRadius() { 143 return 0f; 144 } 145 146 @Override 147 public boolean containsPoint(Vector2f point, float radius) { 148 return super.containsPoint(point, radius); 149 } 150 151 public boolean hasTooltip() { 152 return false; 153 } 154 155 156 public String getTerrainName() { 157 return null; 158 } 159 160 public String getNameForTooltip() { 161 return null; 162 } 163 164 public String getEffectCategory() { 165 return "radio_chatter"; 166 } 167 168 public boolean canPlayerHoldStationIn() { 169 return false; 170 } 171} 172 173 174 175 176 177