package com.planet_ink.coffee_mud.Libraries;
import com.planet_ink.coffee_mud.core.interfaces.*;
import com.planet_ink.coffee_mud.Libraries.interfaces.*;
import com.planet_ink.coffee_mud.Libraries.interfaces.AbilityMapper.AbilityMapping;
import com.planet_ink.coffee_mud.Libraries.interfaces.XMLLibrary.XMLTag;
import com.planet_ink.coffee_mud.core.threads.ServiceEngine;
import com.planet_ink.coffee_mud.core.*;
import com.planet_ink.coffee_mud.core.CMSecurity.DbgFlag;
import com.planet_ink.coffee_mud.core.collections.*;
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.DefaultClan;
import com.planet_ink.coffee_mud.Common.interfaces.*;
import com.planet_ink.coffee_mud.Common.interfaces.Clan.AutoPromoteFlag;
import com.planet_ink.coffee_mud.Common.interfaces.Clan.FullMemberRecord;
import com.planet_ink.coffee_mud.Common.interfaces.Clan.Function;
import com.planet_ink.coffee_mud.Common.interfaces.Clan.Authority;
import com.planet_ink.coffee_mud.Common.interfaces.Clan.MemberRecord;
import com.planet_ink.coffee_mud.Common.interfaces.Clan.Trophy;
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.*;
/**
* Portions Copyright (c) 2003 Jeremy Vyska
* Portions Copyright (c) 2004-2016 Bo Zimmerman
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
public class Clans extends StdLibrary implements ClanManager
{
protected SHashtable<String,Clan> all = new SHashtable<String,Clan>();
protected List<Pair<Clan,Integer>> all2 = new Vector<Pair<Clan,Integer>>();
protected long lastGovernmentLoad = 0;
protected Map<String,Clan> webPathClanMappings = new SHashtable<String,Clan>();
protected Map<String,String> clanWebPathMappings = new SHashtable<String,String>();
@Override public String ID(){return "Clans";}
public boolean isCommonClanRelations(Clan C1, Clan C2, int relation)
{
if((C1==null)||(C2==null))
return relation==Clan.REL_NEUTRAL;
int i1=C1.getClanRelations(C2.clanID());
int i2=C2.getClanRelations(C1.clanID());
if((i1==i2)
&&((i1==Clan.REL_WAR)
||(i1==Clan.REL_ALLY)))
return i1==relation;
for(final Enumeration<Clan> e=clans();e.hasMoreElements();)
{
final Clan C=e.nextElement();
if((C!=C1)&&(C!=C2))
{
if((i1!=Clan.REL_WAR)
&&(C1.getClanRelations(C.clanID())==Clan.REL_ALLY)
&&(C.getClanRelations(C2.clanID())==Clan.REL_WAR))
i1=Clan.REL_WAR;
if((i2!=Clan.REL_WAR)
&&(C2.getClanRelations(C.clanID())==Clan.REL_ALLY)
&&(C.getClanRelations(C1.clanID())==Clan.REL_WAR))
i2=Clan.REL_WAR;
}
}
if(i1==i2)
return relation==i1;
if(Clan.REL_NEUTRALITYGAUGE[i1]<Clan.REL_NEUTRALITYGAUGE[i2])
return relation==i1;
return relation==i2;
}
@Override
public boolean isCommonClanRelations(String clanID1, String clanID2, int relation)
{
if((clanID1==null)||(clanID2==null)||(clanID1.length()==0)||(clanID2.length()==0))
return Clan.REL_NEUTRAL==relation;
return isCommonClanRelations(getClan(clanID1),getClan(clanID1), relation);
}
@Override
public boolean isAtClanWar(MOB M1, MOB M2)
{
final List<Pair<Clan,Clan>> pairs=findUncommonRivalrousClans(M1, M2);
for(final Pair<Clan,Clan> p : pairs)
if(isCommonClanRelations(p.first,p.second, Clan.REL_WAR))
return true;
return false;
}
@Override
public boolean checkClanPrivilege(MOB mob, Clan.Function func)
{
return findPrivilegedClan(mob,func)!=null;
}
@Override
public boolean checkClanPrivilege(MOB mob, String clanID, Clan.Function func)
{
if(mob==null)
return false;
final Pair<Clan,Integer> c=mob.getClanRole(clanID);
if(c==null)
return false;
if(c.first.getAuthority(c.second.intValue(), func) != Clan.Authority.CAN_NOT_DO)
return true;
return false;
}
@Override
public Pair<Clan,Integer> findPrivilegedClan(MOB mob, Clan.Function func)
{
for(final Pair<Clan,Integer> c : mob.clans())
{
if(c.first.getAuthority(c.second.intValue(), func) != Clan.Authority.CAN_NOT_DO)
return c;
}
return null;
}
@Override
public List<Pair<Clan,Integer>> findPrivilegedClans(MOB mob, Clan.Function func)
{
final List<Pair<Clan,Integer>> set=new Vector<Pair<Clan,Integer>>();
for(final Pair<Clan,Integer> c : mob.clans())
{
if(c.first.getAuthority(c.second.intValue(), func) != Clan.Authority.CAN_NOT_DO)
set.add(c);
}
return set;
}
@Override
public Clan findRivalrousClan(MOB mob)
{
for(final Pair<Clan,Integer> c : mob.clans())
{
if(c.first.isRivalrous())
{
return c.first;
}
}
return null;
}
@Override
public Clan findConquerableClan(MOB mob)
{
for(final Pair<Clan,Integer> c : mob.clans())
{
if(c.first.getGovernment().isConquestEnabled())
{
return c.first;
}
}
return null;
}
@Override
public List<Triad<Clan,Integer,Integer>> findCommonRivalrousClans(MOB mob1, MOB mob2)
{
final List<Triad<Clan,Integer,Integer>> list=new XVector<Triad<Clan,Integer,Integer>>(1,true);
if((mob1==null)||(mob2==null))
return list;
for(final Pair<Clan,Integer> c : mob1.clans())
{
if(c.first.isRivalrous())
{
final Pair<Clan,Integer> c2=mob2.getClanRole(c.first.clanID());
if(c2!=null)
list.add(new Triad<Clan,Integer,Integer>(c.first,c.second,c2.second));
}
}
return list;
}
@Override
public List<Pair<Clan,Integer>> findRivalrousClans(MOB mob)
{
final List<Pair<Clan,Integer>> list=new XVector<Pair<Clan,Integer>>(1,true);
for(final Pair<Clan,Integer> c : mob.clans())
if(c.first.isRivalrous())
list.add(c);
return list;
}
@Override
public List<Pair<Clan,Integer>> findRivalrousClans(MOB clanSourceMob, MOB filterMob)
{
final List<Pair<Clan,Integer>> list=new XVector<Pair<Clan,Integer>>(1,true);
if((clanSourceMob==null)||(filterMob==null))
return list;
for(final Pair<Clan,Integer> c : clanSourceMob.clans())
{
if(c.first.isRivalrous())
{
final Pair<Clan,Integer> c2=filterMob.getClanRole(c.first.clanID());
if(c2==null)
list.add(c);
}
}
return list;
}
public List<Pair<Clan,Clan>> findUncommonRivalrousClans(MOB M1, MOB M2)
{
final List<Pair<Clan,Clan>> list=new XVector<Pair<Clan,Clan>>(1,true);
if((M1==null)||(M2==null))
return list;
// i need the disunion here (what's the word for that?), as a order-irrelevant set of pairs
for(final Pair<Clan,Integer> c : M1.clans())
{
if(c.first.isRivalrous())
{
final Pair<Clan,Integer> c2=M2.getClanRole(c.first.clanID());
if(c2==null)
list.add(new Pair<Clan,Clan>(c.first,null));
}
}
final List<Pair<Clan,Clan>> finalList=new XVector<Pair<Clan,Clan>>(1,true);
for(final Pair<Clan,Clan> p : list)
for(final Pair<Clan,Integer> c : M2.clans())
if(c.first.isRivalrous())
finalList.add(new Pair<Clan,Clan>(p.first,c.first));
return finalList;
}
public List<Pair<Clan,Clan>> getAllClanPairs(MOB M1, MOB M2)
{
final List<Pair<Clan,Clan>> list=new XVector<Pair<Clan,Clan>>(1,true);
if((M1==null)||(M2==null))
return list;
// i need the disunion here (what's the word for that?), as a order-irrelevant set of pairs
for(final Pair<Clan,Integer> c : M1.clans())
list.add(new Pair<Clan,Clan>(c.first,null));
final List<Pair<Clan,Clan>> finalList=new XVector<Pair<Clan,Clan>>(1,true);
for(final Pair<Clan,Clan> p : list)
for(final Pair<Clan,Integer> c : M2.clans())
if(p.first!=c.first)
finalList.add(new Pair<Clan,Clan>(p.first,c.first));
return finalList;
}
public int getClanRelations(Clan C1, Clan C2)
{
if((C1==null)||(C2==null))
return Clan.REL_NEUTRAL;
final int i1=C1.getClanRelations(C2.clanID());
final int i2=C2.getClanRelations(C1.clanID());
final int rel=Clan.RELATIONSHIP_VECTOR[i1][i2];
if(rel==Clan.REL_WAR)
return Clan.REL_WAR;
if(rel==Clan.REL_ALLY)
return Clan.REL_ALLY;
for(final Enumeration<Clan> e=clans();e.hasMoreElements();)
{
final Clan C=e.nextElement();
if((C!=C1)
&&(C!=C2)
&&(((C1.getClanRelations(C.clanID())==Clan.REL_ALLY)&&(C.getClanRelations(C2.clanID())==Clan.REL_WAR)))
||((C2.getClanRelations(C.clanID())==Clan.REL_ALLY)&&(C.getClanRelations(C1.clanID())==Clan.REL_WAR)))
return Clan.REL_WAR;
}
return rel;
}
@Override
public int getClanRelations(String clanID1, String clanID2)
{
if((clanID1==null)||(clanID2==null)||(clanID1.length()==0)||(clanID2.length()==0))
return Clan.REL_NEUTRAL;
return getClanRelations(getClan(clanID1),getClan(clanID2));
}
@Override
public boolean findAnyClanRelations(MOB M1, MOB M2, int relation)
{
for(final Pair<Clan,Clan> c : getAllClanPairs(M1, M2))
if(getClanRelations(c.first, c.second)==relation)
return true;
return false;
}
@Override
public boolean isAnyCommonClan(MOB M1, MOB M2)
{
if((M1==null)||(M2==null))
return false;
for(final Pair<Clan,Integer> p : M1.clans())
if(M2.getClanRole(p.first.clanID())!=null)
return true;
return false;
}
@Override
public Clan getClan(String id)
{
if((id==null)||(id.length()==0))
return null;
Clan C=all.get(id.toUpperCase());
if(C!=null)
return C;
for(final Enumeration<Clan> e=all.elements();e.hasMoreElements();)
{
C=e.nextElement();
if(CMLib.english().containsString(CMStrings.removeColors(C.name()),id))
return C;
}
return null;
}
@Override
public Clan findClan(String id)
{
Clan C=getClan(id);
if(C!=null)
return C;
for(final Enumeration<Clan> e=all.elements();e.hasMoreElements();)
{
C=e.nextElement();
if(CMLib.english().containsString(CMStrings.removeColors(C.name()),id))
return C;
}
return null;
}
@Override
public boolean isFamilyOfMembership(MOB M, List<MemberRecord> members)
{
if(M == null)
return false;
if(members.contains(M.Name()))
return true;
if((M.getLiegeID().length()>0)
&&(M.isMarriedToLiege())
&&(members.contains(M.getLiegeID())))
return true;
for(final Enumeration<Tattoo> e=M.tattoos();e.hasMoreElements();)
{
final Tattoo T=e.nextElement();
if(T.getTattooName().startsWith("PARENT:"))
{
final String name=T.getTattooName().substring("PARENT:".length());
final MOB M2=CMLib.players().getLoadPlayer(name.toLowerCase());
if((M2 != null)&&isFamilyOfMembership(M2,members))
return true;
}
}
return false;
}
@Override
public Enumeration<Clan> clans()
{
return all.elements();
}
@Override
public int numClans()
{
return all.size();
}
@Override
public void addClan(Clan C)
{
synchronized(all)
{
if(!CMSecurity.isDisabled(CMSecurity.DisFlag.CLANTICKS))
CMLib.threads().startTickDown(C,Tickable.TICKID_CLAN,(int)CMProps.getTicksPerDay());
all.put(C.clanID().toUpperCase(),C);
all2.add(new Pair<Clan,Integer>(C,Integer.valueOf(C.getGovernment().getAcceptPos())));
setClanWebSiteMappings(C,CMProps.getVar(CMProps.Str.CLANWEBSITES));
CMLib.journals().registerClanForum(C,CMProps.getVar(CMProps.Str.CLANFORUMDATA));
CMLib.map().sendGlobalMessage(CMLib.map().deity(), CMMsg.TYP_CLANEVENT,
CMClass.getMsg(CMLib.map().deity(), CMMsg.MSG_CLANEVENT, "+"+C.name()));
}
}
@Override
public void removeClan(Clan C)
{
synchronized(all)
{
CMLib.threads().deleteTick(C,Tickable.TICKID_CLAN);
all.remove(C.clanID().toUpperCase());
for(final Pair<Clan,Integer> p : all2)
if(p.first==C)
{
all2.remove(p);
break;
}
setClanWebSiteMappings(C,null); // will delete mapping
CMLib.journals().registerClanForum(C,null); // will remove mapping
CMLib.map().sendGlobalMessage(CMLib.map().deity(), CMMsg.TYP_CLANEVENT,
CMClass.getMsg(CMLib.map().deity(), CMMsg.MSG_CLANEVENT, "-"+C.name()));
}
}
@Override
public void tickAllClans()
{
for(final Enumeration<Clan> e=clans();e.hasMoreElements();)
{
final Clan C=e.nextElement();
C.tick(C,Tickable.TICKID_CLAN);
}
}
@Override
public void clanAnnounceAll(String msg)
{
final List<String> channels=CMLib.channels().getFlaggedChannelNames(ChannelsLibrary.ChannelFlag.CLANINFO);
for(int i=0;i<channels.size();i++)
CMLib.commands().postChannel(channels.get(i),clanRoles(),msg,true);
}
@Override public Enumeration<String> clansNames(){return all.keys();}
@Override public Iterable<Pair<Clan,Integer>> clanRoles(){return all2;}
@Override
public String translatePrize(Trophy trophy)
{
String prizeStr="";
switch(trophy)
{
case Areas: prizeStr=CMProps.getVar(CMProps.Str.CLANTROPAREA); break;
case Points: prizeStr=CMProps.getVar(CMProps.Str.CLANTROPCP); break;
case Experience: prizeStr=CMProps.getVar(CMProps.Str.CLANTROPEXP); break;
case PlayerKills: prizeStr=CMProps.getVar(CMProps.Str.CLANTROPPK); break;
case Members: prizeStr=CMProps.getVar(CMProps.Str.CLANTROPMB); break;
case MemberLevel: prizeStr=CMProps.getVar(CMProps.Str.CLANTROPLVL); break;
}
if(prizeStr.length()==0)
return "None";
if(prizeStr.length()>0)
{
final Vector<String> V=CMParms.parse(prizeStr);
if(V.size()>=2)
{
final String type=V.lastElement().toUpperCase();
final String amt=V.firstElement();
if("EXPERIENCE".startsWith(type))
return amt+" experience point bonus.";
}
}
return prizeStr;
}
@Override
public boolean trophySystemActive()
{
return (CMProps.getVar(CMProps.Str.CLANTROPAREA).length()>0)
|| (CMProps.getVar(CMProps.Str.CLANTROPCP).length()>0)
|| (CMProps.getVar(CMProps.Str.CLANTROPEXP).length()>0)
|| (CMProps.getVar(CMProps.Str.CLANTROPMB).length()>0)
|| (CMProps.getVar(CMProps.Str.CLANTROPLVL).length()>0)
|| (CMProps.getVar(CMProps.Str.CLANTROPPK).length()>0);
}
@Override
public boolean goForward(MOB mob, Clan C, List<String> commands, Clan.Function function, boolean voteIfNecessary)
{
if((mob==null)||(C==null))
return false;
final Pair<Clan,Integer> clanRole=mob.getClanRole(C.clanID());
if(clanRole==null)
return false;
final int role=clanRole.second.intValue();
final Clan.Authority allowed=C.getAuthority(role,function);
if(allowed==Clan.Authority.CAN_DO)
return true;
if(allowed==Clan.Authority.CAN_NOT_DO)
return false;
if(function==Clan.Function.ASSIGN)
{
if(C.getAuthority(role,Clan.Function.VOTE_ASSIGN)!=Clan.Authority.CAN_DO)
return false;
}
else
if(C.getAuthority(role,Clan.Function.VOTE_OTHER)!=Clan.Authority.CAN_DO)
return false;
if(!voteIfNecessary)
return true;
final String matter=CMParms.combine(commands,0);
for(final Enumeration<Clan.ClanVote> e=C.votes();e.hasMoreElements();)
{
final Clan.ClanVote CV=e.nextElement();
if((CV.voteStarter.equalsIgnoreCase(mob.Name()))
&&(CV.voteStatus==Clan.VSTAT_STARTED))
{
mob.tell(L("This matter must be voted upon, but you already have a vote underway."));
return false;
}
if(CV.matter.equalsIgnoreCase(matter))
{
mob.tell(L("This matter must be voted upon, and is already BEING voted upon. Use CLANVOTE to see."));
return false;
}
}
if(mob.session()==null)
return false;
try
{
final int numVotes=C.getNumVoters(function);
if(numVotes==1)
return true;
if(mob.session().confirm(L("This matter must be voted upon. Would you like to start the vote now (y/N)?"),"N"))
{
final Clan.ClanVote CV=new Clan.ClanVote();
CV.matter=matter;
CV.voteStarter=mob.Name();
CV.function=function.ordinal();
CV.voteStarted=System.currentTimeMillis();
CV.votes=new PairVector<String,Boolean>();
CV.voteStatus=Clan.VSTAT_STARTED;
C.addVote(CV);
C.updateVotes();
final Clan.Function voteFunctionType = (function == Clan.Function.ASSIGN) ? Clan.Function.VOTE_ASSIGN : Clan.Function.VOTE_OTHER;
final List<Integer> votingRoles = new Vector<Integer>();
for(int i=0;i<C.getRolesList().length;i++)
if(C.getAuthority(i, voteFunctionType)==Clan.Authority.CAN_DO)
votingRoles.add(Integer.valueOf(i));
if(votingRoles.size()>0)
{
final String firstRoleName = C.getRoleName(votingRoles.iterator().next().intValue(), true, true);
final String rest = " "+firstRoleName+" should use CLANVOTE to participate.";
if(votingRoles.size() >= (C.getRolesList().length-2))
{
if(function == Clan.Function.ASSIGN)
clanAnnounce(mob,"The "+C.getGovernmentName()+" "+C.clanID()+" has a new election to vote upon. "+rest);
else
clanAnnounce(mob,"The "+C.getGovernmentName()+" "+C.clanID()+" has a new matter to vote upon. "+rest);
}
else
if(votingRoles.size()==1)
clanAnnounce(mob,"The "+C.getGovernmentName()+" "+C.clanID()+" has a new matter to vote upon. "+rest);
else
{
final String[] roleNames = new String[votingRoles.size()];
for(int i=0;i<votingRoles.size();i++)
{
final Integer roleID=votingRoles.get(i);
roleNames[i]=C.getRoleName(roleID.intValue(), true, true);
}
final String list = CMLib.english().toEnglishStringList(roleNames);
clanAnnounce(mob,"The "+C.getGovernmentName()+" "+C.clanID()+" has a new matter to vote upon. "
+list+" should use CLANVOTE to participate.");
}
}
mob.tell(L("Your vote has started. Use CLANVOTE to cast your vote."));
return false;
}
}
catch(final java.io.IOException e){}
mob.tell(L("Without a vote, this command can not be executed."));
return false;
}
protected String indt(int x)
{
return CMStrings.SPACES.substring(0,x*4);
}
@Override
public long getLastGovernmentLoad()
{
return lastGovernmentLoad;
}
@Override
public String getGovernmentHelp(MOB mob, String named, boolean exact)
{
ClanGovernment helpG=null;
for(final ClanGovernment G : getStockGovernments())
if(G.getName().equalsIgnoreCase(named))
helpG=G;
if((helpG==null)&&(exact))
return null;
if(helpG==null)
for(final ClanGovernment G : getStockGovernments())
if(G.getName().toUpperCase().startsWith(named.toUpperCase()))
helpG=G;
if(helpG==null)
{
final List<ClanGovernment> gtypes=new Vector<ClanGovernment>();
String name=null;
for(final ClanGovernment G : getStockGovernments())
for(final ClanPosition P : G.getPositions())
if(P.getName().equalsIgnoreCase(named)||P.getPluralName().equalsIgnoreCase(named))
{
gtypes.add(G);
name=P.getName();
}
if(gtypes.size()==0)
{
if(exact)
return null;
for(final ClanGovernment G : getStockGovernments())
for(final ClanPosition P : G.getPositions())
if(P.getName().toUpperCase().startsWith(named.toUpperCase())
||P.getPluralName().toUpperCase().startsWith(named.toUpperCase()))
{
gtypes.add(G);
name=P.getName();
}
}
if(gtypes.size()==0)
return null;
final String[] typeNames=new String[gtypes.size()];
for(int g=0;g<gtypes.size();g++)
typeNames[g]=CMStrings.capitalizeAndLower(gtypes.get(g).getName());
return "The "+name+" is a rank or position within the following clan types: "
+CMLib.english().toEnglishStringList(typeNames)
+". Please see help on CLAN or on one of the listed clan types for more information. ";
}
return helpG.getHelpStr();
}
@Override
public ClanGovernment createSampleGovernment()
{
final Authority[] pows1=new Authority[Function.values().length];
for(int i=0;i<pows1.length;i++) pows1[i]=Authority.CAN_NOT_DO;
final Authority[] pows2=new Authority[Function.values().length];
for(int i=0;i<pows2.length;i++) pows2[i]=Authority.CAN_DO;
final ClanPosition P1=(ClanPosition)CMClass.getCommon("DefaultClanPosition");
P1.setID("APPLICANT");
P1.setRoleID(0);
P1.setRank(0);
P1.setName(L("Applicant"));
P1.setPluralName("Applicants");
P1.setMax(Integer.MAX_VALUE);
P1.setInnerMaskStr("");
P1.setFunctionChart(pows1);
P1.setPublic(false);
final ClanPosition P2=(ClanPosition)CMClass.getCommon("DefaultClanPosition");
P2.setID("MEMBER");
P2.setRoleID(1);
P2.setRank(1);
P2.setName(L("Member"));
P2.setPluralName("Members");
P2.setMax(Integer.MAX_VALUE);
P2.setInnerMaskStr("");
P2.setFunctionChart(pows2);
P2.setPublic(false);
final Set<Integer> usedTypeIDs=new HashSet<Integer>();
final ClanGovernment[] gvts=(ClanGovernment[])Resources.getResource("parsed_clangovernments");
int id=0;
if(gvts!=null)
{
for(final ClanGovernment G2 : gvts)
usedTypeIDs.add(Integer.valueOf(G2.getID()));
for(int i=0;i<gvts.length;i++)
if(!usedTypeIDs.contains(Integer.valueOf(i)))
{
id=i; break;
}
}
final ClanGovernment G=(ClanGovernment)CMClass.getCommon("DefaultClanGovernment");
G.setID(id);
G.setName(L("Sample Govt"));
G.setCategory("");
G.setPositions(new ClanPosition[]{P1,P2});
G.setAutoRole(0);
G.setAcceptPos(1);
G.setRequiredMaskStr("");
G.setEntryScript("");
G.setExitScript("");
G.setAutoPromoteBy(AutoPromoteFlag.NONE);
G.setPublic(true);
G.setFamilyOnly(false);
G.setOverrideMinMembers(Integer.valueOf(1));
G.setConquestEnabled(true);
G.setConquestItemLoyalty(true);
G.setConquestByWorship(false);
G.setShortDesc("Change Me!");
G.setLongDesc("");
G.setMaxVoteDays(10);
G.setRivalrous(true);
G.setVoteQuorumPct(66);
G.setDefault(true);
return G;
}
@Override
public void reSaveGovernmentsXML()
{
final ClanGovernment[] govt = getStockGovernments();
final String xml = makeGovernmentXML(govt);
if(!Resources.updateFileResource("clangovernments.xml", xml))
{
Log.errOut("Clans","Can't save clangovernments.xml");
}
Resources.removeResource("parsed_clangovernments");
getStockGovernments();
}
@Override
public ClanGovernment createGovernment(String name)
{
final ClanGovernment[] gvts=getStockGovernments();
final List<ClanGovernment> govts = new SVector<ClanGovernment>(gvts);
for(final ClanGovernment G : gvts)
if(G.getName().equalsIgnoreCase(name))
return null;
final ClanGovernment newG=createSampleGovernment();
final Set<Integer> takenIDs=new HashSet<Integer>();
for(final ClanGovernment g : gvts)
takenIDs.add(Integer.valueOf(g.getID()));
int newID=CMLib.dice().roll(1, Integer.MAX_VALUE, 0);
for(int i=0;i<gvts.length+1;i++)
if(!takenIDs.contains(Integer.valueOf(i)))
newID=i;
newG.setID(newID);
newG.setName(name);
govts.add(newG);
Resources.submitResource("parsed_clangovernments", govts.toArray(new ClanGovernment[0]));
return newG;
}
@Override
public boolean removeGovernment(ClanGovernment government)
{
final ClanGovernment[] gvts=getStockGovernments();
if(gvts.length==1)
return false;
final List<ClanGovernment> govts = new SVector<ClanGovernment>(gvts);
govts.remove(government);
if(govts.size()==gvts.length)
return false;
Resources.submitResource("parsed_clangovernments", govts.toArray(new ClanGovernment[0]));
return true;
}
@Override
public ClanGovernment[] getStockGovernments()
{
ClanGovernment[] gvts=(ClanGovernment[])Resources.getResource("parsed_clangovernments");
if(gvts==null)
{
synchronized(this)
{
gvts=(ClanGovernment[])Resources.getResource("parsed_clangovernments");
if(gvts==null)
{
final StringBuffer str=Resources.getFileResource("clangovernments.xml", true);
if(str==null)
gvts=new ClanGovernment[0];
else
{
gvts=parseGovernmentXML(str);
}
if((gvts==null)||(gvts.length==0))
{
final ClanGovernment gvt=createSampleGovernment();
gvt.setDefault(true);
gvts=new ClanGovernment[]{gvt};
}
lastGovernmentLoad=System.currentTimeMillis();
Resources.submitResource("parsed_clangovernments",gvts);
}
}
}
return gvts;
}
@Override
public ClanGovernment getDefaultGovernment()
{
final ClanGovernment[] gvts=getStockGovernments();
for(final ClanGovernment gvt : gvts)
{
if(gvt.isDefault())
return gvt;
}
return gvts[0];
}
@Override
public ClanGovernment getStockGovernment(int typeid)
{
final ClanGovernment[] gvts=getStockGovernments();
if(gvts.length <= typeid)
{
Log.errOut("Clans","Someone mistakenly requested stock government typeid "+typeid);
return gvts[0];
}
return gvts[typeid];
}
@Override
public String makeGovernmentXML(ClanGovernment gvt)
{
final StringBuilder str=new StringBuilder("");
str.append("<CLANTYPE ").append("TYPEID="+gvt.getID()+" ").append("NAME=\""+gvt.getName()+"\" ").append("CATEGORY=\""+gvt.getCategory()+"\"").append(">\n");
if(gvt.isDefault())
str.append(indt(1)).append("<ISDEFAULT>true</ISDEFAULT>\n");
str.append(indt(1)).append("<SHORTDESC>").append(CMLib.xml().parseOutAngleBrackets(gvt.getShortDesc())).append("</SHORTDESC>\n");
str.append(indt(1)).append("<LONGDESC>").append(CMLib.xml().parseOutAngleBrackets(gvt.getLongDesc())).append("</LONGDESC>\n");
str.append(indt(1)).append("<POSITIONS>\n");
final Set<Clan.Function> voteSet = new HashSet<Clan.Function>();
for(int p=gvt.getPositions().length-1;p>=0;p--)
{
final ClanPosition pos = gvt.getPositions()[p];
str.append(indt(2)).append("<POSITION ").append("ID=\""+pos.getID()+"\" ").append("ROLEID="+pos.getRoleID()+" ")
.append("RANK="+pos.getRank()+" ").append("NAME=\""+pos.getName()+"\" ").append("PLURAL=\""+pos.getPluralName()+"\" ")
.append("MAX="+pos.getMax()+" ").append("INNERMASK=\""+CMLib.xml().parseOutAngleBrackets(pos.getInnerMaskStr())+"\" ")
.append("PUBLIC=\""+pos.isPublic()+"\">\n");
for(final Clan.Function func : Clan.Function.values())
if(pos.getFunctionChart()[func.ordinal()]==Clan.Authority.CAN_DO)
str.append(indt(3)).append("<POWER>").append(func.toString()).append("</POWER>\n");
else
if(pos.getFunctionChart()[func.ordinal()]==Clan.Authority.MUST_VOTE_ON)
voteSet.add(func);
str.append(indt(2)).append("</POSITION>\n");
}
str.append(indt(1)).append("</POSITIONS>\n");
if(voteSet.size()==0)
str.append(indt(1)).append("<VOTING />\n");
else
{
str.append(indt(1)).append("<VOTING ").append("MAXDAYS="+gvt.getMaxVoteDays()+" QUORUMPCT="+gvt.getVoteQuorumPct()+">\n");
for(final Clan.Function func : voteSet)
str.append(indt(2)).append("<POWER>").append(func.toString()).append("</POWER>\n");
str.append(indt(1)).append("</VOTING>\n");
}
str.append(indt(1)).append("<AUTOPOSITION>").append(gvt.getPositions()[gvt.getAutoRole()].getID()).append("</AUTOPOSITION>\n");
str.append(indt(1)).append("<ACCEPTPOSITION>").append(gvt.getPositions()[gvt.getAcceptPos()].getID()).append("</ACCEPTPOSITION>\n");
str.append(indt(1)).append("<REQUIREDMASK>").append(CMLib.xml().parseOutAngleBrackets(gvt.getRequiredMaskStr())).append("</REQUIREDMASK>\n");
str.append(indt(1)).append("<ENTRYSCRIPT>").append(CMLib.xml().parseOutAngleBrackets(gvt.getEntryScript())).append("</ENTRYSCRIPT>\n");
str.append(indt(1)).append("<EXITSCRIPT>").append(CMLib.xml().parseOutAngleBrackets(gvt.getExitScript())).append("</EXITSCRIPT>\n");
str.append(indt(1)).append("<AUTOPROMOTEBY>").append(gvt.getAutoPromoteBy().toString()).append("</AUTOPROMOTEBY>\n");
str.append(indt(1)).append("<PUBLIC>").append(gvt.isPublic()).append("</PUBLIC>\n");
str.append(indt(1)).append("<FAMILYONLY>").append(gvt.isFamilyOnly()).append("</FAMILYONLY>\n");
str.append(indt(1)).append("<RIVALROUS>").append(gvt.isRivalrous()).append("</RIVALROUS>\n");
str.append(indt(1)).append("<XPPERLEVELFORMULA>").append(gvt.getXpCalculationFormulaStr()).append("</XPPERLEVELFORMULA>\n");
if(gvt.getOverrideMinMembers() == null)
str.append(indt(1)).append("<OVERRIDEMINMEMBERS />\n");
else
str.append(indt(1)).append("<OVERRIDEMINMEMBERS>").append(gvt.getOverrideMinMembers().toString()).append("</OVERRIDEMINMEMBERS>\n");
str.append(indt(1)).append("<CONQUEST>\n");
{
str.append(indt(2)).append("<ENABLED>").append(gvt.isConquestEnabled()).append("</ENABLED>\n");
str.append(indt(2)).append("<ITEMLOYALTY>").append(gvt.isConquestItemLoyalty()).append("</ITEMLOYALTY>\n");
str.append(indt(2)).append("<DEITYBASIS>").append(gvt.isConquestByWorship()).append("</DEITYBASIS>\n");
}
str.append(indt(1)).append("</CONQUEST>\n");
gvt.getClanLevelAbilities(null,null,Integer.valueOf(Integer.MAX_VALUE));
final Enumeration<AbilityMapping> m= CMLib.ableMapper().getClassAbles(gvt.getName(), false);
if(!m.hasMoreElements())
str.append(indt(1)).append("<ABILITIES />\n");
else
{
str.append(indt(1)).append("<ABILITIES>\n");
for(;m.hasMoreElements();)
{
final AbilityMapping map=m.nextElement();
final String addExt;
if(map.extFields().size()>0)
{
final List<String> posNames=new ArrayList<String>();
for(String I : map.extFields().keySet())
{
final ClanPosition P=gvt.findPositionRole(I);
if(P!=null)
posNames.add(P.getID());
}
addExt="ROLES=\""+CMParms.toListString(posNames)+"\" ";
}
else
addExt="";
str.append(indt(2)).append("<ABILITY ID=\""+map.abilityID()+"\" PROFF="+map.defaultProficiency()+" LEVEL="+map.qualLevel()+" QUALIFYONLY="+(!map.autoGain())+" "+addExt+"/>\n");
}
str.append(indt(1)).append("</ABILITIES>\n");
}
final int numEffects=CMath.s_int(gvt.getStat("NUMREFF"));
if(numEffects==0)
str.append(indt(1)).append("<EFFECTS />\n");
else
{
str.append(indt(1)).append("<EFFECTS>\n");
for(int a=0;a<numEffects;a++)
{
final String ableID=gvt.getStat("GETREFF"+a);
final String ableParm=gvt.getStat("GETREFFPARM"+a);
final int lvl = CMath.s_int(gvt.getStat("GETREFFLVL"+a));
final String roleList=gvt.getStat("GETREFFROLE"+a);
final String addExt;
if(roleList.trim().length()>0)
{
final List<String> posNames=new ArrayList<String>();
for(String I : CMParms.parseCommas(roleList,true))
{
final ClanPosition P=gvt.findPositionRole(I);
if(P!=null)
posNames.add(P.getID());
}
addExt="ROLES=\""+CMParms.toListString(posNames)+"\" ";
}
else
addExt="";
str.append(indt(2)).append("<EFFECT ID=\""+ableID+"\" LEVEL="+lvl+" PARMS=\""+CMLib.xml().parseOutAngleBrackets(ableParm)+"\" "+addExt+"/>\n");
}
str.append(indt(1)).append("</EFFECTS>\n");
}
str.append("</CLANTYPE>\n");
return str.toString();
}
@Override
public String makeGovernmentXML(ClanGovernment gvts[])
{
final StringBuilder str=new StringBuilder("");
str.append("<CLANTYPES>\n");
for(final ClanGovernment gvt : gvts)
str.append(makeGovernmentXML(gvt));
str.append("</CLANTYPES>\n");
return str.toString();
}
@Override
public List<Pair<Clan,Integer>> getClansByCategory(MOB M, String category)
{
final List<Pair<Clan,Integer>> list=new Vector<Pair<Clan,Integer>>(1);
if(M==null)
return list;
if(category==null)
category="";
for(final Pair<Clan,Integer> p : M.clans())
if(p.first.getCategory().equalsIgnoreCase(category))
list.add(p);
return list;
}
@Override
public ClanGovernment[] parseGovernmentXML(StringBuffer xml)
{
final List<XMLLibrary.XMLTag> xmlV = CMLib.xml().parseAllXML(xml);
final XMLTag clanTypesTag = CMLib.xml().getPieceFromPieces(xmlV, "CLANTYPES");
List<XMLLibrary.XMLTag> clanTypes = null;
if(clanTypesTag != null)
clanTypes = clanTypesTag.contents();
else
{
final XMLLibrary.XMLTag clanType = CMLib.xml().getPieceFromPieces(xmlV, "CLANTYPE");
if(clanType != null)
{
clanTypes = new SVector<XMLLibrary.XMLTag>();
clanTypes.add(clanType);
}
else
{
Log.errOut("Clans","No CLANTYPES found in xml");
return null;
}
}
final List<ClanGovernment> governments=new SVector<ClanGovernment>();
for(final XMLTag clanTypePieceTag : clanTypes)
{
final String typeName=clanTypePieceTag.parms().get("NAME");
final int typeID=CMath.s_int(clanTypePieceTag.parms().get("TYPEID"));
final boolean isDefault=CMath.s_bool(clanTypePieceTag.parms().get("ISDEFAULT"));
String category=clanTypePieceTag.parms().get("CATEGORY");
if(category==null)
category="";
final Authority[] baseFunctionChart = new Authority[Function.values().length];
for(int i=0;i<Function.values().length;i++)
baseFunctionChart[i]=Authority.CAN_NOT_DO;
final XMLTag votingTag = clanTypePieceTag.getPieceFromPieces( "VOTING");
final int maxVotingDays = CMath.s_int(votingTag.parms().get("MAXDAYS"));
final int minVotingPct = CMath.s_int(votingTag.parms().get("QUORUMPCT"));
for(final XMLTag piece : votingTag.contents())
{
if(piece.tag().equalsIgnoreCase("POWER"))
{
final Function power = (Function)CMath.s_valueOf(Clan.Function.values(),piece.value());
if(power == null)
Log.errOut("Clans","Illegal power found in xml: "+piece.value());
else
baseFunctionChart[power.ordinal()] = Authority.MUST_VOTE_ON;
}
}
final List<ClanPosition> positions=new SVector<ClanPosition>();
final XMLTag positionsTag = clanTypePieceTag.getPieceFromPieces( "POSITIONS");
for(final XMLTag posPiece : positionsTag.contents())
{
if(posPiece.tag().equalsIgnoreCase("POSITION"))
{
final Authority[] functionChart = baseFunctionChart.clone();
final String ID=posPiece.parms().get("ID");
final int roleID=CMath.s_int(posPiece.parms().get("ROLEID"));
final int rank=CMath.s_int(posPiece.parms().get("RANK"));
final String name=posPiece.parms().get("NAME");
final String pluralName=posPiece.parms().get("PLURAL");
final int max=CMath.s_int(posPiece.parms().get("MAX"));
final boolean isPublic=CMath.s_bool(posPiece.parms().get("PUBLIC"));
final String innerMaskStr=CMLib.xml().restoreAngleBrackets(posPiece.parms().get("INNERMASK"));
for(final XMLTag powerPiece : posPiece.contents())
{
if(powerPiece.tag().equalsIgnoreCase("POWER"))
{
final Function power = (Function)CMath.s_valueOf(Clan.Function.values(),powerPiece.value());
if(power == null)
Log.errOut("Clans","Illegal power found in xml: "+powerPiece.value());
else
functionChart[power.ordinal()] = Authority.CAN_DO;
}
}
final ClanPosition P=(ClanPosition)CMClass.getCommon("DefaultClanPosition");
P.setID(ID);
P.setRoleID(roleID);
P.setRank(rank);
P.setName(name);
P.setPluralName(pluralName);
P.setMax(max);
P.setInnerMaskStr(innerMaskStr);
P.setFunctionChart(functionChart);
P.setPublic(isPublic);
positions.add(P);
}
}
ClanPosition[] posArray = new ClanPosition[positions.size()];
for(final ClanPosition pos : positions)
if((pos.getRoleID()>=0)&&(pos.getRoleID()<positions.size()))
if(posArray[pos.getRoleID()]!=null)
{
Log.errOut("Clans","Bad ROLEID "+pos.getRoleID()+" in positions list in "+typeName);
posArray=new ClanPosition[0];
break;
}
else
{
posArray[pos.getRoleID()]=pos;
}
if(posArray.length==0)
{
Log.errOut("Clans","Missing positions in "+typeName);
continue;
}
final String autoRoleStr=clanTypePieceTag.getValFromPieces( "AUTOPOSITION");
ClanPosition autoRole=null;
for(final ClanPosition pos : positions)
if(pos.getID().equalsIgnoreCase(autoRoleStr) )
autoRole=pos;
if(autoRole==null)
{
Log.errOut("Clans","Illegal role found in xml: "+autoRoleStr);
continue;
}
final String acceptRoleStr=clanTypePieceTag.getValFromPieces( "ACCEPTPOSITION");
ClanPosition acceptRole=null;
for(final ClanPosition pos : positions)
if(pos.getID().equalsIgnoreCase(acceptRoleStr) )
acceptRole=pos;
if(acceptRole==null)
{
Log.errOut("Clans","Illegal acceptRole found in xml: "+acceptRoleStr);
continue;
}
final String requiredMaskStr=CMLib.xml().restoreAngleBrackets(clanTypePieceTag.getValFromPieces( "REQUIREDMASK"));
final String entryScript=CMLib.xml().restoreAngleBrackets(clanTypePieceTag.getValFromPieces( "ENTRYSCRIPT"));
final String exitScript=CMLib.xml().restoreAngleBrackets(clanTypePieceTag.getValFromPieces( "EXITSCRIPT"));
final String shortDesc=CMLib.xml().restoreAngleBrackets(clanTypePieceTag.getValFromPieces( "SHORTDESC"));
final String longDesc=CMLib.xml().restoreAngleBrackets(clanTypePieceTag.getValFromPieces( "LONGDESC"));
final String autoPromoteStr=clanTypePieceTag.getValFromPieces( "AUTOPROMOTEBY");
final Clan.AutoPromoteFlag autoPromote = AutoPromoteFlag.valueOf(autoPromoteStr);
if(autoPromote==null)
{
Log.errOut("Clans","Illegal AUTOPROMOTEBY found in xml: "+autoPromoteStr);
continue;
}
final boolean isPublic=CMath.s_bool(clanTypePieceTag.getValFromPieces( "PUBLIC"));
final boolean isFamilyOnly=CMath.s_bool(clanTypePieceTag.getValFromPieces( "FAMILYONLY"));
final String overrideMinMembersStr=clanTypePieceTag.getValFromPieces( "OVERRIDEMINMEMBERS");
Integer overrideMinMembers = null;
if((overrideMinMembersStr!=null)&&CMath.isInteger(overrideMinMembersStr))
overrideMinMembers=Integer.valueOf(CMath.s_int(overrideMinMembersStr));
boolean isRivalrous=true;
final String rivalrousStr=clanTypePieceTag.getValFromPieces( "RIVALROUS");
if(CMath.isBool(rivalrousStr))
isRivalrous=CMath.s_bool(rivalrousStr);
final String xpPerLevelFormulaStr=clanTypePieceTag.getValFromPieces( "XPPERLEVELFORMULA");
final XMLTag conquestTag = clanTypePieceTag.getPieceFromPieces( "CONQUEST");
boolean conquestEnabled=true;
boolean conquestItemLoyalty=true;
boolean conquestDeityBasis=false;
if(conquestTag!=null)
{
conquestEnabled=CMath.s_bool(conquestTag.getValFromPieces( "ENABLED"));
conquestItemLoyalty=CMath.s_bool(conquestTag.getValFromPieces( "ITEMLOYALTY"));
conquestDeityBasis=CMath.s_bool(conquestTag.getValFromPieces( "DEITYBASIS"));
}
final ClanGovernment G=(ClanGovernment)CMClass.getCommon("DefaultClanGovernment");
G.setID(typeID);
G.setName(typeName);
G.setCategory(category);
G.setPositions(posArray);
G.setAutoRole(autoRole.getRoleID());
G.setAcceptPos(acceptRole.getRoleID());
G.setRequiredMaskStr(requiredMaskStr);
G.setEntryScript(entryScript);
G.setExitScript(exitScript);
G.setAutoPromoteBy(autoPromote);
G.setPublic(isPublic);
G.setFamilyOnly(isFamilyOnly);
G.setOverrideMinMembers(overrideMinMembers);
G.setConquestEnabled(conquestEnabled);
G.setConquestItemLoyalty(conquestItemLoyalty);
G.setConquestByWorship(conquestDeityBasis);
G.setShortDesc(shortDesc);
G.setLongDesc(longDesc);
G.setXpCalculationFormulaStr(xpPerLevelFormulaStr);
G.setMaxVoteDays(maxVotingDays);
G.setRivalrous(isRivalrous);
G.setVoteQuorumPct(minVotingPct);
G.setDefault(isDefault);
final XMLTag abilitiesTag = clanTypePieceTag.getPieceFromPieces( "ABILITIES");
if((abilitiesTag!=null)&&(abilitiesTag.contents()!=null)&&(abilitiesTag.contents().size()>0))
{
G.setStat("NUMRABLE", Integer.toString(abilitiesTag.contents().size()));
for(int x=0;x<abilitiesTag.contents().size();x++)
{
final XMLTag able = abilitiesTag.contents().get(x);
G.setStat("GETRABLE"+x, able.parms().get("ID"));
G.setStat("GETRABLEPROF"+x, able.parms().get("PROFF"));
G.setStat("GETRABLEQUAL"+x, able.parms().get("QUALIFYONLY"));
G.setStat("GETRABLELVL"+x, able.parms().get("LEVEL"));
G.setStat("GETRABLEROLE"+x, able.parms().get("ROLES"));
}
}
final XMLTag effectsTag = clanTypePieceTag.getPieceFromPieces( "EFFECTS");
if((effectsTag!=null)&&(effectsTag.contents()!=null)&&(effectsTag.contents().size()>0))
{
G.setStat("NUMREFF", Integer.toString(effectsTag.contents().size()));
for(int x=0;x<effectsTag.contents().size();x++)
{
final XMLTag able = effectsTag.contents().get(x);
G.setStat("GETREFF"+x, able.parms().get("ID"));
G.setStat("GETREFFPARM"+x, CMLib.xml().restoreAngleBrackets(able.parms().get("PARMS")));
G.setStat("GETREFFLVL"+x, able.parms().get("LEVEL"));
G.setStat("GETREFFROLE"+x, able.parms().get("ROLES"));
}
}
governments.add(G);
}
final ClanGovernment[] govts=new ClanGovernment[governments.size()];
for(final ClanGovernment govt : governments)
if((govt.getID() < 0)||(govt.getID() >=governments.size()) || (govts[govt.getID()]!=null))
{
Log.errOut("Clans","Bad TYPEID "+govt.getID());
return new ClanGovernment[0];
}
else
govts[govt.getID()]=govt;
if(governments.size()>0)
{
for(int i=0;i<govts.length;i++)
if(govts[i]==null)
govts[i]=governments.get(0);
return govts;
}
else
{
return null;
}
}
@Override
public Clan getWebPathClanMapping(String webPath)
{
if(webPath==null)
return null;
return this.webPathClanMappings.get(webPath.toLowerCase().trim());
}
@Override
public String getClanWebTemplateDir(String webPath)
{
if(webPath==null)
return null;
return this.clanWebPathMappings.get(webPath.toLowerCase().trim());
}
private void setClanWebSiteMappings(Clan clan, String allMappingsStr)
{
for(final Iterator<String> keyIter = this.webPathClanMappings.keySet().iterator();keyIter.hasNext();)
{
final String key=keyIter.next();
final Clan foundClan = this.webPathClanMappings.get(key);
if(foundClan == clan)
{
keyIter.remove();
clanWebPathMappings.remove(key);
}
}
if(allMappingsStr==null)
return;
final List<String> set=CMParms.parseCommas(allMappingsStr,true);
for(String s : set)
{
final String originalS=s;
s=s.trim();
if(s.startsWith("["))
{
int x=s.indexOf(']');
final String cat=s.substring(1,x).trim();
if(clan.getGovernment().getCategory().equalsIgnoreCase(cat))
{
s=s.substring(x+1).trim();
x=s.lastIndexOf(' ');
if(x>0)
{
String siteFilesPathStr=CMStrings.replaceAll(s.substring(0,x),"<CLANNAME>",clan.clanID());
siteFilesPathStr=CMStrings.replaceAll(siteFilesPathStr,"<CLANTYPE>",clan.getGovernmentName());
final String siteFilesPath = new CMFile(siteFilesPathStr.trim(),null).getAbsolutePath();
final String siteTemplatePath = new CMFile(s.substring(x+1).trim(),null).getAbsolutePath();
if(webPathClanMappings.containsKey(siteFilesPath.toLowerCase()))
{
Log.errOut("Clans","Multiple clans at same webclansites path: in coffeemud.ini: "+originalS);
}
else
{
webPathClanMappings.put(siteFilesPath.toLowerCase(), clan);
clanWebPathMappings.put(siteFilesPath.toLowerCase(), siteTemplatePath);
}
return;
}
else
{
Log.errOut("Clans","Unparseable webclansites bit in coffeemud.ini: "+originalS);
}
}
}
}
}
@Override
public Clan getWebPathClan(String sitePath)
{
return webPathClanMappings.get(sitePath.toLowerCase());
}
@Override
public void clanAnnounce(MOB mob, String msg)
{
final List<String> channels=CMLib.channels().getFlaggedChannelNames(ChannelsLibrary.ChannelFlag.CLANINFO);
for(int i=0;i<channels.size();i++)
{
CMLib.commands().postChannel(mob,channels.get(i),msg,true);
}
}
protected int filterMedianLevel(List<FullMemberRecord> members)
{
final List<Integer> lvls=new SortedListWrap<Integer>(new XVector<Integer>());
for(final FullMemberRecord r : members)
{
if(!r.isAdmin)
{
lvls.add(Integer.valueOf(r.level));
}
}
if(lvls.size()>0)
{
return lvls.get(lvls.size()/2).intValue();
}
return 0;
}
protected Clan getTrophyWinner(Trophy trophy)
{
for(final Enumeration<Clan> e=clans();e.hasMoreElements();)
{
final Clan C=e.nextElement();
if(CMath.bset(C.getTrophies(),trophy.flagNum()))
{
return C;
}
}
return null;
}
public void clanTrophyScan()
{
if(trophySystemActive())
{
// calculate winner of the members count contest
if(CMProps.getVar(CMProps.Str.CLANTROPMB).length()>0)
{
Clan winnerC=getTrophyWinner(Trophy.Members);
int winnerMembers=(winnerC==null)?0:winnerC.getSize();
for(final Enumeration<Clan> e=clans();e.hasMoreElements();)
{
final Clan C=e.nextElement(); if(C==winnerC) continue;
final int numMembers=C.getSize();
if(numMembers>winnerMembers)
{
winnerC=C;
winnerMembers=numMembers;
}
}
if(CMSecurity.isDebugging(CMSecurity.DbgFlag.CLANS))
Log.debugOut("Clans","MBTrophy: "+((winnerC==null)?"Noone":winnerC.clanID())+" won with "+winnerMembers);
if((winnerC!=null)&&(!CMath.bset(winnerC.getTrophies(),Trophy.Members.flagNum()))&&(winnerC.getExp()>0))
{
winnerC.setTrophies(winnerC.getTrophies()|Trophy.Members.flagNum());
clanAnnounceAll("The "+winnerC.getGovernmentName()+" "+winnerC.name()+" has been awarded the trophy for "+Trophy.Members.description+".");
}
for(final Enumeration<Clan> e=clans();e.hasMoreElements();)
{
final Clan C=e.nextElement();
if((winnerC!=C)&&(CMath.bset(C.getTrophies(),Trophy.Members.flagNum())))
{
C.setTrophies(C.getTrophies()-Trophy.Members.flagNum());
C.clanAnnounce(L("The @x1 @x2 has lost control of the trophy for @x3.",C.getGovernmentName(),C.name(),Trophy.Members.description));
}
}
}
// calculate winner of the member level contest
if(CMProps.getVar(CMProps.Str.CLANTROPLVL).length()>0)
{
Clan winnerC=getTrophyWinner(Trophy.MemberLevel);
int winnerLevel=(winnerC==null)?0:filterMedianLevel(winnerC.getFullMemberList());
for(final Enumeration<Clan> e=clans();e.hasMoreElements();)
{
final Clan C=e.nextElement(); if(C==winnerC) continue;
final int highestLevel=filterMedianLevel(C.getFullMemberList());
if(highestLevel>winnerLevel)
{
winnerC=C;
winnerLevel=highestLevel;
}
}
if(CMSecurity.isDebugging(CMSecurity.DbgFlag.CLANS))
Log.debugOut("DefaultClan","LVLTrophy: "+((winnerC==null)?"Noone":winnerC.clanID())+" won with "+winnerLevel);
if((winnerC!=null)&&(!CMath.bset(winnerC.getTrophies(),Trophy.MemberLevel.flagNum()))&&(winnerC.getExp()>0))
{
winnerC.setTrophies(winnerC.getTrophies()|Trophy.MemberLevel.flagNum());
clanAnnounceAll("The "+winnerC.getGovernmentName()+" "+winnerC.name()+" has been awarded the trophy for "+Trophy.MemberLevel.description+".");
}
for(final Enumeration<Clan> e=clans();e.hasMoreElements();)
{
final Clan C=e.nextElement();
if((winnerC!=C)&&(CMath.bset(C.getTrophies(),Trophy.MemberLevel.flagNum())))
{
C.setTrophies(C.getTrophies()-Trophy.MemberLevel.flagNum());
C.clanAnnounce(L("The @x1 @x2 has lost control of the trophy for @x3.",C.getGovernmentName(),C.name(),Trophy.MemberLevel.description));
}
}
}
// calculate winner of the exp contest
if(CMProps.getVar(CMProps.Str.CLANTROPEXP).length()>0)
{
Clan winnerC=getTrophyWinner(Trophy.Experience);
for(final Enumeration<Clan> e=clans();e.hasMoreElements();)
{
final Clan C=e.nextElement();
if(C==winnerC)
continue;
if((winnerC==null)||(C.getExp()>winnerC.getExp()))
winnerC=C;
}
if(CMSecurity.isDebugging(CMSecurity.DbgFlag.CLANS))
Log.debugOut("DefaultClan","EXPTrophy: "+((winnerC==null)?"Noone":winnerC.clanID())+" won with "+((winnerC==null)?"0":""+winnerC.getExp()));
if((winnerC!=null)&&(!CMath.bset(winnerC.getTrophies(),Trophy.Experience.flagNum()))&&(winnerC.getExp()>0))
{
winnerC.setTrophies(winnerC.getTrophies()|Trophy.Experience.flagNum());
clanAnnounceAll("The "+winnerC.getGovernmentName()+" "+winnerC.name()+" has been awarded the trophy for "+Trophy.Experience.description+".");
}
for(final Enumeration<Clan> e=clans();e.hasMoreElements();)
{
final Clan C=e.nextElement();
if((winnerC!=C)&&(CMath.bset(C.getTrophies(),Trophy.Experience.flagNum())))
{
C.setTrophies(C.getTrophies()-Trophy.Experience.flagNum());
C.clanAnnounce(L("The @x1 @x2 has lost control of the trophy for @x3.",C.getGovernmentName(),C.name(),Trophy.Experience.description));
}
}
}
// calculate winner of the pk contest
if(CMProps.getVar(CMProps.Str.CLANTROPPK).length()>0)
{
Clan winnerC=getTrophyWinner(Trophy.PlayerKills);
for(final Enumeration<Clan> e=clans();e.hasMoreElements();)
{
final Clan C=e.nextElement();
if(C==winnerC)
continue;
if((winnerC==null)||(C.getCurrentClanKills(null)>winnerC.getCurrentClanKills(null)))
winnerC=C;
}
if(CMSecurity.isDebugging(CMSecurity.DbgFlag.CLANS))
Log.debugOut("DefaultClan","PKTrophy: "+((winnerC==null)?"Noone":winnerC.clanID())+" won with "+((winnerC==null)?"0":""+winnerC.getCurrentClanKills(null)));
if((winnerC!=null)
&&(!CMath.bset(winnerC.getTrophies(),Trophy.PlayerKills.flagNum()))
&&(winnerC.getCurrentClanKills(null)>0))
{
winnerC.setTrophies(winnerC.getTrophies()|Trophy.PlayerKills.flagNum());
clanAnnounceAll("The "+winnerC.getGovernmentName()+" "+winnerC.name()+" has been awarded the trophy for "+Trophy.PlayerKills.description+".");
}
for(final Enumeration<Clan> e=clans();e.hasMoreElements();)
{
final Clan C=e.nextElement();
if((winnerC!=C)&&(CMath.bset(C.getTrophies(),Trophy.PlayerKills.flagNum())))
{
C.setTrophies(C.getTrophies()-Trophy.PlayerKills.flagNum());
C.clanAnnounce(L("The @x1 @x2 has lost control of the trophy for @x3.",C.getGovernmentName(),C.name(),Trophy.PlayerKills.description));
}
}
}
// calculate winner of the conquest contests
if((CMProps.getVar(CMProps.Str.CLANTROPAREA).length()>0)
||(CMProps.getVar(CMProps.Str.CLANTROPCP).length()>0))
{
Clan winnerMostClansControlledC=getTrophyWinner(Trophy.Areas);
long mostClansControlled=(winnerMostClansControlledC==null)?-1:winnerMostClansControlledC.getControlledAreas().size();
Clan winnerMostControlPointsC=getTrophyWinner(Trophy.Points);
long mostControlPoints=(winnerMostControlPointsC==null)?-1:winnerMostControlPointsC.calculateMapPoints();
for(final Enumeration<Clan> e=clans();e.hasMoreElements();)
{
final Clan C=e.nextElement();
if((C!=winnerMostClansControlledC)&&(CMProps.getVar(CMProps.Str.CLANTROPAREA).length()>0))
{
final int controlledAreas=C.getControlledAreas().size();
if(controlledAreas>mostClansControlled)
{
winnerMostClansControlledC=C;
mostClansControlled=controlledAreas;
}
}
if((C!=winnerMostControlPointsC)&&(CMProps.getVar(CMProps.Str.CLANTROPCP).length()>0))
{
final long mapPoints=C.calculateMapPoints();
if(mapPoints>mostControlPoints)
{
winnerMostControlPointsC=C;
mostControlPoints=mapPoints;
}
}
}
if(CMSecurity.isDebugging(CMSecurity.DbgFlag.CLANS))
Log.debugOut("DefaultClan","AREATrophy: "+((winnerMostClansControlledC==null)?"Noone":winnerMostClansControlledC.clanID())+" won with "+mostClansControlled);
if(CMSecurity.isDebugging(CMSecurity.DbgFlag.CLANS))
Log.debugOut("DefaultClan","CPTrophy: "+((winnerMostControlPointsC==null)?"Noone":winnerMostControlPointsC.clanID())+" won with "+mostControlPoints);
if((winnerMostClansControlledC!=null)
&&(CMProps.getVar(CMProps.Str.CLANTROPAREA).length()>0)
&&(mostClansControlled>0))
{
if(!CMath.bset(winnerMostClansControlledC.getTrophies(),Trophy.Areas.flagNum()))
{
winnerMostClansControlledC.setTrophies(winnerMostClansControlledC.getTrophies()|Trophy.Areas.flagNum());
clanAnnounceAll("The "+winnerMostClansControlledC.getGovernmentName()+" "+winnerMostClansControlledC.name()+" has been awarded the trophy for "+Trophy.Areas.description+".");
}
}
for(final Enumeration<Clan> e=clans();e.hasMoreElements();)
{
final Clan C=e.nextElement();
if((winnerMostClansControlledC!=C)
&&(CMath.bset(C.getTrophies(),Trophy.Areas.flagNum())))
{
C.setTrophies(C.getTrophies()-Trophy.Areas.flagNum());
C.clanAnnounce(L("The @x1 @x2 has lost control of the trophy for @x3.",C.getGovernmentName(),C.name(),Trophy.Areas.description));
}
}
if((winnerMostControlPointsC!=null)
&&(CMProps.getVar(CMProps.Str.CLANTROPCP).length()>0)
&&(mostControlPoints>0))
{
if(!CMath.bset(winnerMostControlPointsC.getTrophies(),Trophy.Points.flagNum()))
{
winnerMostControlPointsC.setTrophies(winnerMostControlPointsC.getTrophies()|Trophy.Points.flagNum());
clanAnnounceAll("The "+winnerMostControlPointsC.getGovernmentName()+" "+winnerMostControlPointsC.name()+" has been awarded the trophy for "+Trophy.Points.description+".");
}
}
for(final Enumeration<Clan> e=clans();e.hasMoreElements();)
{
final Clan C=e.nextElement();
if((winnerMostControlPointsC!=C)
&&(CMath.bset(C.getTrophies(),Trophy.Points.flagNum())))
{
C.setTrophies(C.getTrophies()-Trophy.Points.flagNum());
C.clanAnnounce(L("The @x1 @x2 has lost control of the trophy for @x3.",C.getGovernmentName(),C.name(),Trophy.Points.description));
}
}
}
}
}
@Override
public boolean activate()
{
if(serviceClient==null)
{
name="THClans"+Thread.currentThread().getThreadGroup().getName().charAt(0);
serviceClient=CMLib.threads().startTickDown(this, Tickable.TICKID_SUPPORT|Tickable.TICKID_SOLITARYMASK, CMProps.getTickMillis()*CMProps.getTicksPerDay(), 1);
}
return true;
}
@Override public boolean tick(Tickable ticking, int tickID)
{
try
{
if(!CMSecurity.isDisabled(CMSecurity.DisFlag.CLANTICKS))
{
tickStatus=Tickable.STATUS_ALIVE;
isDebugging=CMSecurity.isDebugging(DbgFlag.CLANS);
setThreadStatus(serviceClient,"clan trophy scan");
clanTrophyScan();
setThreadStatus(serviceClient,"sleeping");
}
}
finally
{
tickStatus=Tickable.STATUS_NOT;
setThreadStatus(serviceClient,"sleeping");
}
return true;
}
@Override
public boolean shutdown()
{
for(final Enumeration<Clan> e=all.elements();e.hasMoreElements();)
{
final Clan C=e.nextElement();
CMLib.threads().deleteTick(C,Tickable.TICKID_CLAN);
CMLib.database().DBUpdateClan(C);
CMLib.database().DBUpdateClanItems(C);
}
all.clear();
all2.clear();
if(CMLib.threads().isTicking(this, TICKID_SUPPORT|Tickable.TICKID_SOLITARYMASK))
{
CMLib.threads().deleteTick(this, TICKID_SUPPORT|Tickable.TICKID_SOLITARYMASK);
serviceClient=null;
}
return true;
}
@Override
public void forceTick()
{
serviceClient.tickTicker(false);
}
@Override
public void propertiesLoaded()
{
super.propertiesLoaded();
for(final String clanID : all.keySet())
{
final Clan C=all.get(clanID);
setClanWebSiteMappings(C,null);
CMLib.journals().registerClanForum(C,null);
}
for(final String clanID : all.keySet())
{
final Clan C=all.get(clanID);
setClanWebSiteMappings(C,CMProps.getVar(CMProps.Str.CLANWEBSITES));
CMLib.journals().registerClanForum(C,CMProps.getVar(CMProps.Str.CLANFORUMDATA));
}
}
}