code:
@탈의처리(C_ID, TYPE, OP)
#DIM  C_ID ;대상이 되는 등록 번호
#DIMS TYPE ;처리 내용
#DIMS OP   ;실행 옵션
SELECTCASE TYPE
CASE "전라"
	IF !(C_ID == MASTER) && !STRCOUNT(OP, "「표시 없음」")
		CALL MESSAGE_탈의상
		TSTR:3 = %CALLNAME:C_ID%{EQUIP:C_ID:하반신속옷2}/
		IF (FLAG:시간정지 || TCVAR:C_ID:만취) && EQUIP:하반신속옷2
		;IF (TIMESTOP() == 2|| TCVAR:C_ID:만취) && EQUIP:하반신속옷 2
			CALL MESSAGE_탈의하
			SIF !PANTS_ALREADY_COLLECTED(C_ID)
				SETCOLOR C_PINK
			PRINTFORML %조사처리(CALLNAME:C_ID,"는")% %PANTSNAME(EQUIP:C_ID:하반신속옷2, C_ID)%를 입고 있는 것 같다
			RESETCOLOR
			IF FLAG:팬티도둑 == 1
				CALL 탈의처리(C_ID, "훔친다")
			ELSEIF FLAG:팬티도둑 == 2
				GOTO PANTU_NUGASUDAKE
			ELSE
				PRINTFORML 어떻게 합니까?
				CALL ASK_YN("훔친다","벗기기만 할 뿐")
				IF RESULT == 0
					CALL 탈의처리(C_ID, "훔친다")
				ELSE
					$PANTU_NUGASUDAKE
					CALL MESSAGE_탈의하속옷
					EQUIP:C_ID:하반신속옷2 = 0
				ENDIF
			ENDIF
		ELSEIF EQUIP:하반신속옷2
			CALL MESSAGE_탈의하
			SIF !PANTS_ALREADY_COLLECTED(C_ID)
				SETCOLOR C_PINK
			CALL MESSAGE_탈의하속옷
			PRINTFORML %조사처리(CALLNAME:C_ID,"가")% 입고 있던 %PANTSNAME(EQUIP:C_ID:하반신속옷2, C_ID)%를 받겠습니까?
			RESETCOLOR
			PRINT [0] - 간절히 부탁한다
			PRINT [1] - 그만둔다
			DO
				INPUT
				SIF !GROUPMATCH(RESULT, 0, 1)
					CONTINUE
				IF RESULT
					EQUIP:C_ID:하반신속옷2 = 0
					PRINTL
					BREAK
				ENDIF

				;여기서부터 RESULT == 0
				IF ABL:C_ID:순종 > 7 && ABL:C_ID:친밀 > 7
					IF ABL:C_ID:욕망 > 7 && !RAND:4
						PRINTFORMW %타겟은% 대신에 %CALLNAME:MASTER%의 속옷을 갖고 싶어한다…
						IF EQUIP:MASTER:하반신속옷2
							SIF !PANTS_ALREADY_COLLECTED()
								SETCOLOR C_PINK
							PRINTFORMW %마스터는% 자신의 속옷과 바꿔 %CALLNAME:C_ID%의 %PANTSNAME(EQUIP:C_ID:하반신속옷2, C_ID)%를 손에 넣었다!
							RESETCOLOR
							CALL KOJO_MESSAGE_SEND("EVENT", 28, C_ID, 3, 0)
							TSTR:3 = %CALLNAME:C_ID%{EQUIP:C_ID:하반신속옷2}/
							CSTR:MASTER:12 += TSTR:3
							CALL PANTS_GET(C_ID, "받는다")
							CFLAG:MASTER:노팬티 = 2
							CFLAG:C_ID:팬티2 = 1
							CFLAG:C_ID:당신의팬티 = 1
							EQUIP:MASTER:하반신속옷2 = 0
						ELSE
							PRINTFORMW 그러나 %마스터는% 노팬티였다
							PRINTFORMW %타겟은% 살짝 질겁하고 있다…
						ENDIF
					ELSE
						SIF !PANTS_ALREADY_COLLECTED()
							SETCOLOR C_PINK
						PRINTFORMW %조사처리(CALLNAME:C_ID,"는")% 얼굴이 새빨개져서 벗은지 얼마 안 된 %PANTSNAME(EQUIP:C_ID:하반신속옷2, C_ID)%를 %CALLNAME:MASTER%에 전했다
						PRINTFORMW %마스터는% %CALLNAME:C_ID%의 %PANTSNAME(EQUIP:C_ID:하반신속옷2, C_ID)%를 손에 넣었다!
						RESETCOLOR
						CALL KOJO_MESSAGE_SEND("EVENT", 28, C_ID, 3, 1)
						CALL PANTS_GET(C_ID, "받는다")
					ENDIF
				ELSEIF ABL:TARGET:순종 > 5 && ABL:TARGET:친밀 > 5
					SIF !PANTS_ALREADY_COLLECTED()
						SETCOLOR C_PINK
					PRINTFORMW %조사처리(CALLNAME:C_ID,"는")% 마지못해 벗은지 얼마 안된 %PANTSNAME(EQUIP:C_ID:하반신속옷2, C_ID)%를 내몄다
					PRINTFORMW %마스터는% %CALLNAME:C_ID%의 %PANTSNAME(EQUIP:C_ID:하반신속옷2, C_ID)%를 손에 넣었다!
					RESETCOLOR
					CALL KOJO_MESSAGE_SEND("EVENT", 28, C_ID, 3, 2)
					CALL PANTS_GET(C_ID, "받는다")
				ELSE
					PRINTFORMW %타겟은% 살짝 깨는 눈치로 거부했다
					;PRINTFORMW 어쩔 수 없이 벗기는 만큼 했다…
					CALL KOJO_MESSAGE_SEND("EVENT", 28, C_ID, 3, 3)
					EQUIP:C_ID:하반신속옷2 = 0
				ENDIF
			PRINTL
			BREAK
			LOOP 1
		ELSE
			CALL MESSAGE_탈의하
			CALL MESSAGE_탈의하속옷
		ENDIF
		CALL KOJO_MESSAGE_SEND("EVENT", 28, C_ID, 0, 0)
	ENDIF
	CALL CTRL_CLOTHES_SET(C_ID, "현재 의상의 변경_전라")
	CALL CLOTHES_SETTING_TRAIN(C_ID)
	RETURN 0
CASE "훔친다"
	SIF EQUIP:TARGET:바지
		CALL MESSAGE_탈의하(1)
	TSTR:3 = %CALLNAME:C_ID%{EQUIP:C_ID:하반신속옷2}/
	CALL MESSAGE_탈의하속옷
	SIF !PANTS_ALREADY_COLLECTED(C_ID)
		SETCOLOR C_PINK
	PRINTFORMW %조사처리(CALLNAME:C_ID,"가")% 입고 있던 %PANTSNAME(EQUIP:C_ID:하반신속옷2, C_ID)%를 벗겨 품에 넣었다
	RESETCOLOR
	CALL PANTS_GET(C_ID)
	RETURN 0
CASE "속옷 모습으로 한다"
	IF !(C_ID == MASTER) && !STRCOUNT(OP, "「표시 없음」")
		CALL MESSAGE_탈의윗도리
		CALL MESSAGE_탈의하
		CALL KOJO_MESSAGE_SEND("EVENT", 28, C_ID, 1, 0)
	ENDIF
	CALL CTRL_CLOTHES_SET(C_ID, "현재 의상의 변경_속옷 모습")
	CALL CLOTHES_SETTING_TRAIN(C_ID)
	;"현재 의상의 변경_속옷 모습"에는 TEQUIP의 직접 조작이 있는, 전모를 파악하고 있지 않지만 원래의 구문이라면
	;호출원으로 최종적으로 전캐릭터에 대해서 CLOTHES_SETTING_TRAIN를 실행하고 있었기 때문에
	;거동으로서는 변함없을 것
	;TEQUIP:TARGET:상반신탈의상태 = 1
	RETURN 0
CASE "팬티 받는다"
CASE "반라"
	IF !(C_ID == MASTER) && !STRCOUNT(OP, "「표시 없음」")
		CALL MESSAGE_탈의윗도리
		CALL MESSAGE_탈의하(1)
		CALL KOJO_MESSAGE_SEND("EVENT", 28, C_ID, 2, 0)
	ENDIF
	CALL CTRL_CLOTHES_SET(C_ID, "현재 의상의 변경_반라")
	CALL CLOTHES_SETTING_TRAIN(C_ID)
	RETURN 0
CASEELSE
	THROW 불명한 TYPE %TYPE%
ENDSELECT

@옷을벗게한다
SIF !TARGET
	JUMP SIMATTYAUOJISAN

IF CFLAG:TARGET:노팬티 == 0

	SELECTCASE FLAG:탈의선택
	CASE 0
		PRINTL 반라로 합니까?
		PRINT [0] - 전부탈
		IF TEQUIP:TARGET:윗도리탈의가끝난상태 == 0 || EQUIP:TARGET:상반신속옷1
			SIF EQUIP:0 && TARGET && EQUIP:TARGET:상반신속옷1 != 0 && (EQUIP:TARGET:기모노!= 0 || EQUIP:TARGET:상반신윗도리2 != 0 || EQUIP:TARGET:보디슈트== 3)
				PRINT [1] - 반라 착의 플레이
		ENDIF
		IF TEQUIP:TARGET:윗도리탈의가끝난상태 == 0
			SIF EQUIP:0 && TARGET && (EQUIP:TARGET:상반신속옷1 != 0 || EQUIP:TARGET:상반신속옷2 != 0 || EQUIP:TARGET:하반신속옷1 != 0 || EQUIP:TARGET:하반신속옷2 != 0 || EQUIP:TARGET:레오타드!= 0 || EQUIP:TARGET:보디슈트!= 0)
				PRINT [2] - 속옷인 만큼 한다
		ENDIF
		DO
			INPUT
			SELECTCASE RESULT
			CASE 0
				CALL 탈의처리(TARGET, "전라")
				CALL 탈의처리(MASTER, "전라")
			CASE 1
				CALL 탈의처리(TARGET, "반라")
				CALL 탈의처리(MASTER, "반라")
			CASE 2
				CALL 탈의처리(TARGET, "속옷 모습으로 한다")
				CALL 탈의처리(MASTER, "속옷 모습으로 한다")
			CASEELSE
				CONTINUE
			ENDSELECT
			BREAK
		LOOP 1
	CASE 1
		CALL 탈의처리(TARGET, "전라")
		CALL 탈의처리(MASTER, "전라")
	CASE 2
		IF !TEQUIP:3
			CALL 탈의처리(TARGET, "반라")
			CALL 탈의처리(MASTER, "반라")
		ELSE
			PRINTFORML %CALLNAME:TARGET%의 옷은 벌써 풀어헤쳐지고 있다
			PRINTL 전부 벗기겠습니까?
			PRINT [0] - 네
			PRINT [1] - 아니오
			INPUT
			IF RESULT == 0
				CALL 탈의처리(TARGET, "전라")
				CALL 탈의처리(MASTER, "전라")
			ELSE
				RETURN 0
			ENDIF
		ENDIF
	ENDSELECT
;벌써 입지 않다
ELSE
	IF TEQUIP:TARGET:윗도리탈의가끝난상태
		CALL 탈의처리(TARGET, "전라")
		CALL 탈의처리(MASTER, "전라")
	ELSE
		;착의 플레이의 선택
		PRINTFORML %타겟은% 벌써 입지 않았다
		SELECTCASE FLAG:탈의선택
		CASE 0
			PRINTL 반라로 하겠습니까?
			PRINT [0] - 전부탈
			IF EQUIP:TARGET:상반신속옷1
				SIF EQUIP:0 && TARGET && EQUIP:TARGET:상반신속옷1 && (EQUIP:TARGET:기모노!= 0 || EQUIP:TARGET:상반신윗도리2 != 0 || EQUIP:TARGET:보디슈트== 3)
					PRINT [1] - 반라 착의 플레이
			ENDIF
			SIF EQUIP:0 && TARGET && (EQUIP:TARGET:상반신속옷1 != 0 || EQUIP:TARGET:상반신속옷2 != 0 || EQUIP:TARGET:하반신속옷1 != 0 || EQUIP:TARGET:하반신속옷2 != 0 || EQUIP:TARGET:레오타드!= 0 || EQUIP:TARGET:보디슈트!= 0)
				PRINT [2] - 속옷인 만큼 한다
			DO
				INPUT
				SELECTCASE RESULT
				CASE 0
					CALL 탈의처리(TARGET, "전라")
					CALL 탈의처리(MASTER, "전라")
				CASE 1
					CALL 탈의처리(TARGET, "반라")
					CALL 탈의처리(MASTER, "반라")
				CASE 2
					CALL 탈의처리(TARGET, "속옷 모습으로 한다")
					CALL 탈의처리(MASTER, "속옷 모습으로 한다")
				CASEELSE
					CONTINUE
				ENDSELECT
				BREAK
			LOOP 1
		CASE 1
			CALL 탈의처리(TARGET, "전라")
		CASE 2
			IF !TEQUIP:TARGET:3
				CALL 탈의처리(TARGET, "반라")
				CALL 탈의처리(MASTER, "반라")
			ELSE
				PRINTFORML %CALLNAME:TARGET%의 옷은 벌써 풀어헤쳐지고 있다
				PRINTL 전부 벗게 하겠습니까?
				PRINT [0] - 네
				PRINT [1] - 아니오
				INPUT
				IF RESULT == 0
					CALL 탈의처리(TARGET, "전라")
					CALL 탈의처리(MASTER, "전라")
				ELSE
					RETURN 0
				ENDIF
			ENDIF
		ENDSELECT
	ENDIF
ENDIF

;갈아입히기 플래그 OFF
;EQUIP:TARGET:0 = 0
;캐릭터 전원의 복재세팅
;개개로 하고 있으니 고례등응이라고 생각한다
[SKIPSTART]
FOR LOCAL, 0, CHARANUM
	CALL CLOTHES_SETTING_TRAIN(LOCAL)
NEXT
[SKIPEND]
RETURN 1


code:
;FileName_USERCOM.ERB ------------------------------ Rev1. 00
;커맨드 표시 처리
;CALL		SYSTEM
;ARG		VOID
;RETURN		VOID
;COMMENT
;-----------------------------------------------------------
@SHOW_USERCOM
TFLAG:100 = !TFLAG:101
VARSET LOCAL
;전턴의 MASTER가 사정한 상대를 LOCAL:1에 세트
IF TCVAR:MASTER:112 == 1
	;V
	LOCAL:1 = MASTER_POSE(SET_V, SET_P, 1)
ELSEIF TCVAR:MASTER:112 == 2
	;A
	LOCAL:1 = MASTER_POSE(SET_A, SET_P, 1)
ENDIF

CALL LOOK_AT
PRINTL

CALL 필터표시

;커맨드 표시
FOR LOCAL,0,800
	SIF LOCAL == 355 && (!FLAG:70 || CFLAG:TARGET:344 == 1)
		CONTINUE
	SIF LOCAL == 200 && TFLAG:102 == 2
		PRINTL
	SIF LOCAL == 350 && TFLAG:102 != 2
		PRINTL
	SIF LOCAL == 400 && TFLAG:102 != 2
		PRINTL
	SIF GLOBAL_COMABLE2(LOCAL)
		CONTINUE
	SIF GROUPMATCH(LOCAL,400,405,604)
		CONTINUE
	RESULT = 0
	;현상으로 대상 커맨드가 사용 가능한가 어떤가 판정
	TRYCALLFORM COM_ABLE{LOCAL}
	IF RESULT
		SIF !QUICKFILTER(LOCAL)
			CONTINUE
		IF (LOCAL == 42 && TEQUIP:11) || (LOCAL == 43 && TEQUIP:12) || (LOCAL == 44 && TEQUIP:13) || (LOCAL == 45 && TEQUIP:14) || (LOCAL == 46 && TEQUIP:15) || (LOCAL == 47 && TEQUIP:16) || (LOCAL == 48 && TEQUIP:17)
			PRINTFORMC %TRAINNAME:LOCAL% 해제[{LOCAL, 3}]
		ELSEIF LOCAL == 15
			IF CFLAG:MASTER:장난
				PRINTFORMC 음부 애무[{LOCAL,3}]
			ELSE
				PRINTFORMC 클리 애무[{LOCAL,3}]
			ENDIF
		ELSEIF LOCAL == 81 && LOCAL:1
			PRINTFORMC 청소 펠라[{LOCAL, 3}]
		ELSEIF LOCAL == 82 && (TALENT:105 == -2 || TALENT:105 == -1)
			PRINTFORMC 나이즈리[{LOCAL , 3}]
		ELSEIF LOCAL == 60 && (!BEDROOM(CFLAG:PLAYER:현재위치) && !(BATHROOM() && ITEM:20))
			PRINTFORMC 대면입위[{LOCAL, 3}]
		ELSEIF LOCAL == 61 && (!INROOM(CFLAG:PLAYER:현재위치) && !(BATHROOM() && ITEM:20))
			PRINTFORMC 배면입위[{LOCAL, 3}]
		ELSEIF LOCAL == 62 && (!BEDROOM(CFLAG:PLAYER:현재위치) && !(BATHROOM() && ITEM:20))
			PRINTFORMC 대면입위 애널[{LOCAL, 3}]
		ELSEIF LOCAL == 63 && (!INROOM(CFLAG:PLAYER:현재위치) && !(BATHROOM() && ITEM:20))
			PRINTFORMC 배면입위 애널[{LOCAL, 3}]
		ELSEIF LOCAL == 73 && TCVAR:PLAYER:이기초
			IF TEQUIP:TARGET:체위 == 1 && (BEDROOM(CFLAG:PLAYER:현재위치) || (BATHROOM() && ITEM:20))
				PRINTFORMC 교배 프레스[{LOCAL, 3}]
			ELSEIF TEQUIP:TARGET:체위 == 2
				IF CFLAG:TARGET:생리주기 == 7
					PRINTFORMC 잉태 교미[{LOCAL, 3}]
				ELSE
					PRINTFORMC 교배 교미[{LOCAL, 3}]
				ENDIF
			ELSE
				PRINTFORMC %TRAINNAME:LOCAL%[{LOCAL, 3}]
			ENDIF
		ELSEIF LOCAL == 92 && (!BEDROOM(CFLAG:PLAYER:현재위치) && !(BATHROOM() && ITEM:20))
			PRINTFORMC A대면입위받는다[{LOCAL, 3}]
		ELSEIF LOCAL == 93 && (!INROOM(CFLAG:PLAYER:현재위치) && !(BATHROOM() && ITEM:20))
			PRINTFORMC A배면입위받는다[{LOCAL, 3}]
		ELSEIF LOCAL == 100 && TALENT:TARGET:유치
			PRINTFORMC 엉덩이 팡팡[{LOCAL, 3}]
		ELSEIF LOCAL == 130 && (!BEDROOM(CFLAG:PLAYER:현재위치) && !(BATHROOM() && ITEM:20))
			PRINTFORMC 대면입위받는다[{LOCAL, 3}]
		ELSEIF LOCAL == 131 && (!INROOM(CFLAG:PLAYER:현재위치) && !(BATHROOM() && ITEM:20))
			PRINTFORMC 배면입위받는다[{LOCAL, 3}]
		ELSEIF LOCAL == 301 && CFLAG:TARGET:행동 == 5
			PRINTFORMC 차를 탄다[{LOCAL, 3}]
		ELSEIF LOCAL == 301 && GETBIT(TCVAR:MASTER:특별한차, 0)
			PRINTFORMC 홍차를 탄다[{LOCAL, 3}]
		ELSEIF LOCAL == 334 && CFLAG:TARGET:350 == 49 && (TALENT:TARGET:술내성 == -2 || CFLAG:TARGET:임신자각상태 == 1)
			PRINTFORMC 요리를 권한다[{LOCAL, 3}]
		ELSEIF LOCAL == 304 && CFLAG:TARGET:350 == 46
			PRINTFORMC 놀이에 참가한다[{LOCAL, 3}]
		ELSEIF LOCAL == 315
			IF GETBIT(TALENT:TARGET:성별, 1)
				PRINTFORMC 좆대 애무[{LOCAL, 3}]
			ELSEIF CFLAG:MASTER:장난
				PRINTFORMC 음부 애무[{LOCAL, 3}]
			ELSE
				PRINTFORMC 클리 애무[{LOCAL, 3}]
			ENDIF
		ELSEIF LOCAL == 350
			IF FLAG:70 == 1 && CFLAG:TARGET:344 == 0
				LOCALS = 장난친다
			ELSEIF (CFLAG:현재위치 == 혼숙여관 || CFLAG:현재위치 == 러브호텔)&& !CFLAG:우후후
				LOCALS = 껴안는다
			ELSEIF CFLAG:현재위치 == 서당
				LOCALS = 금지된 개인 수업
			ELSEIF CFLAG:현재위치 == OMANEKIBEYA() && TARGET == 43
				LOCALS = 방중술 수행
			;침대가 없다
			;실외
			ELSEIF !INROOM(CFLAG:PLAYER:현재위치)
				LOCALS = 껴안는다
			ELSE
				LOCALS = 덮친다
			ENDIF
			SIF GET_TARGETNUM() > 1
				LOCALS = 한꺼번에 %LOCALS%
			PRINTFORMC %LOCALS%[{LOCAL,3}]
		ELSEIF LOCAL == 351
			IF CFLAG:TARGET:동행
			ELSEIF COM_351_CONDITION(TARGET) == 1
				SETCOLOR 100, 100, 100
			ELSEIF CAN_IRAI_CHARA_GO_TOGATHER(TARGET)
				SETCOLOR C_GREEN
			ELSE
				SETCOLOR C_AQUA
			ENDIF
			PRINTFORMC %TRAINNAME:LOCAL%[{LOCAL,3}]
			RESETCOLOR
		ELSEIF LOCAL == 491
			SETCOLOR 255, 179, 167
			PRINTFORMC %TRAINNAME:LOCAL%[{LOCAL,3}]
			RESETCOLOR
		ELSEIF LOCAL == 360 && BASE:MASTER:기력 <= 0
			PRINTFORMC 남 하는 대로[{LOCAL,3}]
		ELSEIF LOCAL == 366 && GROUPMATCH(IRAI_CHARA_TO_PROGRESS(TARGET), "의뢰 달성", "의뢰 실패")
			SETCOLOR C_GREEN
			PRINTFORMC 의뢰 보고[{LOCAL,3}]
			RESETCOLOR
		ELSEIF LOCAL == 366 && GROUPMATCH(IRAI_CHARA_TO_PROGRESS(TARGET), "의뢰미수탁")
			SETCOLOR C_GREEN
			PRINTFORMC 의뢰를 듣는다[{LOCAL,3}]
			RESETCOLOR
		ELSEIF LOCAL == 367
			SETCOLOR C_GREEN
			PRINTFORMC %NAME_IRAI_ACT()%[{LOCAL,3}]
			RESETCOLOR
		ELSEIF LOCAL == 368
			;PRINTFORMC %자유행동에맡김_명칭(TARGET)%[{LOCAL,3}]
			PRINTFORMC %FreeAct_Name(TARGET)%[{LOCAL,3}]
		ELSEIF LOCAL == 337
			PRINTFORMC %아이소개명칭(TFLAG:묘사중인아이)%[{LOCAL,3}]
		ELSEIF LOCAL == 417 && TIME >= 660 && TIME <= 900
			PRINTFORMC 낮잠 잔다[{LOCAL,3}]
		ELSEIF LOCAL == 417
			PRINTFORMC 선잠 잔다[{LOCAL,3}]
		ELSEIF LOCAL == 420
			SELECTCASE MAIN_MAP
				CASE 0
					LOCALS = 루코토
				CASE 3
					LOCALS = 메이드 요정
				CASE 9
					LOCALS = 좀비 페어리
			ENDSELECT
			PRINTFORMC %LOCALS%와 대화[{LOCAL,3}]
		ELSEIF LOCAL == 422 && CFLAG:MASTER:현재위치 == 103
			PRINTFORMC 부처님 말씀을 듣는다[{LOCAL,3}]
		ELSEIF LOCAL == 431 && (CFLAG:MASTER:현재위치 == 24 || CFLAG:MASTER:현재위치 == 441||CFLAG:MASTER:현재위치 == 1444)
			PRINTFORMC 온천에서 쉰다[{LOCAL,3}]
		ELSEIF LOCAL == 431 && (CFLAG:MASTER:현재위치 == 대중목욕탕 || CFLAG:MASTER:현재위치 == 940)
			PRINTFORMC 입욕한다[{LOCAL,3}]
		ELSEIF LOCAL == 431 && OPENPLACE(CFLAG:MASTER:현재위치) && ITEM:간이풀장 && !BATHCHECK(CFLAG:MASTER:현재위치)
			PRINTFORMC 수영장에서 쉰다[{LOCAL,3}]
		; ELSEIF LOCAL == 405 && CFLAG:TARGET:동행 && TARGET
		; 	PRINTFORMC 데이트[{LOCAL, 3}]
		ELSEIF LOCAL == 410 && OUTROOF(CFLAG:MASTER:현재위치) && DAY:2 == 4
			PRINTFORMC 눈치우기[{LOCAL,3}]
		ELSEIF LOCAL == 414 && TIME >= 300 && TIME <= 540 && (CFLAG:MASTER:현재위치 == 9 || CFLAG:MASTER:현재위치 == OMANEKIBEYA())
			PRINTFORMC 아침 식사를 한다[{LOCAL,3}]
		ELSEIF LOCAL == 414 && TIME >= 660 && TIME <= 900 && (CFLAG:MASTER:현재위치 == 9 || CFLAG:MASTER:현재위치 == OMANEKIBEYA())
			PRINTFORMC 점심 식사를 한다[{LOCAL,3}]
		ELSEIF LOCAL == 414 && TIME >= 1020 && TIME <= 1200 && (CFLAG:MASTER:현재위치 == 9 || CFLAG:MASTER:현재위치 == OMANEKIBEYA())
			PRINTFORMC 저녁 식사를 한다[{LOCAL,3}]
		ELSEIF LOCAL == 414 && TIME >= 1200 && TIME <= 1440 && (CFLAG:MASTER:현재위치 == 9 || CFLAG:MASTER:현재위치 == OMANEKIBEYA())
			PRINTFORMC 늦은 식사를 한다[{LOCAL,3}]
		ELSEIF LOCAL == 414 && TIME >= 0 && TIME <= 180 && (CFLAG:MASTER:현재위치 == 9 || CFLAG:MASTER:현재위치 == OMANEKIBEYA())
			PRINTFORMC 야식을 먹는다[{LOCAL,3}]
		ELSEIF LOCAL == 414 && CFLAG:TARGET:행동 == 5
			PRINTFORMC 식사 휴식[{LOCAL,3}]
		ELSEIF LOCAL == 443
			PRINTFORMC %NAME_UNIQUE_COM(TARGET)%[{LOCAL,3}]
		ELSEIF LOCAL == 448
			IF HUNTING_SPOT(CFLAG:MASTER:현재위치) && MUSHITORI_SPOT(CFLAG:MASTER:현재위치)
				IF GET_MUSHIDATA(MUSHI_TRAP, "場所") && GROUPMATCH(GET_MUSHIDATA(MUSHI_TRAP, "場所"), TRAP_POINT:1, TRAP_POINT:2, TRAP_POINT:3)
					PRINTFORMC 덫을 본다[{LOCAL,3}]
				ELSE
					PRINTFORMC %TRAINNAME:LOCAL%[{LOCAL,3}]
				ENDIF
			ELSEIF GROUPMATCH(CFLAG:MASTER:현재위치, TRAP_POINT:1, TRAP_POINT:2, TRAP_POINT:3)
				PRINTFORMC 덫을 본다[{LOCAL,3}]
			ELSEIF GROUPMATCH(CFLAG:MASTER:현재위치, GET_MUSHIDATA(MUSHI_TRAP, "場所"))
				PRINTFORMC 벌레 트랩 확인[{LOCAL,3}]
			ELSEIF MUSHITORI_SPOT(CFLAG:MASTER:현재위치)
				PRINTFORMC 벌레 트랩[{LOCAL,3}]
			ELSE
				PRINTFORMC %TRAINNAME:LOCAL%[{LOCAL,3}]
			ENDIF
		ELSEIF LOCAL == 464
			SELECTCASE CFLAG:MASTER:현재위치
				CASE 210
					IF MAIN_MAP == 8
						PRINTFORMC 삭도역으로[{LOCAL,3}]
					ELSE
						PRINTFORMC 절경의 언덕으로[{LOCAL,3}]
					ENDIF
				CASE 820
					IF MAIN_MAP == 2
						PRINTFORMC 마을북쪽거리로[{LOCAL,3}]
					ELSE
						PRINTFORMC 광장으로[{LOCAL,3}]
					ENDIF
				CASE 570
					PRINTFORMC 중유의길로[{LOCAL,3}]
				CASE 760
					PRINTFORMC 작열지옥터로[{LOCAL,3}]
				CASE 970
					PRINTFORMC 간헐천지하센터로[{LOCAL,3}]
				CASEELSE
					LOCALS = %STR:(6000 + SPECIAL_AREAMOVE() / 10)%
					PRINTFORMC %조사처리(LOCALS,"으로")%[{LOCAL,3}]
			ENDSELECT
		ELSEIF LOCAL == 482
			PRINTFORMC %조사처리(CALLNAME:STALKED,"를")% 쫒는다[{LOCAL,3}]
		ELSEIF LOCAL == 626
			PRINTFORMC %GIFTSHOP_NAME(CFLAG:MASTER:데이트중, 1)%[{LOCAL,3}]
		ELSEIF LOCAL == 603 && PREVCOM == 603
			PRINTFORMC 손을 잡아당긴다[{LOCAL, 3}]
		ELSEIF LOCAL == 698
			PRINTFORMC %OMANEKI_PLACE()%로 간다[{LOCAL, 3}]
		ELSEIF STRLENS(TRAINNAME:LOCAL)
			PRINTFORMC %TRAINNAME:LOCAL%[{LOCAL, 3}]
		ENDIF
	ENDIF
NEXT
RESULT = 0
;자동 실행중이라면 아래와 같이 표시를 스킵
SIF !TFLAG:100
	GOTO SKIP
PRINTL
CALL PRINTBUTTON_EX(TFLAG:USERCOM비표시 ? "▽[＋][Ex_COM] ==" # "▼[－][Ex_COM] ==", 3002, TFLAG:USERCOM비표시)
; 개인 임의수정, CONFIG 폭에 따른 = 개수 자동조정
;PRINTFORML %"=" * 100%    ;original
PRINTFORML %"=" * (GETCONFIG("ウィンドウ幅") / 8 - 18)%
SIF TFLAG:USERCOM비표시
	GOTO SKIP
;SIF !GETBIT (FLAG:USERCOM필터, 12)
;	PRINTC 이력 표시[800]
IF GETBIT(FLAG:순간이동, 1) && !CFLAG:MASTER:동행
	SETCOLOR 0x5090FF
ELSE
	SETCOLOR C_GREEN
ENDIF
RESULT = 0
CALL COM_ABLE400
SIF RESULT
	PRINTC 이동[400]
RESULT = 0
RESETCOLOR
CALL COM_ABLE405
IF RESULT
	IF CFLAG:TARGET:동행 && TARGET
		PRINTC 데이트[405]
	ELSE
		PRINTC 나간다[405]
	ENDIF
ENDIF
RESULT = 0

IF GETBIT(FLAG:순간이동, 0) && !FLAG:데이트상대
	SETCOLOR 0x5090FF
ELSE
	SETCOLOR C_GREEN
ENDIF
RESULT = 0
CALL COM_ABLE604
SIF RESULT
	PRINTC 산책[604]
RESETCOLOR
SIF !GETBIT (FLAG:USERCOM필터, 0)
	PRINTC 불결 표시[801]
SIF !CFLAG:동침중 && GET_TARGETNUM() > 1 && !GETBIT (FLAG:USERCOM필터, 1)
	PRINTC 상대를 바꾼다[802]
SIF !GETBIT (FLAG:USERCOM필터, 2)
	PRINTC 능력 표시[803]
SIF !GETBIT (FLAG:USERCOM필터, 3)
	PRINTC 능력 표시(마스터)[804]
SIF !GETBIT (FLAG:USERCOM필터, 4)
	PRINTC 아이템 확인[805]
SIF !GETBIT(FLAG:USERCOM필터, 11)
	PRINTC 커맨드필터[809]
SIF FLAG:1005
	PRINTC CONFIG[810]
SIF TALENT:MASTER:위치짐작 && AT_HOME(MASTER) && (GETBIT(TALENT:MASTER:위치짐작, 1) || !(CFLAG:우후후 || CFLAG:장난 || CFLAG:동침중))
	PRINTC 위치짐작[811]
SIF TALENT:MASTER:오방짐작 && AT_HOME(MASTER) && !(CFLAG:우후후 || CFLAG:장난 || CFLAG:동침중)
	PRINTC 더러운 방 짐작[812]
SIF GETBIT(TALENT:MASTER:정욕감지, 1) && !CFLAG:우후후
	PRINTC 정욕 탐지[813]
SIF FLAG:70 && CFLAG:TARGET:344 == 0 && !CFLAG:TARGET:수면 && AT_HOME(MASTER) == 1 && TARGET > 0 && !CFLAG:우후후
	PRINTC 보쌈[815]
SIF FLAG:70 && TALENT:MASTER:집합 && AT_HOME(MASTER) == 1 && !CFLAG:우후후
	PRINTC 집합[817]
SIF GATHERING_SPOT(CFLAG:MASTER:현재위치) != 0
	PRINTC 채집 리스트[818]
IF CAN_DATE(TARGET)
	SIF TIME_REQUIRED(MAIN_MAP, CFLAG:MASTER:데이트중) < 10
		SETCOLOR 100, 250, 140
	PRINTFORMC %GET_MAPNAME(MAIN_MAP)%로 이끈다({TIME_REQUIRED(MAIN_MAP, CFLAG:MASTER:데이트중)}분)[990]
	RESETCOLOR
ENDIF

IF TALENT:MASTER:179 ;채양보음/채음보양 KR판 구잔재 또는 오리지날
	IF !GETBIT(TALENT:MASTER:179,0)&&!GETBIT(TALENT:MASTER:179,1)
		PRINTC 채양보음／채음보양[990]
	ELSE
		PRINTFORMC %GET_TALENTNAME(179, TALENT:MASTER:179)% 사용중[990]
	ENDIF
ENDIF

SIF CFLAG:MASTER:현재위치 == CFLAG:MASTER:초기위치 && !FLAG:자실잠금 ;내 방(신사 이외 가능) 잠금기능 KR판 구잔재
	PRINTC 잠근다[991]
SIF CFLAG:MASTER:현재위치 == CFLAG:MASTER:초기위치 && FLAG:자실잠금
	PRINTC 잠금을 푼다[991]
;;워프 이동했을 때를 위해서(때문에)
;IF FLAG:자실잠금 && CFLAG:MASTER:현재위치 != 53
;	SETCOLOR 0 , 255, 0
;	PRINTC ※원격건해정[991]
;	RESETCOLOR
;ENDIF

SIF CAN_DATE(TARGET)
	PRINTC 데이트 신청한다[992]
SIF CFLAG:MASTER:현재위치 == CFLAG:MASTER:초기위치
	PRINTC 달력[993]
SIF FLAG:팬티수송
	PRINTC 소지 팬티 확인[994]
IF AT_HOME(MASTER) && GETBIT(FLAG:순간이동, 1)
	SETCOLOR 0x5090FF
ELSEIF !AT_HOME(MASTER) && GETBIT(FLAG:순간이동, 0)
	SETCOLOR 0x5090FF
ENDIF
SIF !GETBIT(FLAG:USERCOM필터, 13)
	PRINTC 자동 시간정지 이동[995]
RESETCOLOR

;자동청소
IF AT_HOME(MASTER) && GETBIT(FLAG:자동청소, 1)
	SETCOLOR 0x5090FF
ELSEIF !AT_HOME(MASTER) && GETBIT(FLAG:자동청소, 0)
	SETCOLOR 0x5090FF
ENDIF
SIF !GETBIT(FLAG:USERCOM필터, 14) & AT_HOME(MASTER) && !CFLAG:우후후 && !CFLAG:동침중
	PRINTC 자동청소[996]
RESETCOLOR

PRINTL
IF FLAG:70 == 1 && CFLAG:TARGET:344 == 0
	SIF EQUIP:0 && TARGET && CFLAG:우후후
		PRINTC 옷을 벗긴다[820]
	IF EQUIP:0 && TARGET && EQUIP:TARGET:하반신속옷2 != 0
		IF !PANTS_ALREADY_COLLECTED()
			FONTBOLD
			SETCOLOR COLOR("PINK")
		ENDIF
			PRINTC 팬티를 훔친다[821]
			RESETCOLOR
			FONTREGULAR
	ENDIF
	IF (TEQUIP:5 == 0 || EQUIP:TARGET:상반신속옷1) && CFLAG:우후후
		SIF EQUIP:0 && TARGET && EQUIP:TARGET:상반신속옷1 != 0 && (EQUIP:TARGET:기모노!= 0 || EQUIP:TARGET:상반신윗도리2 != 0 || EQUIP:TARGET:보디슈트== 3)
			PRINTC 상하의를 벗는다[822]
	ENDIF
	IF TEQUIP:5 == 0 && CFLAG:우후후
		SIF EQUIP:0 && TARGET && (EQUIP:TARGET:상반신속옷1 || EQUIP:TARGET:상반신속옷2 || EQUIP:TARGET:하반신속옷1 || EQUIP:TARGET:하반신속옷2 || EQUIP:TARGET:레오타드 || EQUIP:TARGET:보디슈트) && (EQUIP:TARGET:상반신윗도리1 || EQUIP:TARGET:상반신윗도리2 || EQUIP:TARGET:원피스 || EQUIP:TARGET:기모노 || EQUIP:TARGET:외투)
			PRINTC 속옷 바람으로 한다[823]
	ENDIF
	IF MEASUREMENTCHECK(CFLAG:TARGET:현재위치)
		IF CFLAG:TARGET:신체측정 != 2
			PRINTC 신체측정한다[824]
		ELSE
			PRINTC 신체측정을 끝낸다[824]
		ENDIF
	ENDIF
	SIF TFLAG:팬티수탈
		PRINTC 팬티 수탈[825]
	IF TARGET
		IF TEQUIP:애태우기모드
			PRINTC 애태우기 종료[826]
		ELSE
			PRINTC 애태운다[826]
		ENDIF
	ENDIF
	IF CFLAG:우후후
		PRINTC 장난을 그만둔다[999]
	ELSE
		PRINTC 시간정지 해제[999]
	ENDIF
ELSEIF FLAG:70 == 1 && CFLAG:TARGET:344 == 1
		PRINTC 시간정지 해제[999]
	IF CFLAG:우후후
		SIF EQUIP:0 && TARGET
			PRINTC 옷을 벗긴다[820]

		IF CFLAG:우후후 == 2
			IF TFLAG:껴안기모드
				PRINTC 뿌리친다[850]
			ELSE
				PRINTC 빠져나간다[850]
			ENDIF
			IF TEQUIP:애태우기모드
				PRINTC 애태우기 종료[826]
			ELSE
				PRINTC 애태운다[826]
			ENDIF
		ELSE
			PRINTC 밀회 종료[999]
		ENDIF
	ENDIF
ELSEIF CFLAG:우후후 && !CFLAG:장난
	SIF EQUIP:0 && TARGET && !(TFLAG:102 == 3 && TFLAG:껴안기모드)
		PRINTC 옷을 벗긴다[820]
		IF TARGET
			IF TEQUIP:애태우기모드
				PRINTC 애태우기 종료[826]
			ELSE
				PRINTC 애태운다[826]
			ENDIF
		ENDIF
	IF FLAG:70 == 1 && CFLAG:TARGET:344 == 0
		PRINTC 시간정지해제[999]
	ELSEIF CFLAG:우후후 == 2
		IF TFLAG:껴안기모드
			PRINTC 뿌리친다[850]
		ELSE
			PRINTC 빠져나간다[850]
		ENDIF
	ELSE
		PRINTC 밀회 종료[999]
	ENDIF
ENDIF

IF CFLAG:장난
	SIF CFLAG:장난 < 2 && (EXP:TARGET:수면간경험 > 100 || TCVAR:수면제강도 || TCVAR:수면심도 > 2000)
		PRINTC 옷을 헤친다[830]
	IF CFLAG:장난 < 2
		PRINTC 장난 종료[999]
		IF EQUIP:TARGET:하반신속옷2
			IF !PANTS_ALREADY_COLLECTED()
				FONTBOLD
				SETCOLOR COLOR("PINK")
			ENDIF
			PRINTC 팬티를 훔친다[821]
			RESETCOLOR
			FONTREGULAR
		ENDIF
	ENDIF
	SIF CFLAG:장난 > 1
	PRINTC 수면간 종료[999]
ENDIF
IF CFLAG:동침중
	PRINTC 동침 종료[999]
ENDIF
IF CHK_DATENOW(CFLAG:MASTER:데이트중) && (!FLAG:70 || CFLAG:TARGET:344 == 1) && !CFLAG:MASTER:우후후 && CFLAG:MASTER:현재위치 != OMANEKIBEYA() && TFLAG:망상중 != 1
	SIF TIME_REQUIRED(MAIN_MAP, CFLAG:MASTER:데이트중) < 10
		SETCOLOR 100, 250, 140
	PRINTFORMC 귀로에 접어든다({TIME_REQUIRED(MAIN_MAP, CFLAG:MASTER:데이트중)}분)[999]
	RESETCOLOR
ENDIF
$SKIP
IF PREVCOM >= 0
	IF TFLAG:151
		STR:0 = %STR:(1500 + TFLAG:151)%
	ELSE
		STR:0 = %TRAINNAME:PREVCOM%
	ENDIF
ENDIF
SIF PREVCOM == 304 && CFLAG:TARGET:350 == 49 && TALENT:TARGET:술내성 != -2
	STR:0 = 잔를 나눈다
SIF PREVCOM == 304 && CFLAG:TARGET:350 == 49 && (TALENT:TARGET:술내성 == -2 || CFLAG:TARGET:임신자각상태 == 1)
	STR:0 = 요리를 권한다
SIF PREVCOM == 304 && CFLAG:TARGET:350 == 51
	STR:0 = 간호한다
IF !TFLAG:USERCOM비표시
	IF PREVCOM >= 0 && PREVCOM < 300
		PRINTL
		PRINT ＜전회 조교 커맨드:
		PRINTS STR:0
		SIF TFLAG:150
			PRINT (조수)
		PRINTL ＞
	ELSE
		PRINTL
		PRINT ＜전회 커맨드:
		PRINTS STR:0
		PRINTL ＞
	ENDIF
ENDIF

license: mit


code:
@GANKAKE_0(ARG, ARG:1)

FLAG:발원내용 = ARG
IF CFLAG:ARG:신사거주 && ARG > 0
;	// 호감도 상승 //
	CFLAG:ARG:호감도 += 10 + RAND:10
	CFLAG:ARG:신뢰도 += 5 + RAND:10
ELSEIF CFLAG:ARG:내방불능
	FLAG:발원내용 = -1
ELSE
	FOR LOCAL, 1, CHARANUM
	;	// 이사로 자택이 바뀌므로 자택 멤버도 발원함 플래그는 세우기로 한다 //
	;	SIF CFLAG:LOCAL:신사거주 > 0
	;		CONTINUE
		IF ARG == LOCAL
			CFLAG:LOCAL:다음날내방 = 1
		ELSE
			CFLAG:LOCAL:다음날내방 = 0
		ENDIF
	NEXT
ENDIF

@GANKAKE_1(ARG)
#FUNCTION
#DIM 버프가능개소수
#DIM 버프하는곳후보, 12
#DIM 실제버프하는곳

;버프하는곳후보:0~12에 소질번호를 할당해, 그때마다 버프가능개소수를 늘린다

VARSET 버프하는곳후보
버프가능개소수 = 0
실제버프하는곳 = 0

IF TALENT:ARG:사모 || IS_LOVER(ARG)
	IF TALENT:ARG:성적흥미 < 1
		버프하는곳후보:버프가능개소수 = 23
		버프가능개소수 ++
	ENDIF
	IF TALENT:ARG:자기애 < 1
		버프하는곳후보:버프가능개소수 = 31
		버프가능개소수 ++
	ENDIF
	IF TALENT:ARG:젖기쉬움 < 1
		버프하는곳후보:버프가능개소수 = 41
		버프가능개소수 ++
	ENDIF
	IF TALENT:ARG:쾌감응답 < 1
		버프하는곳후보:버프가능개소수 = 70
		버프가능개소수 ++
	ENDIF
	IF TALENT:ARG:도착적 < 1
		버프하는곳후보:버프가능개소수 = 80
		버프가능개소수 ++
	ENDIF
	IF TALENT:ARG:새드 < 1
		버프하는곳후보:버프가능개소수 = 82
		버프가능개소수 ++
	ENDIF
	IF TALENT:ARG:마조 < 1
		버프하는곳후보:버프가능개소수 = 83
		버프가능개소수 ++
	ENDIF
ENDIF

FOR LOCAL,101,105
	IF TALENT:ARG:LOCAL < 1
		버프하는곳후보:버프가능개소수 = LOCAL
		버프가능개소수 ++
	ENDIF
NEXT
IF TALENT:ARG:106 < 1
	버프하는곳후보:버프가능개소수 = 106
	버프가능개소수 ++
ENDIF

SIF !버프가능개소수
	RETURNF 버프가능개소수

실제버프하는곳 = 버프하는곳후보:(RAND:버프가능개소수)
TALENT:ARG:실제버프하는곳 ++
TCVAR:TARGET:발원함보정 = 실제버프하는곳
TFLAG:193 = 실제버프하는곳

RETURNF 버프가능개소수

@SHOW_CHALALIST
SIF FLAG:정렬
	CALL CHARASORT_EX
FOR LOCAL:1, 1, EX_CHARANUM
	IF FLAG:정렬
		LOCAL = RESULT:(LOCAL:1)
		SIF LOCAL < 0
			CONTINUE
	ELSE
		LOCAL = LOCAL:1
		SIF LOCAL >= CHARANUM
			BREAK
	ENDIF
	SIF !CFLAG:LOCAL:출금 && !TALENT:LOCAL:스침
		PRINTFORMLC [{LOCAL, 3}] %CALLNAME:LOCAL,15,LEFT%
NEXT
;21/08/27 반발 이력 삭제 추가, 반발 해제 시 반발 이력도 삭제 가능으로 변경
; KR판 임의수정, 8~13 한판 고유기능으로 인한 충돌로 반발이력삭제를 8 > 14로 이동
@IKENIE(ARG,ARG:1)
;ARG 대상
;ARG:1 소원(1=반발 해제 2=감도 일시 상승 3=요술망치 4=시간정지들킴 해제[オミット]
;			 5=천벌 6=자식 기원 7=새드끼 감소 14=반발이력삭제)
#DIM 총계
#DIM 종류수
#DIM 중복
#DIM 바친매수
#DIM 바치는매수
#DIM 필요매수
VARSET LOCAL
CALL CHECK_COLLECTION(ARG)
총계 = RESULT:0
종류수 = RESULT:1
중복 = 총계 - 종류수
바친매수 = 0
바치는매수 = 0
;KR판 오리지널 CASE 8,9,10,11,12,13
SELECTCASE ARG:1
	CASE 1,8
		필요매수 = 10
	CASE 2
		필요매수 = 3
	CASE 3
		필요매수 = CFLAG:MASTER:마력회수 / 2 + 1
	CASE 4,6,14
		필요매수 = 1
	CASE 5,7
		필요매수 = 3
	CASE 9,10,11,12,13
		필요매수 = 5
ENDSELECT

PRINTL 머릿속에 목소리가 울린다…
PRINTW ((그 소망을 이루고 싶다면, 공물을 바쳐라…))
PRINTFORMW ((%CALLNAME:ARG%의 팬티를{필요매수}매 바쳐라……))
PRINTFORM 현재%CALLNAME:ARG%의 팬티를
IF !종류수
	PRINTL 한 장도 가지고 있지 않다
	RETURN -1
ENDIF
PRINTFORML 전부{총계}매{종류수}종, 겹치고 있는 것은{중복}매 가지고 있다
IF 총계 < 필요매수
	PRINTFORML 소망하고 있는 매수에{필요매수 - 총계}매 부족하다
	RETURN -1
ENDIF

LOCALS = 바친다
SIF 중복 < 필요매수
	LOCALS = 겹치지 않은 것도 사용하게 되지만 바친다
$LOOP
CALL ASK_M("바치지 않는다",1,@"%LOCALS%",총계 >= 필요매수)
IF RESULT == 1
	FOR LOCAL, 0, MAXPANTS
		IF CFLAG:ARG:(팬티관리 + LOCAL) > 1
			바치는매수 = MIN(CFLAG:ARG:(팬티관리 + LOCAL) - 1, (필요매수 - 바친매수))
			CFLAG:ARG:(팬티관리 + LOCAL) -= 바치는매수
			바친매수 += 바치는매수
			SIF 바친매수 >= 필요매수
				BREAK
		ENDIF
	NEXT
	IF 바친매수 < 필요매수
		FOR LOCAL, 0, MAXPANTS
			바치는매수 = MIN(CFLAG:ARG:(팬티관리 + LOCAL), (필요매수 - 바친매수))
			CFLAG:ARG:(팬티관리 + LOCAL) -= 바치는매수
			바친매수 += 바치는매수
			FLAG:700 --
			SIF 바친매수 >= 필요매수
				BREAK
		NEXT
	ENDIF
	SIF ARG:1 == 1
		CALL ASK_M("이력도 지운다",1,"이력은 남긴다",1)
	SELECTCASE ARG:1
		CASE 1
			MARK:ARG:반발각인 --
			SIF !RESULT
				MARK:ARG:반발취득이력 --
			TFLAG:193 = 30
		CASE 2
			FLAG:발원내용 = 999
		CASE 3
			CFLAG:MASTER:마력회수 = 1
			SIF (CFLAG:MASTER:요술망치 == 4 || CFLAG:MASTER:요술망치 == 5) && TALENT:MASTER:형상 == 2
				TALENT:MASTER:형상 = CFLAG:MASTER:382
		CASE 4
			CFLAG:ARG:시간정지들킴 = 0
		CASE 5
			FLAG:발원내용 = 204
			TFLAG:193 = 200
			FLAG:개운대문구입회수 = 1
			BASE:53:체력 = 1
			BASE:53:기력 = 0
		CASE 6
			FLAG:발원내용 = 206
			IF FLAG:자식기원 == TARGET
				CFLAG:자식보정 ++
			ELSE
				FOR LOCAL,1,CHARANUM
					CFLAG:LOCAL:자식보정 = 0
				NEXT
				CFLAG:자식보정 ++
			ENDIF
			SIF TALENT:임신소망
				CFLAG:자식보정 ++
			SIF TALENT:연인
				CFLAG:자식보정 ++
			FLAG:자식기원 = TARGET
		CASE 7
			ABL:ARG:새드끼 -= 1
			JUEL:ARG:우월 = 0
			EXP:ARG:가학쾌락경험 = MAX(EXP:ARG:가학쾌락경험 - 200, 0)
		;KR판 오리지널 CASE 8,9,10,11,12,13
		CASE 8
			CFLAG:ARG:약점잡음=0
		CASE 9,10,11,12
			TALENT:ARG:((ARG:1)-8+100)++
		CASE 13
			TALENT:ARG:M감도++
		CASE 14
			MARK:ARG:반발취득이력 = 0
			TFLAG:193 = 35
	ENDSELECT
	PRINTFORML %마스터가% 비장의 콜렉션을 늘어놓고 빌자, 이 세상 아닌 불꽃이{필요매수}매의 팬티를 타다 남은것 하나 남기지 않고 다 태워 버렸다!
	FLAG:독신 += 필요매수
	IF ARG:1 == 7
		CALL COLORMESSAGE(@"%CALLNAME:ARG%의 새드끼가 내려갔다",C_YELLOW,2,1)
		CALL COLORMESSAGE(@"%CALLNAME:ARG%의 가학쾌락경험이 내려갔다",C_YELLOW,2,1)
		CALL COLORMESSAGE(@"%CALLNAME:ARG%의 우월의 구슬이 0이 되었다",C_YELLOW,2,1)
	ENDIF
	IF ARG:1 == 6
		PRINTFORML ((그 아가씨에게로의 정과 기원을 빠뜨리지 말것))
		PRINTFORMW ((자 그렇다면 머지않아 소원은 성취하자……))
	ELSEIF ARG:1 == 2 && !GANKAKE_1(ARG)
		PRINTW
		PRINTW …
		PRINTW ……
		PRINTW ………
		PRINTW …………
		PRINTFORML 팬티님도 %ARG는% 더 이상 야하게 할 수 없을 것 같다……
		RETURN -1
	ELSE
		PRINTW ((네 소원은 성취되었도다……))
	ENDIF
	PRINTFORML %마스터는% 팬티님에 대한 경신의 생각을 새로이 했다
	RETURN 0
ELSE
	RETURN -1
ENDIF

@PINK_WIND
#DIM 供物
#DIM 捧げる枚数
#DIM 総数
#DIM HIT
捧げる枚数 = 0
総数 = 0
DO
	IF FLAG:팬티수송 == 0
		供物 = 0
		BREAK
	ENDIF
	PRINTFORML 공물로 소지한 팬티를 추가로 바치겠습니까？
	CALL ASK_M("하지 않는다", 1, "바친다", 1, "소지 팬티 확인", 1)
	SELECTCASE RESULT
		CASE 0, 1
			供物 = RESULT
			BREAK
		CASE 2
			CALL SHOW_HAVE_COLLECTION()
			PRINTL
	ENDSELECT
LOOP 1
SETCOLOR 255,100,255
FONTBOLD
PRINTFORMW 환상향에 분홍빛 바람이 불었다!
FOR LOCAL,1,CHARANUM
	IF 供物
		CALL CHECK_COLLECTION(LOCAL, 1)
		捧げる枚数 = RESULT
	ENDIF
	HIT = !RAND:15
	;供物を捧げることにより元の持ち主に桃色の風を確定で当てる
	IF HIT || (供物 && 捧げる枚数 > 0)
		IF 供物
			IF 捧げる枚数 > 0
				IF HIT
					PRINTFORM 〇●
					;従来通りの確率に当たりかつ捧げた場合に加算
					総数 ++
				ELSE
					PRINTFORM 〇
				ENDIF
				;同キャラのパンツを2枚以上捧げた枚数分加算
				SIF 捧げる枚数 > 1
					総数 += (捧げる枚数 - 1) * 2
			ELSEIF HIT
				PRINTFORM 　●
			ENDIF
		ENDIF

		PRINTFORML 분홍빛 바람을 받은 %조사처리(CALLNAME:LOCAL,"는")% 이상한 기분이 되었다…
		CFLAG:LOCAL:욕구불만도 += LIMIT((10 + RAND:20 + RAND:20 + RAND:20) * ABL:LOCAL:욕망, 200,1000)
		;捧げてかつ、くすねてはいていない場合追加効果あってもよさげ？
	ENDIF
NEXT
RESETCOLOR
FONTREGULAR
PRINTW ((네 소원은 성취되었도다……))
IF 供物
	PRINTFORML 정신을 차려보니 공물로 바쳤던 팬티는 사라져 있었다
	VARSET PANTS_TEMP
	FLAG:팬티수송 = 0
ENDIF
PRINTFORML %마스터는% 팬티님에 대한 경신의 생각을 새로이 했다
FLAG:독신 += (1 + 総数)

@DOWSING_PANTS
#DIM CHK_SLOT
#DIM CHARA
#DIM HIT
PRINTFORMW %마스터는% 의뢰된 물건을 찾을 수 있기를 기도했다……
PRINTL
HIT = 0
FOR CHK_SLOT, 1, 6
	SIF !GETBIT(CAN_DOWSING(), CHK_SLOT)
		CONTINUE
	CHARA = 0
	SELECTCASE IRAI_SLOT_TO_TASKNAME(CHK_SLOT)
	CASE "수색(인물)"
		CHARA = IRAI_SLOT_TO_PERSON(CHK_SLOT)
		;手持ち
		CALL CHECK_COLLECTION(CHARA, 1)
		IF RESULT
			CALL DOWSING_PANTS_MESSAGE(CHARA, 1)
			HIT = 1
		ELSE
			;コレクション
			CALL CHECK_COLLECTION(CHARA, 0)
			IF RESULT
				CALL DOWSING_PANTS_MESSAGE(CHARA, 0)
				HIT = 1
			ENDIF
		ENDIF
	CASE "수색(장소)"
		;自宅があるキャラを抽出
		FOR CHARA, 1, CHARANUM
			IF CFLAG:CHARA:자택위치 == GET_MAP_REPLACEMENT(IRAI_SLOT_TO_PLACE(CHK_SLOT))
				;手持ち
				CALL CHECK_COLLECTION(CHARA, 1)
				IF RESULT
					CALL DOWSING_PANTS_MESSAGE(CHARA, 1)
					HIT = 1
					BREAK
				ELSE
					;コレクション
					CALL CHECK_COLLECTION(CHARA, 0)
					IF RESULT
						CALL DOWSING_PANTS_MESSAGE(CHARA, 0)
						HIT = 1
						BREAK
					ENDIF
				ENDIF
			ENDIF
		NEXT
	CASEELSE
		CONTINUE
	ENDSELECT
NEXT
SIF !HIT
	PRINTFORMW ……그러나 기도는 이루어지지 않았다

@DOWSING_PANTS_MESSAGE(CHARA, HAND)
#DIM CHARA
#DIM HAND
#DIM 종류
#DIM 소유수
CALL FISHER_YATES_SHAFFLE(MAXPANTS)
SETCOLOR C_YELLOW
FOR LOCAL, 0, MAXPANTS
	종류 = SHAFFLE_ARRAY:LOCAL
	IF !HAND
		IF CFLAG:CHARA:(종류 + 팬티관리)
			PRINTFORMW 이럴수가! 보관하고 있었던 %CALLNAME:CHARA%의 %조사처리(PANTSNAME(종류,CHARA),"가")% 빛나기 시작했다!
			BREAK
		ENDIF
	ELSE
		IF PANTS_TEMP:CHARA:종류
			PRINTFORMW 이럴수가! 손에 들고 있었던 %CALLNAME:CHARA%의 %조사처리(PANTSNAME(종류,CHARA),"가")% 빛나기 시작했다!
			BREAK
		ENDIF
	ENDIF
NEXT
RESETCOLOR


code:
@외출처로부터귀가
#DIM DIST_TO_HOME
#DIM ReqTSP
#DIM 道迷い時間
#DIMS 低気圧位置

低気圧位置 = %GET_LOCATION_LOW()%

ReqTSP = TIME_REQUIRED(MAIN_MAP,CFLAG:MASTER:데이트중) * 3
IF !FLAG:데이트상대 && !FLAG:70 && BASE:MASTER:TSP >= ReqTSP
	PRINTL TSP를 소비하여 시간 경과 없이 귀가할 수 있습니다.
	PRINTL TSP를 사용하겠습니까?
	CALL ASK_YN
	IF !RESULT
		IF BASE:MASTER:TSP < ReqTSP
			PRINTW TSP가 부족했다
		ELSE
			BASE:MASTER:TSP -= ReqTSP
			GOTO WARP
		ENDIF
	ENDIF
ENDIF
IF !FLAG:70
	;(天候パッチ)連続降水カウンター20以上で土砂崩れに巻き込まれる可能性
	IF CONTINUOUS_RAINFALL >= 20 && RAND:(MAX(2, (40 - CONTINUOUS_RAINFALL) / 2)) == 0
		PRINTFORML …길을 걷고 있는데 산 고지대에서 이상한 소리가 들려왔다
		PRINTFORMW ！！　산사태다！！

		PRINTFORML
		PRINTFORML %마스터는% 토사에 휩쓸리면서도
		PRINTFORML 가까스로 탈출하는데 성공했다…
		PRINTL
		CALL ASK_DIARY("산사태와 조우했다")
		BASE:MASTER:체력 -= (MAXBASE:MASTER:체력 * 3)

		GOTO WARP2
	ENDIF
	;(天候パッチ)雪崩発生フラグが立っているとき雪崩に巻き込まれる可能性
	IF POSSIBLITY_AVALANCHE == 1 && POWER_COLD_AIR >= 3 && RAND:((6 - POWER_COLD_AIR) * 10) == 0
		PRINTFORML …길을 걷고 있는데 산 고지대에서 무언가가 덮쳐왔다
		PRINTFORMW ！！　눈사태다！！

		PRINTFORML
		PRINTFORML %마스터는% 눈사태에 휘말리면서도
		PRINTFORML 가까스로 탈출하는데 성공했다…
		PRINTL

		POSSIBLITY_AVALANCHE = 0
		CONTINUOUS_SNOWFALL = 0

		CALL ASK_DIARY("눈사태와 조우했다")
		BASE:MASTER:체력 -= (MAXBASE:MASTER:체력 * 3)

		GOTO WARP4
	ELSEIF POSSIBLITY_AVALANCHE == 2 && POWER_WARM_AIR >= 2 && RAND:((6 - POWER_WARM_AIR) * 10) == 0
		PRINTFORML …길을 걷고 있는데 산 고지대에서 무언가가 덮쳐왔다
		PRINTFORMW ！！　눈사태다！！

		PRINTFORML
		PRINTFORML %마스터는% 눈사태에 휘말리면서도
		PRINTFORML 가까스로 탈출하는데 성공했다…
		PRINTL

		POSSIBLITY_AVALANCHE = 0
		CONTINUOUS_SNOWFALL = 0
		SNOW_COVERAGE = 0

		CALL ASK_DIARY("눈사태와 조우했다")
		BASE:MASTER:체력 -= (MAXBASE:MASTER:체력 * 3)

		GOTO WARP5
	ENDIF
	;(天候パッチ)暴風雪発生時にホワイトアウト発生の可能性 颶風時には確率上昇
	IF TIME:5 == 9 && ((WIND_VELOCITY == 2 && RAND:3 == 0) || WIND_VELOCITY >= 3)
		道迷い時間 = 60 + RAND:120
		PRINTFORML 쏟아지는 눈이 맹렬한 바람에 몰아쳐
		PRINTFORMW 눈 앞이 새하얘졌다！
		PRINTFORML
		PRINTFORML ……길을 잃고 {道迷い時間}분 쓸데없이 걸어 버렸다
		TIME:0 += 道迷い時間
		BASE:MASTER:체력 = MAX(BASE:MASTER:체력 - (20 * 道迷い時間), 0)

		GOTO WARP6
	ELSEIF TIME:5 == 8 && ((WIND_VELOCITY == 2 && RAND:10 == 0) || WIND_VELOCITY >= 3)
		道迷い時間 = 30 + RAND:60
		PRINTFORML 쏟아지는 눈이 맹렬한 바람에 몰아쳐
		PRINTFORMW 눈 앞이 새하얘졌다！
		PRINTFORML
		PRINTFORML ……길을 잃고 {道迷い時間}분 쓸데없이 걸어 버렸다
		TIME:0 += 道迷い時間
		BASE:MASTER:체력 = MAX(BASE:MASTER:체력 - (15 * 道迷い時間), 0)

		GOTO WARP7
	ENDIF
	CALL 외출이벤트
	$WARP2
	$WARP4
	$WARP5
	$WARP6
	$WARP7
	CALL 귀가의시간경과
ELSEIF BASE:MASTER:TSP < ReqTSP
	PRINTW TSP가 부족하기 때문에 시간을 멈춘 상태로는 돌아갈 수 없다
	RETURN -1
ELSE
	BASE:MASTER:TSP -= ReqTSP
ENDIF

$WARP
IF CFLAG:패배자 && TALENT:스침 == 1
	PRINTFORML %타겟을% 데리고 돌아왔습니다
ELSEIF BASE:MASTER:체력 <= 0
	PRINTFORML %마스터는% 마지막 있는 힘을 다해、%GET_MAPNAME(MAIN_MAP)%까지 돌아왔다…
	PRINTFORML 하지만 %NAME_FROM_PLACE(ENTRANCE)%에 간신히 도착하자마자 의식을 잃었다…
	PRINTFORMW
ELSE
	PRINTFORMW \@ CFLAG:MASTER:데이트중 != CFLAG:TARGET:데이트중 || TARGET == MASTER ?  외출 # 데이트 \@에서 돌아왔습니다
ENDIF
CALL 모리야복권데이트상대의리셋()
FOR LOCAL, 1, CHARANUM
	IF CHK_DATENOW(CFLAG:LOCAL:데이트중)
		CALL DATE_EVENT(LOCAL)
		CALL SET_DATE(99, LOCAL)
	ENDIF
NEXT
SIF CHK_DATENOW(CFLAG:MASTER:데이트중)
	CALL SET_DATE(99, MASTER)

CFLAG:MASTER:현재위치 = GET_ENTRANCE(MAIN_MAP)

@귀가의시간경과
;남은 시간 산출
IF TFLAG:데이트도중
	;도중의 경우
	TIME = TIME + TIME_REQUIRED(MAIN_MAP, CFLAG:MASTER:데이트중) - TFLAG:데이트도중
ELSE
	;데이트처 도착 끝난 경우
	TIME = TIME + TIME_REQUIRED(MAIN_MAP, CFLAG:MASTER:데이트중)
ENDIF
CALL 모리야복권데이트상대의리셋()

@외출처로부터권할수있을까(ARG)
LOCAL = FLAG:데이트상대
IF CFLAG:ARG:행동 == 5
	PRINTFORMW %ARG는% 지금 일하는 중이다
	RETURN 0
ENDIF
IF LOCAL != ARG && LOCAL != MASTER
	PRINTFORM %조사처리(CALLNAME:LOCAL,"가")% %CALLNAME:MASTER%
	;심약계
	IF CFLAG:LOCAL:성격경향 == 1
		PRINTFORML 의 옷의 옷자락을 잡아 거절하고 있다
	;강경세계
	ELSEIF CFLAG:LOCAL:성격경향 == 2
		PRINTFORML %조사만처리(CALLNAME:MASTER,"를")% 번쩍빛나는 눈으로 응시해 온다
	;솔직함계
	ELSEIF CFLAG:LOCAL:성격경향 == 3
		PRINTFORML %조사만처리(CALLNAME:MASTER,"를")% 응시하면서 나만을 보았으면 좋겠다고 알려온다
	;진면목계
	ELSEIF CFLAG:LOCAL:성격경향 == 4
		PRINTFORML 에게 그것은 안 된다며 참견해 온다
	;그 외
	ELSEIF CFLAG:LOCAL:성격경향 == 5
		PRINTFORML 에게 한숨을 내쉬고, 고개를 저었다
	ENDIF
	PRINTFORMW %마스터는% %ARG를% 권하는 것을 단념했다
	RETURN 0
ENDIF
IF !VISIT(ARG)
	PRINTFORMW 지금은 안된다고 들었다
	RETURN 0
ENDIF
IF ARG == 93 && !ITEM:간이풀장
	PRINTW 그녀는 데리고 갈 수 없다…
	RETURN 0
ELSEIF BASE:ARG:기력 < 500
	PRINTFORMW %ARG는% 피곤한 것 같다
	RETURN 0
ELSEIF !CHARA_HOLIDAY(ARG) && BASE:ARG:일량 && TCVAR:ARG:일개시 < TIME + 180
	PRINTFORMW %ARG는% 지금부터 일이 있다
	RETURN 0
ELSE
	CFLAG:ARG:거점내방 = 1
	RETURN 1
ENDIF

;FileName_DATE_CMN.ERB ------------------------------- Rev1. 00
;데이트 신청할 수 있을까
;-----------------------------------------------------------
@CAN_DATE(ARG)
#FUNCTION

SIF !CHK_DATENOW(CFLAG:MASTER:데이트중)
	RETURNF 0
SIF !SHIRAHU(ARG)
	RETURNF 0
SIF CFLAG:MASTER:현재위치 == OMANEKIBEYA()
	RETURNF 0
IF !CFLAG:ARG:패배자
	SIF !CFLAG:ARG:태도 && TARGET != RANDOM_CHARANUM
		RETURNF 0
	SIF CFLAG:ARG:빡침
		RETURNF 0
ENDIF
;잠복モード中は不可
SIF GETBIT(FLAG:잠복,0)
	RETURNF 0
SIF CHK_DATENOW(CFLAG:ARG:데이트중)
	RETURNF 0
SIF (!TALENT:TARGET:사모 && !TALENT:TARGET:연모 && !TALENT:TARGET:애욕 && TARGET != RANDOM_CHARANUM)
	RETURNF 0
RETURNF 1

path: ERB/커맨드관련/외출처로부터귀가_t.ERB


code:
@SYUGO
#DIM 집합, 캐릭터수상한, 3      ;집합:X:Y
                               ;Y=0：캐릭터 등록 번호
                               ;  1：설정, 이동 여부(1p0: 이동 불가, 1p3: 이동 대상)
                               ;  2：이동코스트
#DIM 인원수                    ;동일 맵에 있는 인원수, 이동할 수 없는 캐릭터도 표시되어 인원수에 가산되어 있다
#DIM 입력값                    ;RESULT 취득용
CALL SYUGOS_GETDATA(인원수, 집합)
IF 인원수 == 0
	PRINTW 아무도 없다
	RETURN
ENDIF
IF CFLAG:MASTER:현재위치 == 54
	PRINTFORMW 여기서는 무리다
	RETURN
ENDIF

;전원분의 코스트 계산을 먼저 한다(아마 전원 집합의 빈도가 많기 때문에)
CALL SYUGOS_COST(인원수, 집합)

PRINTL 누구를 이동 시키겠습니까?
DO
	CALL SYUGOS_DISPDATA(인원수, 집합)
	PRINTBUTTON "[444:전원 설정]", 444
	PRINTBUTTON "[555:전원 해제]", 555
	PRINTBUTTON "[666:실행 개시]", 666
	PRINTFORML
	PRINTBUTTON "[999:취소]", 999
	INPUT
	입력값 = RESULT
	SELECTCASE 입력값
	;개인 선택
	CASE 0 TO 인원수 - 1
		SIF !GETBIT(집합:입력값:1, 0)
			INVERTBIT 집합:입력값:1, 3
	;전체 설정
	CASE 444
		FOR LOCAL, 0, 인원수
			SIF GETBIT(집합:LOCAL:1, 0)
				CONTINUE
			SETBIT 집합:LOCAL:1, 3
		NEXT
	;전원 해제
	CASE 555
		FOR LOCAL, 0, 인원수
			CLEARBIT 집합:LOCAL:1, 3
		NEXT
	;실행 처리
	CASE 666
		IF TFLAG:운반
			PRINTFORMW %마스터는% %조사처리(CALLNAME:(TFLAG:운반),"를")% 내렸다
			TFLAG:운반 = 0
		ENDIF
		FOR LOCAL, 0, 인원수
			SIF !GETBIT(집합:LOCAL:1, 3)
				CONTINUE

			;가는 길 소비
			SIF TALENT:MASTER:체형 < -4
				BASE:MASTER:TSP -= (15 * 집합:LOCAL:2)
			BASE:MASTER:TSP -= (5 * 집합:LOCAL:2)
			SIF BASE:MASTER:TSP <= 0
				BREAK
			;돌아오는 길 소비
			SIF TALENT:MASTER:체형 < -4
				BASE:MASTER:TSP -= (15 * 집합:LOCAL:2)
			BASE:MASTER:TSP -= (5 * 집합:LOCAL:2)
			BASE:MASTER:TSP -= (3 * 집합:LOCAL:2)
			CFLAG:(집합:LOCAL:0):현재위치 = CFLAG:MASTER:현재위치
			;자유 행동의 중단
			Activity_Duration:(집합:LOCAL:0) = 0
			Activity_Type:(집합:LOCAL:0) = 0
			PRINTFORMW %조사처리(CALLNAME:(집합:LOCAL:0),"를")% %조사처리(NAME_FROM_PLACE(CFLAG:MASTER:현재위치),"로")% 업고 와서 내렸다
			SIF BASE:MASTER:TSP <= 0
				BREAK
		NEXT
		RETURN
	CASE 999
		RETURN
	ENDSELECT
	CLEARLINE 인원수 + 3
LOOP 1

@SYUGOS_GETDATA(인원수, 집합)
#DIM REF 집합, ,
#DIM REF 인원수
#DIM C_ID
VARSET 집합
VARSET 인원수
FOR LOCAL, 1, CHARANUM
	SIF AT_HOME(LOCAL) == 0
		CONTINUE
	SIF TALENT:MASTER:위치짐작 == 0 && CFLAG:MASTER:현재위치 != CFLAG:LOCAL:현재위치 && CAN_MOVE(CFLAG:MASTER:현재위치, CFLAG:LOCAL:현재위치) == 0
		CONTINUE
	SIF CFLAG:LOCAL:현재위치 == MAXROOM && CFLAG:LOCAL:수면
		CONTINUE
	집합:인원수:0 = LOCAL
	C_ID = 집합:인원수:0
	;선택 여부
	IF CFLAG:C_ID:현재위치 == CFLAG:MASTER:현재위치
		SETBIT 집합:인원수:1, 0
	ELSEIF CFLAG:C_ID:수면
		SETBIT 집합:인원수:1, 0
	ELSEIF !MAP_CAN_MOVE(CFLAG:C_ID:현재위치)
		SETBIT 집합:인원수:1, 0
	ELSEIF BATHCHECK(CFLAG:C_ID:현재위치) || IN_TOILET(CFLAG:C_ID:현재위치)
		SETBIT 집합:인원수:1, 0
	ELSEIF CFLAG:C_ID:현재위치 == MAXROOM || CFLAG:C_ID:현재위치 == OMANEKIBEYA()
		SETBIT 집합:인원수:1, 0
	ELSEIF CFLAG:C_ID:행동 == 5
		SETBIT 집합:인원수:1, 0
	ENDIF
	인원수 ++
NEXT

@SYUGOS_DISPDATA(인원수,집합)
#DIM REF 집합,,
#DIM 인원수
#DIM C_ID
FOR LOCAL, 0, 인원수
	C_ID = 집합:LOCAL:0
	LOCALS = {LOCAL}
	LOCALS = [%LOCALS,3,RIGHT%] - %CALLNAME:C_ID,15,LEFT%
	IF CFLAG:C_ID:현재위치 == CFLAG:MASTER:초기위치
		LOCALS = %LOCALS%%CALLNAME:MASTER%의 방
	ELSE
		LOCALS = %LOCALS%%NAME_FROM_PLACE(CFLAG:C_ID:현재위치)%
	ENDIF
	IF !MAP_CAN_MOVE(CFLAG:C_ID:현재위치)
		LOCALS = %LOCALS%%" "*(48-STRLENS(LOCALS))% 침입 불가
	ELSEIF CFLAG:C_ID:수면
		LOCALS = %LOCALS%%" "*(48-STRLENS(LOCALS))% 취침 중
	ELSEIF CFLAG:C_ID:행동 == 5
		IF CFLAG:C_ID:현재위치 == TFLAG:연회장 && TIME_PROGRESS(TIME:1) && (CFLAG:C_ID:직종 == 49 || CFLAG:C_ID:직종 == 51)
			LOCALS = %LOCALS%%" "*(48-STRLENS(LOCALS))% 연회 중
		ELSE
			LOCALS = %LOCALS%%" "*(48-STRLENS(LOCALS))% 일하는 중
		ENDIF
	ELSEIF 집합:LOCAL:2 > 0
		LOCALS = %LOCALS%%" "*(48-STRLENS(LOCALS))% 이동 거리 {집합:LOCAL:2}
	ENDIF
	IF GETBIT(집합:LOCAL:1, 0)
		SETCOLOR C_GRAY
		PRINTPLAINFORM %LOCALS%
	ELSEIF GETBIT(집합:LOCAL:1, 3)
		SETCOLOR C_AQUA
		PRINTFORM %LOCALS%
	ELSE
		PRINTFORM %LOCALS%
	ENDIF
	PRINTL
	RESETCOLOR
NEXT

;모든 캐릭터를 대상으로 이동 비용을 산출한다
;불러오기 전에 모든 캐릭터 루프를 한다면 코스트 산출 측에서 더 모든 캐릭터 루프를 하는 것보다
;산출 끝난 지점을 기억해 두는 편이 빠른 것이 아닐까?
@SYUGOS_COST(인원수, 집합)
#DIM 인원수
#DIM REF 집합,,
#DIM LIST_ID                 ;참조하고 있는 LIST의 ID
#DIM DYNAMIC DONE_CNT        ;산출 끝난 지점의 수
#DIM DYNAMIC DONE_PLACE, 100 ;산출 끝난 지점의 PLACE_ID
#DIM DYNAMIC DONE_COST,  100 ;산출 끝난 지점의 코스트
#DIM TEMP_PLACE              ;참조용 일시변수
FOR LIST_ID, 0, 인원수
	;NG처리는 먼저 해 둔다
	IF GETBIT(집합:LIST_ID:1, 0)
		집합:LIST_ID:2 = -1
		CONTINUE
	ENDIF

	TEMP_PLACE = FINDELEMENT(DONE_PLACE, CFLAG:(집합:LIST_ID:0):현재위치, 0, DONE_CNT)
	;산출 끝남
	IF TEMP_PLACE >= 0
		집합:LIST_ID:2 = DONE_COST:TEMP_PLACE
	;산출 아직
	ELSE
		CALL CALC_SYUGOS_COST(집합, LIST_ID)
		DONE_PLACE:DONE_CNT   = CFLAG:(집합:LIST_ID:0):현재위치
		DONE_COST:DONE_CNT    = 집합:LIST_ID:2
		DONE_CNT ++
	ENDIF
NEXT

;집합 코스트 산출
;F함수화하고 싶었지만 SKIPMOVE를 사용하고 있어서 포기, 유감
@CALC_SYUGOS_COST(집합, 대상)
#LOCALSIZE 1
#LOCALSSIZE 1
#DIM REF 집합,,
#DIM 대상
#DIM 이동코스트
#DIM 잠정목적지
#DIM 최종목적지
#DIM TEMP_현재위치
#DIM C_ID
C_ID = 집합:대상:0
TEMP_현재위치 = CFLAG:MASTER:현재위치
최종목적지 = CFLAG:C_ID:현재위치
잠정목적지 = 최종목적지
[IF_DEBUG]
PRINTFORML %CALLNAME:C_ID%의 이동코스트 계산
[ENDIF]
IF CAN_MOVE(TEMP_현재위치, 잠정목적지) & 1
	이동코스트 = 1
ELSE
	FOR 이동코스트, 1, 20
		WHILE !(CAN_MOVE(TEMP_현재위치, 잠정목적지) & 1)
			TRYCALLFORM SKIP_MOVE_{MAIN_MAP}(잠정목적지, TEMP_현재위치)
			SIF !잠정목적지
				THROW 잠정목적지가 이상합니다
			[IF_DEBUG]
			PRINTFORML {TEMP_현재위치}에서 {잠정목적지}로 직접 갈 수 없으니까 {RESULT}를 목표로 한다
			[ENDIF]
			잠정목적지 = RESULT
		WEND
		SIF CAN_MOVE(잠정목적지, 최종목적지) & 1
			BREAK
		TEMP_현재위치 = 잠정목적지
		잠정목적지 = 최종목적지
	NEXT
ENDIF
집합:대상:2 = 이동코스트
[IF_DEBUG]
PRINTFORML %CALLNAME:C_ID%의 이동코스트는 {이동코스트}
[ENDIF]

@AssembleForMeal
#DIM 집합, 캐릭터수상한, 3 ;집합:X:Y
#DIM 인원수                      ;同一マップにいる인원수、移動できないキャラも表示され、인원수に加算されている
#DIM 입력값                    ;RESULT取得用
#DIM C_ID
#DIM NOW_TARGET
SIF CFLAG:MASTER:현재위치 == OMANEKIBEYA()
	RETURN
SIF !AT_HOME(MASTER)
	RETURN
SIF CFLAG:MASTER:현재위치 == CFLAG:MASTER:초기위치
	RETURN
SIF PRIVATEROOM:(CFLAG:MASTER:현재위치 % 100)
	RETURN
CALL SYUGOS_GETDATA(인원수, 집합)
CALL SYUGOS_COST(인원수, 집합)
SIF TARGET
	NOW_TARGET = TARGET
FOR LOCAL, 0, 인원수
	C_ID = 집합:LOCAL:0
	SIF GETBIT(집합:LOCAL:1, 0)
		CONTINUE
	;이동 횟수가 많으면 제외
	SIF 집합:LOCAL:2 > 2
		CONTINUE
	SIF CFLAG:C_ID:빡침
		CONTINUE
	IF DISH_TYPE == "디저트"
		SIF !TIME_PROGRESS(TCVAR:C_ID:디저트공복시각)
			CONTINUE
	ELSE
		SIF !TIME_PROGRESS(TCVAR:C_ID:공복시각)
			CONTINUE
	ENDIF
	CFLAG:C_ID:현재위치 = CFLAG:MASTER:현재위치
	CFLAG:C_ID:동실 = 1
	;자유행동의 중단
	Activity_Duration:C_ID = 0
	Activity_Type:C_ID = 0
	PRINTFORML 식사 낌새를 냄새로 알아차리고 %조사처리(CALLNAME:C_ID,"가")% 찾아왔다
NEXT
CALL TARGETSET_CHACK
SIF NOW_TARGET
	TARGET = NOW_TARGET
PRINTFORMW


code:
;-----------------------------------------------------------
;LOCAL					FOR~NEXT용
;LOCAL:1~LOCAL:7		예정일(DAY:3)
;LOCAL:8				리셋용 데이터
;LOCAL:11~LOCAL:17		예정 일째(DAY)
;LOCAL:101~LOCAL:107	달을 또 있고로 있을까(0=또 있고가 아닌,1=뿌렸다로 있다)
;-----------------------------------------------------------
@캘린더
#DIM 예정종별 = 0
;[SKIPSTART]
VARSET LOCAL
FOR COUNT, 1, 9
	LOCAL:COUNT = DAY:3 + COUNT - 1
	LOCAL:(COUNT + 10) = DAY + COUNT - 1
	IF LOCAL:COUNT > 31
		LOCAL:COUNT -= 31
		LOCAL:(COUNT + 100) = 1
	ENDIF
NEXT
PRINTL ┌──┬──────────────────────────────────────
PRINT │ Day│이벤트/연회 정보/【돌쌓기 테마】／
IF 예정종별 == 0
	SETCOLOR 0 , 255, 0
	PRINT 일
	RESETCOLOR
	IF FLAG:1007
		PRINT /
		PRINTBUTTON "위험일", 901
	ENDIF
ELSE
	PRINTBUTTON "일", 900
	IF FLAG:1007
		PRINT /
		SETCOLOR 0 , 255, 0
		PRINT 위험일
		RESETCOLOR
	ENDIF
ENDIF
PRINTL
PRINTL ├──┼──────────────────────────────────────
PRINT │
SETCOLOR 0 , 255, 0
;{LOCAL:1(~9)}+100의 수치가 CHARANUM 이하라면 버그가 되므로
;미실장동안은 버튼 기능 자체 죽여 둔다
;기능 실장시에 적절한 값을 설정 다시 하는 것
;PRINTBUTTON (LOCAL:1 > 9 ?  TOSTR(LOCAL:1) # TOFULL(TOSTR(LOCAL:1))), (LOCAL:1 + 100)
PRINTFORM %(LOCAL:1 > 9 ?  TOSTR(LOCAL:1) # TOFULL(TOSTR(LOCAL:1)))%
PRINT 일
RESETCOLOR
PRINT │
;예정표내에서 1행째에 이벤트·연회 정보, 2행째에 이름 리스트 표시
;요일도 예정표내에서 표시한다
;예정표를 부르면(자) 시간이 진행되므로 세심의 주위를 기울인다
CALL 예정표(LOCAL:1, LOCAL:11, LOCAL:101, 1, 예정종별)
PRINTL
PRINTL ├──┼──────────────────────────────────────
PRINT │
;PRINTBUTTON (LOCAL:2 > 9 ?  TOSTR(LOCAL:2) # TOFULL(TOSTR(LOCAL:2))), (LOCAL:2 + 100)
PRINTFORM %(LOCAL:2 > 9 ?  TOSTR(LOCAL:2) # TOFULL(TOSTR(LOCAL:2)))%
PRINT 일│
CALL 예정표(LOCAL:2, LOCAL:12, LOCAL:102, 2, 예정종별)
PRINTL
PRINTL ├──┼──────────────────────────────────────
PRINT │
;PRINTBUTTON (LOCAL:3 > 9 ?  TOSTR(LOCAL:3) # TOFULL(TOSTR(LOCAL:3))), (LOCAL:3 + 100)
PRINTFORM %(LOCAL:3 > 9 ?  TOSTR(LOCAL:3) # TOFULL(TOSTR(LOCAL:3)))%
PRINT 일│
CALL 예정표(LOCAL:3, LOCAL:13, LOCAL:103, 3, 예정종별)
PRINTL

PRINTL ├──┼──────────────────────────────────────
PRINT │
;PRINTBUTTON (LOCAL:4 > 9 ?  TOSTR(LOCAL:4) # TOFULL(TOSTR(LOCAL:4))), (LOCAL:4 + 100)
PRINTFORM %(LOCAL:4 > 9 ?  TOSTR(LOCAL:4) # TOFULL(TOSTR(LOCAL:4)))%
PRINT 일│
CALL 예정표(LOCAL:4, LOCAL:14, LOCAL:104, 4, 예정종별)
PRINTL

PRINTL ├──┼──────────────────────────────────────
PRINT │
;PRINTBUTTON (LOCAL:5 > 9 ?  TOSTR(LOCAL:5) # TOFULL(TOSTR(LOCAL:5))), (LOCAL:5 + 100)
PRINTFORM %(LOCAL:5 > 9 ?  TOSTR(LOCAL:5) # TOFULL(TOSTR(LOCAL:5)))%
PRINT 일│
CALL 예정표(LOCAL:5, LOCAL:15, LOCAL:105, 5, 예정종별)
PRINTL

PRINTL ├──┼──────────────────────────────────────
PRINT │
;PRINTBUTTON (LOCAL:6 > 9 ?  TOSTR(LOCAL:6) # TOFULL(TOSTR(LOCAL:6))), (LOCAL:6 + 100)
PRINTFORM %(LOCAL:6 > 9 ?  TOSTR(LOCAL:6) # TOFULL(TOSTR(LOCAL:6)))%
PRINT 일│
CALL 예정표(LOCAL:6, LOCAL:16, LOCAL:106, 6, 예정종별)
PRINTL

PRINTL ├──┼──────────────────────────────────────
PRINT │
;PRINTBUTTON (LOCAL:7 > 9 ?  TOSTR(LOCAL:7) # TOFULL(TOSTR(LOCAL:7))), (LOCAL:7 + 100)
PRINTFORM %(LOCAL:7 > 9 ?  TOSTR(LOCAL:7) # TOFULL(TOSTR(LOCAL:7)))%
PRINT 일│
CALL 예정표(LOCAL:7, LOCAL:17, LOCAL:107, 7, 예정종별)
PRINTL

PRINTL └──┴──────────────────────────────────────
PRINTL [0] - 돌아온다

;시간을 되돌리기 위해서(때문에) 리셋용의 예정표를 부른다
CALL 예정표(LOCAL:8, LOCAL:18, LOCAL:108, 8)
INPUT
IF RESULT >= 1 && RESULT <= CHARANUM
	PRINTFORML %CALLNAME:RESULT%
	IF CFLAG:RESULT:자택위치
		PRINT 자택위치：
		IF CFLAG:RESULT:신사거주
			PRINTFORML %NAME_FROM_PLACE(CFLAG:RESULT:신사거주)%
		ELSE
			PRINTFORML %NAME_FROM_PLACE((CFLAG:RESULT:자택위치) / 10 + 6000)%
		ENDIF
	ENDIF
	PRINT 일정보：
	SIF CSTR:RESULT:3 == ""
		PRINT ?
	PRINTFORML %CSVCSTR(RESULT, 3, )%
	PRINT 　직장　：
	SIF CSTR:RESULT:2 == ""
		PRINT ?
;	// GET_JOBPLACE("일", ARG)로 직장의 개서 처리가 있으므로 변경
;	재변경했습니다, 1 외출 먼저 대응하고 있지 않는, 2 직장이 다수 있는 캐릭터에게 대응할 수 없는, 싶은
	PRINTFORML %CSVCSTR(RESULT, 2)%
;	PRINTFORML %NAME_FROM_PLACE(CFLAG:RESULT:직장)%
	RESTART
;기능 실장시에 조건을 설정 다시 한다
;ELSEIF RESULT >= 101 && RESULT <= 131
;	PRINTFORMW {RESULT - 100}일의 예정　※미실장
;	RESTART
ELSEIF RESULT >= 900 && RESULT <= 901
;900:일예정(예정=0)
;901:위험일 예정(예정=1)
	예정종별 = RESULT - 900
	RESTART
ENDIF
;[SKIPEND]
RETURN

;-----------------------------------------------------------
;ARG	0=날,1=총날짜,2=달을 또 있고로 있는지,3=호출 회수,4=예정종별(0:일 1:위험일)
;		현재=원래의 DAY, 오늘=원래의 DAY:2, 이번달=원래의 DAY:3, 다음달=이번달부터 본 다음달
;-----------------------------------------------------------
@예정표(ARG, ARG:1, ARG:2, ARG:3, ARG:4=0)
#DIM 현재
#DIM 오늘
#DIM 이번달
#DIM 다음달

#DIM 전일량
#DIM 전일개시
#DIM 전일종료
#DIM 전직장
#DIM 전직종
#DIM 원급료
#DIM 원답례

#DIM 표시카운트

;TIME를 만지므로 역산
IF ARG:2 && DAY:2 != 이번달
	IF DAY:2 == 1
		이번달 = 4
	ELSE
		이번달 = DAY:2 - 1
	ENDIF
ELSE
	이번달 = DAY:2
ENDIF
IF DAY:2 == 4
	다음달 = 1
ELSE
	다음달 = DAY:2 + 1
ENDIF
;TIME를 만진다
SIF ARG:2 && DAY:2 == 이번달
	DAY:2 = 다음달
DAY = ARG:1
DAY:3 = ARG
;역산
현재 = DAY - ARG:3 + 1
IF 이번달 != DAY:2
	오늘 = DAY:3 - ARG:3 + 32
ELSE
	오늘 = DAY:3 - ARG:3 + 1
ENDIF
;마지막 호출로 리셋
IF ARG:3 == 8
	DAY = 현재
	DAY:2 = 이번달
	DAY:3 = 오늘
	RETURN
ENDIF

;확인용(다음달은 1일 라그가 있지만 문제 없다)
;PRINTFORM 오늘{오늘}　이번달{이번달}　다음달{다음달} 현재{현재} DAY:3-{DAY:3} DAY:2-{DAY:2} DAY - {DAY}
;여기에서는 일시적으로 시간이 진행된 상태로 산출하는(GET_DAY()나 연회 예정도 진행된 상태)

;예정표 1행째
IF FESTIVAL() != ""
	SETCOLOR C_RED
	PRINTFORM %FESTIVAL()%
	RESETCOLOR
ENDIF

;연회도 일자가 바뀐 상태로 체크
;연회 정보의 표시를 1행째로 변경
CALL 연회예정판정

SETCOLOR C_YELLOW
IF FLAG:개시일 - DAY == 0 && FLAG:연회개최플래그
	IF STONE_PLAYCOUNT:2 == 16 && (STONE_UKETSUKEDAY + 14 - DAY:0) > 0 && (STONE_UKETSUKEDAY + 14 - DAY:0) < 15
		PRINTFORM   【{STONE_UKETSUKEDAY + 14 - DAY:0}일 후까지 중지 중】
	ELSE
		PRINTFORM   【%STONECombiDAY(DAY:3)%】
	ENDIF
ELSE
	IF STONE_PLAYCOUNT:2 == 16 && (STONE_UKETSUKEDAY + 14 - DAY:0) > 0 && (STONE_UKETSUKEDAY + 14 - DAY:0) < 15
		PRINTFORM 【{STONE_UKETSUKEDAY + 14 - DAY:0}일 후까지 중지 중】
	ELSE
		PRINTFORM 【%STONECombiDAY(DAY:3)%】
	ENDIF
ENDIF
RESETCOLOR

;예정표 2행째 이후
;요일도 바뀌어 있는(첫날은 그대로)
PRINTL
PRINTFORM │(%GET_DAY()%)│
표시카운트 = 0
FOR LOCAL, 1, CHARANUM
	IF !ARG:4
		전일량 = MAXBASE:LOCAL:일량
		전일개시 = TCVAR:LOCAL:일개시
		전일종료 = TCVAR:LOCAL:일종료
		전직장 = CFLAG:LOCAL:직장
		전직종 = CFLAG:LOCAL:직종
		원급료 = TCVAR:LOCAL:급료
		원답례 = TCVAR:LOCAL:답례

	;더부살이캐릭터에서도 일하러 나가므로 우선 코멘트 아웃
	;	SIF CFLAG:LOCAL:신사거주
	;		CONTINUE
	;	;일이 랜덤의 경우는 있는 것 전제
		;…(으)로 하면(자) 오늘의 일에 영향이 나오므로 예정도 랜덤(다음에 일하는지 아닌지)에
	;	SIF DAY:3 != 오늘
	;		TCVAR:LOCAL:일의유무 = 2
		CALL 일내용설정(LOCAL, 1)
		IF !CHARA_HOLIDAY(LOCAL, 1) && CFLAG:LOCAL:신뢰도 >= 10
			표시카운트++
			IF 표시카운트 > 9
				PRINTL
				PRINT │　　│
				표시카운트 = 0
			ENDIF
	;		너무 편리할 생각이 들므로 자중
	;		SIF CFLAG:LOCAL:행동 == 5
	;			SETCOLOR 255, 100, 0
			PRINTBUTTON CALLNAME:LOCAL, LOCAL
			RESETCOLOR
			PRINT
		ENDIF

		MAXBASE:LOCAL:일량 = 전일량
		TCVAR:LOCAL:일개시 = 전일개시
		TCVAR:LOCAL:일종료 = 전일종료
		CFLAG:LOCAL:직장 = 전직장
		CFLAG:LOCAL:직종 = 전직종
		TCVAR:LOCAL:급료 = 원급료
		TCVAR:LOCAL:답례 = 원답례
	ELSE
		IF ESTRUS_CATEGORY(LOCAL, ARG:3-1) == "위험일" && FLAG:1007
			표시카운트++
			IF 표시카운트 > 9
				PRINTL
				PRINT │　　│
				표시카운트 = 0
			ENDIF
	;		착상제라면 이름을 핑크로 한다
			SIF CFLAG:LOCAL:임신경과일수
				SETCOLOR C_PINK
			PRINTBUTTON CALLNAME:LOCAL, LOCAL
			SETCOLOR C_PINK
			CALL HEART
			RESETCOLOR
			PRINT
		ENDIF
	ENDIF
NEXT

@연회예정판정
IF FLAG:개시일 - DAY == 0 && FLAG:연회개최플래그
	SETCOLOR C_GREEN
	CALL 연회예정표시
	RESETCOLOR
ENDIF


code:
Copyright (C) 2008- Emuera, 妊）|дﾟ)の中の人

本ソフトウェアは「現状のまま」で、明示であるか暗黙であるかを問わず、何らの保証もなく提供されます。 本ソフトウェアの使用によって生じるいかなる損害についても、作者は一切の責任を負わないものとします。

以下の制限に従う限り、商用アプリケーションを含めて、本ソフトウェアを任意の目的に使用し、自由に改変して再頒布することをすべての人に許可します。

1.本ソフトウェアの出自について虚偽の表示をしてはなりません。あなたがオリジナルのソフトウェアを作成したと主張してはなりません。 あなたが本ソフトウェアを製品内で使用する場合、製品の文書に謝辞を入れていただければ幸いですが、必須ではありません。
2.ソースを変更した場合は、そのことを明示しなければなりません。オリジナルのソフトウェアであるという虚偽の表示をしてはなりません。
3.ソースの頒布物から、この表示を削除したり、表示の内容を変更したりしてはなりません。

## Korean ##
본 소프트웨어는 "있는 그대로"로 명시인지 암시인지를 불문하고 어떠한 보증도없이 제공됩니다. 본 소프트웨어의 사용으로 인해 발생한 손해에 대해서도 저자는 일체의 책임을지지 않습니다합니다.

다음 제한 사항을 준수하는 한 상용 응용 프로그램을 포함하여 소프트웨어를 어떤 용도로 사용하고 자유롭게 수정하고 재배포하는 것을 모든 사람에게 허용합니다.

1. 소프트웨어의 출신에 대해 허위의 표시를 할 수 없습니다. 당신이 원래의 소프트웨어를 작성했다고 주장해서는 안됩니다. 당신이 소프트웨어를 제품에 사용하는 경우 제품 문서에 감사를 넣어 주시면 다행입니다 만, 필수는 아닙니다.
2. 소스를 변경 한 경우에는 그 사실을 명시하여야합니다. 원래의 소프트웨어라는 허위의 표시를 할 수 없습니다.
3. 소스 배포 물에서이 표시를 제거하거나 표시 내용을 변경하거나 해가되지 않습니다.

## English ##
THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTIES, EXPRESS OR IMPLIED. The author shall not be liable for any damage resulting from the use of this software.

All people are permitted to use this software for any purpose, including commercial applications, freely modify and redistribute it, subject to the following restrictions.

1. You may not misrepresent the origin of this software. Do not claim that you created the original software. If you use the software in a product, we would appreciate it if you acknowledge the product documentation, but it is not required.
2. If you change the source, you must state that. You must not falsely claim that it is the original software.
3. You may not remove this display or change the content of the display from the source distribution.

Translate by Google Translator

## XEraEmulator Changes ##
Please reference git repository's (https://gitgud.io/subroutineuser/ezEmuera) commits.


code:
@echo off
cd /d %~dp0
start EMUERA1824+V11+WEBP+TEST+FIX.EXE -debug


code:
@echo off
cd /d %~dp0
start XEraEmulator.exe -debug


code:
大文字小文字の違いを無視する:YES
_Rename.csvを利用する:YES
_Replace.csvを利用する:YES
マウスを使用する:YES
メニューを使用する:YES
デバッグコマンドを使用する:NO
多重起動を許可する:YES
オートセーブを行なう:YES
キーボードマクロを使用する:YES
ウィンドウの高さを可変にする:YES
描画インターフェース:TEXTRENDERER
イメージバッファを使用する:YES
ウィンドウ幅:1200
ウィンドウ高さ:800
ウィンドウ位置X:0
ウィンドウ位置Y:0
起動時のウィンドウ位置を指定する:NO
起動時にウィンドウを最大化する:NO
履歴ログの行数:5000
PRINTCを並べる数:5
PRINTCの文字数:25
フォント名:굴림체
フォントサイズ:16
一行の高さ:16
文字色:192,192,192
背景色:0,0,0
選択中文字色:255,255,0
履歴文字色:192,192,192
フレーム毎秒:5
最大スキップフレーム数:3
スクロール行数:1
無限ループ警告までのミリ秒数:5000
表示する最低警告レベル:1
ロード時にレポートを表示する:NO
ロード時に引数を解析する:YES
呼び出されなかった関数を無視する:YES
関数が見つからない警告の扱い:IGNORE
関数が呼び出されなかった警告の扱い:IGNORE
ボタンの途中で行を折りかえさない:YES
サブディレクトリを検索する:YES
読み込み順をファイル名順にソートする:YES
表示するセーブデータ数:20
eramaker互換性に関する警告を表示する:NO
システム関数の上書きを許可する:YES
システム関数が上書きされたとき警告を表示する:YES
関連づけるテキストエディタ:notepad
テキストエディタコマンドライン指定:USER_SETTING
エディタに渡す行指定引数:
同名の非イベント関数が複数定義されたとき警告する:YES
解釈不可能な行があっても実行する:NO
CALLNAMEが空文字列の時にNAMEを代入する:NO
セーブデータをsavフォルダ内に作成する:YES
擬似変数RANDの仕様をeramakerに合わせる:NO
関数・属性については大文字小文字を無視しない:NO
全角スペースをホワイトスペースに含める:NO
セーブデータをUTF-8で保存する:YES
ver1739以前の非ボタン折り返しを再現する:NO
内部で使用する東アジア言語:KOREAN
ONEINPUT系命令でマウスによる2文字以上の入力を許可する:NO
イベント関数のCALLを許可する:NO
SPキャラを使用する:NO
セーブデータをバイナリ形式で保存する:YES
ユーザー関数の全ての引数の省略を許可する:NO
ユーザー関数の引数に自動的にTOSTRを補完する:YES
FORM中の三連記号を展開しない:YES
TIMESの計算をeramakerにあわせる:NO
キャラクタ変数の引数を補完しない:NO
文字列変数の代入に文字列式を強制する:NO
MachineTranslate:NO
MachineTranslatorPath:


code:
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg

# PyInstaller
#  Usually these files are written by a python script from a template
#  before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*,cover
.hypothesis/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
target/

# IPython Notebook
.ipynb_checkpoints

# pyenv
.python-version

# celery beat schedule file
celerybeat-schedule

# dotenv
.env

# virtualenv
venv/
ENV/

# Spyder project settings
.spyderproject

# Rope project settings
.ropeproject

# Start.tw
src/config/start.tw

path: .gitignore


code:
further development:
-specialized slave schools
-fortifications
-more levels for militia edict (further militarize society)
-conquering other arcologies?

Events:
-famous criminal escapes to the arcology, followed by another arcology police force

Bugs:
-sometimes troop counts breaks
-sometimes rebel numbers have fractionary parts


code:
# How to vector art

Please read the whole document before starting to work.
Some aspects are not obvious right away.

Note: This does not actually describe how to be an artist.

## TL;DR

    killall inkscape
    artTools/vector_layer_split.py artTools/vector_source.svg tw src/art/vector/layers/
    compile

## 1. Be an artist

Make changes to the vector_source.svg.
Inkscape was thoroughly tested.
Adobe Illustrator might work decently, too.

## 2. Respect the structure

While editing, keep the Layers in mind.

* In Inkscape, Layers are special "Inkscape groups".
* In Illustrator, Layers are groups with user-definded IDs.
* All Layers should have an ID that is globally unique
  (not just within their subtree).

* Please use anonymous groups only for the ease of editing. Remove all "helper" groups before finally saving the file.
* Anonymous groups can be used for continous scaling (of e.g. boobs).

* Every asset that should go into a separate file needs to be in a labelled group
  (even if that is a group with only one shape).
* There are some globally available styles defined as CSS classes (e.g. skin, hair).
  Use them if your asset should be changed upon display.
  Do not set the style directly in the object.

## 3. Fix the document (before commiting, Inkscape only)

Inkscape shows weird behaviour in some regards.
If you use Inkscape, close the document and run

    python3 inkscape_svg_fixup.py vector_source.svg

before continuing. Open the file in Inkscape and save it again.
You need to make a minor change, as Inkscape will not save a unchanged file
(move the notes back and forth or something). The fixup does not produce
the same linebreaks as Inkscape or Illustrator and git will go mad because
the whole seems to have changed.

What it does:
* Adobe Illustrator uses group IDs as layer labels.
  Inkscape however uses layer labels and a separate, auto-generated group ID.
  inkscape_svg_fixup.py overwrites the group ID with the Inkscape layer label
  so they are synchronised with Inkscape layer labels.
* Inkscape copies the global style definition into the object *every time*
  the object is edited. If an object references a CSS class AND at the same time
  has a local style, the local style is removed
  so global dynamic styling is possible later on.

Note: Behaviour of Adobe Illustrator is untested.

## 4. Split the layers

Execute

    python3 vector_layer_split.py vector_source.svg tw ../src/art/vector/layers/

. This application reads all groups in `vector_source.svg`.
Each group is stored in a separate file in the target directory `/src/art/vector/layers/`.
The group ID sets the file name. Therefore, the group ID **must not** contain spaces or any other weird characters.

Also consider:
* A group with ID ending in _ is ignored. Use Layers ending in _ to keep overview.
* A group with ID starting with "g" (Inkscape) or "XMLID" (Illustrator) is also ignored.
* Existing files are overwritten **without enquiry**.
* The target directory is not emptied. If a file is no longer needed, you should remove it manually.
* This procedure removes global definitions. This means, SVG filters are currently not supported.

Available output formats are `svg` and `tw`.
`svg` output exists for debug reasons.
`tw` embeds the SVG data into Twine files, but removes the global style definitions so they can be set during display.

## 5. Edit the code

`/src/art/` contains Twine code which shows the assets in the story.
There are many helpful comments in `/src/art/artWidgets.tw`.
The code also generates the previously removed global style definitions on the fly and per display.

## 6. Compile the story

Use the provided compile script (Windows batch or shell) for compiling.

## 7. Advanced usage

You can define multiple CSS classes to one element, e.g. "skin torso". When procedurally generating CSS, you can then set a global "skin" style, and a different one for "torso".

You can put variable text into the image using single quotes, e.g. "'+_tattooText+'". The single quotes *break* the quoting in Twine so the content of the Twine variable `_tattooText` is shown upon display. You can even align text on paths.

An anonymous group can be used for dynamic transformation. However, finding the correct parameters for the affine transformation matrix can be cumbersome. Use any method you see fit. See `src/art/vector/Boob.tw` for one example of the result.


code:
#!/usr/bin/env python3

'''
Application for "fixing" SVGs edited with Inkscape

These problems are addressed:

* Inkscape notoriously copies class styles into the object definitions.
https://bugs.launchpad.net/inkscape/+bug/167937

* Inkscape uses labels on layers. Layers are basically named groups.
  Inkscape does not sync the group id with the layer label.

Usage Example:
python3 inkscape_svg_fixup.py vector_source.svg

Note:
The output of lxml differs greatly from standard SVG indentation.
Please open and save the file in Inkscape before committing.
'''

import lxml.etree as etree
import sys

def fix(tree):
  # know namespaces
  ns = {
    'svg' : 'http://www.w3.org/2000/svg',
    'inkscape' : 'http://www.inkscape.org/namespaces/inkscape'
  }

  # find document global style definition
  # mangle it and interpret as python dictionary
  style_element = tree.find('./svg:style',namespaces=ns)
  style_definitions = style_element.text
  pythonic_style_definitions = '{'+style_definitions.\
  replace('\t.','"').replace('{','":"').replace('}','",').\
  replace('/*','#')+'}'
  styles = eval(pythonic_style_definitions)

  # go through all SVG elements
  for elem in tree.iter():
    if (elem.tag == etree.QName(ns['svg'], 'g')):
      # compare inkscape label with group element ID
      l = elem.get(etree.QName(ns['inkscape'], 'label'))
      if l:
        i = elem.get('id')
        if (i != l):
          print("Overwriting ID %s with Label %s..."%(i, l))
          elem.set('id', l)

    # remove all offending style attributes
    s = elem.get('style')
    c = elem.get('class')
    if (c and s):
      s = s.lower()
      c = c.split(' ')[0] # regard main style only
      cs = ''
      if c in styles:
        cs = styles[c].strip('; ').lower()
      if (c not in styles):
        print("Object id %s references unknown style class %s."%(i,c))
      else:
        if (cs != s.strip('; ')):
          print("Style %s removed from object id %s differed from class %s style %s."%(s,i,c,cs))
        del elem.attrib["style"]

if __name__ == "__main__":
  input_file = sys.argv[1]
  tree = etree.parse(input_file)
  fix(tree)
  # store SVG into file (input file is overwritten)
  svg = etree.tostring(tree, pretty_print=True)
  with open(input_file, 'wb') as f:
    f.write('<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n'.encode("utf-8"))
    f.write(svg)


code:
#!/usr/bin/env python3

'''
Application for procedural content adaption
*THIS IS VERY EXPERIMENTAL*
Contains a very poor man's implementation of spline mesh warping.

This application parses SVG path data of an outfit sample aligned to a body part.
The outfit is then replicated for other shapes of the same body part.

Example data is geared towards generating a strap outfit for boobs and torso
for all sizes of boobs and all shapes of torsos based on a single outfit for
boobs of size 2 and a hourglass torso respectively.

Limitations:
* handles paths only
* only svg.path Line and CubicBezier are tested
* only the aforementioned examples are tested

Usage:
python3 vector_clothing_replicator.py infile clothing bodypart destinationfile

Usage Example:
python3 vector_clothing_replicator.py vector_source.svg Straps Boob vector_destination.svg
python3 vector_clothing_replicator.py vector_source.svg Straps Torso vector_destination.svg
'''

from svg.path import parse_path
import copy
import lxml.etree as etree
import sys

REFERENCE_PATH_SAMPLES = 200
EMBED_REPLICATIONS = True # wether to embed all replications into the input file or output separate files

input_file = sys.argv[1]
clothing = sys.argv[2]
bodypart = sys.argv[3]
output_file_embed = sys.argv[4]

# TODO: make these configurable
output_file_pattern = '%s_%s_%s.svg' #bodypart, target_id, clothing

if ('Torso' == bodypart):
  xpath_shape = './svg:g[@id="Torso_"]/svg:g[@id="Torso_%s"]/svg:path[@class="skin torso"]/@d' # TODO: formulate more general, independent of style
  xpath_outfit_container = '//svg:g[@id="Torso_Outfit_%s_"]'%(clothing)
  xpath_outfit = '//svg:g[@id="Torso_Outfit_%s_%s"]'%(clothing,'%s')
  target_ids = "Unnatural,Hourglass,Normal".split(",")
  reference_id = "Hourglass"
else:
  raise RuntimeError("Please specify a bodypart for clothing to replicate.")

tree = etree.parse(input_file)
ns = {'svg' : 'http://www.w3.org/2000/svg'}

canvas = copy.deepcopy(tree)
for e in canvas.xpath('./svg:g',namespaces=ns)+canvas.xpath('./svg:path',namespaces=ns):
  # TODO: this should be "remove all objects, preserve document properties"
  e.getparent().remove(e)

def get_points(xpath_shape):
  '''
  This funciton extracts reference paths by the given xpath selector.
  Each path is used to sample a fixed number of points.
  '''
  paths_data = tree.xpath(xpath_shape,namespaces=ns)
  points = []
  path_length = None
  for path_data in paths_data:
    p = parse_path(path_data)
    points += [
      p.point(1.0/float(REFERENCE_PATH_SAMPLES)*i)
      for i in range(REFERENCE_PATH_SAMPLES)
    ]
  if (not points):
    raise RuntimeError(
      'No paths for reference points found by selector "%s".'%(xpath_shape)
    )
  return points

def point_movement(point, reference_points, target_points):
  '''
  For a given point, finds the nearest point in the reference path.
  Gives distance vector from the nearest reference point to the
  respective target reference point.
  '''
  distances = [abs(point-reference_point) for reference_point in reference_points]
  min_ref_dist_idx = min(enumerate(distances), key=lambda x:x[1])[0]
  movement = target_points[min_ref_dist_idx] - reference_points[min_ref_dist_idx]
  return movement

reference_points = get_points(xpath_shape%(reference_id))
container = tree.xpath(xpath_outfit_container,namespaces=ns)
if (len(container) != 1):
  raise RuntimeError('Outfit container selector "%s" does not yield exactly one layer.'%(xpath_outfit_container))
container = container[0]
outfit_source = container.xpath(xpath_outfit%(reference_id),namespaces=ns)
if (len(outfit_source) != 1):
  raise RuntimeError('Outfit source selector "%s" does not yield exactly one outfit layer in container selected by "%s".'%(xpath_outfit%(reference_id), xpath_outfit_container))
outfit_source = outfit_source[0]

for target_id in target_ids:
  print(
    'Generating variant "%s" of clothing "%s" for bodypart "%s"...'%
    (target_id, clothing, bodypart)
  )
  outfit = copy.deepcopy(outfit_source)
  paths = outfit.xpath('./svg:path',namespaces=ns)
  if target_id == reference_id:
    print("This is the source variant. Skipping...")
  else:
    layerid = outfit.get('id').replace('_%s'%(reference_id),'_%s'%(target_id))
    outfit.set('id', layerid)
    outfit.set(etree.QName('http://www.inkscape.org/namespaces/inkscape', 'label'), layerid) # for the Inkscape-users
    target_points = get_points(xpath_shape%(target_id))
    if (len(reference_points) != len(target_points)):
      raise RuntimeError(
        ('Different amounts of sampled points in reference "%s" and target "%s" paths. '+
        'Selector "%s" probably matches different number of paths in the two layers.')%
        (reference_id, target_id, xpath_shape)
      )
    for path in paths:
      path_data = path.get("d")
      p = parse_path(path_data)
      for segment in p:
        original_distance = abs(segment.end-segment.start)
        start_movement = point_movement(segment.start, reference_points, target_points)
        segment.start += start_movement
        end_movement = point_movement(segment.end, reference_points, target_points)
        segment.end += end_movement
        distance = abs(segment.end-segment.start)
        try:
          # enhance position of CubicBezier control points
          # amplification is relative to the distance gained by movement
          segment.control1 += start_movement
          segment.control1 += (segment.control1-segment.start)*(distance/original_distance-1.0)
          segment.control2 += end_movement
          segment.control2 += (segment.control2-segment.end)*(distance/original_distance-1.0)
        except AttributeError as ae:
          # segment is not a CubicBezier
          pass
      path.set("d", p.d())
    if EMBED_REPLICATIONS:
      container.append(outfit)
  if not EMBED_REPLICATIONS:
    container = copy.deepcopy(canvas).xpath('.',namespaces=ns)[0]
    container.append(outfit)

  if not EMBED_REPLICATIONS:
    svg = etree.tostring(container, pretty_print=True)
    with open((output_file_pattern%(bodypart, target_id, clothing)).lower(), 'wb') as f:
      f.write('<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n'.encode("utf-8"))
      f.write(svg)

if EMBED_REPLICATIONS:
  svg = etree.tostring(tree, pretty_print=True)
  with open(output_file_embed, 'wb') as f:
    f.write('<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n'.encode("utf-8"))
    f.write(svg)


code:
#!/usr/bin/env python3

'''
Application for splitting groups from one SVG file into separate files

Usage:
python3 vector_layer_split.py infile format outdir

Usage Example:
python3 vector_layer_split.py vector_source.svg tw ../src/art/vector/layers/
'''

import lxml.etree as etree
import sys
import os
import copy
import re
import inkscape_svg_fixup

input_file = sys.argv[1]
output_format = sys.argv[2]
output_directory = sys.argv[3]
if not os.path.exists(output_directory):
    os.makedirs(output_directory)

ns = {
  'svg' : 'http://www.w3.org/2000/svg',
  'inkscape' : 'http://www.inkscape.org/namespaces/inkscape',
  'sodipodi':"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd",
}

tree = etree.parse(input_file)
inkscape_svg_fixup.fix(tree)

# prepare output template
template = copy.deepcopy(tree)
root = template.getroot()

# remove all svg root attributes except document size
for a in root.attrib:
  if (a != "viewBox"):
    del root.attrib[a]

# add placeholder for CSS class (needed for workaround for non HTML 5.1 compliant browser)
if output_format == 'tw':
  root.attrib["class"] = "'+_art_display_class+'"

# remove all content, including metadata
# for twine output, style definitions are removed, too
defs = None
for e in root:
  if (e.tag == etree.QName(ns['svg'], 'defs')):
    defs = e
  if (e.tag == etree.QName(ns['svg'], 'g') or
      e.tag == etree.QName(ns['svg'], 'metadata') or
      e.tag == etree.QName(ns['svg'], 'defs') or
      e.tag == etree.QName(ns['sodipodi'], 'namedview') or
      (output_format == 'tw' and e.tag == etree.QName(ns['svg'], 'style'))
      ):
    root.remove(e)
# template preparation finished

# prepare regex for later use
regex_xmlns = re.compile(' xmlns[^ ]+',)
regex_space = re.compile('[>][ ]+[<]',)

# find all groups
layers = tree.xpath('//svg:g',namespaces=ns)
for layer in layers:
  i = layer.get('id')
  if ( # disregard non-content groups
    i.endswith("_") or # manually suppressed with underscore
    i.startswith("XMLID") or # Illustrator generated group
    i.startswith("g") # Inkscape generated group
  ):
    continue
  # create new canvas
  output = copy.deepcopy(template)
  # copy all shapes into template
  canvas = output.getroot()
  for e in layer:
    canvas.append(e)
  # represent template as SVG (binary string)
  svg = etree.tostring(output, pretty_print=False)
  # poor man's conditional defs insertion
  # TODO: extract only referenced defs (filters, gradients, ...)
  # TODO: detect necessity by traversing the elements. do not stupidly search in the string representation
  if ("filter:" in svg.decode('utf-8')):
    # it seems there is a filter referenced in the generated SVG, re-insert defs from main document
    canvas.insert(0,defs)
    # re-generate output
    svg = etree.tostring(output, pretty_print=False)

  if (output_format == 'tw'):
    # remove unnecessary attributes
    # TODO: never generate unnecessary attributes in the first place
    svg = svg.decode('utf-8')
    svg = regex_xmlns.sub('',svg)
    svg = svg.replace(' inkscape:connector-curvature="0"','') # this just saves space
    svg = svg.replace('\n','').replace('\r','') # print cannot be multi-line
    svg = regex_space.sub('><',svg) # remove indentaion
    svg = svg.replace('svg:','') # svg namespace was removed
    svg = svg.replace('<g ','<g transform="\'+_art_transform+\'"') # internal groups are used for scaling
    svg = svg.encode('utf-8')

  # save SVG string to file
  i = layer.get('id')
  output_path = os.path.join(output_directory,i+'.'+output_format)
  with open(output_path, 'wb') as f:
    if (output_format == 'svg'):
      # Header for normal SVG (XML)
      f.write('<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n'.encode("utf-8"))
      f.write(svg)
    elif (output_format == 'tw'):
      # Header for SVG in Twine file (SugarCube print statement)
      f.write((':: Art_Vector_%s [nobr]\n\n'%(i)).encode("utf-8"))
      f.write("<<print '<html>".encode("utf-8"))
      f.write(svg)
      f.write("</html>' >>".encode("utf-8"))


code:
# Ignore everything in this directory
*
# Except the following:
!.gitignore
!resources/vector/*


code:
#!/bin/bash

# Find and insert current commit
COMMIT=$(git rev-list HEAD --count)
sed -i "s/COMMIT/$COMMIT/" ./src/init/storyInit.tw

# Run sanity check.
./sanityCheck

HASH=`git log -n1 |grep commit | sed 's/commit //'`

if [ $(uname -m) = "x86_64" ]
then
	echo "x64 arch"
	./devTools/tweeGo/tweego_nix64 -o bin/FC_pregmod.html src/
else
	echo "x86 arch"
	./devTools/tweeGo/tweego_nix86 -o bin/FC_pregmod.html src/
fi

#Make the output prettier, replacing \t with a tab and \n with a newline
sed -i -e '/^.*<div id="store-area".*$/s/\\t/\t/g' -e '/^.*<div id="store-area".*$/s/\\n/\n/g'  bin/FC_pregmod.html

# Revert ./src/init/storyInit.tw for next compilation
git checkout -- ./src/init/storyInit.tw

path: compile


code:
#!/bin/bash

# Run sanity check.
./sanityCheck

HASH=`git log -n1 |grep -m1 commit | sed 's/commit //'`

if [ $(uname -m) = "x86_64" ]
then
	echo "x64 arch"
	./devTools/tweeGo/tweego_nix64 -o bin/FC_pregmod_$HASH.html src/
else
	echo "x86 arch"
	./devTools/tweeGo/tweego_nix86 -o bin/FC_pregmod_$HASH.html src/
fi

#Make the output prettier, replacing \t with a tab and \n with a newline
sed -i -e '/^<div id="store-area".*$/s/\\t/\t/g' -e '/^<div id="store-area".*$/s/\\n/\n/g'  bin/FC_pregmod_$HASH.html

echo "FC_pregmod_$HASH.html" compilation finished.

path: compile-git


code:
@echo off
:: Free Cities Basic Compiler - Windows

:: Set working directory
pushd %~dp0

:: Run the appropriate compiler for the user's CPU architecture.
if %PROCESSOR_ARCHITECTURE% == AMD64 (
    CALL "%~dp0devTools\tweeGo\tweego_win64.exe" -o "%~dp0bin/FC_pregmod.html" "%~dp0src"
) else (
    CALL "%~dp0devTools\tweeGo\tweego_win86.exe" -o "%~dp0bin/FC_pregmod.html" "%~dp0src"
)

popd
ECHO Done


code:
@echo off
:: Free Cities Basic Compiler - Windows

:: Set working directory
pushd %~dp0

:: See if we can find a git installation
setlocal enabledelayedexpansion

for %%k in (HKCU HKLM) do (
    for %%w in (\ \Wow6432Node\) do (
        for /f "skip=2 delims=: tokens=1*" %%a in ('reg query "%%k\SOFTWARE%%wMicrosoft\Windows\CurrentVersion\Uninstall\Git_is1" /v InstallLocation 2^> nul') do (
            for /f "tokens=3" %%z in ("%%a") do (
                set GIT=%%z:%%b
				set GITFOUND=yes
                goto FOUND
            )
        )
    )
)
:FOUND
if %GITFOUND% == yes (
	set "PATH=%GIT%bin;%PATH%"
	bash --login -c ./sanityCheck
)

:: Compile the game
call "%~dp0compile.bat"

if %GITFOUND% == yes (
	:: Make the output prettier, replacing \t with a tab and \n with a newline
	bash -c "sed -i -e '/^.*<div id=\"store-area\".*$/s/\\\t/\t/g' -e '/^.*<div id=\"store-area\".*$/s/\\\n/\n/g' bin/FC_pregmod.html"

	:: Revert ./src/init/storyInit.tw for next compilation
	git checkout -- ./src/init/storyInit.tw
)

popd
PAUSE


code:
@echo off
:: Free Cities Basic Compiler - Windows

:: Set working directory
pushd %~dp0

:: Compile the game
call "%~dp0compile.bat"

popd
PAUSE


code:
Anatomy of a FreeCities event

Type
There are several types of events. They all happen during the end-of-week calculation, AFTER the normal changes to the slaves and all the economic effects (including you messing with your corporation) happened.

Scheduled events
Nonrandom events
Random nonindividual events
Random individual events

The differences between them are almost non-existent. If they happen, they happen in this order, so you could say it's a kind of event priority ordering. The last two events pre-select a slave (in $eventSlave), with the "nonindividual" events using all your slaves while the "individual" events use only non-fuckdolls, typically from your penthouse. When writing your event, you're free to ignore this and choose your own slave or create a new one. By convention, scheduled events tend to go back to the "Scheduled Event" passage so that other such events can run; all the others tend to just skip to the next event category. Nothing in code forces you to do it this way for your events.

Preconditions
Most events have some kind of precondition for when they happen. Scheduled events always happen when their preconditions are true. Nonrandom events happen when their preconditions are true and no other nonrandom events get picked first (so writing a too-often-true precondition is a good way to break the game by blocking any further such events). The two other types of events get put in a pool ($events) if they match the precondition, then at most one event gets pulled from the pool per type.

	NonRandomEvent (26-33)
	<<elseif (_effectiveWeek == 14) && $badC != 1>>
	<<set _valid = $slaves.find(function(s) { return s.curatives > 1 || s.inflationType == "curative"; })>>
	<<if def _valid>>
		<<set $badC = 1, $Event = "bad curatives">>
		<<goto "Generic Plot Events">>
	<<else>>
		<<set $badC = 1>>
		<<goto "Nonrandom Event">>
	<</if>>

If it is week fourteen and the player player hasn't ready seen the event, a check is then made for slaves that either are on curatives or have their implants filled by curatives. If it was sucessful then load the "bad curatives" generic event, if unsucessful set the flag anyway and read from the Nonrandom Event passage.

Immediate effects

Every event can have immediate effects, which happen when the event gets chosen. For most events, those are what should happen if the player ignores the event (by hitting "Continue" or the space bar on the keyboard). Choice effects (see below) can override or roll back those.

		reRecuit (4-19)
		<<if Array.isArray($recruit)>>
	  <<if $cheatMode == 1>>
		<<set $nextButton = "Back", $nextLink = "Nonrandom Event", $returnTo = "Nonrandom Event">> /* if user just clicks spacebar */
		''A random recruit event would have been selected from the following:''

		<<for _i = 0; _i < $recruit.length; _i++>>
			<<print "[[$recruit[_i]|RE recruit][$recruit = $recruit[" + _i + "]]]">>

		<</for>>

[[Go Back to Random Nonindividual Event|Random Nonindividual Event][$eventSlave = 0]]
	  <<else>>
		<<set $recruit = $recruit.random()>>
		<<goto "RE recruit">>
	  <</if>>
	<<else>>

	If cheat mode is enabled and the user presses the space bar go back to the start.

Main event text
The bulk of the writing will be in the main event text. There are quite a few rules to deal with here.
The PC is referred to in the second person singular ("you"), everyone else in third person.
The PC has no direct speech. All the things "you" say are described, not quoted.
A slave can be linked with the macro <<EventNameLink _Slave>>. This allows the player to click on the slave name and view their description, then go back to the event. WARNING: Going back triggers the event passage again, so if your event has immediate effects (see above), make sure to NOT repeat them by setting corresponding flags (this is harder than it sounds in general).

<<SlaveTitle _Slave>> sets $desc (which ends up being a string like "slavegirl", "MILF", "futanari" and so on, depending on slave).

<<SlavePronouns _Slave>> allows you to use the variables $pronoun ("she"/"he"/"it"), $pronounCap ("She"/"He"/"It"), $possessive ("her"/"his"/"its"), $possessiveCap ("Her"/"His"/"Its") and $object ("her"/"him"/"it"). There is NO variable for self-possession ("hers"/"his"/"its") and for "herself", you need to use <<= $object>>self.
One more macro initialises several others and is required when you have a slave speak and want to use direct quotes: <<Enunciate _Slave>> allows you to use <<Master>>, <<WrittenMaster>>, <<says>> (which turns into "lisps" when that's the case) and the lisping replacers <<s>>, <<ss>>, <<S>>, <<c>> and <<z>>.

The text should be about large enough to fit on the screen assuming typical monitor sizes. In terms of visible text, about 1000 words are a fine limit to aim for. There's a lot to keep in mind in terms of different appearances and circumstances, so keep your document with slave variables as a reference nearby.

It's fine - and a part of the normal workflow - to first write an event without any variation, then go through it and vary the text here and there.

Choices
You should keep the amount of choices small, but not too small. About three to five is generally a good number. Choices which can't be taken due to the current situation should be displayed as such ("You lack the funds ...") if they are an obvious choice, hidden when they aren't (for example, in event chains you might want to hide choices if the player didn't do something specific or didn't acquire some specific bit of knowledge). Every choice should be a simple sentence of the form "Do something." followed by a short explanation of the obvious effects.

Choices should also be hidden when they run against the game rules, like for example the setting if the player wants to see "extreme" content.

	diary (313-325)
	<<if $dairyFeedersUpgrade == 1>>
	The milking machines can hold feeders in slaves' mouths and inject drugs into their bodies, ensuring ideal nutrition and production.

    The feeders are
	<<if $dairyFeedersSetting == 2>>
		''industrial.'' [[Moderate|Dairy][$dairyFeedersSetting = 1, $dairyFeedersSettingChanged = -1]]
	<<elseif $dairyFeedersSetting == 1>>
		''active.'' [[Inactive|Dairy][$dairyFeedersSetting = 0]]<<if ($seeExtreme != 0) && ($dairyRestraintsSetting == 2)>> | [[Industrial|Dairy][$dairyFeedersSetting = 2, $dairyFeedersSettingChanged = 1]]<</if>>
	<<else>>
		''inactive.'' [[Active|Dairy][$dairyFeedersSetting = 1]]
	<</if>>
	<<else>>
	$dairyNameCaps is equipped to feed and clean slaves normally. [[Upgrade the milking machines with intubators|Dairy][$cash -= _Tmult1, $dairyFeedersUpgrade = 1]] //Costs ¤_Tmult1 and will increase upkeep costs//
	<</if>>

	In order to enable the industrial feeder option both any of the see extreme content options has be enabled and the restraint's have to be already set to industrial.

Remember that "do nothing" is almost always a choice (it's called "Continue" and can be found on the left side of the screen) so your events don't need this as an extra choice.

Choice text
This should be a short text describing the effects of your choice. Generally shorter than the main text, but all the other things mentioned there apply.
Try to keep surprise buttsex to a minimum.

For example this cut up version of "paternalist encounter" from REFS (l:106-139).

	<<link "Alert your drones and keep walking">>

	<</link>>
	<<if $cash >= 2000>>

<<link "Take the poor slave girl into your custody">>

<<link "Publicly confront the citizen">>

	So here you can either, A) "Alert your drones and keep walking", B) if $cash is above 2000 you can take acquire the slave or C) "Publicly confront the citizen".

Choice effect
A choice doesn't need to have a specific effect. If your event has an immediate effect, remember to take that into account when you decide on the choice's effects.

	<<link "Alert your drones and keep walking">>
	<<replace "#result">>
	You inform $assistantName that you have a slave beater in need of detainment by your security drones, then continue on your way confident in your knowledge that the citizen will soon be in custody.
	<</replace>>
	<</link>>
	<<if $cash >= 2000>>

<<link "Take the poor slave girl into your custody">>
	<<replace "#result">>
	Confronting the citizen is simplicity in itself, he would not dare defy you under threat of arrest by your security drones and is unlikely to garner any sympathy from the public for his degradationist behaviors. As such, you are able to take civil ownership over the poor slave girl and take her into your care with only minimal compensation to the citizen. As you stride away from her former owner with the girl in your arms, she leans over to plant a chaste kiss of thanks on your cheek.
	<<set $cash -= 2000>>
		<<set $activeSlaveOneTimeMaxAge = 22>>
		<<include "Generate New Slave">>
		<<set $activeSlave.origin = "She was taken into your custody from an abusive owner.">>
		<<set $activeSlave.devotion = random(-25,0)>>
		<<set $activeSlave.trust = random(-25,0)>>
		<<set $activeSlave.boobs = random(300,450)>>
		<<set $activeSlave.hips = random(-2,-1)>>
		<<set $activeSlave.butt = random(0,2)>>
		<<set $activeSlave.health = random(10,20)>>
		<<include "New Slave Intro">>
		<<set $nextLink = "AS Dump", $returnTo = "RIE Eligibility Check">>
	<</replace>>
	<</link>> // Taking custody of the girl will cost ¤2000. //
	<</if>>

<<link "Publicly confront the citizen">>
	<<replace "#result">>
	Your walk up to the citizen is not accompanied by shaking ground or tumultuous fanfare, yet the citizen looks as if death itself has come before him. You don't hurt him physically, instead chastising him publicly in front of his fellow peers who begin to cheer their agreement. You end your tirade of verbal abuse with a reminder that although the man is a citizen of your arcology, that does not give him the impunity to shirk the law. To make it clear his next offense will be his last, a brace of your security drones hover behind you threateningly. The crowd that gathered @@.green;approve of your rebuke of the citizen@@.
	<<set $rep += 500>>
	<</replace>>
	<</link>>

	So here the results of the choices are, A) nothing, B) reduce cash by 2000 but acquire the slave C) chastise the citizen for plus 500 rep.


code:
Extended family mode (mod)

In short, extended family mode replaces the old .relation + .relationTarget system with a completely new system capable of handling a limitless number of relatives. Or at least until your game crashes from trying to handle it all. Fully incompatable with the old system and fully functional with ng+.

The backbone of the system: .father and .mother

Everything about a slave's family can be gathered by looking into her mother and father. Beyond the obvious mother-daughter relation, you can check two seperate slaves' parents to see if they are related to each other, allowing for sisters, half-sisters, and with a .birthWeek check, twins with little effort.
The following values are used with .mother and .father:
Valid slave IDs (in other words, a value > 0) - Serves as both a target for checks and as a check itself to see if effort should be expended to search for the parent.
0 - Slave has no known parent. A slave with a parent value of 0 is capable of having a parent added via reRelativeRecruiter
MissingParentIDs (in other words, a value < -2) - Serves as a placeholder to preserve sibling relations in the case of a parent being sold or lost. Outside of extreme cases, this value will never be restored to its' previous value. $missingParentID starts at -10000 and decrements after application. On NG+, positive values are incremented the same as a normal slave and checked for validity. Should it be invalid, it will be replaced with $missingParentID. Negative values, on the other hand, are decremented by 1200000. Values of -1 and -2 are ignored by the JS, so don't use them. Also -9999 through -9994 are used by hero slaves to preserve their sibling status no matter when they are purchased or obtained during the same game.

The limiters: .sisters and .daughters
Extended family mode is VERY for loop intensive, and as such, has limiters to prevent it from needlessly looping. A value greater than 0 for either of these slave variables signals that slave has a sibling/daughter for various checks. Furthermore, the value of .sisters and .daughters accurately tracks the number of sisters and daughters, particularly for checks that require all of them to be found. You'll learn to hate these, but on the plus side, they can safely be recalculated with no side effects. Nearly entirely handled by <<AddSlave>> and removeActiveSlave, you do not understand how huge of a plus this is.

The recruiting check: .canRecruit

Checked by reRelativeRecruiter to see if a slave is eligible to have relatives added. Hero slaves, special slaves, and often event slaves are ineligible for recruiting. Gets disabled if the slave is called into the recruiting event but fails to qualify for additional relatives due to unaddable slots or too many existing relatives.

A quick list of the JS that gets things done and various useful JS calls:

sameDad(slave1, slave2) - checks if the slaves share the same father and returns true/false.
sameMom(slave1, slave2) - checks if the slaves share the same mother and returns true/false.
sameTParent(slave1, slave2) - an exception catcher that handles such things as "slave1 knocked up slave2 and got impregnated by slave2, their children will be sisters" and returns the sister variable (0 - not related, 1 - twins, 2 - sisters, 3 - half-sisters). (subJS, never call on its own)
areTwins(slave1, slave2) - checks if the slaves are twins and returns true/false.
areSisters(slave1, slave2) - combines all of the above and returns the sister variable (0 - not related, 1 - twins, 2 - sisters, 3 - half-sisters). A widely used check to identify sister relatives. Generally gated by a .sisters check. Recommended to use in a <<switch>> macro instead of calling it for each outcome.

totalRelatives(slave) - returns how many relatives a slave has as an integer. Useful both as a check and for its value. Recommended to use as a check in instances where you want a relative, but don't care what it is.

mutualChildren(slave1, slave2, slaves) - checks the slave array for children shared by the two slave arguements and returns the number of mutual children as an integer. Currently used solely to encourage two slaves into a relationship if they have kids together.

The utility JS, courtesy of FCGudder. This JS should only be called if you know it will find something, use your limiters! These will always return the only relative if only one outcome is possible, so technically they can be used creatively. randomAvailable JS should be followed with random JS as a fallback for circumstances where you must find something, but would prefer it to be sensible if possible.
randomRelatedSlave(slave, filterFunction) - returns a random related slave to the slave passed into it. filterFunction is called in the following JS but not needed if you just want a random relative.
randomRelatedAvailableSlave(slave) - returns a random available related slave.
randomSister(slave) - returns a random sister.
randomTwinSister(slave) - returns a random twin.
randomAvailableSister(slave) - returns a random available sister.
randomAvailableTwinSister(slave) - returns a random available twin.
randomDaughter(slave) - returns a random daughter.
randomAvailableDaughter(slave) - returns a random available daughter.
randomParent(slave) - returns a random parent.
randomAvailableParent(slave) - returns a random available parent.

path: devNotes/Extended Family Mode Explained.txt


code:
Security Expansion

	10/18/17

	1

	3

	10/22/17

	5

	10/24/17

	6
	-balance adjustments
	-fixed improper name assignment
	-added renaming of units
	-reworked casualties logic
	-added statistics to arcology management screen
	-various other fixes

	10/28/17

	7
	-SFanon additions
	-fixes
	-balance

	10/29/17

	7.1
	-fixes
	-couple of balance adjustments.

	11/01/17

	7.5

	7.6
	-fixed reported issue
	-balance adjustments (run backward compatibility to apply them)

	7.7

	11/03/17

	8
	-various fixes
	-balance
	-rebellions

	11/05/17

	8.5
	-fixes
	-rebellions

	11/06/17

	Pregmod v113

	8.6
	-fixes

	8.7
	-fixed reported issue maybe pretty please?

	11/07/17

	Pregmod v114/Pregmod v114.1

	8.8
	-fixes

	9.2
	-small fixes
	-new edicts
	-new units upgrade
	-new barracks upgrade

	Pregmod v115

	9.6
	-fixes
	-loyalty work

	11/09/17

	Pregmod v119

	9.6
	-small fixes

	11/10/17

	10
	-fixes
	-weapons manufacturing
	-balance

	11/11/17

	Pregmod v121

	10.2
	-fixes

	Pregmod v122

	11
	-fixes
	-proclamations
	-balance

	11.1

	11.2
	-fixes
	-extra options

	11/12/17

	Pregmod v124

	11.5
	-fixes
	-balance

	11.6
	-fixed reported issues
	-balance

	Pregmod v125

	12
	-fixes
	-transport hub and trade
	-balance

	11/13/17

	12.3
	-fixes
	-SFanon additions
	-balance

	Pregmod v126

	12.4

	11/14/17

	Pregmod v130

	12.5
	-fixes
	-SFanon stuff
	-balance

	Pregmod v132

	12.6
	-fixes
	-anon's stuff

	12.8
	-fixes
	-balance

	12.9
	-fixes

	11/15/17

	13
	-fixes
	-balance

	11/16/17

	13.1
	-fixes
	-balance

	13.3
	-fixes

	13.4
	-fixed >>142293 (Attack value NaN during major battle)

	11/17/17

	Pregmod v135

	13.4
	-fixes
	-balance
	-difficulty settings

	Pregmod v136
	13.6
	-fixes

	11/18/17

	13.7
	-balance
	-(maybe) fix for battle terrain not showing up.

	13.8
	-(maybe) fixed >>142732

	Pregmod v137

	v13.9
	-fixes (couple of)

	Pregmod v139

	14
	-fixes
	-spell checked attack report. My god was is bad.

	14.1
	-fixes

	11/20/17

	14.2
	-fixes
	-balance
	-very satisfying version number.