Added phone item

This commit is contained in:
2026-05-31 21:54:33 +03:00
parent f94dce1bfb
commit 65bd932473
13 changed files with 229 additions and 32 deletions
+8 -5
View File
@@ -80,7 +80,7 @@ State of the C++ module as of the latest pass. File references use `Source/Naked
### 1.1 Implemented
- **Item identity scaffold (GDD §6.1)** — `Items/ItemInstance.h` defines `UItemInstance` as an abstract `UObject` with a stable `FGuid InstanceID`, auto-assigned in `PostInitProperties` and refreshed in `PostDuplicate`. `Clothing/ClothingItemInstance.h` inherits from it and holds per-instance `Condition`, a pointer to the immutable `UClothingItem` definition, and a `StoredItems` array for container slots.
- **Item identity scaffold (GDD §6.1)** — `Items/ItemInstance.h` defines `UItemInstance` as an abstract `UObject` with a stable `FGuid InstanceID`, auto-assigned in `PostInitProperties` and refreshed in `PostDuplicate`. `Clothing/ClothingItemInstance.h` inherits from it and holds per-instance `Condition`, and a pointer to the immutable `UClothingItem` definition. (The legacy per-garment `StoredItems` container array was removed per GDD §27 — only bags hold items; the item list will live on a future bag `UItemInstance` subclass.)
- **Definition / instance split (GDD §6.1, §17.4)** — `Clothing/ClothingItem.h` is the immutable `UPrimaryDataAsset` definition. Most fields align with the current GDD: `Coverage`, `CanExpose`, `ContainerSlots` (typed S/M/L via `EGarmentContainerSlotType` + `FGarmentContainerSlot`), `ProgressionPath`, plus rendering data (`SkeletalMesh`, `Materials`, `StaticMesh`). The `IsUnderwear` and `IsRestrictive` fields also exist but **no longer match the locked spec** (§20 #20, §20 #21) — see §1.4 for the removal / migration work.
- **Progression path enum (GDD §5)** — `Progression/ProgressionPath.h` defines `EProgressionPath { None, Slut, Exhibitionist, Slave }`. Used on `UClothingItem::ProgressionPath`.
- **Body-part enum (GDD §6.3)** — `Clothing/BodyPart.h` defines `EBodyPart { None, Boobs, Ass, Genitals }`. Used on `UClothingItem::CanExpose`.
@@ -123,7 +123,10 @@ State of the C++ module as of the latest pass. File references use `Source/Naked
- **NPC types (§10.2)** — only one generic `ANPC` class. No Walker / Stalker / Blogger / Snitch / Harasser, no Police, no Wanted-poster mechanic.
- **Calendar, rent, sleep (§2.4, §15.2)** — **core landed (Phase 5):** `UTimeOfDaySubsystem` (`Global/TimeOfDaySubsystem`) owns the clock, rolls the calendar at 04:00, fires `OnHourChanged`/`OnDayChanged`/`OnPhaseChanged`, charges `WEEKLY_RENT` every 7th roll with immediate eviction via `OnCampaignEnded(Evicted)`, and exposes `Sleep()`/`SkipToNextMorning()`/`SkipTime()`. Mission refresh moved to `GameMode::HandleDayChanged`. The apartment **bed interactable** (`Interactables/Bed`) is in — interacting calls `USessionLossResolver::ResolveSleepLoss()` (outside-clothing loss) then `UTimeOfDaySubsystem::Sleep()`, with a BP `PlaySleepTransition` fade hook. **Still to do:** rewire the UltraDynamicSky actor to follow `SetCurrentTime` (and stop the old BP clock from advancing independently — otherwise the clock double-advances); the §4.4 cutscenes calling into the new skip API; the ending/eviction screen reacting to `OnCampaignEnded`; daily follower deposit is stubbed (no follower count until Phase 8); phone charge-to-100% on sleep stubbed (Phase 9). `WEEKLY_RENT` is a §21 tuning placeholder.
- **Item-world AActor (§6.1)** — no `AItemActor` / `AClothingPickup` base.
- **Bag inventory (§6.4)** — absent.
- **Bag inventory (§6.4)** — absent. Per the locked model (GDD §6.4 / §27): bags are the **only** container, capacity is a flat per-bag **item count** (no S/M/L size classes), and any item type can be stored. The container concept is removed from clothing — the per-garment `UClothingItemInstance::StoredItems` array has been deleted; the item list will live on a future bag `UItemInstance` subclass.
- **Dedicated carry slots (§6.5 / §27)** — `Phone`, `Bag`, `Key` are single-item slots on the player, separate from the 18 clothing/accessory/restraint/toy slots and from the old (removed) hand slot. Deliberately **not** in `EClothingSlotType` (it's clothing-named); each carry slot is modeled independently.
- **Phone slot + phone item — done (data + slot).** `Phone/PhoneItemDefinition` (`UItemDefinition`) + `Phone/PhoneItemInstance` (`UItemInstance`, per-instance `BatteryPercent` in `FPhoneInstanceState`). The slot lives on `UInventorySubsystem`: `EquippedPhone`, `GetEquippedPhone()`, `OnPhoneChanged`, hot-swap on equip (§9.9). `EquipFromWardrobe`/`UnequipToWardrobe` route phones to `EquipPhone`/`UnequipPhone`; the equipped phone persists via the shared `EquippedItems` save bucket and re-hydrates in `EnsureHydrated` (clothing in that bucket is still hydrated by `ClothingManager`). **Follow-ups:** no phone-slot UI widget yet and the wardrobe list (`WardrobeInventoryWidget`) renders clothing only, so a phone is equippable from code / `StartingItems` but not yet via the wardrobe screen; battery drain/charge is Phase 8/9.
- **Bag + key slots — pending** (deferred with the bag system, see above).
- **Theft (§6.3.4)** — new chance-based model (per-tick `P_theft` after grace period) not implemented. No theft timer / probability code at all.
- **Rip & tear (§6.3.5)** — absent. `UClothingItemInstance::Condition` is read-only in code; no decrement source.
- **Expose action (§6.3.6)** — `CanExpose` data exists on the definition; runtime action absent.
@@ -345,12 +348,12 @@ Phase estimates are rough and assume one engineer. Adjust as we go.
### Phase 8 — Phone + forum UI + battery + livestream (34 weeks)
- Phone as an `AItemActor` (Phase 2 base) with hand / pocket / bag location semantics (§9).
- Phone as an `AItemActor` (Phase 2 base). Usable from the dedicated **phone slot** (§6.5 / §27); placed-in-world streaming exception still applies (§9.1.1).
- `PhoneSubsystem` (§17.1): tickable; owns battery %, active app, livestream session lifecycle, charger interaction.
- **Battery (§9.8):**
- Passive base drain + per-app multiplier (Forum/Bank/Maps/Health Tracker/Gallery ~1×, back-camera ~3×, livestream ~5×). Livestream stacks on top of foreground app.
- Apartment charger interactable: place phone on it, recharges at a fixed rate.
- **Portable powerbank**: consumable `UItemInstance` purchasable at Convenience Store (§10.4). Single-use, restores fixed % when consumed. S-size container slot.
- **Portable powerbank**: consumable `UItemInstance` purchasable at Convenience Store (§10.4). Single-use, restores fixed % when consumed. Stored in the equipped bag like any other item (no size classes, §6.4 / §27).
- **Hard shutdown at 0%**: all apps lock; livestream ends and deposits earnings-to-date; future tips forfeit. Phone wakes from a consumed powerbank.
- **Sleep auto-charges to 100%** (voluntary or energy-zero cutscene).
- Battery % is part of the phone's `UItemInstance` state; persists across saves.
@@ -385,7 +388,7 @@ Phase estimates are rough and assume one engineer. Adjust as we go.
### Phase 10 — Remaining systems & polish
- Bag inventory (§6.4) — uses Phase 2's `AItemActor` for world placement.
- Bag inventory (§6.4) — uses Phase 2's `AItemActor` for world placement. Bag `UItemInstance` subclass holds a count-limited list of any `UItemInstance` (no size classes); add the `Phone` / `Bag` / `Key` carry slots (§6.5 / §27).
- **Food (§6.7):**
- Implement the locked vocabulary: 2 instant effects (energy restore, lust decrease) + 4 timed buffs (stamina regen +, max stamina +, embarrassment-gain resistance, lust-gain resistance).
- Universal built-in effect: every food restores effective max energy to base max (hunger reset; §7.3 hookpoint from Phase 4).