Compare commits

...

5 Commits
master ... main

Author SHA1 Message Date
zhx
a288fc661b Adjust loading screen progress layout 2026-05-30 20:29:51 +08:00
zhx
9c66a54df0 Export local database dump 2026-05-30 20:24:47 +08:00
zhx
046ae79b1d 宠物系统 2026-05-30 20:23:54 +08:00
zhx
27361bb3ed Update local MySQL dump 2026-05-30 17:40:41 +08:00
zhx
b5d3e6444d Track database SQL dumps 2026-05-30 17:31:08 +08:00
125 changed files with 6167 additions and 6257 deletions

2
.gitignore vendored
View File

@ -2,6 +2,8 @@
# Local database dumps should not be pushed by default.
*.sql
!muchang_20211111_141209.sql
!muchang/mysql/mysql.sql
# Godot generated/import cache and exported builds.
godot/FarmGodot/.godot/

View File

@ -0,0 +1,429 @@
# 宠物对决偷菜玩法产品方案
## 1. 产品定位
本玩法不定位为“偷别人菜赚钱”,而定位为:
**围绕主播、好友、CP、家族关系链的轻 PVP 庄园社交玩法。**
核心目标是通过被偷、复仇、求救、协防、集火、守护等事件制造回流和社交互动,而不是让农场成为主金币产出工具。
## 2. 设计目标
1. 提升农场玩法的日活和次日回流。
2. 强化语音房、好友、CP、家族之间的互动。
3. 给宠物养成提供实际使用场景和消耗点。
4. 控制用户损失,避免强挫败导致流失。
5. 防止工作室通过偷菜机制刷金币或刷收益。
6. 避免大号、家族、主播粉丝团无限欺负小号。
## 3. 核心设计原则
1. 不允许偷走用户全部收益。
2. 不允许无限攻击同一用户。
3. 不允许高战力玩家无成本碾压低战力玩家。
4. 不允许农场收益直接大量兑换主金币。
5. 宠物不能死亡、掉级或永久受损。
6. 被攻击方必须有求救、协防、复仇手段。
7. 所有 PVP 行为必须有次数、消耗和保护期。
8. 集火玩法必须受人数、频次和收益上限限制。
## 4. 核心玩法流程
1. 用户种植作物。
2. 作物成熟后,系统生成“可偷池”。
3. 其他用户发现该庄园。
4. 攻击方消耗体力或挑战券发起偷菜。
5. 双方宠物进入对决。
6. 攻击方胜利则可偷取少量作物。
7. 攻击方失败时,可造成一定守护值伤害。
8. 多名攻击者可在限制内发起集火。
9. 宠物守护值归零后,庄园进入短暂破防窗口。
10. 仅参与攻击的用户可在破防窗口内偷菜。
11. 破防结束后,庄园进入保护期。
12. 被偷用户获得复仇机会。
13. 好友可协防、回血、反击并获得奖励。
## 5. 宠物状态设计
不使用“死亡”概念,改为更温和的状态表达。
| 概念 | 说明 |
| --- | --- |
| 宠物血量 | 守护值或精力值 |
| 血量为 0 | 宠物进入疲劳状态 |
| 疲劳状态 | 庄园进入破防窗口 |
| 破防结束 | 宠物自动恢复部分守护值 |
| 恢复后 | 庄园进入保护期 |
推荐文案:
> 你的守护宠物太累了,庄园进入短暂破防状态。
避免文案:
> 你的宠物被打死了,菜被抢光了。
## 6. 战斗规则
宠物血量会影响战斗力,但不能形成死亡螺旋。
推荐公式:
```text
有效战斗力 = 基础战斗力 ×0.75 + 0.25 × 当前血量比例)
```
效果:
| 当前血量 | 有效战斗力 |
| --- | --- |
| 满血 | 100% |
| 半血 | 87.5% |
| 低血 | 最低接近 75% |
战力对比规则:
| 攻击方 / 防守方战力 | 结果 |
| --- | --- |
| ≥ 1.2 | 大概率直接胜利,可偷菜 |
| 0.9 - 1.2 | 进入胜率区间,约 40% - 70% |
| 0.6 - 0.9 | 偷菜失败,但造成少量守护伤害 |
| < 0.6 | 基本无效仅造成极低伤害 |
## 7. 偷菜收益规则
每块成熟土地收益拆为两部分:
| 收益类型 | 占比 |
| --- | --- |
| 安全收益 | 70% - 85% |
| 可偷收益 | 15% - 30% |
示例:
一块地总价值 100 农场币,主人至少保底获得 80最多被偷 20。
限制规则:
1. 每块地最多被偷 20% 收益。
2. 每人每天最多偷 3 个用户。
3. 每个目标最多被偷 3 块地。
4. 单个庄园每日损失达到上限后,进入保护到次日。
## 8. 破防窗口规则
宠物守护值归零后,庄园进入破防窗口。
推荐规则:
| 规则项 | 数值 |
| --- | --- |
| 破防窗口 | 10 分钟 |
| 可偷用户 | 仅参与攻击的人 |
| 单人可偷土地 | 1 - 3 块 |
| 破防期间最多被偷 | 3 块地 |
| 破防后保护期 | 4 小时 |
| 同一目标每日破防次数 | 最多 1 次 |
## 9. 集火规则
集火用于制造社交,但必须严格限制。
推荐规则:
1. 每次集火最多 3 - 5 人。
2. 每人每天最多参与 5 次集火。
3. 同一目标每小时最多承受 1 次集火。
4. 同一目标每天最多被同一阵营集火 1 次。
5. 没有参与攻击的人不能在破防后白嫖偷菜。
## 10. 防守与协防
当宠物守护值低于 50% 时,防守方可点击“召唤好友守护”。
好友可执行:
1. 给宠物回血。
2. 增加临时护盾。
3. 帮忙反击攻击者。
4. 获得友情值、宠物经验、守护积分、少量农场币。
协防收益建议与关系链绑定:
| 关系 | 奖励 |
| --- | --- |
| 普通协防 | 友情值 |
| 好友协防 | 额外友情值 |
| CP 协防 | 亲密度 |
| 粉丝团协防 | 庄园贡献 |
## 11. 复仇机制
被偷后,系统应主动发放复仇机会。
示例文案:
> XX 偷走了你的 2 个番茄,你获得一次免费复仇机会。
复仇加成:
1. 免费攻击一次。
2. 伤害 +20%。
3. 成功后获得额外奖励。
4. 可邀请好友助战。
## 12. 资源消耗
攻击不能免费无限进行。
推荐消耗:
1. 体力。
2. 偷菜券。
3. 挑战券。
4. 宠物精力。
推荐发放:
1. 每日免费 5 次攻击。
2. 语音房活跃额外获得 3 次。
3. 任务或送礼获得挑战券。
4. 金币可购买少量额外次数,但不能无限购买。
## 13. 保护机制
保护期规则:
| 触发条件 | 保护时长 |
| --- | --- |
| 被成功偷菜 | 2 小时 |
| 被破防 | 4 小时 |
| 当日损失达到上限 | 保护到次日 |
| 新用户 | 前 3 天不可被偷 |
| 低等级农场 | 农场等级 5 级前不可被攻击 |
保护期内:
1. 不能被偷。
2. 可以被访问、浇水、留言。
3. 可以主动复仇别人。
## 14. 经济规则
偷菜不应直接产出大量主金币。
推荐产出:
1. 农场币。
2. 农产品。
3. 材料。
4. 宠物经验。
5. 宠物食物。
6. 活动积分。
主金币兑换限制:
1. 每日兑换上限 100 - 300 金币。
2. 超出部分只能用于农场内消费。
3. 兑换资格需要绑定语音房活跃任务。
4. 异常互偷账号不具备金币兑换资格。
## 15. 宠物职业设计
宠物不应只比战斗力,应提供职业差异。
| 类型 | 作用 |
| --- | --- |
| 攻击型 | 偷菜时伤害更高 |
| 防御型 | 守家减伤 |
| 治疗型 | 自动回血 |
| 反击型 | 被攻击时反伤 |
| 侦查型 | 更容易发现高价值目标 |
| 辅助型 | 协防收益更高 |
## 16. 陷阱与防御道具
防守方不能只有宠物,可增加轻量防守道具。
| 道具 | 效果 |
| --- | --- |
| 捕兽夹 | 让偷菜者宠物掉血 |
| 稻草人 | 降低对方偷菜成功率 |
| 假菜 | 对方偷到低价值作物 |
| 迷雾 | 隐藏真实成熟时间 |
| 反击铃铛 | 被偷时自动通知好友 |
防御道具不能强到完全偷不了,偷菜仍需保留成功感。
## 17. 初版数值建议
| 模块 | 数值 |
| --- | --- |
| 初始宠物 HP | 100 |
| 普通攻击伤害 | 8 - 15 |
| 低战力攻击伤害 | 3 - 8 |
| 超低战力攻击伤害 | 0 - 3 |
| 单人每天对同一目标最大伤害 | 25 |
| 破防窗口 | 10 分钟 |
| 破防期间最多被偷 | 3 块地 |
| 破防后保护期 | 4 小时 |
| 每人每天最多偷 | 3 个用户 |
| 每次集火人数 | 最多 5 人 |
| 每人每天参与集火 | 最多 5 次 |
| 宠物自动恢复 | 每小时 20% HP |
| 免费满血恢复 | 每天 1 次 |
## 18. 反作弊规则
重点防范:
1. 小号种菜,大号偷菜。
2. 小号互相打残,大号收割。
3. 固定账号组对刷。
4. 批量账号刷农场币。
5. 农场币兑换金币后刷礼物提现。
限制策略:
1. 新号收益降低。
2. 同设备收益衰减。
3. 同 IP 收益衰减。
4. 同支付账户收益衰减。
5. 高频固定互偷降权。
6. 异常账号取消金币兑换资格。
7. 农场收益兑换金币必须绑定语音房活跃。
## 19. 语音房关系链绑定
该玩法不建议做成纯随机偷陌生人,应与语音房关系链绑定。
### 19.1 主播庄园战
主播 A 的粉丝可以攻击主播 B 的庄园。
限制规则:
1. 每天固定活动时间开放。
2. 只偷活动积分,不直接偷大量金币。
3. 主播开播时,全体粉丝宠物获得 BUFF。
### 19.2 房间求救
用户被攻击时,可以在正在听的语音房里发起求救:
> 我的庄园被偷袭了,帮我守一下!
其他用户点击后可进入协防。
### 19.3 CP / 好友守护
好友、CP、粉丝团成员帮忙守护时收益更高。
| 关系 | 奖励 |
| --- | --- |
| 普通协防 | +10 友情值 |
| 好友协防 | +20 友情值 |
| CP 协防 | +30 亲密度 |
| 粉丝团协防 | +20 庄园贡献 |
## 20. 排行榜设计
可设计榜单:
1. 今日偷菜王。
2. 今日守护王。
3. 今日复仇王。
4. 今日协防达人。
5. 主播庄园战力榜。
6. 家族偷菜榜。
避免羞辱型命名。
“今日被偷最多”建议改为:
1. 最热闹庄园。
2. 最受欢迎庄园。
## 21. MVP 范围建议
### 21.1 第一期
必须做:
1. 可偷池。
2. 宠物守护值。
3. 宠物对决。
4. 破防窗口。
5. 保护期。
6. 复仇机会。
7. 攻击次数限制。
8. 新手保护。
9. 战力分层。
10. 基础反作弊。
### 21.2 第二期
继续扩展:
1. 好友求救。
2. 协防奖励。
3. 集火邀请。
4. 宠物职业。
5. 陷阱道具。
6. 排行榜。
### 21.3 第三期
语音房深度绑定:
1. 主播庄园战。
2. 家族庄园战。
3. 房间求救消息。
4. 开播宠物 BUFF。
5. 粉丝团协防奖励。
## 22. 成功指标
核心指标:
1. 农场 DAU。
2. 偷菜参与率。
3. 复仇转化率。
4. 协防参与率。
5. 被偷后次日回流率。
6. 语音房导流点击率。
7. 农场币产出与消耗比。
8. 金币兑换总量。
9. 被偷用户投诉率。
10. PVP 后流失率。
## 23. 风险与对应方案
| 风险 | 对应方案 |
| --- | --- |
| 强者无限欺负弱者 | 匹配分层、收益衰减、攻击次数限制、保护期 |
| 用户损失太大 | 主人保底 70% - 85%、可偷池限制、当日损失封顶 |
| 农场直接产大量金币 | 农场产农场币和材料,金币兑换每日封顶,兑换绑定语音房活跃 |
| 集火没有限制 | 每次最多 3 - 5 人,同目标每日破防上限,同人攻击上限 |
| 宠物受伤太痛 | 自动回血、免费恢复、不掉级、不永久死亡 |
| 只有攻击没有防守社交 | 求救、协防、反击、复仇、好友守护奖励 |
## 24. 最终结论
该玩法可以做,但不能做成“强者随便偷弱者”的纯抢夺玩法。
推荐产品方向是:
**轻损失、强互动、可复仇、可协防、收益封顶、绑定语音房关系链的庄园社交 PVP。**
必须加上的 8 个核心保护:
1. 可偷池,不偷全量收益。
2. 破防窗口,不无限偷。
3. 保护期,不连续挨打。
4. 集火人数上限,不允许霸凌。
5. 匹配分层,不允许大号虐小号。
6. 宠物自动回血,不永久损失。
7. 农场币和金币隔离,不直接印钱。
8. 求救、协防、复仇,把负面情绪转成社交互动。

Binary file not shown.

Before

Width:  |  Height:  |  Size: 489 KiB

After

Width:  |  Height:  |  Size: 474 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 437 KiB

After

Width:  |  Height:  |  Size: 474 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 478 KiB

After

Width:  |  Height:  |  Size: 484 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 367 KiB

After

Width:  |  Height:  |  Size: 367 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 471 KiB

After

Width:  |  Height:  |  Size: 474 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 473 KiB

After

Width:  |  Height:  |  Size: 367 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 393 KiB

After

Width:  |  Height:  |  Size: 398 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 364 KiB

After

Width:  |  Height:  |  Size: 357 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 478 KiB

After

Width:  |  Height:  |  Size: 482 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 488 KiB

After

Width:  |  Height:  |  Size: 474 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 403 KiB

After

Width:  |  Height:  |  Size: 391 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 439 KiB

After

Width:  |  Height:  |  Size: 439 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 439 KiB

After

Width:  |  Height:  |  Size: 439 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 382 KiB

After

Width:  |  Height:  |  Size: 382 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 382 KiB

After

Width:  |  Height:  |  Size: 383 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 486 KiB

After

Width:  |  Height:  |  Size: 476 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 500 KiB

After

Width:  |  Height:  |  Size: 484 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 490 KiB

After

Width:  |  Height:  |  Size: 476 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://ce0cxhwt6i4eu"
path="res://.godot/imported/loading_bar_bg.png-eddb5c3c0e75f0534f30638d7eb7ebee.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/replacement/loading/loading_bar_bg.png"
dest_files=["res://.godot/imported/loading_bar_bg.png-eddb5c3c0e75f0534f30638d7eb7ebee.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://fktosfx24tlq"
path="res://.godot/imported/loading_bar_fill.png-04a8fad6be9e44ec7bb14d1d29d35aa4.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/replacement/loading/loading_bar_fill.png"
dest_files=["res://.godot/imported/loading_bar_fill.png-04a8fad6be9e44ec7bb14d1d29d35aa4.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://curvjsf5mi8kc"
path="res://.godot/imported/loading_bg.jpg-ad1ed31e50ae1d22b3f25fafc39641ee.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/replacement/loading/loading_bg.jpg"
dest_files=["res://.godot/imported/loading_bg.jpg-ad1ed31e50ae1d22b3f25fafc39641ee.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://djdieythyi0jj"
path="res://.godot/imported/vs_0000.webp-d6e5f7888525d2d6639a341dfc49fe50.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/replacement/pet_battle_vs/vs_0000.webp"
dest_files=["res://.godot/imported/vs_0000.webp-d6e5f7888525d2d6639a341dfc49fe50.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://d1sw3cwjdw2v4"
path="res://.godot/imported/vs_0001.webp-463adf7089ef0b16777d5779cd897f22.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/replacement/pet_battle_vs/vs_0001.webp"
dest_files=["res://.godot/imported/vs_0001.webp-463adf7089ef0b16777d5779cd897f22.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dnj5dwa7r7pr6"
path="res://.godot/imported/vs_0002.webp-1f472a7312e01c5a8d4ea6118a1af20b.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/replacement/pet_battle_vs/vs_0002.webp"
dest_files=["res://.godot/imported/vs_0002.webp-1f472a7312e01c5a8d4ea6118a1af20b.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dhm4o4j5ofs6c"
path="res://.godot/imported/vs_0003.webp-5eda1815fccaca216af68b6caa40e2eb.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/replacement/pet_battle_vs/vs_0003.webp"
dest_files=["res://.godot/imported/vs_0003.webp-5eda1815fccaca216af68b6caa40e2eb.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://d1pv2b1jxs503"
path="res://.godot/imported/vs_0004.webp-bb63a65bcfb1f2adafb5707b4680cd8f.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/replacement/pet_battle_vs/vs_0004.webp"
dest_files=["res://.godot/imported/vs_0004.webp-bb63a65bcfb1f2adafb5707b4680cd8f.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cc6lq636hb5kx"
path="res://.godot/imported/vs_0005.webp-98c5f2bb35430148e9eb514693834a3c.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/replacement/pet_battle_vs/vs_0005.webp"
dest_files=["res://.godot/imported/vs_0005.webp-98c5f2bb35430148e9eb514693834a3c.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://boic8jlsymc4r"
path="res://.godot/imported/vs_0006.webp-5edfb0dc5ada4821bd1d3ddf5b47a82d.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/replacement/pet_battle_vs/vs_0006.webp"
dest_files=["res://.godot/imported/vs_0006.webp-5edfb0dc5ada4821bd1d3ddf5b47a82d.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://drynywqn4eq0g"
path="res://.godot/imported/vs_0007.webp-a2a7c378a538903e08e4dc5b9ee00c43.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/replacement/pet_battle_vs/vs_0007.webp"
dest_files=["res://.godot/imported/vs_0007.webp-a2a7c378a538903e08e4dc5b9ee00c43.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://8riat3eu2i07"
path="res://.godot/imported/vs_0008.webp-a85e95903b8558e6c1a8580fc4f861b4.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/replacement/pet_battle_vs/vs_0008.webp"
dest_files=["res://.godot/imported/vs_0008.webp-a85e95903b8558e6c1a8580fc4f861b4.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 396 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cofikqswentci"
path="res://.godot/imported/vs_0009.png-862e2d90f21b6d8eaee881855e95777f.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/replacement/pet_battle_vs/vs_0009.png"
dest_files=["res://.godot/imported/vs_0009.png-862e2d90f21b6d8eaee881855e95777f.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://hw2cfga3h265"
path="res://.godot/imported/vs_0010.webp-7760d9afb43468b7406cf7486fa4a7c1.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/replacement/pet_battle_vs/vs_0010.webp"
dest_files=["res://.godot/imported/vs_0010.webp-7760d9afb43468b7406cf7486fa4a7c1.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bjc5eq84dddyd"
path="res://.godot/imported/vs_0011.webp-3f105109fb1c5a90698ea763724cba8f.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/replacement/pet_battle_vs/vs_0011.webp"
dest_files=["res://.godot/imported/vs_0011.webp-3f105109fb1c5a90698ea763724cba8f.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://vx10keq1n3rj"
path="res://.godot/imported/vs_0012.webp-c2c7c0c136face4b88049b64d453b8a4.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/replacement/pet_battle_vs/vs_0012.webp"
dest_files=["res://.godot/imported/vs_0012.webp-c2c7c0c136face4b88049b64d453b8a4.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dg36nt54uupth"
path="res://.godot/imported/vs_0013.webp-6a4f3d0af235c8e2883004ed66bde2c9.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/replacement/pet_battle_vs/vs_0013.webp"
dest_files=["res://.godot/imported/vs_0013.webp-6a4f3d0af235c8e2883004ed66bde2c9.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bmg1scccigpih"
path="res://.godot/imported/vs_0014.webp-90cc22d60e21b376205d849aaca74267.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/replacement/pet_battle_vs/vs_0014.webp"
dest_files=["res://.godot/imported/vs_0014.webp-90cc22d60e21b376205d849aaca74267.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bgemmc4wc8el3"
path="res://.godot/imported/vs_0015.webp-e5cb96882ba9b55179903a519f2b202e.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/replacement/pet_battle_vs/vs_0015.webp"
dest_files=["res://.godot/imported/vs_0015.webp-e5cb96882ba9b55179903a519f2b202e.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://b3aiwaihttq5g"
path="res://.godot/imported/vs_0016.webp-a4e6169140553b0b6b85369848877c8c.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/replacement/pet_battle_vs/vs_0016.webp"
dest_files=["res://.godot/imported/vs_0016.webp-a4e6169140553b0b6b85369848877c8c.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://lw4bckitbanb"
path="res://.godot/imported/vs_0017.webp-4a8983ffd940ba565f7b9be0cb6f79c2.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/replacement/pet_battle_vs/vs_0017.webp"
dest_files=["res://.godot/imported/vs_0017.webp-4a8983ffd940ba565f7b9be0cb6f79c2.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dnspcg4k676t7"
path="res://.godot/imported/vs_0018.webp-7623ad86960528ee06527e124a63298d.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/replacement/pet_battle_vs/vs_0018.webp"
dest_files=["res://.godot/imported/vs_0018.webp-7623ad86960528ee06527e124a63298d.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 437 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cmx403pvpka6l"
path="res://.godot/imported/vs_0019.png-8db73604f7d9457976ce0d407f334cdf.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/replacement/pet_battle_vs/vs_0019.png"
dest_files=["res://.godot/imported/vs_0019.png-8db73604f7d9457976ce0d407f334cdf.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dnbu24gov4t68"
path="res://.godot/imported/vs_0020.webp-f448b7420efb45bd79dd0de82c6abd4e.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/replacement/pet_battle_vs/vs_0020.webp"
dest_files=["res://.godot/imported/vs_0020.webp-f448b7420efb45bd79dd0de82c6abd4e.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bybq7npk454ep"
path="res://.godot/imported/vs_0021.webp-923460ea1208bb157d3a39b26940e738.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/replacement/pet_battle_vs/vs_0021.webp"
dest_files=["res://.godot/imported/vs_0021.webp-923460ea1208bb157d3a39b26940e738.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://rosrxbqwwpwh"
path="res://.godot/imported/vs_0022.webp-9123f0a39f64317c780c95427e3fb89b.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/replacement/pet_battle_vs/vs_0022.webp"
dest_files=["res://.godot/imported/vs_0022.webp-9123f0a39f64317c780c95427e3fb89b.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bh8pixy2my444"
path="res://.godot/imported/vs_0023.webp-b05b81fa9958c800cfa9eae24d7df09c.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/replacement/pet_battle_vs/vs_0023.webp"
dest_files=["res://.godot/imported/vs_0023.webp-b05b81fa9958c800cfa9eae24d7df09c.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://nyscvmwj2nxw"
path="res://.godot/imported/vs_0024.webp-3a9f7f702e3454eb3735d698f4e950ac.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/replacement/pet_battle_vs/vs_0024.webp"
dest_files=["res://.godot/imported/vs_0024.webp-3a9f7f702e3454eb3735d698f4e950ac.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://c07gkambo8q0m"
path="res://.godot/imported/vs_0025.webp-33c711326bcfd9dc7981c4468c8d946c.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/replacement/pet_battle_vs/vs_0025.webp"
dest_files=["res://.godot/imported/vs_0025.webp-33c711326bcfd9dc7981c4468c8d946c.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://d15rnf1w5lseg"
path="res://.godot/imported/vs_0026.webp-8fd243bfa8254646fc63d53fd936ac95.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/replacement/pet_battle_vs/vs_0026.webp"
dest_files=["res://.godot/imported/vs_0026.webp-8fd243bfa8254646fc63d53fd936ac95.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dnm38cckoxtec"
path="res://.godot/imported/vs_0027.webp-da8f104b2ed73e08ec4e0b5232290a79.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/replacement/pet_battle_vs/vs_0027.webp"
dest_files=["res://.godot/imported/vs_0027.webp-da8f104b2ed73e08ec4e0b5232290a79.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cvp1cut4dwspf"
path="res://.godot/imported/vs_0028.webp-fe5a984ea6e8f33bc722a1852c2b98c7.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/replacement/pet_battle_vs/vs_0028.webp"
dest_files=["res://.godot/imported/vs_0028.webp-fe5a984ea6e8f33bc722a1852c2b98c7.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://ds3gqvxoewovh"
path="res://.godot/imported/vs_0029.webp-9471bf469b4ded55a1637f267e9bf31d.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/replacement/pet_battle_vs/vs_0029.webp"
dest_files=["res://.godot/imported/vs_0029.webp-9471bf469b4ded55a1637f267e9bf31d.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://ym3f7r58dd77"
path="res://.godot/imported/vs_0030.webp-3558e805abb809c0b8b8587be9134500.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/replacement/pet_battle_vs/vs_0030.webp"
dest_files=["res://.godot/imported/vs_0030.webp-3558e805abb809c0b8b8587be9134500.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dwsu7htsc0d75"
path="res://.godot/imported/vs_0031.webp-bbea2c868b95e18fa08aa3a5b43924f3.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/replacement/pet_battle_vs/vs_0031.webp"
dest_files=["res://.godot/imported/vs_0031.webp-bbea2c868b95e18fa08aa3a5b43924f3.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://x0s30lmqrt5g"
path="res://.godot/imported/stamina_bar.png-49b1bce6538fc2fb61b1ae9fa8742c43.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/replacement/ui/stamina_bar.png"
dest_files=["res://.godot/imported/stamina_bar.png-49b1bce6538fc2fb61b1ae9fa8742c43.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

View File

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cef8m7q2a3lhl"
path="res://.godot/imported/stamina_text.png-14b5426b753716b4fa500af45fca72da.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/replacement/ui/stamina_text.png"
dest_files=["res://.godot/imported/stamina_text.png-14b5426b753716b4fa500af45fca72da.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

View File

@ -35,6 +35,8 @@
[ext_resource type="Texture2D" path="res://assets/egret/menu2/menu2_left_sign_png.tres" id="36_left_sign"]
[ext_resource type="Texture2D" path="res://assets/egret/menu2/menu2_left_rewardgift_png.tres" id="37_left_reward"]
[ext_resource type="Texture2D" path="res://assets/replacement/menu2/market.png" id="39_market"]
[ext_resource type="Texture2D" path="res://assets/replacement/ui/stamina_text.png" id="40_stamina_text"]
[ext_resource type="Texture2D" path="res://assets/replacement/ui/stamina_bar.png" id="41_stamina_bar"]
[node name="GameScene" type="Control" unique_id=1830263827]
clip_contents = true
@ -295,9 +297,9 @@ stretch_mode = 5
[node name="TopPanelFront" type="TextureRect" parent="TopLayer/TopButtonGroup" unique_id=322036384]
layout_mode = 0
offset_left = 182.0
offset_top = 94.0
offset_top = 124.0
offset_right = 631.0
offset_bottom = 201.0
offset_bottom = 231.0
texture = ExtResource("10_top_panel")
expand_mode = 1
stretch_mode = 5
@ -305,51 +307,51 @@ stretch_mode = 5
[node name="TopLog" type="TextureRect" parent="TopLayer/TopButtonGroup" unique_id=353748731]
layout_mode = 0
offset_left = 200.0
offset_top = 109.0
offset_top = 139.0
offset_right = 274.0
offset_bottom = 183.0
offset_bottom = 213.0
texture = ExtResource("12_top_log")
[node name="TopLandup" type="TextureRect" parent="TopLayer/TopButtonGroup" unique_id=1777779145]
layout_mode = 0
offset_left = 292.5
offset_top = 102.0
offset_top = 132.0
offset_right = 388.5
offset_bottom = 184.0
offset_bottom = 214.0
texture = ExtResource("13_top_landup")
[node name="TopPay" type="TextureRect" parent="TopLayer/TopButtonGroup" unique_id=188030335]
visible = false
layout_mode = 0
offset_left = 423.0
offset_top = 104.0
offset_top = 134.0
offset_right = 479.0
offset_bottom = 184.0
offset_bottom = 214.0
texture = ExtResource("14_top_pay")
[node name="TopPayGift" type="TextureRect" parent="TopLayer/TopButtonGroup" unique_id=348171596]
layout_mode = 0
offset_left = 518.0
offset_top = 102.5
offset_top = 132.5
offset_right = 603.0
offset_bottom = 182.5
offset_bottom = 212.5
texture = ExtResource("15_top_paygift")
[node name="TopLottery" type="TextureRect" parent="TopLayer/TopButtonGroup" unique_id=389428429]
layout_mode = 0
offset_left = 414.5
offset_top = 101.0
offset_top = 131.0
offset_right = 500.5
offset_bottom = 184.0
offset_bottom = 214.0
texture = ExtResource("18_top_lottery")
[node name="FriendRedpoint" type="TextureRect" parent="TopLayer/TopButtonGroup" unique_id=1340198862]
visible = false
layout_mode = 0
offset_left = 541.5
offset_top = 118.0
offset_top = 148.0
offset_right = 569.5
offset_bottom = 146.0
offset_bottom = 176.0
texture = ExtResource("21_redpoint")
[node name="Laba" type="TextureRect" parent="TopLayer/TopButtonGroup" unique_id=111719876]
@ -489,9 +491,9 @@ text = "LV.20"
[node name="ExpText" type="TextureRect" parent="TopLayer" unique_id=1987309012]
layout_mode = 0
offset_left = 212.0
offset_left = 203.0
offset_top = 52.0
offset_right = 271.0
offset_right = 262.0
offset_bottom = 88.0
texture = ExtResource("28_exp_text")
@ -507,9 +509,9 @@ stretch_mode = 5
[node name="ExpBarBg" type="NinePatchRect" parent="TopLayer" unique_id=7405427]
layout_mode = 0
offset_left = 275.0
offset_left = 265.0
offset_top = 60.0
offset_right = 504.0
offset_right = 371.0
offset_bottom = 81.0
texture = ExtResource("30_exp_bg")
patch_margin_left = 8
@ -520,9 +522,9 @@ patch_margin_bottom = 15
[node name="ExpFill" type="NinePatchRect" parent="TopLayer" unique_id=1648615383]
unique_name_in_owner = true
layout_mode = 0
offset_left = 278.0
offset_left = 268.0
offset_top = 62.5
offset_right = 501.0
offset_right = 368.0
offset_bottom = 77.5
texture = ExtResource("31_exp_fill")
patch_margin_left = 8
@ -533,10 +535,56 @@ patch_margin_bottom = 9
[node name="LabelExp" type="Label" parent="TopLayer" unique_id=261798175]
unique_name_in_owner = true
layout_mode = 0
offset_left = 275.0
offset_left = 265.0
offset_top = 58.0
offset_right = 504.0
offset_right = 371.0
offset_bottom = 83.0
text = "125/36555"
horizontal_alignment = 1
vertical_alignment = 1
[node name="StaminaText" type="TextureRect" parent="TopLayer" unique_id=122101001]
layout_mode = 0
offset_left = 384.0
offset_top = 52.0
offset_right = 452.0
offset_bottom = 88.0
texture = ExtResource("40_stamina_text")
expand_mode = 1
stretch_mode = 5
[node name="StaminaBarBg" type="NinePatchRect" parent="TopLayer" unique_id=122101002]
layout_mode = 0
offset_left = 454.0
offset_top = 60.0
offset_right = 560.0
offset_bottom = 81.0
texture = ExtResource("30_exp_bg")
patch_margin_left = 8
patch_margin_top = 5
patch_margin_right = 24
patch_margin_bottom = 15
[node name="StaminaFill" type="NinePatchRect" parent="TopLayer" unique_id=122101003]
unique_name_in_owner = true
layout_mode = 0
offset_left = 457.0
offset_top = 62.5
offset_right = 557.0
offset_bottom = 77.5
texture = ExtResource("41_stamina_bar")
patch_margin_left = 16
patch_margin_top = 5
patch_margin_right = 16
patch_margin_bottom = 9
[node name="LabelStamina" type="Label" parent="TopLayer" unique_id=122101004]
unique_name_in_owner = true
layout_mode = 0
offset_left = 454.0
offset_top = 58.0
offset_right = 560.0
offset_bottom = 83.0
text = "20/20"
horizontal_alignment = 1
vertical_alignment = 1

View File

@ -4,21 +4,97 @@ const ApiClientScript := preload("res://scripts/services/api_client.gd")
const AUTO_USERNAME := "13800000001"
const AUTO_PASSWORD := "123456"
const DESIGN_SIZE := Vector2(640.0, 960.0)
const LOADING_BG_PATH := "res://assets/replacement/loading/loading_bg.jpg"
const LOADING_BAR_BG_PATH := "res://assets/replacement/loading/loading_bar_bg.png"
const LOADING_BAR_FILL_PATH := "res://assets/replacement/loading/loading_bar_fill.png"
const LOADING_BAR_SOURCE_SIZE := Vector2(1117.0, 223.0)
const LOADING_BAR_TARGET_WIDTH := 500.0
const LOADING_BAR_SIZE := Vector2(
LOADING_BAR_TARGET_WIDTH,
LOADING_BAR_TARGET_WIDTH * LOADING_BAR_SOURCE_SIZE.y / LOADING_BAR_SOURCE_SIZE.x
)
const LOADING_BAR_POSITION := Vector2((DESIGN_SIZE.x - LOADING_BAR_SIZE.x) * 0.5, 792.0)
const LOADING_BAR_SLOT_REGION := Rect2(190.0, 83.0, 738.0, 68.0)
const LOADING_FILL_SOURCE_REGION := Rect2(57.0, 55.0, 1003.0, 113.0)
const STARTUP_ASSET_PATHS := [
"res://scenes/ui/game_scene.tscn",
"res://assets/egret/common/common.png",
"res://assets/egret/assets/common.png",
"res://assets/egret/assets/game/menu2/menu3.png",
"res://assets/egret/assets/game/friend/friend.png",
"res://assets/egret/assets/game/rank/rank.png",
"res://assets/egret/assets/game/building/building.png",
"res://assets/egret/assets/game/landup/landup.png",
"res://assets/egret/assets/game/sign/sign.png",
"res://assets/egret/assets/game/roleinfo/roleinfo.png",
"res://assets/egret/assets/game/createrole/createrole.png",
"res://assets/egret/assets/common2.png",
"res://assets/egret/assets/game/gift/onLineGift.png",
"res://assets/egret/assets/game/lottery/lottery.png",
"res://assets/egret/assets/game/mofahecheng/mofahecheng.png",
"res://assets/egret/assets/game/battlePet/battle_pet.png",
"res://assets/egret/assets/game/pay/pay_com.png",
"res://assets/egret/assets/game/pay/pay_bg.png",
"res://assets/egret/land/land0.png",
"res://assets/egret/land/land1.png",
"res://assets/egret/land/land-1.png",
"res://assets/egret/assets/icon/land/land2.png",
"res://assets/egret/assets/icon/land/land3.png",
"res://assets/egret/common/land_light_png.tres",
"res://assets/egret/common/bag_bg_png.tres",
"res://assets/egret/common/bag_line_png.tres",
"res://assets/egret/common/log_itembg_png.tres",
"res://assets/egret/common/m_phase_clock_png.tres",
"res://assets/egret/common/m_phase_pro_bar_png.tres",
"res://assets/egret/common/m_phase_pro_bg_png.tres",
"res://assets/egret/menu/menu_p_plant.png",
"res://assets/egret/menu/menu_p_gain.png",
"res://assets/egret/menu/menu_p_uproot.png",
"res://assets/egret/menu/menu_p_manure.png",
"res://assets/egret/assets/game/menu/menu_p_put_water.png",
"res://assets/egret/menu/menu_p_die_bug.png",
"res://assets/egret/menu/menu_p_die_grass.png",
"res://assets/egret/assets/game/menu/menu_p_steal.png",
"res://assets/egret/assets/game/menu/menu_p_put_bug.png",
"res://assets/egret/assets/game/menu/menu_p_put_grass.png",
"res://assets/egret/menu/plant_state1.png",
"res://assets/egret/menu/plant_state2.png",
"res://assets/egret/menu/plant_state3.png",
"res://assets/replacement/menu2/market.png",
"res://assets/replacement/panels/panel_content.png",
"res://assets/replacement/panels/panel_shell.png",
]
@export var main_scene: PackedScene
var _current_scene: Node
var _api_client: ApiClient
var _loading_layer: Control
var _loading_fill_clip: Control
var _loading_percent_label: Label
var _loading_fill_size := Vector2.ZERO
var _preloaded_resources: Array[Resource] = []
func _ready() -> void:
_build_loading_ui()
_set_loading_progress(0.0)
_api_client = ApiClientScript.new()
add_child(_api_client)
await get_tree().process_frame
_auto_login()
await _preload_startup_assets()
var player_data := await _auto_login()
if player_data.is_empty():
_set_loading_text("登录失败")
return
_set_loading_progress(1.0)
await get_tree().process_frame
_show_main_scene(player_data)
func _auto_login() -> void:
func _auto_login() -> Dictionary:
_set_loading_progress(0.86)
var login_path := str(ProjectSettings.get_setting("farm_game/api/login_path", "user/login"))
var result := await _api_client.post_json(login_path, {
"username": AUTO_USERNAME,
@ -29,13 +105,14 @@ func _auto_login() -> void:
result.get("status", 0),
result.get("game_status", "unknown")
])
return
return {}
_set_loading_progress(0.94)
var body = result.get("body", {})
var player_data: Dictionary = {}
if body is Dictionary and body.get("data", {}) is Dictionary:
player_data = body["data"]
_show_main_scene(player_data)
return player_data
func _show_main_scene(player_data: Dictionary) -> void:
@ -47,6 +124,8 @@ func _show_main_scene(player_data: Dictionary) -> void:
if main.has_method("setup"):
main.setup(player_data)
_show_scene(main)
_hide_loading_ui()
_preloaded_resources.clear()
func _show_scene(scene: Node) -> void:
@ -54,3 +133,177 @@ func _show_scene(scene: Node) -> void:
_current_scene.queue_free()
_current_scene = scene
add_child(_current_scene)
func _build_loading_ui() -> void:
if _loading_layer != null and is_instance_valid(_loading_layer):
return
_loading_layer = Control.new()
_loading_layer.name = "LoadingLayer"
_loading_layer.size = DESIGN_SIZE
_loading_layer.mouse_filter = Control.MOUSE_FILTER_STOP
add_child(_loading_layer)
var background := TextureRect.new()
background.name = "Background"
var background_texture := load(LOADING_BG_PATH) as Texture2D
background.texture = background_texture
var background_size := _fit_cover_size(background_texture.get_size(), DESIGN_SIZE)
background.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
background.stretch_mode = TextureRect.STRETCH_SCALE
background.position = (DESIGN_SIZE - background_size) * 0.5
background.size = background_size
background.mouse_filter = Control.MOUSE_FILTER_IGNORE
_loading_layer.add_child(background)
var bar_group := Control.new()
bar_group.name = "ProgressBar"
bar_group.position = LOADING_BAR_POSITION
bar_group.size = LOADING_BAR_SIZE
bar_group.mouse_filter = Control.MOUSE_FILTER_IGNORE
_loading_layer.add_child(bar_group)
var bar_bg := TextureRect.new()
bar_bg.name = "Bg"
bar_bg.texture = load(LOADING_BAR_BG_PATH) as Texture2D
bar_bg.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
bar_bg.stretch_mode = TextureRect.STRETCH_SCALE
bar_bg.size = LOADING_BAR_SIZE
bar_bg.mouse_filter = Control.MOUSE_FILTER_IGNORE
bar_group.add_child(bar_bg)
var fill_texture := load(LOADING_BAR_FILL_PATH) as Texture2D
var fill_rect := _loading_fill_rect()
_loading_fill_size = fill_rect.size
_loading_fill_clip = Control.new()
_loading_fill_clip.name = "FillClip"
_loading_fill_clip.position = fill_rect.position
_loading_fill_clip.size = Vector2(0.0, fill_rect.size.y)
_loading_fill_clip.clip_contents = true
_loading_fill_clip.mouse_filter = Control.MOUSE_FILTER_IGNORE
bar_group.add_child(_loading_fill_clip)
var fill := TextureRect.new()
fill.name = "Fill"
fill.texture = _make_atlas_texture(fill_texture, LOADING_FILL_SOURCE_REGION)
fill.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
fill.stretch_mode = TextureRect.STRETCH_SCALE
fill.size = fill_rect.size
fill.mouse_filter = Control.MOUSE_FILTER_IGNORE
_loading_fill_clip.add_child(fill)
_loading_percent_label = Label.new()
_loading_percent_label.name = "Percent"
_loading_percent_label.position = fill_rect.position
_loading_percent_label.size = fill_rect.size
_loading_percent_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
_loading_percent_label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
_loading_percent_label.mouse_filter = Control.MOUSE_FILTER_IGNORE
_loading_percent_label.add_theme_font_size_override("font_size", 24)
_loading_percent_label.add_theme_color_override("font_color", Color.WHITE)
_loading_percent_label.add_theme_color_override("font_outline_color", Color.html("#5b2a0e"))
_loading_percent_label.add_theme_constant_override("outline_size", 3)
bar_group.add_child(_loading_percent_label)
func _fit_cover_size(source_size: Vector2, target_size: Vector2) -> Vector2:
if source_size.x <= 0.0 or source_size.y <= 0.0:
return target_size
var scale := maxf(target_size.x / source_size.x, target_size.y / source_size.y)
return source_size * scale
func _loading_bar_scale() -> float:
return LOADING_BAR_SIZE.x / LOADING_BAR_SOURCE_SIZE.x
func _loading_fill_rect() -> Rect2:
var scale := _loading_bar_scale()
var slot_position := LOADING_BAR_SLOT_REGION.position * scale
var slot_size := LOADING_BAR_SLOT_REGION.size * scale
var fill_size := Vector2(
slot_size.x,
slot_size.x * LOADING_FILL_SOURCE_REGION.size.y / LOADING_FILL_SOURCE_REGION.size.x
)
var fill_position := slot_position + Vector2(0.0, (slot_size.y - fill_size.y) * 0.5)
return Rect2(fill_position, fill_size)
func _make_atlas_texture(texture: Texture2D, region: Rect2) -> Texture2D:
if texture == null:
return null
var atlas := AtlasTexture.new()
atlas.atlas = texture
atlas.region = region
return atlas
func _preload_startup_assets() -> void:
var total := maxi(STARTUP_ASSET_PATHS.size(), 1)
for index in range(STARTUP_ASSET_PATHS.size()):
var path := str(STARTUP_ASSET_PATHS[index])
await _preload_asset(path, index, total)
_set_loading_progress(0.84)
func _preload_asset(path: String, index: int, total: int) -> void:
if not ResourceLoader.exists(path):
push_warning("Startup asset missing: %s" % path)
_set_loading_progress(_asset_progress(index + 1.0, total))
return
var request_error := ResourceLoader.load_threaded_request(path)
if request_error != OK:
var resource := load(path) as Resource
if resource != null:
_preloaded_resources.append(resource)
_set_loading_progress(_asset_progress(index + 1.0, total))
await get_tree().process_frame
return
var progress: Array = []
while true:
progress.clear()
var status := ResourceLoader.load_threaded_get_status(path, progress)
var item_progress := 0.0
if not progress.is_empty():
item_progress = clampf(float(progress[0]), 0.0, 1.0)
_set_loading_progress(_asset_progress(float(index) + item_progress, total))
if status == ResourceLoader.THREAD_LOAD_LOADED:
var loaded_resource := ResourceLoader.load_threaded_get(path)
if loaded_resource is Resource:
_preloaded_resources.append(loaded_resource)
_set_loading_progress(_asset_progress(index + 1.0, total))
return
if status == ResourceLoader.THREAD_LOAD_FAILED or status == ResourceLoader.THREAD_LOAD_INVALID_RESOURCE:
push_warning("Startup asset failed to load: %s" % path)
_set_loading_progress(_asset_progress(index + 1.0, total))
return
await get_tree().process_frame
func _asset_progress(value: float, total: int) -> float:
return 0.05 + clampf(value / maxf(float(total), 1.0), 0.0, 1.0) * 0.79
func _set_loading_progress(progress: float) -> void:
var normalized := clampf(progress, 0.0, 1.0)
if _loading_fill_clip != null and is_instance_valid(_loading_fill_clip):
var fill_size := _loading_fill_size
if fill_size == Vector2.ZERO:
fill_size = _loading_fill_rect().size
_loading_fill_clip.size = Vector2(fill_size.x * normalized, fill_size.y)
if _loading_percent_label != null and is_instance_valid(_loading_percent_label):
_loading_percent_label.text = "%d%%" % roundi(normalized * 100.0)
func _set_loading_text(text: String) -> void:
if _loading_percent_label != null and is_instance_valid(_loading_percent_label):
_loading_percent_label.text = text
func _hide_loading_ui() -> void:
if _loading_layer == null or not is_instance_valid(_loading_layer):
return
_loading_layer.queue_free()
_loading_layer = null
_loading_fill_clip = null
_loading_percent_label = null

View File

@ -50,6 +50,11 @@ const EN := {
"施肥已经到达上限": "Fertilizing is already maxed",
"施肥时间错误": "Cannot fertilize now",
"土地等级不够,无法种植该植物": "Land level too low for this crop",
"体力不足": "Not enough stamina",
"Not enough stamina": "Not enough stamina",
"You did not participate in the pet duel and cannot steal.": "You did not participate in the pet duel and cannot steal.",
"Pet duel failed": "Pet duel failed",
"Pet defeated. Farm weakened.": "Pet defeated. Farm weakened.",
"物品": "Item",
"作物": "Crop",
"神秘种子": "Mystery Seed",

View File

@ -0,0 +1,35 @@
class_name StaminaRules
extends RefCounted
const DEFAULT_MAX := 20
const DEFAULT_RECOVER_AMOUNT := 2
const DEFAULT_RECOVER_INTERVAL := 3600
const DEFAULT_STEAL_COST := 10
static func snapshot(player_data: Dictionary) -> Dictionary:
var max_value := maxi(int(player_data.get("stamina_max", DEFAULT_MAX)), 1)
var value := clampi(int(player_data.get("stamina", max_value)), 0, max_value)
var next_recover_time := int(player_data.get("stamina_next_recover_time", 0))
var recover_amount := maxi(int(player_data.get("stamina_recover_amount", DEFAULT_RECOVER_AMOUNT)), 1)
var recover_interval := maxi(int(player_data.get("stamina_recover_interval", DEFAULT_RECOVER_INTERVAL)), 1)
if value < max_value and next_recover_time > 0:
var now := int(Time.get_unix_time_from_system())
if now >= next_recover_time:
var passed_intervals := 1 + int((now - next_recover_time) / recover_interval)
value = mini(max_value, value + passed_intervals * recover_amount)
return {
"value": value,
"max": max_value,
"recover_amount": recover_amount,
"recover_interval": recover_interval,
"steal_cost": steal_cost(player_data),
}
static func has_steal_cost(player_data: Dictionary) -> bool:
return int(snapshot(player_data).get("value", DEFAULT_MAX)) >= steal_cost(player_data)
static func steal_cost(player_data: Dictionary) -> int:
return maxi(int(player_data.get("stamina_cost_steal", DEFAULT_STEAL_COST)), 1)

View File

@ -0,0 +1 @@
uid://duy6ug4voihso

View File

@ -11,6 +11,8 @@ extends RefCounted
#
# 控制器只处理接口请求和业务回写,不持有场景节点。
const StaminaRulesScript := preload("res://scripts/domain/rules/stamina_rules.gd")
const ACTION_STEAL := "steal"
const ACTION_PUT_BUG := "put_bug"
const ACTION_PUT_GRASS := "put_grass"
@ -80,17 +82,32 @@ func interact_land(action: String) -> void:
if token.is_empty() or visited_friend_id <= 0:
_show_toast("登录已失效")
return
if interaction_type == INTERACTION_TYPE_STEAL and not StaminaRulesScript.has_steal_cost(_own_player_data()):
_show_toast("Not enough stamina")
return
var old_land := _land_data(position)
_set_busy(true)
var result: Dictionary = await _interaction_api.interact(token, visited_friend_id, position, interaction_type)
_set_busy(false)
if not result.get("ok", false):
var fail_data = _response_data(result, {})
if fail_data is Dictionary:
_sync_stamina(fail_data)
_show_toast(_response_status_text(result, "好友互动失败"))
return
var data = _response_data(result, {})
var response_data: Dictionary = data if data is Dictionary else {}
_sync_stamina(response_data)
var pet_battle_data := _pet_battle_data(response_data)
if not pet_battle_data.is_empty():
_sync_pet_battle(pet_battle_data)
if _pet_battle_triggered(pet_battle_data):
await _call_async("play_pet_battle_vs")
if interaction_type == INTERACTION_TYPE_STEAL and not _pet_battle_allows_steal(pet_battle_data):
_show_pet_battle_result(pet_battle_data)
return
var land_data: Dictionary = old_land.duplicate(true)
var returned_land = response_data.get("land", {})
if returned_land is Dictionary:
@ -160,11 +177,6 @@ func _apply_interaction_reward(interaction_type: int, response_data: Dictionary,
func _apply_steal_reward(response_data: Dictionary, old_land: Dictionary) -> void:
var deduct_gold := int(response_data.get("deduct_gold", 0))
if deduct_gold > 0:
_call("decrease_player_currency", [deduct_gold, 0])
_show_toast("偷菜不幸被狗狗发现,逃跑过程中遗落了%s金币" % deduct_gold)
return
var steal_count := int(response_data.get("steal_count", 0))
var crop_id := int(old_land.get("crop_id", 0))
if crop_id <= 0:
@ -182,6 +194,40 @@ func _apply_steal_reward(response_data: Dictionary, old_land: Dictionary) -> voi
_show_toast("偷取%sx%s" % [crop_name, steal_count])
func _sync_stamina(response_data: Dictionary) -> void:
var stamina_data = response_data.get("stamina", {})
if stamina_data is Dictionary:
_call("apply_player_stamina", [stamina_data])
func _sync_pet_battle(pet_battle_data: Dictionary) -> void:
_call("apply_pet_battle_data", [pet_battle_data])
func _pet_battle_data(response_data: Dictionary) -> Dictionary:
var data = response_data.get("pet_battle", {})
return data if data is Dictionary else {}
func _pet_battle_triggered(pet_battle_data: Dictionary) -> bool:
return int(pet_battle_data.get("triggered", 0)) == 1
func _pet_battle_allows_steal(pet_battle_data: Dictionary) -> bool:
return int(pet_battle_data.get("allow_steal", 1)) == 1
func _show_pet_battle_result(pet_battle_data: Dictionary) -> void:
var damage := int(pet_battle_data.get("damage", 0))
var result := str(pet_battle_data.get("result", ""))
if result == "damage":
_show_toast("Pet duel dealt %s damage" % damage)
elif result == "weak_opened":
_show_toast("Pet defeated. Farm weakened.")
else:
_show_toast("Pet duel failed")
func _selected_position() -> int:
return int(_call("selected_position", [], -1))
@ -194,6 +240,11 @@ func _player_id() -> int:
return int(_call("player_id", [], 0))
func _own_player_data() -> Dictionary:
var data = _call("own_player_data", [], {})
return data if data is Dictionary else {}
func _visited_friend_id() -> int:
return int(_call("visited_friend_id", [], 0))
@ -232,3 +283,10 @@ func _call(name: String, args: Array = [], fallback: Variant = null) -> Variant:
if not callable.is_valid():
return fallback
return callable.callv(args)
func _call_async(name: String, args: Array = [], fallback: Variant = null) -> Variant:
var callable: Callable = _callbacks.get(name, Callable())
if not callable.is_valid():
return fallback
return await callable.callv(args)

Some files were not shown because too many files have changed in this diff Show More