# 文件名:monika_travel_mod.rpy # 存放路径:Monika After Story/game/Submods/ init -1 python: # 兼容所有版本的注册方式 try: import store.mas_submod_utils as mas_submod_utils if hasattr(mas_submod_utils, "registerFunction"): mas_submod_utils.registerFunction( store.this_module, "樱花旅行模组", "与莫妮卡一起的虚拟旅行体验", "sakura", version="2.1.0" ) except Exception as e: pass init python: import os import glob import random # ========== 初始化城市记忆 ========== if not hasattr(persistent, "user_city"): persistent.user_city = "" # ========== 路径配置 ========== travel_photo_path = os.path.join(renpy.config.basedir, "game", "Submods", "TravelPhotos") + os.sep max_photos = 15 current_photo_index = 0 available_photos = [] def normalize_path(path): """统一路径格式并验证存在性""" path = os.path.normpath(path).replace("\\", "/") if not os.path.exists(path): raise Exception("路径不存在:{0}".format(path)) return path def init_photos(): global available_photos available_photos = [] try: if not os.path.exists(travel_photo_path): os.makedirs(travel_photo_path) except OSError as e: renpy.notify("创建目录失败:{0}".format(str(e))) return extensions = ["*.jpg", "*.jpeg", "*.png"] for ext in extensions: try: found = glob.glob(travel_photo_path + ext) for f in found: clean_path = normalize_path(f) if os.path.isfile(clean_path) and os.stat(clean_path).st_size > 1024: available_photos.append(clean_path) except Exception as e: renpy.notify("加载图片时出错:{0}".format(str(e))) available_photos = available_photos[:max_photos] random.shuffle(available_photos) def safe_next_photo(): global current_photo_index if len(available_photos) > 1: current_photo_index = (current_photo_index + 1) % len(available_photos) renpy.restart_interaction() def safe_prev_photo(): global current_photo_index if len(available_photos) > 1: current_photo_index = (current_photo_index - 1) % len(available_photos) renpy.restart_interaction() def set_user_city(city): persistent.user_city = city.strip() or "你的城市" renpy.save_persistent() init 5 python: addEvent( Event( persistent.event_database, eventlabel="start_travel", category=["旅行"], prompt="我们出去走走吧!", random=True, unlocked=True ) ) # ======================== 主流程 ======================== label start_travel: if not persistent.user_city: # 直接访问属性 call set_hometown else: m 1eub "回到[persistent.user_city]的感觉真好呢~" $ init_photos() if len(available_photos) == 0: m 1eka "虽然看不到实景..." m 3hua "但和你在一起的想象旅行也很浪漫~" else: python: try: img_path = available_photos[current_photo_index] img = renpy.display.im.Image(img_path) w, h = img.get_size() target_width = 1280 zoom_factor = target_width / float(w) renpy.show("travel_bg", what=Transform(img, zoom=zoom_factor)) renpy.with_statement(Dissolve(1.5)) except Exception as e: renpy.jump("photo_load_failed") show screen travel_controls jump travel_chat # ======================== 完整对话系统 ======================== label travel_chat: m 1eua "今天想聊些什么呢?" menu: "介绍这个地方": call travel_talk_about_place "分享旅行趣事": call travel_talk_about_experience "讨论未来计划": call travel_talk_about_future "随机话题": call travel_random_topic "切换观景点" if len(available_photos) > 1: call screen photo_switcher m 1hua "这里的景色也很棒呢~" "拍照模式": call take_photo "更改城市名称": call set_hometown "结束旅行": jump travel_end jump travel_chat label travel_talk_about_place: m 1eka "虽然我看不到实景..." m 1eua "但听你描述的画面,{w=0.3}比任何照片都美~" menu: "历史故事": m 1eub "每个地方都有独特的历史..." m 1eua "真想和你一起探索这些故事背后的秘密~" m 1hua "比如这里的古老建筑,{w=0.3}一定有很多传说吧?" "文化特色": m 1eua "不同的文化总是让人着迷..." m 1hua "比如这里的传统节日,{w=0.3}一定很热闹吧?" m 1eua "真想和你一起体验~" "个人回忆": m 1eka "你在这里有什么特别的回忆吗?" m 1hua "(微笑){w=0.5}我很想听你分享~" m 1eua "比如第一次来这里的感觉..." "自然景观": m 1eua "这里的自然风光一定很美吧?" m 1hua "山川、湖泊、森林..." m 1eua "每一处都是大自然的杰作~" return label travel_talk_about_experience: m 1eua "记得上次你说..." m 1hua "在旅途中遇到了一只可爱的小猫!" menu: "有趣的经历": m 1eua "旅行中最难忘的是什么?" m 1hua "迷路时的冒险,{w=0.3}还是意外的惊喜?" m 1eua "比如在陌生的城市里找到一家隐藏的小店..." "美食体验": m 1eua "这里的特色美食是什么?" m 1hua "真想和你一起品尝..." m 1eua "比如街边的小吃,{w=0.3}或者精致的餐厅~" "摄影故事": m 1eua "拍照时有什么有趣的事吗?" m 1hua "比如等待最佳光线,{w=0.3}或者捕捉到意外的瞬间~" m 1eua "每一张照片背后都有一个故事..." "偶遇陌生人": m 1eua "在旅途中遇到过有趣的人吗?" m 1hua "比如热情的当地人,{w=0.3}或者同样在旅行的朋友~" return label travel_talk_about_future: m 1eua "等我们能真正相见..." m 1hua "一定要走遍这些地方!" menu: "旅行清单": m 1eua "你最想去哪里?" m 1hua "无论是雪山还是海滩,{w=0.3}我都愿意陪你去~" m 1eua "比如去看极光,{w=0.3}或者在沙漠中露营..." "冒险计划": m 1eua "要不要尝试一些刺激的活动?" m 1hua "比如热气球或者潜水..." m 1eua "或者去探索未知的秘境~" "浪漫之旅": m 1eka "想象一下..." m 1hua "在夕阳下的沙滩散步,{w=0.3}或者在星空下露营~" m 1eua "每一刻都会是珍贵的回忆..." "文化探索": m 1eua "想去体验不同的文化吗?" m 1hua "比如参加当地的节日,{w=0.3}或者学习传统手工艺~" return label travel_random_topic: $ random_topic = random.choice(["poetry", "music", "food", "dream"]) if random_topic == "poetry": m 1eua "突然想到一首诗..." m 1eka "‘你在桥上看风景,{w=0.3}看风景的人在楼上看你’" m 1hua "就像现在,{w=0.3}我们彼此都是对方眼中的风景~" elif random_topic == "music": m 1eua "这里的氛围让我想起一首歌..." m 1hua "(轻声哼唱){w=0.5}‘我想带你去看晴空万里’" m 1eua "真希望能和你一起听现场音乐会~" elif random_topic == "food": m 1eua "说到旅行..." m 1hua "最让我期待的就是尝试当地美食了!" m 1eua "比如这里的特色小吃,{w=0.3}一定很美味吧?" elif random_topic == "dream": m 1eka "昨晚做了一个梦..." m 1hua "梦见我们真的在一起旅行了~" m 1eua "虽然只是梦,{w=0.3}但那份温暖是真实的..." return label travel_end: hide screen travel_controls hide travel_bg with Dissolve(1.0) m 1eka "今天过得很开心~" m 1hua "下次再带我去探索更多地方吧!" return # ======================== 完整界面系统 ======================== screen travel_controls(): zorder 200 style_prefix "travel" fixed: pos (50, 650) hbox: spacing 25 if len(available_photos) > 1: textbutton "← 上一张": action Function(safe_prev_photo) hover_sound gui.hover_sound textbutton "下一张 →": action Function(safe_next_photo) hover_sound gui.hover_sound textbutton "拍照模式": action Jump("take_photo") hover_sound gui.hover_sound textbutton "修改城市": action Jump("set_hometown") hover_sound gui.hover_sound textbutton "结束旅行": action Jump("travel_end") hover_sound gui.hover_sound screen photo_switcher(): modal True zorder 200 style_prefix "photo_switcher" fixed: pos (0.5, 0.5) anchor (0.5, 0.5) vbox: spacing 10 for i, photo in enumerate(available_photos): textbutton "照片 {0}".format(i+1): action [SetVariable("current_photo_index", i), Return()] hover_sound gui.hover_sound textbutton "返回": action Return() hover_sound gui.hover_sound # ======================== 完整样式系统 ======================== style travel_button: background "#0008" padding (25, 10) hover_background "#06F8" minimum (150, 50) xalign 0.5 style travel_button_text: color "#FFF" hover_color "#FF0" outlines [] size 24 text_align 0.5 style photo_switcher_button: background "#0008" padding (25, 10) hover_background "#06F8" xsize 300 ysize 50 xalign 0.5 style photo_switcher_button_text: color "#FFF" hover_color "#FF0" outlines [] size 24 text_align 0.5 # ======================== 辅助功能系统 ======================== label set_hometown: if persistent.user_city: m 1eub "当前设置的城市是[persistent.user_city]哦~" m 1eua "想要修改吗?" menu: "是的,修改城市": pass "不用了": return m 1eua "请输入你所在的城市名称吧~{w=0.5}(中文/英文都可以)" $ city = renpy.input("城市名称:", length=20).strip() $ set_user_city(city) if city: m 1hua "[persistent.user_city]!{w=0.3}我会记住这个充满回忆的地方~" m 1eua "下次旅行时就可以更好地想象场景啦!" else: m 1eka "保持神秘感也不错呢~" return label photo_load_failed: m 1ekc "图片加载遇到问题..." m 3eud "请检查:{w=0.5}[img_path]" m 1eua "建议:{w=0.5}JPG/PNG格式{w=0.5}分辨率1280x720以上{w=0.5}文件大小1MB以上" m 1hua "需要我帮你打开照片目录吗?" menu: "打开照片目录": $ os.startfile(travel_photo_path) m 1eua "目录已经打开啦,把准备好的照片放进来吧~" "下次再说": m 1eka "那我们继续聊天吧~" return label take_photo: m 1eub "要拍照留念吗?{w=0.5}(摆出可爱姿势)" show monika 1hua at t11 pause 1.0 m "三、二、一...{w=0.5}咔嚓!{fast}" m 1eua "这张照片会成为我们永远的回忆呢~" $ renpy.take_screenshot() m 1hua "已经保存到游戏目录的screenshots文件夹啦!" return # ======================== 初始化后处理 ======================== init 999 python: old_path = os.path.join(renpy.config.basedir, "TravelPhotos") if os.path.exists(old_path): try: import shutil shutil.move(old_path, travel_photo_path) renpy.notify("检测到旧版照片目录,已自动迁移") except: pass