package com.planet_ink.coffee_mud.Libraries;
import com.planet_ink.coffee_mud.Libraries.interfaces.*;
import com.planet_ink.coffee_mud.core.interfaces.*;
import com.planet_ink.coffee_mud.core.*;
import com.planet_ink.coffee_mud.Abilities.interfaces.*;
import com.planet_ink.coffee_mud.Areas.interfaces.*;
import com.planet_ink.coffee_mud.Behaviors.interfaces.*;
import com.planet_ink.coffee_mud.CharClasses.interfaces.*;
import com.planet_ink.coffee_mud.Commands.interfaces.*;
import com.planet_ink.coffee_mud.Common.interfaces.*;
import com.planet_ink.coffee_mud.Exits.interfaces.*;
import com.planet_ink.coffee_mud.Items.interfaces.*;
import com.planet_ink.coffee_mud.Locales.interfaces.*;
import com.planet_ink.coffee_mud.MOBS.interfaces.*;
import com.planet_ink.coffee_mud.Races.interfaces.*;
import java.util.*;
/**
* <p>Portions Copyright (c) 2003 Jeremy Vyska</p>
* <p>Portions Copyright (c) 2004 Bo Zimmerman</p>
* <p>Licensed under the Apache License, Version 2.0 (the "License");
* <p>you may not use this file except in compliance with the License.
* <p>You may obtain a copy of the License at
*
* <p> http://www.apache.org/licenses/LICENSE-2.0
*
* <p>Unless required by applicable law or agreed to in writing, software
* <p>distributed under the License is distributed on an "AS IS" BASIS,
* <p>WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* <p>See the License for the specific language governing permissions and
* <p>limitations under the License.
*/
public class Factions extends StdLibrary implements FactionManager
{
public String ID(){return "Factions";}
public Hashtable factionSet = new Hashtable();
public Hashtable hashedFactionRanges=new Hashtable();
public Hashtable factionSet(){return factionSet;}
public void clearFactions()
{
factionSet.clear();
hashedFactionRanges.clear();
}
public void reloadFactions(String factionList)
{
Vector preLoadFactions=CMParms.parseSemicolons(factionList,true);
clearFactions();
for(int i=0;i<preLoadFactions.size();i++)
getFaction((String)preLoadFactions.elementAt(i));
}
public Hashtable rangeCodeNames(){ return hashedFactionRanges; }
public boolean isRangeCodeName(String key){ return rangeCodeNames().containsKey(key.toUpperCase());}
public boolean isFactionedThisWay(MOB mob, String rangeCodeName)
{
Faction.FactionRange FR=(Faction.FactionRange)rangeCodeNames().get(rangeCodeName.toUpperCase());
if(FR==null) return false;
Faction.FactionRange FR2=FR.myFaction().fetchRange(mob.fetchFaction(FR.myFaction().factionID()));
if(FR2==null) return false;
return FR2.codeName().equalsIgnoreCase(FR.codeName());
}
public String rangeDescription(String rangeCodeName, String andOr)
{
Faction.FactionRange FR=(Faction.FactionRange)rangeCodeNames().get(rangeCodeName.toUpperCase());
if((FR==null)||(FR.myFaction()==null)||(FR.myFaction().ranges().size()<=0))
return "";
Vector relevantFactions=new Vector();
for(int r=0;r<FR.myFaction().ranges().size();r++)
{
if((((Faction.FactionRange)FR.myFaction().ranges().elementAt(r)).codeName().equalsIgnoreCase(FR.codeName())))
relevantFactions.addElement(FR.myFaction().ranges().elementAt(r));
}
if(relevantFactions.size()==0) return "";
if(relevantFactions.size()==1)
return FR.myFaction().name()+" of "+((Faction.FactionRange)relevantFactions.firstElement()).name();
StringBuffer buf=new StringBuffer(FR.myFaction().name()+" of ");
for(int i=0;i<relevantFactions.size()-1;i++)
buf.append(((Faction.FactionRange)relevantFactions.elementAt(i)).name()+", ");
buf.append(andOr+((Faction.FactionRange)relevantFactions.lastElement()).name());
return buf.toString();
}
public Faction getFaction(String factionID)
{
if(factionID==null) return null;
Faction F=(Faction)factionSet.get(factionID.toUpperCase());
if(F!=null) return F;
StringBuffer buf=new CMFile("resources/"+factionID,null,true).text();
if((buf!=null)&&(buf.length()>0))
{
F=(Faction)CMClass.getCommon("DefaultFaction");
F.initializeFaction(buf,factionID);
for(int r=0;r<F.ranges().size();r++)
{
Faction.FactionRange FR=(Faction.FactionRange)F.ranges().elementAt(r);
String CodeName=(FR.codeName().length()>0)?FR.codeName().toUpperCase():FR.name().toUpperCase();
if(!hashedFactionRanges.containsKey(CodeName))
hashedFactionRanges.put(CodeName,FR);
}
factionSet.put(factionID.toUpperCase(),F);
return F;
}
return null;
}
public Faction getFactionByRangeCodeName(String rangeCodeName)
{
if(hashedFactionRanges.containsKey(rangeCodeName.toUpperCase()))
return (Faction)hashedFactionRanges.get(rangeCodeName.toUpperCase());
return null;
}
public Faction getFactionByName(String factionNamed)
{
for(Enumeration e=factionSet.keys();e.hasMoreElements();)
{
Faction f=(Faction)factionSet.get(e.nextElement());
if(f.name().equalsIgnoreCase(factionNamed)) return f;
}
return null;
}
public boolean removeFaction(String factionID)
{
if(factionID==null)
{
for(Enumeration e=factionSet.keys();e.hasMoreElements();)
{
Faction f=(Faction)factionSet.get(e.nextElement());
removeFaction(f.factionID());
}
return true;
}
Faction F=getFactionByName(factionID);
if(F==null) F=getFaction(factionID);
if(F==null) return false;
Resources.removeResource(F.factionID());
factionSet.remove(F.factionID().toUpperCase());
return true;
}
public String listFactions()
{
StringBuffer msg=new StringBuffer();
msg.append("\n\r^.^N");
msg.append("+--------------------------------+-----------------------------------------+\n\r");
msg.append("| ^HFaction Name^N | ^HFaction INI Source File (Faction ID)^N |\n\r");
msg.append("+--------------------------------+-----------------------------------------+\n\r");
for(Enumeration e=factionSet.keys();e.hasMoreElements();)
{
Faction f=(Faction)factionSet.get(e.nextElement());
msg.append("| ");
msg.append(CMStrings.padRight(f.name(),30));
msg.append(" | ");
msg.append(CMStrings.padRight(f.factionID(),39));
msg.append(" |\n\r");
}
msg.append("+--------------------------------+-----------------------------------------+\n\r");
msg.append("\n\r");
return msg.toString();
}
public String name(){return "Factions";}
public long getTickStatus(){ return Tickable.STATUS_NOT;}
public String getName(String factionID) { Faction f=getFaction(factionID); if(f!=null) return f.name(); return ""; }
public int getMinimum(String factionID) { Faction f=getFaction(factionID); if(f!=null) return f.minimum(); return 0; }
public int getMaximum(String factionID) { Faction f=getFaction(factionID); if(f!=null) return f.maximum(); return 0; }
public int getPercent(String factionID, int faction) { Faction f=getFaction(factionID); if(f!=null) return f.asPercent(faction); return 0; }
public int getPercentFromAvg(String factionID, int faction) { Faction f=getFaction(factionID); if(f!=null) return f.asPercentFromAvg(faction); return 0; }
public Faction.FactionRange getRange(String factionID, int faction) { Faction f=getFaction(factionID); if(f!=null) return f.fetchRange(faction); return null; }
public Vector getRanges(String factionID) { Faction f=getFaction(factionID); if(f!=null) return f.ranges(); return null; }
public double getRangePercent(String factionID, int faction)
{
Faction F=getFaction(factionID);
if(F==null) return 0.0;
return CMath.div((int)Math.round(CMath.div((faction - F.minimum()),(F.maximum() - F.minimum())) * 10000.0),100.0);
}
public double getRateModifier(String factionID) { Faction f=getFaction(factionID); if(f!=null) return f.rateModifier(); return 0; }
public int getTotal(String factionID) { Faction f=getFaction(factionID); if(f!=null) return (f.maximum()-f.minimum()); return 0; }
public int getRandom(String factionID) { Faction f=getFaction(factionID); if(f!=null) return f.randomFaction(); return 0; }
public String AlignID() { return "alignment.ini"; }
public void setAlignment(MOB mob, int newAlignment)
{
if(getFaction(AlignID())!=null)
mob.addFaction(AlignID(),getAlignThingie(newAlignment));
}
public void setAlignmentOldRange(MOB mob, int oldRange)
{
if(getFaction(AlignID())!=null)
{
if(oldRange>=650)
setAlignment(mob,Faction.ALIGN_GOOD);
else
if(oldRange>=350)
setAlignment(mob,Faction.ALIGN_NEUTRAL);
else
if(oldRange>=0)
setAlignment(mob,Faction.ALIGN_EVIL);
else{ /* a -1 value is the new norm */}
}
}
public boolean tick(Tickable ticking, int tickID)
{
if(CMLib.sessions().size()==0)
return true;
try
{
Session S=null;
MOB mob=null;
Faction F=null;
Faction.FactionChangeEvent CE=null;
DVector outSiders=new DVector(2);
DVector timers=new DVector(2);
for(Enumeration e=factionSet.elements();e.hasMoreElements();)
{
F=(Faction)e.nextElement();
CE=F.findChangeEvent("ADDOUTSIDER");
if(CE!=null) outSiders.addElement(CE,F);
CE=F.findChangeEvent("TIME");
if(CE!=null) timers.addElement(CE,F);
}
if((outSiders.size()==0)&&(timers.size()==0))
return true;
for(int s=0;s<CMLib.sessions().size();s++)
{
S=CMLib.sessions().elementAt(s);
mob=(!S.killFlag())?S.mob():null;
if(mob!=null)
{
for(int o=0;o<outSiders.size();o++)
{
CE=(Faction.FactionChangeEvent)outSiders.elementAt(o,1);
F=(Faction)outSiders.elementAt(o,2);
if((CE.applies(mob))&&(!F.hasFaction(mob)))
F.executeChange(mob,mob,CE);
}
for(int o=0;o<timers.size();o++)
{
CE=(Faction.FactionChangeEvent)timers.elementAt(o,1);
F=(Faction)timers.elementAt(o,2);
if((CE.applies(mob))&&(F.hasFaction(mob)))
F.executeChange(mob,mob,CE);
}
}
}
}catch(Exception e){}
return true;
}
public int getAlignPurity(int faction, int AlignEq)
{
int bottom=Integer.MAX_VALUE;
int top=Integer.MIN_VALUE;
int pct=getPercent(AlignID(),faction);
Vector ranges = getRanges(AlignID());
for(int i=0;i<ranges.size();i++)
{
Faction.FactionRange R=(Faction.FactionRange)ranges.elementAt(i);
if(R.alignEquiv()==AlignEq)
{
if(R.low()<bottom) bottom=R.low();
if(R.high()>top) top=R.high();
}
}
switch(AlignEq)
{
case Faction.ALIGN_GOOD:
return Math.abs(pct - getPercent(AlignID(),top));
case Faction.ALIGN_EVIL:
return Math.abs(getPercent(AlignID(),bottom) - pct);
case Faction.ALIGN_NEUTRAL:
return Math.abs(getPercent(AlignID(),(int)Math.round(CMath.div((top+bottom),2))) - pct);
default:
return 0;
}
}
// Please don't mock the name, I couldn't think of a better one. Sadly.
public int getAlignThingie(int AlignEq)
{
int bottom=Integer.MAX_VALUE;
int top=Integer.MIN_VALUE;
Vector ranges = getRanges(AlignID());
if(ranges==null) return 0;
for(int i=0;i<ranges.size();i++)
{
Faction.FactionRange R=(Faction.FactionRange)ranges.elementAt(i);
if(R.alignEquiv()==AlignEq) {
if(R.low()<bottom) bottom=R.low();
if(R.high()>top) top=R.high();
}
}
switch(AlignEq)
{
case Faction.ALIGN_GOOD:
return top;
case Faction.ALIGN_EVIL:
return bottom;
case Faction.ALIGN_NEUTRAL:
return (int)Math.round(CMath.div((top+bottom),2));
default:
return 0;
}
}
public int isFactionTag(String tag)
{
for(int i=0;i<Faction.ALL_TAGS.length;i++)
if(tag.equalsIgnoreCase(Faction.ALL_TAGS[i]))
return i;
else
if(Faction.ALL_TAGS[i].endsWith("*")&&tag.startsWith(Faction.ALL_TAGS[i].substring(0,Faction.ALL_TAGS[i].length()-1)))
return i;
return -1;
}
public int getAlignEquiv(String str)
{
if(str.equalsIgnoreCase(Faction.ALIGN_NAMES[Faction.ALIGN_GOOD]))
return Faction.ALIGN_GOOD;
else
if(str.equalsIgnoreCase(Faction.ALIGN_NAMES[Faction.ALIGN_NEUTRAL]))
return Faction.ALIGN_NEUTRAL;
else
if(str.equalsIgnoreCase(Faction.ALIGN_NAMES[Faction.ALIGN_EVIL]))
return Faction.ALIGN_EVIL;
else
return Faction.ALIGN_INDIFF;
}
}