2 * daily period in village
4 * License : The MIT License
5 * Copyright(c) 2008 olyutorskii
8 package jp.sfjp.jindolf.data;
10 import java.io.IOException;
11 import java.util.Collections;
12 import java.util.HashMap;
13 import java.util.HashSet;
14 import java.util.LinkedList;
15 import java.util.List;
18 import java.util.logging.Level;
19 import java.util.logging.Logger;
20 import jp.osdn.jindolf.parser.EntityConverter;
21 import jp.osdn.jindolf.parser.HtmlAdapter;
22 import jp.osdn.jindolf.parser.HtmlParseException;
23 import jp.osdn.jindolf.parser.HtmlParser;
24 import jp.osdn.jindolf.parser.PageType;
25 import jp.osdn.jindolf.parser.SeqRange;
26 import jp.osdn.jindolf.parser.content.DecodedContent;
27 import jp.sfjp.jindolf.net.HtmlSequence;
28 import jp.sfjp.jindolf.net.ServerAccess;
29 import jp.sfjp.jindolf.util.StringUtils;
30 import jp.sourceforge.jindolf.corelib.EventFamily;
31 import jp.sourceforge.jindolf.corelib.GameRole;
32 import jp.sourceforge.jindolf.corelib.LandDef;
33 import jp.sourceforge.jindolf.corelib.PeriodType;
34 import jp.sourceforge.jindolf.corelib.SysEventType;
35 import jp.sourceforge.jindolf.corelib.TalkType;
36 import jp.sourceforge.jindolf.corelib.Team;
37 import jp.sourceforge.jindolf.corelib.VillageState;
41 * 村の進行の一区切り。プロローグやエピローグも含まれる。
43 * <p>将来、24時間更新でなくなる可能性の考慮が必要。
45 * 24時間以上の期間を持つPeriodが生成される可能性の考慮が必要。
48 // TODO Comparable も implement する?
50 private static final HtmlParser PARSER = new HtmlParser();
51 private static final PeriodHandler HANDLER =
54 private static final Logger LOGGER = Logger.getAnonymousLogger();
57 PARSER.setBasicHandler (HANDLER);
58 PARSER.setSysEventHandler(HANDLER);
59 PARSER.setTalkHandler (HANDLER);
62 private final Village homeVillage;
63 private final PeriodType periodType;
64 private final int day;
65 private int limitHour;
66 private int limitMinute;
68 private String loginName;
69 private boolean isFullOpen = false;
71 private final List<Topic> topicList = new LinkedList<>();
72 private final List<Topic> unmodList =
73 Collections.unmodifiableList(this.topicList);
77 * この Period が進行中の村の最新日で、
78 * 今まさに次々と発言が蓄積されているときは
80 * ※重要: Hot な Period は meslog クエリーを使ってダウンロードできない。
82 private boolean isHot;
87 * この段階では発言データのロードは行われない。
89 * @param homeVillage 所属するVillage
90 * @param periodType Period種別
92 * @throws java.lang.NullPointerException 引数にnullが渡された場合。
94 public Period(Village homeVillage,
95 PeriodType periodType,
97 throws NullPointerException{
98 this(homeVillage, periodType, day, false);
104 * この段階では発言データのロードは行われない。
105 * @param homeVillage 所属するVillage
106 * @param periodType Period種別
107 * @param day Period通番
108 * @param isHot Hotか否か
109 * @throws java.lang.NullPointerException 引数にnullが渡された場合。
111 private Period(Village homeVillage,
112 PeriodType periodType,
115 throws NullPointerException{
116 if( homeVillage == null
117 || periodType == null ) throw new NullPointerException();
119 throw new IllegalArgumentException("Period day is too small !");
134 this.homeVillage = homeVillage;
135 this.periodType = periodType;
147 * Periodを更新する。Topicのリストが更新される。
149 * @param force trueなら強制再読み込み。
150 * falseならまだ読み込んで無い時のみ読み込み。
151 * @throws IOException ネットワーク入力エラー
153 public static void parsePeriod(Period period, boolean force)
155 if( ! force && period.hasLoaded() ) return;
157 Village village = period.getVillage();
158 Land land = village.getParentLand();
159 ServerAccess server = land.getServerAccess();
161 if(village.getState() != VillageState.PROGRESS){
162 period.isFullOpen = true;
163 }else if(period.getType() != PeriodType.PROGRESS){
164 period.isFullOpen = true;
166 period.isFullOpen = false;
169 HtmlSequence html = server.getHTMLPeriod(period);
171 period.topicList.clear();
173 boolean wasHot = period.isHot();
175 HANDLER.setPeriod(period);
176 DecodedContent content = html.getContent();
178 PARSER.parseAutomatic(content);
179 }catch(HtmlParseException e){
180 LOGGER.log(Level.WARNING, "発言抽出に失敗", e);
183 if(wasHot && ! period.isHot() ){
184 parsePeriod(period, true);
195 public Village getVillage(){
196 return this.homeVillage;
203 public PeriodType getType(){
204 return this.periodType;
222 public String getLimit(){
223 StringBuilder result = new StringBuilder();
225 if(this.limitHour < 10) result.append('0');
226 result.append(this.limitHour).append(':');
228 if(this.limitMinute < 10) result.append('0');
229 result.append(this.limitMinute);
231 return result.toString();
238 public boolean isHot(){
244 * @param isHotArg Hot指定
246 public void setHot(boolean isHotArg){
247 this.isHot = isHotArg;
252 * @return プロローグならtrue
254 public boolean isPrologue(){
255 if(getType() == PeriodType.PROLOGUE) return true;
261 * @return エピローグならtrue
263 public boolean isEpilogue(){
264 if(getType() == PeriodType.EPILOGUE) return true;
272 public boolean isProgress(){
273 if(getType() == PeriodType.PROGRESS) return true;
278 * このPeriodにアクセスするためのクエリーを生成する。
281 public String getCGIQuery(){
282 StringBuilder result = new StringBuilder();
284 Village village = getVillage();
285 result.append(village.getCGIQuery());
288 result.append("&mes=all"); // 全表示指定
289 return result.toString();
292 Land land = village.getParentLand();
293 LandDef ldef = land.getLandDef();
295 if(ldef.getLandId().equals("wolfg")){
296 result.append("&meslog=");
297 String dnum = "000" + (getDay() - 1);
298 dnum = dnum.substring(dnum.length() - 3);
301 result.append("000_ready");
304 result.append(dnum).append("_progress");
307 result.append(dnum).append("_party");
314 result.append("&meslog=").append(village.getVillageID());
317 result.append("_ready_0");
320 result.append("_progress_").append(getDay() - 1);
323 result.append("_party_").append(getDay() - 1);
332 result.append("&mes=all");
334 return result.toString();
338 * Periodに含まれるTopicのリストを返す。
342 public List<Topic> getTopicList(){
343 return this.unmodList;
347 * Periodに含まれるTopicの総数を返す。
350 public int getTopics(){
351 return this.topicList.size();
357 * @throws java.lang.NullPointerException nullが渡された場合。
359 protected void addTopic(Topic topic) throws NullPointerException{
360 if(topic == null) throw new NullPointerException();
361 this.topicList.add(topic);
366 * Periodのキャプション文字列を返す。
370 public String getCaption(){
378 result = getDay() + "日目";
393 * このPeriodをダウンロードしたときのログイン名を返す。
394 * @return ログイン名。ログアウト中はnull。
396 public String getLoginName(){
397 return this.loginName;
402 * @param talkNo 公開発言番号
403 * @return 発言。見つからなければnull
405 public Talk getNumberedTalk(int talkNo){
406 if(talkNo <= 0) throw new IllegalArgumentException();
408 for(Topic topic : this.topicList){
409 if( ! (topic instanceof Talk) ) continue;
410 Talk talk = (Talk) topic;
411 if(talkNo == talk.getTalkNo()) return talk;
418 * このPeriodの内容にゲーム進行上隠された部分がある可能性を判定する。
419 * @return 隠れた要素がありうるならfalse
421 public boolean isFullOpen(){
422 return this.isFullOpen;
427 * @return ロード済みならtrue
429 public boolean hasLoaded(){
430 return getTopics() > 0;
436 public void unload(){
438 this.limitMinute = 0;
439 this.loginName = null;
440 this.isFullOpen = false;
444 this.topicList.clear();
453 * @return 襲撃メッセージがあればtrue
455 public boolean hasAssaultTried(){
456 for(Topic topic : this.topicList){
457 if(topic instanceof Talk){
458 Talk talk = (Talk) topic;
459 if(talk.getTalkCount() <= 0) return true;
460 }else if(topic instanceof SysEvent){
461 SysEvent sysEvent = (SysEvent) topic;
462 SysEventType type = sysEvent.getSysEventType();
463 if(type == SysEventType.ASSAULT) return true;
472 * @return 処刑されたAvatar。突然死などなんらかの理由でいない場合はnull
474 public Avatar getExecutedAvatar(){
475 Avatar result = null;
477 for(Topic topic : getTopicList()){
478 if( ! (topic instanceof SysEvent) ) continue;
479 SysEvent event = (SysEvent) topic;
480 result = event.getExecutedAvatar();
481 if(result != null) break;
488 * 投票に参加したAvatarの集合を返す。
489 * @return 投票に参加したAvatarのSet
491 public Set<Avatar> getVoterSet(){
492 Set<Avatar> result = new HashSet<>();
494 for(Topic topic : getTopicList()){
495 if( ! (topic instanceof SysEvent) ) continue;
496 SysEvent event = (SysEvent) topic;
497 result = event.getVoterSet(result);
504 * 任意のタイプのシステムイベントを返す。
505 * 複数存在する場合、返すのは最初の一つだけ。
506 * @param type イベントタイプ
509 public SysEvent getTypedSysEvent(SysEventType type){
510 for(Topic topic : getTopicList()){
511 if( ! (topic instanceof SysEvent) ) continue;
512 SysEvent event = (SysEvent) topic;
513 if(event.getSysEventType() == type) return event;
522 private static class PeriodHandler extends HtmlAdapter{
524 private static final int TALKTYPE_NUM = TalkType.values().length;
526 private final EntityConverter converter =
527 new EntityConverter(true);
528 // TODO: SMP面文字に彩色対応するまでの暫定措置
530 private final Map<Avatar, int[]> countMap =
533 private Period period = null;
535 private TalkType talkType;
536 private Avatar avatar;
538 private String anchorId;
539 private int talkHour;
540 private int talkMinute;
541 private DecodedContent talkContent = null;
543 private EventFamily eventFamily;
544 private SysEventType sysEventType;
545 private DecodedContent eventContent = null;
546 private final List<Avatar> avatarList = new LinkedList<>();
547 private final List<GameRole> roleList = new LinkedList<>();
548 private final List<Integer> integerList = new LinkedList<>();
549 private final List<CharSequence> charseqList =
555 public PeriodHandler(){
561 * パース結果を格納するPeriodを設定する。
562 * @param period Period
564 public void setPeriod(Period period){
565 this.period = period;
571 * 村に未登録のAvatarであればついでに登録される。
573 * @param range 文字列内のAvatarフルネームを示す領域
576 private Avatar toAvatar(DecodedContent content, SeqRange range){
577 Village village = this.period.getVillage();
578 String fullName = this.converter
579 .convert(content, range)
581 Avatar result = village.getAvatar(fullName);
583 result = new Avatar(fullName);
584 village.addAvatar(result);
591 * Avatar別、会話種ごとに発言回数をカウントする。
593 * @param targetAvatar 対象Avatar
594 * @param targetType 対象会話種
597 private int countUp(Avatar targetAvatar, TalkType targetType){
598 int[] countArray = this.countMap.get(targetAvatar);
599 if(countArray == null){
600 countArray = new int[TALKTYPE_NUM];
601 this.countMap.put(targetAvatar, countArray);
603 int count = ++countArray[targetType.ordinal()];
609 * @param content {@inheritDoc}
610 * @throws HtmlParseException {@inheritDoc}
613 public void startParse(DecodedContent content)
614 throws HtmlParseException{
615 this.period.loginName = null;
616 this.period.topicList.clear();
617 this.countMap.clear();
623 * @param content {@inheritDoc}
624 * @param loginRange {@inheritDoc}
625 * @throws HtmlParseException {@inheritDoc}
628 public void loginName(DecodedContent content, SeqRange loginRange)
629 throws HtmlParseException{
630 DecodedContent loginName =
631 this.converter.convert(content, loginRange);
633 this.period.loginName = loginName.toString();
640 * @param type {@inheritDoc}
641 * @throws HtmlParseException {@inheritDoc}
644 public void pageType(PageType type) throws HtmlParseException{
645 if(type != PageType.PERIOD_PAGE){
646 throw new HtmlParseException(
647 "意図しないページを読み込もうとしました。");
654 * @param month {@inheritDoc}
655 * @param day {@inheritDoc}
656 * @param hour {@inheritDoc}
657 * @param minute {@inheritDoc}
658 * @throws HtmlParseException {@inheritDoc}
661 public void commitTime(int month, int day, int hour, int minute)
662 throws HtmlParseException{
663 this.period.limitHour = hour;
664 this.period.limitMinute = minute;
671 * 自分へのリンクが見つかればこのPeriodを非Hotにする。
673 * 今読んでるHTMLは別のPeriodのために書かれたものということ。
674 * 考えられる原因は、HotだったPeriodがゲーム進行に従い
676 * @param content {@inheritDoc}
677 * @param anchorRange {@inheritDoc}
678 * @param periodType {@inheritDoc}
679 * @param day {@inheritDoc}
680 * @throws HtmlParseException {@inheritDoc}
683 public void periodLink(DecodedContent content,
684 SeqRange anchorRange,
685 PeriodType periodType,
687 throws HtmlParseException{
689 if(this.period.getType() != periodType) return;
691 if( periodType == PeriodType.PROGRESS
692 && this.period.getDay() != day ){
696 if( ! anchorRange.isValid() ) return;
698 this.period.setHot(false);
705 * @throws HtmlParseException {@inheritDoc}
708 public void startTalk() throws HtmlParseException{
709 this.talkType = null;
712 this.anchorId = null;
714 this.talkMinute = -1;
715 this.talkContent = new DecodedContent(100 + 1);
722 * @param type {@inheritDoc}
723 * @throws HtmlParseException {@inheritDoc}
726 public void talkType(TalkType type)
727 throws HtmlParseException{
728 this.talkType = type;
734 * @param content {@inheritDoc}
735 * @param avatarRange {@inheritDoc}
736 * @throws HtmlParseException {@inheritDoc}
739 public void talkAvatar(DecodedContent content, SeqRange avatarRange)
740 throws HtmlParseException{
741 this.avatar = toAvatar(content, avatarRange);
747 * @param hour {@inheritDoc}
748 * @param minute {@inheritDoc}
749 * @throws HtmlParseException {@inheritDoc}
752 public void talkTime(int hour, int minute)
753 throws HtmlParseException{
754 this.talkHour = hour;
755 this.talkMinute = minute;
761 * @param tno {@inheritDoc}
762 * @throws HtmlParseException {@inheritDoc}
765 public void talkNo(int tno) throws HtmlParseException{
772 * @param content {@inheritDoc}
773 * @param idRange {@inheritDoc}
774 * @throws HtmlParseException {@inheritDoc}
777 public void talkId(DecodedContent content, SeqRange idRange)
778 throws HtmlParseException{
779 this.anchorId = content.subSequence(idRange.getStartPos(),
780 idRange.getEndPos() )
787 * @param content {@inheritDoc}
788 * @param textRange {@inheritDoc}
789 * @throws HtmlParseException {@inheritDoc}
792 public void talkText(DecodedContent content, SeqRange textRange)
793 throws HtmlParseException{
794 this.converter.append(this.talkContent, content, textRange);
800 * @throws HtmlParseException {@inheritDoc}
803 public void talkBreak()
804 throws HtmlParseException{
805 this.talkContent.append('\n');
811 * @throws HtmlParseException {@inheritDoc}
814 public void endTalk() throws HtmlParseException{
815 Talk talk = new Talk(this.period,
820 this.talkHour, this.talkMinute,
823 int count = countUp(this.avatar, this.talkType);
824 talk.setCount(count);
826 this.period.addTopic(talk);
828 this.talkType = null;
831 this.anchorId = null;
833 this.talkMinute = -1;
834 this.talkContent = null;
841 * @param family {@inheritDoc}
842 * @throws HtmlParseException {@inheritDoc}
845 public void startSysEvent(EventFamily family)
846 throws HtmlParseException{
847 this.eventFamily = family;
848 this.sysEventType = null;
849 this.eventContent = new DecodedContent();
850 this.avatarList.clear();
851 this.roleList.clear();
852 this.integerList.clear();
853 this.charseqList.clear();
859 * @param type {@inheritDoc}
860 * @throws HtmlParseException {@inheritDoc}
863 public void sysEventType(SysEventType type)
864 throws HtmlParseException{
865 this.sysEventType = type;
871 * @param content {@inheritDoc}
872 * @param contentRange {@inheritDoc}
873 * @throws HtmlParseException {@inheritDoc}
876 public void sysEventContent(DecodedContent content,
877 SeqRange contentRange)
878 throws HtmlParseException{
879 this.converter.append(this.eventContent, content, contentRange);
885 * @param content {@inheritDoc}
886 * @param anchorRange {@inheritDoc}
887 * @param contentRange {@inheritDoc}
888 * @throws HtmlParseException {@inheritDoc}
891 public void sysEventContentAnchor(DecodedContent content,
892 SeqRange anchorRange,
893 SeqRange contentRange)
894 throws HtmlParseException{
895 this.converter.append(this.eventContent, content, contentRange);
901 * @throws HtmlParseException {@inheritDoc}
904 public void sysEventContentBreak() throws HtmlParseException{
905 this.eventContent.append('\n');
911 * @param content {@inheritDoc}
912 * @param entryNo {@inheritDoc}
913 * @param avatarRange {@inheritDoc}
914 * @throws HtmlParseException {@inheritDoc}
917 public void sysEventOnStage(DecodedContent content,
919 SeqRange avatarRange)
920 throws HtmlParseException{
921 Avatar newAvatar = toAvatar(content, avatarRange);
922 this.integerList.add(entryNo);
923 this.avatarList.add(newAvatar);
929 * @param role {@inheritDoc}
930 * @param num {@inheritDoc}
931 * @throws HtmlParseException {@inheritDoc}
934 public void sysEventOpenRole(GameRole role, int num)
935 throws HtmlParseException{
936 this.roleList.add(role);
937 this.integerList.add(num);
943 * @param content {@inheritDoc}
944 * @param avatarRange {@inheritDoc}
945 * @throws HtmlParseException {@inheritDoc}
948 public void sysEventMurdered(DecodedContent content,
949 SeqRange avatarRange)
950 throws HtmlParseException{
951 Avatar murdered = toAvatar(content, avatarRange);
952 this.avatarList.add(murdered);
958 * @param content {@inheritDoc}
959 * @param avatarRange {@inheritDoc}
960 * @throws HtmlParseException {@inheritDoc}
963 public void sysEventSurvivor(DecodedContent content,
964 SeqRange avatarRange)
965 throws HtmlParseException{
966 Avatar survivor = toAvatar(content, avatarRange);
967 this.avatarList.add(survivor);
973 * @param content {@inheritDoc}
974 * @param voteByRange {@inheritDoc}
975 * @param voteToRange {@inheritDoc}
976 * @throws HtmlParseException {@inheritDoc}
979 public void sysEventCounting(DecodedContent content,
980 SeqRange voteByRange,
981 SeqRange voteToRange)
982 throws HtmlParseException{
983 if(voteByRange.isValid()){
984 Avatar voteBy = toAvatar(content, voteByRange);
985 this.avatarList.add(voteBy);
987 Avatar voteTo = toAvatar(content, voteToRange);
988 this.avatarList.add(voteTo);
994 * @param content {@inheritDoc}
995 * @param voteByRange {@inheritDoc}
996 * @param voteToRange {@inheritDoc}
997 * @throws HtmlParseException {@inheritDoc}
1000 public void sysEventCounting2(DecodedContent content,
1001 SeqRange voteByRange,
1002 SeqRange voteToRange)
1003 throws HtmlParseException{
1004 sysEventCounting(content, voteByRange, voteToRange);
1010 * @param content {@inheritDoc}
1011 * @param avatarRange {@inheritDoc}
1012 * @throws HtmlParseException {@inheritDoc}
1015 public void sysEventSuddenDeath(DecodedContent content,
1016 SeqRange avatarRange)
1017 throws HtmlParseException{
1018 Avatar suddenDeath = toAvatar(content, avatarRange);
1019 this.avatarList.add(suddenDeath);
1025 * @param content {@inheritDoc}
1026 * @param avatarRange {@inheritDoc}
1027 * @param anchorRange {@inheritDoc}
1028 * @param loginRange {@inheritDoc}
1029 * @param isLiving {@inheritDoc}
1030 * @param role {@inheritDoc}
1031 * @throws HtmlParseException {@inheritDoc}
1034 public void sysEventPlayerList(DecodedContent content,
1035 SeqRange avatarRange,
1036 SeqRange anchorRange,
1037 SeqRange loginRange,
1040 throws HtmlParseException{
1041 Avatar who = toAvatar(content, avatarRange);
1043 CharSequence anchor;
1044 if(anchorRange.isValid()){
1045 anchor = this.converter.convert(content, anchorRange);
1049 CharSequence account = this.converter
1050 .convert(content, loginRange);
1053 if(isLiving) liveOrDead = 1;
1054 else liveOrDead = 0;
1056 this.avatarList.add(who);
1057 this.charseqList.add(anchor);
1058 this.charseqList.add(account);
1059 this.integerList.add(liveOrDead);
1060 this.roleList.add(role);
1067 * @param content {@inheritDoc}
1068 * @param avatarRange {@inheritDoc}
1069 * @param votes {@inheritDoc}
1070 * @throws HtmlParseException {@inheritDoc}
1073 public void sysEventExecution(DecodedContent content,
1074 SeqRange avatarRange,
1076 throws HtmlParseException{
1077 Avatar who = toAvatar(content, avatarRange);
1079 this.avatarList.add(who);
1080 this.integerList.add(votes);
1087 * @param hour {@inheritDoc}
1088 * @param minute {@inheritDoc}
1089 * @param minLimit {@inheritDoc}
1090 * @param maxLimit {@inheritDoc}
1091 * @throws HtmlParseException {@inheritDoc}
1094 public void sysEventAskEntry(int hour, int minute,
1095 int minLimit, int maxLimit)
1096 throws HtmlParseException{
1097 this.integerList.add(hour * 60 + minute);
1098 this.integerList.add(minLimit);
1099 this.integerList.add(maxLimit);
1105 * @param hour {@inheritDoc}
1106 * @param minute {@inheritDoc}
1107 * @throws HtmlParseException {@inheritDoc}
1110 public void sysEventAskCommit(int hour, int minute)
1111 throws HtmlParseException{
1112 this.integerList.add(hour * 60 + minute);
1118 * @param content {@inheritDoc}
1119 * @param avatarRange {@inheritDoc}
1120 * @throws HtmlParseException {@inheritDoc}
1123 public void sysEventNoComment(DecodedContent content,
1124 SeqRange avatarRange)
1125 throws HtmlParseException{
1126 Avatar noComAvatar = toAvatar(content, avatarRange);
1127 this.avatarList.add(noComAvatar);
1133 * @param winner {@inheritDoc}
1134 * @param hour {@inheritDoc}
1135 * @param minute {@inheritDoc}
1136 * @throws HtmlParseException {@inheritDoc}
1139 public void sysEventStayEpilogue(Team winner, int hour, int minute)
1140 throws HtmlParseException{
1141 GameRole role = null;
1144 case VILLAGE: role = GameRole.INNOCENT; break;
1145 case WOLF: role = GameRole.WOLF; break;
1146 case HAMSTER: role = GameRole.HAMSTER; break;
1147 default: assert false; break;
1150 this.roleList.add(role);
1151 this.integerList.add(hour * 60 + minute);
1158 * @param content {@inheritDoc}
1159 * @param guardByRange {@inheritDoc}
1160 * @param guardToRange {@inheritDoc}
1161 * @throws HtmlParseException {@inheritDoc}
1164 public void sysEventGuard(DecodedContent content,
1165 SeqRange guardByRange,
1166 SeqRange guardToRange)
1167 throws HtmlParseException{
1168 Avatar guardBy = toAvatar(content, guardByRange);
1169 Avatar guardTo = toAvatar(content, guardToRange);
1170 this.avatarList.add(guardBy);
1171 this.avatarList.add(guardTo);
1177 * @param content {@inheritDoc}
1178 * @param judgeByRange {@inheritDoc}
1179 * @param judgeToRange {@inheritDoc}
1180 * @throws HtmlParseException {@inheritDoc}
1183 public void sysEventJudge(DecodedContent content,
1184 SeqRange judgeByRange,
1185 SeqRange judgeToRange)
1186 throws HtmlParseException{
1187 Avatar judgeBy = toAvatar(content, judgeByRange);
1188 Avatar judgeTo = toAvatar(content, judgeToRange);
1189 this.avatarList.add(judgeBy);
1190 this.avatarList.add(judgeTo);
1196 * @throws HtmlParseException {@inheritDoc}
1199 public void endSysEvent() throws HtmlParseException{
1200 SysEvent event = new SysEvent();
1201 event.setEventFamily(this.eventFamily);
1202 event.setSysEventType(this.sysEventType);
1203 event.setContent(this.eventContent);
1204 event.addAvatarList(this.avatarList);
1205 event.addRoleList(this.roleList);
1206 event.addIntegerList(this.integerList);
1207 event.addCharSequenceList(this.charseqList);
1209 this.period.addTopic(event);
1211 if( this.sysEventType == SysEventType.MURDERED
1212 || this.sysEventType == SysEventType.NOMURDER ){
1213 for(Topic topic : this.period.topicList){
1214 if( ! (topic instanceof Talk) ) continue;
1215 Talk talk = (Talk) topic;
1216 if(talk.getTalkType() != TalkType.WOLFONLY) continue;
1218 .isTerminated(talk.getDialog(),
1219 "!\u0020今日がお前の命日だ!") ){
1223 this.countMap.clear();
1227 this.eventFamily = null;
1228 this.sysEventType = null;
1229 this.eventContent = null;
1230 this.avatarList.clear();
1231 this.roleList.clear();
1232 this.integerList.clear();
1233 this.charseqList.clear();
1240 * @throws HtmlParseException {@inheritDoc}
1243 public void endParse() throws HtmlParseException{
1247 // TODO 村名のチェックは不要か?