feat(world): add persistent citizen simulation with needs, jobs, and social features
- Adds Character model with survival needs (hunger, thirst, energy) and state machine - Implements city:tick world ticker for offline progression every minute - Adds city territory expansion and building construction system - Introduces job economy, inventory, and transaction audit trail - Adds social graph (friends, marriage, children) and character chat - Implements admin approval workflow for new registrations - Adds hospital admission system for traffic accidents - Includes comprehensive feature tests and world seeders
This commit is contained in:
Regular → Executable
+102
-1
@@ -103,5 +103,106 @@
|
||||
"city.chat_accepted": "Message sent to agent.",
|
||||
"city.chat_error": "Sorry, I can't reply right now. Please try again.",
|
||||
"city.chat_send": "Send",
|
||||
"city.chat_with": "Chatting with"
|
||||
"city.chat_with": "Chatting with",
|
||||
"city.clock": "Time",
|
||||
"city.weather": "Weather",
|
||||
"city.weather_clear": "Sunny",
|
||||
"city.weather_cloudy": "Cloudy",
|
||||
"city.weather_rain": "Rain",
|
||||
"city.weather_storm": "Storm",
|
||||
"city.vehicles_count": "vehicles",
|
||||
"city.pedestrians_count": "pedestrians",
|
||||
"auth.pending": "Your account is awaiting administrator approval.",
|
||||
"auth.pending_title": "Awaiting approval",
|
||||
"auth.pending_body": "Your registration was received. An administrator must approve your account before you can enter the city. You can close this page and try again later.",
|
||||
"admin.citizens.title": "Citizens",
|
||||
"admin.citizens.hint": "Approve pending accounts to create their city character.",
|
||||
"admin.citizens.name": "Name",
|
||||
"admin.citizens.status": "Status",
|
||||
"admin.citizens.character": "Character",
|
||||
"admin.citizens.actions": "Actions",
|
||||
"admin.citizens.approve": "Approve",
|
||||
"admin.citizens.approved": "Citizen approved and character created.",
|
||||
"admin.citizens.ban": "Ban",
|
||||
"admin.citizens.banned": "Citizen banned.",
|
||||
"admin.citizens.cannot_ban_self": "You cannot ban your own account.",
|
||||
"admin.cities.title": "Cities and territory",
|
||||
"admin.cities.hint": "Create new cities or expand existing territory (+40 per block).",
|
||||
"admin.cities.name": "City name",
|
||||
"admin.cities.create": "Create city",
|
||||
"admin.cities.created": "City created.",
|
||||
"admin.cities.bounds": "Bounds",
|
||||
"admin.cities.expansions": "Expansions",
|
||||
"admin.cities.expand": "Expand",
|
||||
"admin.cities.expanded": "Territory expanded.",
|
||||
"admin.cities.max_expansions": "Expansion limit reached.",
|
||||
"nav.citizens": "Citizens",
|
||||
"nav.cities": "Cities",
|
||||
"city.action_unknown": "Unknown action.",
|
||||
"city.action_ok": "Action completed.",
|
||||
"city.no_food": "You have no food in inventory.",
|
||||
"city.no_water": "You have no water in inventory.",
|
||||
"city.no_house": "You need a completed house to sleep.",
|
||||
"city.no_job": "You are unemployed. Apply for a job.",
|
||||
"city.no_school": "No school available in this city.",
|
||||
"city.job_other_city": "That job belongs to another city.",
|
||||
"city.job_education": "Not enough education for this job.",
|
||||
"city.no_money": "Not enough money.",
|
||||
"city.no_inventory": "Not enough inventory quantity.",
|
||||
"city.out_of_bounds": "Position outside city bounds.",
|
||||
"city.no_materials": "You need 50 materials to build.",
|
||||
"city.site_taken": "This lot is already occupied.",
|
||||
"city.build_started": "Construction started. The ticker finishes the house.",
|
||||
"city.social_unknown": "Unknown social action.",
|
||||
"city.social_self": "You cannot do that to yourself.",
|
||||
"city.social_exists": "Relationship already exists or is pending.",
|
||||
"city.social_friend_sent": "Friend request sent.",
|
||||
"city.social_friend_ok": "Friendship accepted.",
|
||||
"city.social_need_friend": "You must be accepted friends first.",
|
||||
"city.social_married": "You are already married.",
|
||||
"city.social_married_ok": "Marriage completed.",
|
||||
"city.social_need_spouse": "You must be married to have a child.",
|
||||
"city.social_child_ok": "A child was born in the city!",
|
||||
"city.chat_sent": "Message sent.",
|
||||
"city.hud_hunger": "Hunger",
|
||||
"city.hud_thirst": "Thirst",
|
||||
"city.hud_energy": "Energy",
|
||||
"city.hud_money": "Money",
|
||||
"city.hud_state": "State",
|
||||
"city.hud_education": "Education",
|
||||
"city.hud_inventory": "Inventory",
|
||||
"city.hud_jobs": "Jobs",
|
||||
"city.hud_actions": "Actions",
|
||||
"city.hud_social": "Social",
|
||||
"city.act_eat": "Eat",
|
||||
"city.act_drink": "Drink",
|
||||
"city.act_sleep": "Sleep",
|
||||
"city.act_wake": "Wake up",
|
||||
"city.act_work": "Work",
|
||||
"city.act_stop": "Stop",
|
||||
"city.act_study": "Study",
|
||||
"city.act_buy": "Buy kit",
|
||||
"city.act_sell_v": "Sell product",
|
||||
"city.act_build": "Build house (50 mat.)",
|
||||
"city.act_apply": "Apply",
|
||||
"city.act_friend": "Friend",
|
||||
"city.act_marry": "Marry",
|
||||
"city.act_child": "Child",
|
||||
"city.me": "My character",
|
||||
"city.citizens_near": "Citizens",
|
||||
"city.apply_job": "Apply for",
|
||||
"city.buy_hint": "Buys 1 food + 1 water + 10 materials",
|
||||
"city.hospital_hit": "You were hit by a vehicle! Hospitalized for 2 days.",
|
||||
"city.hospital_already": "You are already in the hospital.",
|
||||
"city.hospital_blocked": "You are hospitalized and cannot do that right now.",
|
||||
"city.hospital_bed": "Hospitalized",
|
||||
"city.hospital_released": "Hospital discharge: you are free to go.",
|
||||
"city.hospital_title": "Hospitalized",
|
||||
"city.hospital_left": "Discharge in",
|
||||
"city.audio": "Audio",
|
||||
"city.vol_master": "Master",
|
||||
"city.vol_music": "Music",
|
||||
"city.vol_sfx": "Effects",
|
||||
"city.mute": "Mute",
|
||||
"city.audio_hint": "Volume saved on this device."
|
||||
}
|
||||
|
||||
Regular → Executable
+102
-1
@@ -103,5 +103,106 @@
|
||||
"city.chat_accepted": "Mensaje enviado al agente.",
|
||||
"city.chat_error": "Lo siento, no puedo responder ahora. Inténtalo de nuevo.",
|
||||
"city.chat_send": "Enviar",
|
||||
"city.chat_with": "Chateando con"
|
||||
"city.chat_with": "Chateando con",
|
||||
"city.clock": "Hora",
|
||||
"city.weather": "Clima",
|
||||
"city.weather_clear": "Soleado",
|
||||
"city.weather_cloudy": "Nublado",
|
||||
"city.weather_rain": "Lluvia",
|
||||
"city.weather_storm": "Tormenta",
|
||||
"city.vehicles_count": "vehículos",
|
||||
"city.pedestrians_count": "peatones",
|
||||
"auth.pending": "Su cuenta espera la aprobación del administrador.",
|
||||
"auth.pending_title": "Esperando aprobación",
|
||||
"auth.pending_body": "Su registro fue recibido. Un administrador debe aprobar su cuenta antes de entrar a la ciudad. Puede cerrar esta página e intentar más tarde.",
|
||||
"admin.citizens.title": "Ciudadanos",
|
||||
"admin.citizens.hint": "Apruebe cuentas pendientes para crear su personaje en la ciudad.",
|
||||
"admin.citizens.name": "Nombre",
|
||||
"admin.citizens.status": "Estado",
|
||||
"admin.citizens.character": "Personaje",
|
||||
"admin.citizens.actions": "Acciones",
|
||||
"admin.citizens.approve": "Aprobar",
|
||||
"admin.citizens.approved": "Ciudadano aprobado y personaje creado.",
|
||||
"admin.citizens.ban": "Banear",
|
||||
"admin.citizens.banned": "Ciudadano baneado.",
|
||||
"admin.citizens.cannot_ban_self": "No puede banear su propia cuenta.",
|
||||
"admin.cities.title": "Ciudades y territorio",
|
||||
"admin.cities.hint": "Cree nuevas ciudades o expanda el territorio (+40 por cuadra).",
|
||||
"admin.cities.name": "Nombre de la ciudad",
|
||||
"admin.cities.create": "Crear ciudad",
|
||||
"admin.cities.created": "Ciudad creada.",
|
||||
"admin.cities.bounds": "Límites",
|
||||
"admin.cities.expansions": "Expansiones",
|
||||
"admin.cities.expand": "Expandir",
|
||||
"admin.cities.expanded": "Territorio expandido.",
|
||||
"admin.cities.max_expansions": "Límite de expansiones alcanzado.",
|
||||
"nav.citizens": "Ciudadanos",
|
||||
"nav.cities": "Ciudades",
|
||||
"city.action_unknown": "Acción desconocida.",
|
||||
"city.action_ok": "Acción realizada.",
|
||||
"city.no_food": "No tiene comida en el inventario.",
|
||||
"city.no_water": "No tiene agua en el inventario.",
|
||||
"city.no_house": "Necesita una casa terminada para dormir.",
|
||||
"city.no_job": "No tiene empleo. Solicite una vacante.",
|
||||
"city.no_school": "No hay escuela disponible en esta ciudad.",
|
||||
"city.job_other_city": "Esa vacante es de otra ciudad.",
|
||||
"city.job_education": "Educación insuficiente para esta vacante.",
|
||||
"city.no_money": "Dinero insuficiente.",
|
||||
"city.no_inventory": "Cantidad insuficiente en el inventario.",
|
||||
"city.out_of_bounds": "Posición fuera de los límites de la ciudad.",
|
||||
"city.no_materials": "Necesita 50 materiales para construir.",
|
||||
"city.site_taken": "Este terreno ya está ocupado.",
|
||||
"city.build_started": "Construcción iniciada. El ticker termina la casa.",
|
||||
"city.social_unknown": "Acción social desconocida.",
|
||||
"city.social_self": "No puede hacer eso consigo mismo.",
|
||||
"city.social_exists": "La relación ya existe o está pendiente.",
|
||||
"city.social_friend_sent": "Solicitud de amistad enviada.",
|
||||
"city.social_friend_ok": "Amistad aceptada.",
|
||||
"city.social_need_friend": "Primero deben ser amigos aceptados.",
|
||||
"city.social_married": "Ya está casado(a).",
|
||||
"city.social_married_ok": "Matrimonio realizado.",
|
||||
"city.social_need_spouse": "Debe estar casado(a) para tener un hijo.",
|
||||
"city.social_child_ok": "¡Nació un hijo en la ciudad!",
|
||||
"city.chat_sent": "Mensaje enviado.",
|
||||
"city.hud_hunger": "Hambre",
|
||||
"city.hud_thirst": "Sed",
|
||||
"city.hud_energy": "Energía",
|
||||
"city.hud_money": "Dinero",
|
||||
"city.hud_state": "Estado",
|
||||
"city.hud_education": "Educación",
|
||||
"city.hud_inventory": "Inventario",
|
||||
"city.hud_jobs": "Empleos",
|
||||
"city.hud_actions": "Acciones",
|
||||
"city.hud_social": "Social",
|
||||
"city.act_eat": "Comer",
|
||||
"city.act_drink": "Beber",
|
||||
"city.act_sleep": "Dormir",
|
||||
"city.act_wake": "Despertar",
|
||||
"city.act_work": "Trabajar",
|
||||
"city.act_stop": "Parar",
|
||||
"city.act_study": "Estudiar",
|
||||
"city.act_buy": "Comprar kit",
|
||||
"city.act_sell_v": "Vender producto",
|
||||
"city.act_build": "Construir casa (50 mat.)",
|
||||
"city.act_apply": "Solicitar",
|
||||
"city.act_friend": "Amistad",
|
||||
"city.act_marry": "Casarse",
|
||||
"city.act_child": "Hijo",
|
||||
"city.me": "Mi personaje",
|
||||
"city.citizens_near": "Ciudadanos",
|
||||
"city.apply_job": "Solicitar",
|
||||
"city.buy_hint": "Compra 1 comida + 1 agua + 10 materiales",
|
||||
"city.hospital_hit": "¡Te atropelló un vehículo! Internado en el hospital por 2 días.",
|
||||
"city.hospital_already": "Ya está internado en el hospital.",
|
||||
"city.hospital_blocked": "Está internado y no puede hacer eso ahora.",
|
||||
"city.hospital_bed": "Internado en el hospital",
|
||||
"city.hospital_released": "Alta del hospital: libre para salir.",
|
||||
"city.hospital_title": "Hospitalizado",
|
||||
"city.hospital_left": "Alta en",
|
||||
"city.audio": "Audio",
|
||||
"city.vol_master": "General",
|
||||
"city.vol_music": "Música",
|
||||
"city.vol_sfx": "Efectos",
|
||||
"city.mute": "Silenciar",
|
||||
"city.audio_hint": "Volumen guardado en este dispositivo."
|
||||
}
|
||||
|
||||
Regular → Executable
+102
-1
@@ -103,5 +103,106 @@
|
||||
"city.chat_accepted": "Mensagem enviada ao agente.",
|
||||
"city.chat_error": "Desculpe, não consegui responder agora. Tente novamente.",
|
||||
"city.chat_send": "Enviar",
|
||||
"city.chat_with": "Conversando com"
|
||||
"city.chat_with": "Conversando com",
|
||||
"city.clock": "Horário",
|
||||
"city.weather": "Clima",
|
||||
"city.weather_clear": "Ensolarado",
|
||||
"city.weather_cloudy": "Nublado",
|
||||
"city.weather_rain": "Chuva",
|
||||
"city.weather_storm": "Tempestade",
|
||||
"city.vehicles_count": "veículos",
|
||||
"city.pedestrians_count": "pedestres",
|
||||
"auth.pending": "Sua conta aguarda aprovação do administrador.",
|
||||
"auth.pending_title": "Aguardando aprovação",
|
||||
"auth.pending_body": "Seu cadastro foi recebido. Um administrador precisa aprovar sua conta antes que você possa entrar na cidade. Você pode fechar esta página e tentar novamente mais tarde.",
|
||||
"admin.citizens.title": "Cidadãos",
|
||||
"admin.citizens.hint": "Aprove contas pendentes para criar o personagem na cidade.",
|
||||
"admin.citizens.name": "Nome",
|
||||
"admin.citizens.status": "Status",
|
||||
"admin.citizens.character": "Personagem",
|
||||
"admin.citizens.actions": "Ações",
|
||||
"admin.citizens.approve": "Aprovar",
|
||||
"admin.citizens.approved": "Cidadão aprovado e personagem criado.",
|
||||
"admin.citizens.ban": "Banir",
|
||||
"admin.citizens.banned": "Cidadão banido.",
|
||||
"admin.citizens.cannot_ban_self": "Você não pode banir a própria conta.",
|
||||
"admin.cities.title": "Cidades e território",
|
||||
"admin.cities.hint": "Crie novas cidades ou expanda o território das existentes (+40 por quadra).",
|
||||
"admin.cities.name": "Nome da cidade",
|
||||
"admin.cities.create": "Criar cidade",
|
||||
"admin.cities.created": "Cidade criada.",
|
||||
"admin.cities.bounds": "Limites",
|
||||
"admin.cities.expansions": "Expansões",
|
||||
"admin.cities.expand": "Expandir",
|
||||
"admin.cities.expanded": "Território expandido.",
|
||||
"admin.cities.max_expansions": "Limite de expansões atingido.",
|
||||
"nav.citizens": "Cidadãos",
|
||||
"nav.cities": "Cidades",
|
||||
"city.action_unknown": "Ação desconhecida.",
|
||||
"city.action_ok": "Ação realizada.",
|
||||
"city.no_food": "Você não tem comida no inventário.",
|
||||
"city.no_water": "Você não tem água no inventário.",
|
||||
"city.no_house": "Você precisa de uma casa concluída para dormir.",
|
||||
"city.no_job": "Você não tem emprego. Candidate-se a uma vaga.",
|
||||
"city.no_school": "Não há escola disponível nesta cidade.",
|
||||
"city.job_other_city": "Esta vaga pertence a outra cidade.",
|
||||
"city.job_education": "Educação insuficiente para esta vaga.",
|
||||
"city.no_money": "Dinheiro insuficiente.",
|
||||
"city.no_inventory": "Quantidade insuficiente no inventário.",
|
||||
"city.out_of_bounds": "Posição fora dos limites da cidade.",
|
||||
"city.no_materials": "Você precisa de 50 materiais para construir.",
|
||||
"city.site_taken": "Este terreno já está ocupado.",
|
||||
"city.build_started": "Construção iniciada. O ticker conclui a casa.",
|
||||
"city.social_unknown": "Ação social desconhecida.",
|
||||
"city.social_self": "Você não pode fazer isso consigo mesmo.",
|
||||
"city.social_exists": "Relação já existe ou está pendente.",
|
||||
"city.social_friend_sent": "Pedido de amizade enviado.",
|
||||
"city.social_friend_ok": "Amizade aceita.",
|
||||
"city.social_need_friend": "Vocês precisam ser amigos aceitos.",
|
||||
"city.social_married": "Você já é casado(a).",
|
||||
"city.social_married_ok": "Casamento realizado.",
|
||||
"city.social_need_spouse": "Você precisa ser casado(a) para ter um filho.",
|
||||
"city.social_child_ok": "Nasceu um filho na cidade!",
|
||||
"city.chat_sent": "Mensagem enviada.",
|
||||
"city.hud_hunger": "Fome",
|
||||
"city.hud_thirst": "Sede",
|
||||
"city.hud_energy": "Energia",
|
||||
"city.hud_money": "Dinheiro",
|
||||
"city.hud_state": "Estado",
|
||||
"city.hud_education": "Educação",
|
||||
"city.hud_inventory": "Inventário",
|
||||
"city.hud_jobs": "Empregos",
|
||||
"city.hud_actions": "Ações",
|
||||
"city.hud_social": "Social",
|
||||
"city.act_eat": "Comer",
|
||||
"city.act_drink": "Beber",
|
||||
"city.act_sleep": "Dormir",
|
||||
"city.act_wake": "Acordar",
|
||||
"city.act_work": "Trabalhar",
|
||||
"city.act_stop": "Parar",
|
||||
"city.act_study": "Estudar",
|
||||
"city.act_buy": "Comprar kit",
|
||||
"city.act_sell_v": "Vender produto",
|
||||
"city.act_build": "Construir casa (50 mat.)",
|
||||
"city.act_apply": "Candidate-se",
|
||||
"city.act_friend": "Amizade",
|
||||
"city.act_marry": "Casar",
|
||||
"city.act_child": "Filho",
|
||||
"city.me": "Meu personagem",
|
||||
"city.citizens_near": "Cidadãos",
|
||||
"city.apply_job": "Aplicar para",
|
||||
"city.buy_hint": "Compra 1 comida+1 água+10 materiais",
|
||||
"city.hospital_hit": "Você foi atropelado! Internado no hospital por 2 dias.",
|
||||
"city.hospital_already": "Você já está internado no hospital.",
|
||||
"city.hospital_blocked": "Você está internado no hospital e não pode fazer isso agora.",
|
||||
"city.hospital_bed": "Internado no hospital",
|
||||
"city.hospital_released": "Alta do hospital: você foi liberado.",
|
||||
"city.hospital_title": "Hospitalizado",
|
||||
"city.hospital_left": "Alta em",
|
||||
"city.audio": "Áudio",
|
||||
"city.vol_master": "Geral",
|
||||
"city.vol_music": "Música",
|
||||
"city.vol_sfx": "Efeitos",
|
||||
"city.mute": "Mudo",
|
||||
"city.audio_hint": "Volume salvo neste dispositivo."
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user