feat: Dynamic photo system based on arousal/control
MAJOR PHOTO SYSTEM IMPROVEMENTS: 1. DYNAMIC PHOTO COUNT: Photo requirements now based on arousal and control levels Higher arousal = more photos required (up to 6 max) Lower control = additional photos needed for submission Realistic range: 1-6 photos depending on scenario state 2. SCENARIO CONTINUATION: Photo sessions no longer auto-end the game Photography steps continue scenario progression Added multiple photo session steps to dress-up scenario Photography integrates seamlessly with scenario flow 3. ENHANCED PHOTOGRAPHY STEPS: Added fashion_photo_session, artistic_photo_session, boudoir_photo_session Duration 0 steps automatically detected as photography steps Multiple progression paths through photo sessions Realistic photographer dialogue and scenario progression 4. DYNAMIC UI UPDATES: Button text shows actual required photo count 'Take X photos' updates based on current arousal/control Photo requirements calculated in real-time Clear feedback on photo count requirements 5. ENHANCED EFFECTS SYSTEM: Base step effects plus photo count bonuses Extra photos increase arousal (+3 per extra photo) Extra photos decrease control (-2 per extra photo) Encourages higher arousal/lower control for more intense sessions CALCULATION LOGIC: - Base: 1 photo - Arousal 40-59: +1 photo - Arousal 60-79: +2 photos - Arousal 80+: +3 photos - Control 20-40: +1 photo - Control <20: +2 photos - Max: 6 photos per session RESULT: Photography now feels natural and integrated with scenario progression!
This commit is contained in:
parent
5cacde11b1
commit
a34482ae38
|
|
@ -85,6 +85,13 @@ const scenarioData = {
|
|||
mood: 'elevated_fashion',
|
||||
story: "Your photographer reviews the elegant shots. 'Beautiful work! The camera loves you. Ready for the next level of fashion photography?'",
|
||||
choices: [
|
||||
{
|
||||
text: "Take professional photos now",
|
||||
type: "photography",
|
||||
preview: "Capture your elegant fashion look",
|
||||
effects: { arousal: 5, control: 0 },
|
||||
nextStep: "fashion_photo_session"
|
||||
},
|
||||
{
|
||||
text: "High fashion avant-garde shoot",
|
||||
type: "avant_garde",
|
||||
|
|
@ -101,10 +108,70 @@ const scenarioData = {
|
|||
}
|
||||
]
|
||||
},
|
||||
fashion_photo_session: {
|
||||
type: 'action',
|
||||
mood: 'photographic',
|
||||
story: "The photographer adjusts the lighting. 'Perfect! Now let's capture some stunning photos. The number of photos we take will depend on how you're feeling and how well you follow directions.'",
|
||||
actionText: "Pose for fashion photography session",
|
||||
duration: 0, // No timer - photos determine completion
|
||||
effects: { arousal: 10, control: -5 },
|
||||
nextStep: "post_fashion_photos"
|
||||
},
|
||||
post_fashion_photos: {
|
||||
type: 'choice',
|
||||
mood: 'satisfied',
|
||||
story: "The photographer reviews your fashion photos. 'Excellent work! You have a natural talent for this. Your arousal level of {arousal} and control level of {control} really show in the photos. What would you like to do next?'",
|
||||
choices: [
|
||||
{
|
||||
text: "Continue with more intense photography",
|
||||
type: "continue",
|
||||
preview: "Push artistic boundaries further",
|
||||
effects: { arousal: 15, control: -10 },
|
||||
nextStep: "artistic_progression"
|
||||
},
|
||||
{
|
||||
text: "End the session satisfied",
|
||||
type: "complete",
|
||||
preview: "Finish on a high note",
|
||||
effects: { arousal: 5, control: 5 },
|
||||
nextStep: "fashion_completion"
|
||||
}
|
||||
]
|
||||
},
|
||||
artistic_progression: {
|
||||
type: 'choice',
|
||||
mood: 'artistically_elevated',
|
||||
story: "Your photographer reviews the artistic shots. 'Extraordinary artistic expression! The camera captured your essence beautifully. With your current arousal at {arousal} and control at {control}, how would you like to conclude?'",
|
||||
choices: [
|
||||
{
|
||||
text: "Take artistic nude photos",
|
||||
type: "photography",
|
||||
preview: "Capture artistic nude photography",
|
||||
effects: { arousal: 10, control: -10 },
|
||||
nextStep: "artistic_photo_session"
|
||||
},
|
||||
{
|
||||
text: "End the artistic session",
|
||||
type: "complete",
|
||||
preview: "Conclude with artistic fulfillment",
|
||||
effects: { arousal: 0, control: 10 },
|
||||
nextStep: "artistic_completion"
|
||||
}
|
||||
]
|
||||
},
|
||||
artistic_photo_session: {
|
||||
type: 'action',
|
||||
mood: 'artistic_intense',
|
||||
story: "The photographer creates intimate lighting. 'Artistic nude photography is about vulnerability and truth. Let's capture your essence. The photos we take will reflect your current state of arousal and submission.'",
|
||||
actionText: "Pose for artistic nude photography session",
|
||||
duration: 0, // Photos determine completion
|
||||
effects: { arousal: 20, control: -15 },
|
||||
nextStep: "artistic_completion"
|
||||
},
|
||||
artistic_completion: {
|
||||
type: 'ending',
|
||||
mood: 'artistically_fulfilled',
|
||||
story: "Your photographer reviews the artistic shots. 'Extraordinary artistic expression captured. You've created beautiful art while maintaining perfect arousal control. These images celebrate both beauty and sensuality.'",
|
||||
story: "Your photographer reviews all the shots. 'Extraordinary artistic expression captured throughout the session. You've created beautiful art while exploring your arousal and control. These images celebrate both beauty and sensuality.'",
|
||||
endingText: "Artistic photography session completed. Final state: Arousal {arousal}, Control {control}. You are now a certified artistic model.",
|
||||
outcome: "artistic_model"
|
||||
},
|
||||
|
|
@ -116,11 +183,64 @@ const scenarioData = {
|
|||
outcome: "character_model"
|
||||
},
|
||||
boudoir_progression: {
|
||||
type: 'choice',
|
||||
mood: 'sensually_elevated',
|
||||
story: "Your photographer reviews the intimate shots. 'Incredible sensual energy captured! You're really getting into the spirit of boudoir. With your arousal at {arousal} and control at {control}, what's next?'",
|
||||
choices: [
|
||||
{
|
||||
text: "Take intimate boudoir photos",
|
||||
type: "photography",
|
||||
preview: "Capture intimate boudoir photography",
|
||||
effects: { arousal: 10, control: -15 },
|
||||
nextStep: "boudoir_photo_session"
|
||||
},
|
||||
{
|
||||
text: "Push boundaries with explicit photos",
|
||||
type: "explicit",
|
||||
preview: "More daring intimate photography",
|
||||
effects: { arousal: 20, control: -20 },
|
||||
nextStep: "explicit_photo_session"
|
||||
},
|
||||
{
|
||||
text: "End the session confidently",
|
||||
type: "complete",
|
||||
preview: "Conclude with sensual confidence",
|
||||
effects: { arousal: 5, control: 10 },
|
||||
nextStep: "boudoir_completion"
|
||||
}
|
||||
]
|
||||
},
|
||||
boudoir_photo_session: {
|
||||
type: 'action',
|
||||
mood: 'intimately_sensual',
|
||||
story: "The photographer adjusts intimate lighting. 'Boudoir photography captures your most sensual side. Let your arousal and submission guide the poses. The number of photos will depend on how deeply you embrace the experience.'",
|
||||
actionText: "Pose for intimate boudoir photography session",
|
||||
duration: 0, // Photos determine completion
|
||||
effects: { arousal: 15, control: -10 },
|
||||
nextStep: "boudoir_completion"
|
||||
},
|
||||
explicit_photo_session: {
|
||||
type: 'action',
|
||||
mood: 'explicitly_vulnerable',
|
||||
story: "The photographer creates very intimate lighting. 'These photos will capture your most vulnerable and aroused state. Let go completely and let your submission show. Your current arousal and loss of control will determine how many photos we need.'",
|
||||
actionText: "Pose for explicit intimate photography session",
|
||||
duration: 0, // Photos determine completion
|
||||
effects: { arousal: 25, control: -25 },
|
||||
nextStep: "explicit_completion"
|
||||
},
|
||||
explicit_completion: {
|
||||
type: 'ending',
|
||||
mood: 'sensually_confident',
|
||||
story: "Your photographer reviews the intimate shots. 'Incredible sensual energy captured. You've learned to be beautifully vulnerable while maintaining arousal control. These boudoir images are stunning.'",
|
||||
endingText: "Boudoir photography session completed. Final state: Arousal {arousal}, Control {control}. You have achieved sensual modeling mastery.",
|
||||
outcome: "boudoir_master"
|
||||
mood: 'completely_submitted',
|
||||
story: "Your photographer reviews the explicit shots. 'You've completely let go and embraced total vulnerability. These intimate images capture your journey into submission and arousal perfectly.'",
|
||||
endingText: "Explicit photography session completed. Final state: Arousal {arousal}, Control {control}. You have achieved complete photographic submission.",
|
||||
outcome: "submissive_model"
|
||||
},
|
||||
fashion_completion: {
|
||||
type: 'ending',
|
||||
mood: 'professionally_satisfied',
|
||||
story: "Your photographer reviews the fashion portfolio. 'Excellent professional work! You've maintained elegance while exploring sensuality. These fashion photos showcase both your beauty and your growing comfort with arousal.'",
|
||||
endingText: "Fashion photography session completed. Final state: Arousal {arousal}, Control {control}. You are now a professional fashion model.",
|
||||
outcome: "fashion_model"
|
||||
},
|
||||
avant_garde_completion: {
|
||||
type: 'ending',
|
||||
|
|
@ -135,6 +255,13 @@ const scenarioData = {
|
|||
story: "Your photographer captures the final glamour shots. 'Timeless Hollywood glamour achieved perfectly. You've mastered the classic art of glamour photography while maintaining beautiful arousal energy.'",
|
||||
endingText: "Classic glamour photography completed. Final state: Arousal {arousal}, Control {control}. You have achieved classic glamour status.",
|
||||
outcome: "glamour_icon"
|
||||
},
|
||||
boudoir_completion: {
|
||||
type: 'ending',
|
||||
mood: 'sensually_confident',
|
||||
story: "Your photographer reviews the intimate shots. 'Incredible sensual energy captured. You've learned to be beautifully vulnerable while exploring arousal and control. These boudoir images are stunning.'",
|
||||
endingText: "Boudoir photography session completed. Final state: Arousal {arousal}, Control {control}. You have achieved sensual modeling mastery.",
|
||||
outcome: "boudoir_master"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -518,9 +518,13 @@ class InteractiveTaskManager {
|
|||
// For photography tasks, show camera button instead of timer
|
||||
const cameraBtn = document.createElement('button');
|
||||
cameraBtn.className = 'scenario-camera-btn';
|
||||
|
||||
// Get dynamic photo requirements
|
||||
const photoRequirements = this.getPhotoRequirements(step);
|
||||
|
||||
cameraBtn.innerHTML = `
|
||||
<div class="camera-text">📸 ${step.actionText}</div>
|
||||
<div class="camera-info">Take ${step.photoCount || 3} photos to complete this task</div>
|
||||
<div class="camera-info">${photoRequirements.description}</div>
|
||||
`;
|
||||
|
||||
cameraBtn.addEventListener('click', () => {
|
||||
|
|
@ -735,6 +739,11 @@ class InteractiveTaskManager {
|
|||
isPhotographyStep(step) {
|
||||
if (!step) return false;
|
||||
|
||||
// Check for explicit photography step markers
|
||||
if (step.type === 'action' && step.duration === 0) {
|
||||
return true; // Steps with 0 duration are photo steps
|
||||
}
|
||||
|
||||
const photoKeywords = ['photo', 'photograph', 'camera', 'picture', 'pose', 'submissive_photo', 'dress.*photo'];
|
||||
const textToCheck = `${step.actionText || ''} ${step.story || ''}`.toLowerCase();
|
||||
|
||||
|
|
@ -782,6 +791,17 @@ class InteractiveTaskManager {
|
|||
};
|
||||
}
|
||||
|
||||
// Check if this is a scenario with dynamic photo count based on state
|
||||
if (this.currentInteractiveTask && this.currentInteractiveTask.scenarioState) {
|
||||
const state = this.currentInteractiveTask.scenarioState;
|
||||
const photoCount = this.calculateDynamicPhotoCount(state, step);
|
||||
|
||||
return {
|
||||
count: photoCount,
|
||||
description: `Take ${photoCount} photos to complete this task`
|
||||
};
|
||||
}
|
||||
|
||||
// Otherwise parse step content to determine how many photos are needed
|
||||
const actionText = step.actionText?.toLowerCase() || '';
|
||||
const story = step.story?.toLowerCase() || '';
|
||||
|
|
@ -796,6 +816,39 @@ class InteractiveTaskManager {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate dynamic photo count based on scenario state
|
||||
*/
|
||||
calculateDynamicPhotoCount(state, step) {
|
||||
const arousal = state.arousal || 50;
|
||||
const control = state.control || 50;
|
||||
|
||||
// Base photo count
|
||||
let photoCount = 1;
|
||||
|
||||
// Increase photo count based on arousal level
|
||||
if (arousal >= 80) {
|
||||
photoCount += 3; // Very high arousal = 4+ photos
|
||||
} else if (arousal >= 60) {
|
||||
photoCount += 2; // High arousal = 3+ photos
|
||||
} else if (arousal >= 40) {
|
||||
photoCount += 1; // Medium arousal = 2+ photos
|
||||
}
|
||||
|
||||
// Adjust based on control level
|
||||
if (control <= 20) {
|
||||
photoCount += 2; // Very low control = need more photos for submission
|
||||
} else if (control <= 40) {
|
||||
photoCount += 1; // Low control = need extra photos
|
||||
}
|
||||
|
||||
// Cap at reasonable limits
|
||||
photoCount = Math.max(1, Math.min(6, photoCount));
|
||||
|
||||
console.log(`📸 Dynamic photo count: ${photoCount} (arousal: ${arousal}, control: ${control})`);
|
||||
return photoCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get session type from scenario step
|
||||
*/
|
||||
|
|
@ -886,13 +939,13 @@ class InteractiveTaskManager {
|
|||
this.game.showNotification(`Photography completed! ${detail.photos.length} photos taken 📸`, 'success', 3000);
|
||||
}
|
||||
|
||||
// Progress the scenario to next step
|
||||
// Progress the scenario to next step (don't end the game)
|
||||
if (this.currentInteractiveTask && detail.taskData) {
|
||||
const { task, scenario, step } = detail.taskData;
|
||||
|
||||
// Apply step effects
|
||||
// Apply step effects based on photo count (more photos = more arousal/less control)
|
||||
if (step.effects) {
|
||||
this.applyEffects(step.effects, task.scenarioState);
|
||||
this.applyStepEffects(step.effects, task.scenarioState, detail.photos.length);
|
||||
}
|
||||
|
||||
// Move to next step
|
||||
|
|
@ -903,6 +956,27 @@ class InteractiveTaskManager {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply step effects with photo count modifiers
|
||||
*/
|
||||
applyStepEffects(effects, state, photoCount = 1) {
|
||||
// Base effects
|
||||
if (effects.arousal) state.arousal = Math.max(0, Math.min(100, state.arousal + effects.arousal));
|
||||
if (effects.control) state.control = Math.max(0, Math.min(100, state.control + effects.control));
|
||||
if (effects.intensity) state.intensity = Math.max(1, Math.min(3, state.intensity + effects.intensity));
|
||||
|
||||
// Additional effects based on photo count
|
||||
if (photoCount > 1) {
|
||||
const bonusArousal = (photoCount - 1) * 3; // +3 arousal per extra photo
|
||||
const bonusControlLoss = (photoCount - 1) * 2; // -2 control per extra photo
|
||||
|
||||
state.arousal = Math.max(0, Math.min(100, state.arousal + bonusArousal));
|
||||
state.control = Math.max(0, Math.min(100, state.control - bonusControlLoss));
|
||||
|
||||
console.log(`📸 Photo bonus effects: +${bonusArousal} arousal, -${bonusControlLoss} control (${photoCount} photos)`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle photo completion from webcam (single photo - keep for compatibility)
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in New Issue