| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231 |
- using UnityEngine;
- using System;
- /// <summary>
- /// Base class for all travel events that can occur during journeys
- /// </summary>
- [Serializable]
- public abstract class TravelEvent : ScriptableObject
- {
- [Header("Basic Event Info")]
- public string eventName;
- [TextArea(3, 6)]
- public string eventDescription;
- public EventType eventType;
- public EventRarity rarity = EventRarity.Common;
- [Header("Terrain Preferences")]
- [Range(0f, 1f)]
- public float plainsChance = 0.5f;
- [Range(0f, 1f)]
- public float forestChance = 0.5f;
- [Range(0f, 1f)]
- public float mountainChance = 0.5f;
- [Range(0f, 1f)]
- public float roadChance = 0.5f;
- [Range(0f, 1f)]
- public float riverChance = 0.5f;
- [Range(0f, 1f)]
- public float lakeChance = 0.5f;
- [Range(0f, 1f)]
- public float oceanChance = 0.5f;
- [Header("Feature Preferences")]
- [Range(0f, 1f)]
- public float townChance = 0.5f;
- [Range(0f, 1f)]
- public float villageChance = 0.5f;
- [Range(0f, 1f)]
- public float bridgeChance = 0.5f;
- [Range(0f, 1f)]
- public float tunnelChance = 0.5f;
- [Range(0f, 1f)]
- public float ferryChance = 0.5f;
- [Header("Timing")]
- public bool canOccurMultipleTimes = true;
- public float cooldownDays = 0f; // Days before this event can occur again
- /// <summary>
- /// Calculate the chance of this event occurring on a specific tile
- /// </summary>
- public virtual float GetEventChance(MapTile tile)
- {
- float baseChance = GetBaseChanceForRarity();
- float terrainModifier = GetTerrainModifier(tile.terrainType);
- float featureModifier = GetFeatureModifier(tile.featureType);
- return baseChance * terrainModifier * featureModifier;
- }
- /// <summary>
- /// Execute the event - must be implemented by derived classes
- /// </summary>
- public abstract EventResult ExecuteEvent(TravelEventContext context);
- /// <summary>
- /// Check if this event can occur given the current context
- /// </summary>
- public virtual bool CanOccur(TravelEventContext context)
- {
- // Check cooldown
- if (!canOccurMultipleTimes && context.eventHistory.HasOccurred(this))
- {
- return false;
- }
- if (cooldownDays > 0f && context.eventHistory.GetTimeSinceLastOccurrence(this) < cooldownDays)
- {
- return false;
- }
- return true;
- }
- private float GetBaseChanceForRarity()
- {
- return rarity switch
- {
- EventRarity.VeryCommon => 0.25f,
- EventRarity.Common => 0.15f,
- EventRarity.Uncommon => 0.08f,
- EventRarity.Rare => 0.04f,
- EventRarity.VeryRare => 0.02f,
- EventRarity.Legendary => 0.005f,
- _ => 0.1f
- };
- }
- private float GetTerrainModifier(TerrainType terrain)
- {
- return terrain switch
- {
- TerrainType.Plains => plainsChance,
- TerrainType.Forest => forestChance,
- TerrainType.Mountain => mountainChance,
- TerrainType.River => riverChance,
- TerrainType.Lake => lakeChance,
- TerrainType.Ocean => oceanChance,
- TerrainType.ForestRiver => forestChance * riverChance, // Hybrid terrain
- _ => 0.5f
- };
- }
- private float GetFeatureModifier(FeatureType feature)
- {
- return feature switch
- {
- FeatureType.Road => roadChance,
- FeatureType.Town => townChance,
- FeatureType.Village => villageChance,
- FeatureType.Bridge => bridgeChance,
- FeatureType.Tunnel => tunnelChance,
- FeatureType.Ferry => ferryChance,
- FeatureType.None => 1f, // No modifier for no feature
- _ => 0.5f
- };
- }
- }
- [Serializable]
- public enum EventType
- {
- Combat, // Battle encounters
- Trading, // Merchant encounters
- Discovery, // Finding items/resources
- Social, // Meeting NPCs, getting information
- Hazard, // Environmental dangers
- Rest, // Camping, healing opportunities
- Mystery // Strange occurrences, puzzles
- }
- [Serializable]
- public enum EventRarity
- {
- VeryCommon, // 25% base chance
- Common, // 15% base chance
- Uncommon, // 8% base chance
- Rare, // 4% base chance
- VeryRare, // 2% base chance
- Legendary // 0.5% base chance
- }
- /// <summary>
- /// Result of executing a travel event
- /// </summary>
- [Serializable]
- public class EventResult
- {
- public bool eventOccurred = true;
- public bool shouldStopTravel = false;
- public bool startBattle = false;
- public bool openTrading = false;
- public string resultMessage = "";
- // Resource changes
- public int goldChange = 0;
- public int foodChange = 0;
- public int healthChange = 0;
- // Battle setup (if startBattle is true)
- public BattleEventData battleData;
- // Trading setup (if openTrading is true)
- public TradingEventData tradingData;
- public EventResult(string message)
- {
- resultMessage = message;
- }
- public static EventResult NoEvent()
- {
- return new EventResult("") { eventOccurred = false };
- }
- public static EventResult SimpleBattle(string message, int enemyCount, string enemyType = "Bandit")
- {
- return new EventResult(message)
- {
- shouldStopTravel = true,
- startBattle = true,
- battleData = new BattleEventData
- {
- enemyCount = enemyCount,
- enemyType = enemyType
- }
- };
- }
- public static EventResult SimpleTrading(string message, string merchantType = "Traveling Merchant")
- {
- return new EventResult(message)
- {
- shouldStopTravel = true,
- openTrading = true,
- tradingData = new TradingEventData
- {
- merchantType = merchantType,
- hasRareItems = UnityEngine.Random.value < 0.3f
- }
- };
- }
- }
- [Serializable]
- public class BattleEventData
- {
- public int enemyCount = 1;
- public string enemyType = "Bandit";
- public string battleDescription = "";
- [Tooltip("Reference to the actual enemy data asset (safer than string names)")]
- public EnemyCharacterData enemyCharacterData = null;
- }
- [Serializable]
- public class TradingEventData
- {
- public string merchantType = "Traveling Merchant";
- public bool hasRareItems = false;
- public float priceModifier = 1f; // 1f = normal prices, 0.8f = 20% discount, etc.
- }
|