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