Hmm… let me see if I can answer all the questions. If I miss one… smack me, I’ll answer it eventually.
Will it effect players. All stats are based off the following code, so apply modifiers via spells, weather, etc are extremely easy to handle.
public class cStat implements Serializable {
String name;
float base = 0, altered = 0, equip = 0, effect = 0, factored = 0, current = 0;
public cStat() { }
public void initStat(String name) {
this.name = name;
}
public void setBase(float value) { base = value; totalFactored(); }
public void addBase(float value) { base += value; totalFactored(); }
public void subBase(float value) { base -= value; totalFactored(); }
public float getBase() { return base; }
public void setAltered(float value) { altered = value; totalFactored(); }
public void addAltered(float value) { altered += value; totalFactored(); }
public void subAltered(float value) { altered -= value; totalFactored(); }
public float getAltered() { return altered; }
public void setEquip(float value) { equip = value; totalFactored(); }
public void addEquip(float value) { equip += value; totalFactored(); }
public void subEquip(float value) { equip -= value; totalFactored(); }
public float getEquip() { return equip; }
public void setEffect(float value) { effect = value; totalFactored(); }
public void addEffect(float value) { effect += value; totalFactored(); }
public void subEffect(float value) { effect -= value; totalFactored(); }
public float getEffect() { return effect; }
public void setFactored(float value) { factored = value; }
public void addFactored(float value) { factored += value; }
public void subFactored(float value) { factored -= value; }
public float getFactored() { return factored; }
public void setCurrent(float value) { current = value; }
public void addCurrent(float value) { current += value; }
public void subCurrent(float value) { current -= value; }
public float getCurrent() { return current; }
public void resetCurrent() { current = factored; }
private void totalFactored() {
factored = base+altered+equip+effect;
if (factored < current) current = factored;
}
}
All objects are derived of a collect of stats (among other things). A stat can be anything (obviously), so effecting the players attack speed, movement speed, overall weight, etc, etc, etc is as easy as calling addEffect… or subEffect. If these are timer based, that expire automatically–or in the case of weather changes received from the server (also considering player skills that would counter the effect)… could potentially effect any number of attributes.
As for how I did the lightning (This worked for a really great looking torch effect as well):
Lightning—lighting effect
// for the dureation of the lightning effect
float lColor = (float)(Math.random()*.3f)+.7f;
lLight.setColor(new ColorRGBA(lColor, lColor, lColor, 1));
// otherwise, set the light to Black
Torch—lighting effect
if (!skyBox.getIsDay()){
float red = ((float)Math.random()*.2f)+.6f;
float green = red-.2f;//((float)Math.random()*.2f)+.4f;
float radius = ((float)Math.random()*2)+6;
torch.setColor(new ColorRGBA(red,green,.0f,.8f));
torch.setRadius(radius);
}
As for the lightning & rain display—
A billboarded quad set to Bucket.Sky – for the lightning
A particle emitter — for the rain
the code in the update of the control is fairly straight forward:
public void update(float tpf) {
int pos;
float x, y;
pos = (int)Math.round(Math.random());
x = (float)(Math.random()*(size*3));
if (pos == 0) x = -x;
pos = (int)Math.round(Math.random());
y = (float)(Math.random()*(size*3));
if (pos == 0) y = -y;
weather.setLocalTranslation(x, size, y);
if (showLightning) {
lShowCount += tpf;
if (lShowCount > 1.5) {
// Set material to notta after lightning ends
effectNode.setMaterial(mat_LTrans);
showLightning = false;
lShowCount = 0;
lLight.setColor(ColorRGBA.Black);
} else {
if (lBegin) {
// Position quad & set material.. need to update to image defined by server
effectNode.setLocalTranslation(lV);
effectNode.setMaterial(mat_L);
lBegin = false;
}
// Flicker lightning light
float lColor = (float)(Math.random()*.3f)+.7f;
lLight.setColor(new ColorRGBA(lColor, lColor, lColor, 1));
}
}
}
public void showLightning(float[] position, int imageIndex) {
lV = new Vector3f(position[0], position[1], position[2]);
lBegin = true;
showLightning = true;
}