martes, 7 de febrero de 2017
Pack de mapas para M&BW
Hace en torno a un año participamos con los chicos de la conocida comunidad para M&BW multijugador TrollGame Comunity en el diseño de varios mapas multijugador basados en el modulo NeoGK. El resultado se puede ver en vivo ingresando en alguno de sus servidores oficiales de juego. Los mapas son de uso público y otras comunidades los han incluido también en sus propios servidores, en algunos casos realizando sus propias modificaciones.
| Imágenes de ejemplo |
Sinceros agradecimientos a TrollGame Community.
A continuación compartimos todos los mapas que hemos publicado.
A continuación compartimos todos los mapas que hemos publicado.
jueves, 6 de octubre de 2016
Reclutar unidades en otros asentamientos de M&BW
Este tutorial contiene el código necesario para agregar nuevos menús de reclutamiento en Mount&Blade Warband, permitiendo así reclutar tropas en otros asentamientos como castillos y ciudades, no solo en aldeas.
Antecedentes
En la versión nativa del juego solo es posible alistar unidades a nuestro ejercito desde las aldea; sin embargo, algunos modders prefieren poder disponer de la posibilidad de reclutar en otros asentamientos y según sus propias condiciones.
*Notas:
-El código aquí presente fue desarrollado por JBJ y está incluido en la programación de Hispania 1200, en este tutorial se dan los pasos para incluirlo con éxito en otros mods.
-Este tutorial no trata sobre el aprendizaje de la programación del MS; es más, fragmentos del código, en especial los scripts, deberán ser modificados por el interesado para poder adaptarlos a su mod, por esta razón hay que tener nociones básicas de programación con el MS si se desea implementar con éxito el código en un mod.
-Este tutorial no trata sobre el aprendizaje de la programación del MS; es más, fragmentos del código, en especial los scripts, deberán ser modificados por el interesado para poder adaptarlos a su mod, por esta razón hay que tener nociones básicas de programación con el MS si se desea implementar con éxito el código en un mod.
Programación
Este es un tutorial sencillo en el que solo necesitaremos trabajar con la programación y necesitas conocer el 'Module System', ver aquí o aquí, para poder avanzar.
Descripción del proyecto
Se permitirá reclutar un tipo de unidad en ciudades y castillos, además de dos tipos en castillos de propiedad. La disponibilidad y el número de reclutas seguirá las mismas normas que el reclutamiento en aldeas y en los castillos dependerá también de la relación del jugador con el dueño del mismo. El tipo de recluta y el coste unitario será a nuestro antojo.
Solución paso a paso
Directamente nos vamos al MS y comenzamos añadiendo y modificando código en varios de sus archivos:
-En module_menus.py
Buscamos un buen lugar para colocar las nuevas opciones que aparecerán en los menús principales de los castillos y las ciudades. El lugar elegido será sobre la opción 'Salir' de dichos menús, puedes encontrar esta opción en el código como:
Ahora los submenus y sus acciones. Un buen lugar para colocarlo es tras el submenú de reclutar en las aldeas, puedes encontrarlo buscando este código:
En Hispania 1200 se contempla que la cantidad de tropas disponible a reclutar en un castillo dependa de la relación del dueño del castillo con el jugador, al igual que en las ciudades y aldeas depender de la relación con el populacho.
En los castillos debemos tener una relación >=1 para poder reclutar.
Modificaremos el menú del castillo para que en la parte superior informe de la relación con el dueño a semejanza con lo que sucede en aldeas y ciudades.
Para esto debemos ir a las operaciones que se ejecutan al inicio del menú "town", exactamente tras el siguiente código:
-En module_string.py
Como en el código anterior hicimos uso de una cadena, ahora debemos declararla al final del documento y antes del cierre global:
-En module_constant.py
Estos menús que hemos crado necesitan de un slot al que llamaremos slot_faction_tier_6_troop que contenga para cada facción el tipo de tropas que se reclutarán en el asentamiento.
Un buen sitio para colocarlo es tras el slot
Debemos buscar también:
-En module_script.py
Estos slots deben ser inicializados y para ello buscamos la línea de código:
Debemos añadir entonces una nueva línea tras de cada slot_faction_tier_5_troop, una por cultura de la forma:
Donde A es el identificador de la cultura y B el identificador de la unidad a reclutar.
Tambien debemos buscar la línea:
Para que todo funcione correctamente es necesario modificar algunos scripts por defecto del juego, el primero será script_village_recruit_volunteers_recruit
Tiene bastantes pequeñas modificaciones así que lo mejor es sustituirlo entero por esta nueva versión:
Otro script a modificar es el script_game_start , en concreto buscamos las siguientes líneas de código:
Ahora debemos ir al script_change_player_relation_with_center, casi al final del mismo se encuentra esta línea:
En el scriptscript_update_volunteer_troops_in_village
hay que hacer muchas modificaciones de nuevo, así que lo sustituiremos entero:
Por último añadimos este script al final del documento:
Sino olvidé nada esto debe funcionar perfectamente, recuerda que este código está incluido en el MS liberado junto a Hispania 1200, con el tag 'reclutamiento', puede encontrar fácilmente el código referente a este tema. Los nuevos textos que hemos incluido están en inglés, si quieres traducirlos a otro idioma debes generar nuevos documentos de idiomas y traducir las frases.
"town_leave",[],"Leave...",En este lugar definimos los nuevos menús que hemos programado:
##########################################################
#hispania 1200, reclutamiento
("Mrecruit_volunteers_town", #hispania 1200, reclutamiento en ciudad
[
(party_slot_eq,"$current_town",slot_party_type, spt_town),
(call_script, "script_cf_village_recruit_volunteers_cond"),
]
,"Recruit Volunteers.",
[
(try_begin),
(call_script, "script_cf_enter_center_location_bandit_check"),
(else_try),
(jump_to_menu, "mnu_recruit_volunteers_town"),
(try_end),
]),
("Mrecruit_volunteers_castle", #hispania 1200, reclutamiento en castillo
[
(party_slot_eq,"$current_town",slot_party_type, spt_castle),
(party_slot_ge,"$current_town",slot_center_player_relation,1), #El juego por defecto desactiva los menus de reclutamiento para relaciones menores a 0 pero no para iguales a 0, en el castillo este caso tambien debe deshabilitarse.
(call_script, "script_cf_village_recruit_volunteers_cond"),
]
,"Recruit Volunteers.",
[
(jump_to_menu, "mnu_recruit_volunteers_castle"),
]),
##########################################################
Ahora los submenus y sus acciones. Un buen lugar para colocarlo es tras el submenú de reclutar en las aldeas, puedes encontrarlo buscando este código:
"recruit_volunteers",0,Este es el nuevo código:
##################################################
#hispania 1200, reclutamiento
("recruit_volunteers_town",0, #hispania 1200, reclutamiento en ciudad
"{s18}",
"none",
[
(party_get_slot, ":volunteer_troop", "$current_town", slot_center_volunteer_troop_type),
(party_get_slot, ":volunteer_amount", "$current_town", slot_center_volunteer_troop_amount),
(party_get_free_companions_capacity, ":free_capacity", "p_main_party"),
(store_troop_gold, ":gold", "trp_player"),
(store_div, ":gold_capacity", ":gold", 25),#25 denars per man
(assign, ":party_capacity", ":free_capacity"),
(val_min, ":party_capacity", ":gold_capacity"),
(try_begin),
(gt, ":party_capacity", 0),
(val_min, ":volunteer_amount", ":party_capacity"),
(try_end),
(assign, reg5, ":volunteer_amount"),
(assign, reg7, 0),
(try_begin),
(gt, ":volunteer_amount", ":gold_capacity"),
(assign, reg7, 1), #not enough money
(try_end),
(try_begin),
(eq, ":volunteer_amount", 0),
(str_store_string, s18, "@No one here seems to be willing to join your party."),
(else_try),
(store_mul, reg6, ":volunteer_amount", 25),#25 denars per man
(str_store_troop_name_by_count, s3, ":volunteer_troop", ":volunteer_amount"),
(try_begin),
(eq, reg5, 1),
(str_store_string, s18, "@One {s3} volunteers to follow you."),
(else_try),
(str_store_string, s18, "@{reg5} {s3} volunteer to follow you."),
(try_end),
(set_background_mesh, "mesh_pic_recruits"),
(try_end),
],
[
("continue_not_enough_gold",
[
(eq, reg7, 1),
],
"I don't have enough money...",
[
(jump_to_menu,"mnu_town"),
]),
("continue",
[
(eq, reg7, 0),
(eq, reg5, 0), #Bugfix (le, reg5, 0),
], #noone willing to join
"Continue...",
[
(party_set_slot, "$current_town", slot_center_volunteer_troop_amount, -1),
(jump_to_menu,"mnu_town"),
]),
("recruit_them",
[
(eq, reg7, 0),
(gt, reg5, 0),
],
"Recruit them ({reg6} denars).",
[
(call_script, "script_town_recruit_volunteers_recruit"),
(jump_to_menu,"mnu_town"),
]),
("forget_it",
[
(eq, reg7, 0),
(gt, reg5, 0),
],
"Forget it.",
[
(jump_to_menu,"mnu_town"),
]),
],
),
("recruit_volunteers_castle",0, #hispania 1200, reclutamiento en castillo, caballeria y nobles
"{s18}",
"none",
[
#primer tipo de unidad, caballeria
(party_get_slot, ":volunteer_troop", "$current_town", slot_center_volunteer_troop_type),
(party_get_slot, ":volunteer_amount", "$current_town", slot_center_volunteer_troop_amount),
(party_get_free_companions_capacity, ":free_capacity", "p_main_party"),
(store_troop_gold, ":gold", "trp_player"),
(store_div, ":gold_capacity", ":gold", 100),#50 denars per man
(assign, ":party_capacity", ":free_capacity"),
(val_min, ":party_capacity", ":gold_capacity"),
(try_begin),
(gt, ":party_capacity", 0),
(val_min, ":volunteer_amount", ":party_capacity"),
(try_end),
(assign, reg5, ":volunteer_amount"),
(assign, reg7, 0),
(try_begin),
(gt, ":volunteer_amount", ":gold_capacity"),
(assign, reg7, 1), #not enough money
(try_end),
#segundo tipo de unidad, nobles
(party_get_slot, ":volunteer_troop_2", "$current_town", slot_center_volunteer_troop_type2),
(party_get_slot, ":volunteer_amount_2", "$current_town", slot_center_volunteer_troop_amount),
(party_get_free_companions_capacity, ":free_capacity_2", "p_main_party"),
(store_troop_gold, ":gold_2", "trp_player"),
(store_div, ":gold_capacity_2", ":gold_2", 500),#100 denars per man
(assign, ":party_capacity_2", ":free_capacity_2"),
(val_min, ":party_capacity_2", ":gold_capacity_2"),
(try_begin),
(gt, ":party_capacity_2", 0),
(val_min, ":volunteer_amount_2", ":party_capacity_2"),
(try_end),
(assign, reg15, ":volunteer_amount_2"),
(assign, reg17, 0),
(try_begin),
(gt, ":volunteer_amount_2", ":gold_capacity_2"),
(assign, reg17, 1), #not enough money
(try_end),
#para ambas unidades
(try_begin),
(eq, ":volunteer_amount", 0),
(str_store_string, s18, "@No one here seems to be willing to join your party."),
(else_try),
(store_mul, reg6, ":volunteer_amount", 100),#50 denars per man
(store_mul, reg16, ":volunteer_amount_2", 500),#100 denars per man
(str_store_troop_name_by_count, s3, ":volunteer_troop", ":volunteer_amount"),
(str_store_troop_name_by_count, s4, ":volunteer_troop_2", ":volunteer_amount_2"),
(try_begin),
(party_slot_eq, "$current_town", slot_town_lord, "trp_player"), #castillo es propiedad del jugador
(try_begin),
(eq, reg5, 1),
(eq, reg17, 1),
(str_store_string, s18, "@One {s3} volunteers to follow you."),
(else_try),
(eq, reg5, 1),
(eq, reg17, 0),
(str_store_string, s18, "@One {s3} volunteers or one {s4} to follow you."),
(else_try),
(str_store_string, s18, "@{reg5} {s3} volunteer or {reg15} {s4} to follow you."),
(try_end),
(else_try),
(try_begin),
(eq, reg5, 1),
(str_store_string, s18, "@One {s3} volunteers to follow you."),
(else_try),
(str_store_string, s18, "@{reg5} {s3} volunteer to follow you."),
(try_end),
(try_end),
(set_background_mesh, "mesh_pic_recruits"),
(try_end),
],
[
("continue_not_enough_gold",
[
(eq, reg7, 1),
],
"I don't have enough money...",
[
(jump_to_menu,"mnu_town"),
]),
("continue",
[
(eq, reg7, 0),
(eq, reg5, 0), #Bugfix (le, reg5, 0),
], #noone willing to join
"Continue...",
[
(party_set_slot, "$current_town", slot_center_volunteer_troop_amount, -1),
(jump_to_menu,"mnu_town"),
]),
("recruit_them_1", #caballeria
[
(eq, reg7, 0),
(gt, reg5, 0),
],
"Recruit {s3} ({reg6} denars).",
[
(call_script, "script_castle_recruit_volunteers_recruit_1"),
(jump_to_menu,"mnu_town"),
]),
("recruit_them_2", #nobles
[
(party_slot_eq, "$current_town", slot_town_lord, "trp_player"), #los nobles solo se reclutan en castillos de propiedad
(eq, reg17, 0),
(gt, reg15, 0),
],
"Recruit {s4} ({reg16} denars).",
[
(call_script, "script_castle_recruit_volunteers_recruit_2"),
(jump_to_menu,"mnu_town"),
]),
("forget_it",
[
(eq, reg7, 0),
(gt, reg5, 0),
],
"Forget it.",
[
(jump_to_menu,"mnu_town"),
]),
],
),
################################################################
En Hispania 1200 se contempla que la cantidad de tropas disponible a reclutar en un castillo dependa de la relación del dueño del castillo con el jugador, al igual que en las ciudades y aldeas depender de la relación con el populacho.
En los castillos debemos tener una relación >=1 para poder reclutar.
Modificaremos el menú del castillo para que en la parte superior informe de la relación con el dueño a semejanza con lo que sucede en aldeas y ciudades.
Para esto debemos ir a las operaciones que se ejecutan al inicio del menú "town", exactamente tras el siguiente código:
(try_begin),
(party_slot_eq,"$current_town",slot_party_type, spt_town),
(party_get_slot, ":center_relation", "$current_town", slot_center_player_relation),
(call_script, "script_describe_center_relation_to_s3", ":center_relation"),
(assign, reg9, ":center_relation"),
(str_store_string, s12, "@{!} {s3} ({reg9})."),
(try_end),
Pegamos esto que hemos programado:################################################################
#hispania 1200, reclutamiento (actualiza e informa de la relacion con el castillo)
#Esto solo se usa para code al jugador el valor actualizado de la relacion lord/castillo hacia el jugador
#La actualizacion de tropas voluntarias atendiendo a la relacion se hace comun a todos los asentamientos, cada 72 horas se activa el trigger que llama a script_update_volunteer_troops_in_village
(try_begin),
(party_slot_eq,"$current_town",slot_party_type, spt_castle),
(call_script, "script_center_relation_is_lord_relation", "$current_town"),
(neg|eq, ":center_lord", "trp_player"),
(str_clear, s12),
(party_get_slot, ":center_relation", "$current_town", slot_center_player_relation),
(assign, reg9, ":center_relation"),
(str_store_string, s12, "str_relation_castle"), #nueva string
(try_end),
################################################################
-En module_string.py
Como en el código anterior hicimos uso de una cadena, ahora debemos declararla al final del documento y antes del cierre global:
################################################################
("relation_castle", " Your relationship with the lord of this castle is ({reg9})"), #hispania 1200, reclutamiento
################################################################
-En module_constant.py
Estos menús que hemos crado necesitan de un slot al que llamaremos slot_faction_tier_6_troop que contenga para cada facción el tipo de tropas que se reclutarán en el asentamiento.
Un buen sitio para colocarlo es tras el slot
slot_faction_tier_5_troop = 45Aquí la línea:
################################################################ slot_faction_tier_6_troop = 46 #hispania 1200, reclutamiento ################################################################
Debemos buscar también:
slot_center_volunteer_troop_amount= 93Y añadir debajo este slot:
################################################################ slot_center_volunteer_troop_type2 = 94 #hispania 1200, reclutamiento ################################################################
-En module_script.py
Estos slots deben ser inicializados y para ello buscamos la línea de código:
(faction_set_slot, "fac_culture_1", slot_faction_tier_5_troop,Observamos como ahí se inicializan todas los otros slot_faction_tier_X_troop según la cultura .
Debemos añadir entonces una nueva línea tras de cada slot_faction_tier_5_troop, una por cultura de la forma:
########################################## (faction_set_slot, "fac_culture_A", slot_faction_tier_6_troop, "trp_B"), ##########################################
Tambien debemos buscar la línea:
(faction_set_slot, ":faction_no", slot_faction_tier_5_troop, ":troop"),y añadir justo después:
########################################## (faction_get_slot, ":troop", ":culture", slot_faction_tier_6_troop), #hispania 1200, reclutamiento, tropas, iniciar tier_6 (faction_set_slot, ":faction_no", slot_faction_tier_6_troop, ":troop"), ##########################################
Para que todo funcione correctamente es necesario modificar algunos scripts por defecto del juego, el primero será script_village_recruit_volunteers_recruit
Tiene bastantes pequeñas modificaciones así que lo mejor es sustituirlo entero por esta nueva versión:
##########################################
#script_village_recruit_volunteers_recruit
# INPUT: none
# OUTPUT: none
("village_recruit_volunteers_recruit",
[(party_get_slot, ":volunteer_troop", "$current_town", slot_center_volunteer_troop_type),
(party_get_slot, ":volunteer_amount", "$current_town", slot_center_volunteer_troop_amount),
(party_get_free_companions_capacity, ":free_capacity", "p_main_party"),
(val_min, ":volunteer_amount", ":free_capacity"),
(store_troop_gold, ":gold", "trp_player"),
(store_div, ":gold_capacity", ":gold", 10),#10 denars per man
(val_min, ":volunteer_amount", ":gold_capacity"),
(party_add_members, "p_main_party", ":volunteer_troop", ":volunteer_amount"),
(party_set_slot, "$current_town", slot_center_volunteer_troop_amount, -1),
(store_mul, ":cost", ":volunteer_amount", 10),#10 denars per man
(troop_remove_gold, "trp_player", ":cost"),
]),
("town_recruit_volunteers_recruit", #hispania 1200, reclutamiento en ciudades
[(party_get_slot, ":volunteer_troop", "$current_town", slot_center_volunteer_troop_type),
(party_get_slot, ":volunteer_amount", "$current_town", slot_center_volunteer_troop_amount),
(party_get_free_companions_capacity, ":free_capacity", "p_main_party"),
(val_min, ":volunteer_amount", ":free_capacity"),
(store_troop_gold, ":gold", "trp_player"),
(store_div, ":gold_capacity", ":gold", 25),#25 denars per man
(val_min, ":volunteer_amount", ":gold_capacity"),
(party_add_members, "p_main_party", ":volunteer_troop", ":volunteer_amount"),
(party_set_slot, "$current_town", slot_center_volunteer_troop_amount, -1),
(store_mul, ":cost", ":volunteer_amount", 25),#25 denars per man
(troop_remove_gold, "trp_player", ":cost"),
]),
("castle_recruit_volunteers_recruit_1", #hispania 1200, reclutamiento en castillos, caballeria
[
(party_get_slot, ":volunteer_troop", "$current_town", slot_center_volunteer_troop_type),
(party_get_slot, ":volunteer_amount", "$current_town", slot_center_volunteer_troop_amount),
(party_get_free_companions_capacity, ":free_capacity", "p_main_party"),
(val_min, ":volunteer_amount", ":free_capacity"),
(store_troop_gold, ":gold", "trp_player"),
(store_div, ":gold_capacity", ":gold", 100),#50 denars per man
(val_min, ":volunteer_amount", ":gold_capacity"),
(party_add_members, "p_main_party", ":volunteer_troop", ":volunteer_amount"),
(party_set_slot, "$current_town", slot_center_volunteer_troop_amount, -1),
(store_mul, ":cost", ":volunteer_amount", 100),#50 denars per man
(troop_remove_gold, "trp_player", ":cost"),
]),
("castle_recruit_volunteers_recruit_2", #hispania 1200, reclutamiento en castillos, nobles, de propiedad
[
(party_get_slot, ":volunteer_troop", "$current_town", slot_center_volunteer_troop_type2),
(party_get_slot, ":volunteer_amount", "$current_town", slot_center_volunteer_troop_amount),
(party_get_free_companions_capacity, ":free_capacity", "p_main_party"),
(val_min, ":volunteer_amount", ":free_capacity"),
(store_troop_gold, ":gold", "trp_player"),
(store_div, ":gold_capacity", ":gold", 500),#100 denars per man
(val_min, ":volunteer_amount", ":gold_capacity"),
(party_add_members, "p_main_party", ":volunteer_troop", ":volunteer_amount"),
(party_set_slot, "$current_town", slot_center_volunteer_troop_amount, -1),
(store_mul, ":cost", ":volunteer_amount", 500),#100 denars per man
(troop_remove_gold, "trp_player", ":cost"),
]),
##########################################
Otro script a modificar es el script_game_start , en concreto buscamos las siguientes líneas de código:
(try_for_range, ":village_no", villages_begin, villages_end), (call_script, "script_update_volunteer_troops_in_village", ":village_no"), (try_end),Y las sustituimos por estas:
################################## (try_for_range, ":cur_center", centers_begin, centers_end), (call_script, "script_update_volunteer_troops_in_village", ":cur_center"), #hispania 1200, reclutamiento (para todo asentamiento) (try_end), ##################################
Ahora debemos ir al script_change_player_relation_with_center, casi al final del mismo se encuentra esta línea:
(party_slot_eq, ":center_no", slot_party_type, spt_village),Pues hay que borrarla o convertirla en comentario.
En el scriptscript_update_volunteer_troops_in_village
hay que hacer muchas modificaciones de nuevo, así que lo sustituiremos entero:
##################################
#script_update_volunteer_troops_in_village #hispania 1200, actualizacion de reclutamiento
# INPUT: arg1 = center_no
# OUTPUT: none
("update_volunteer_troops_in_village",
[
(store_script_param, ":center_no", 1),
#------------------------------------------
#hispania 1200, reclutamiento, relacion (actualizar la relacion con el castillo)
(try_begin),
(party_slot_eq,":center_no",slot_party_type, spt_castle),
(call_script, "script_center_relation_is_lord_relation", ":center_no"),
(try_end),
#------------------------------------------
(party_get_slot, ":player_relation", ":center_no", slot_center_player_relation),
(party_get_slot, ":center_culture", ":center_no", slot_center_culture),
## (try_begin),
## (eq, "$cheat_mode", 2),
## (str_store_party_name, s4, ":center_no"),
## (str_store_faction_name, s5, ":center_culture"),
## (display_message, "str_updating_volunteers_for_s4_faction_is_s5"),
## (try_end),
#------------------------------------------
#hispania 1200, reclutamiento,
#En los castillos no se da probabilidad de aumento de rango
(try_begin),
(party_slot_eq,":center_no",slot_party_type, spt_town),
(faction_get_slot, ":volunteer_troop", ":center_culture", slot_faction_tier_4_troop),
(else_try),
(party_slot_eq,":center_no",slot_party_type, spt_castle),
(faction_get_slot, ":volunteer_troop_castle1", ":center_culture", slot_faction_tier_5_troop),
(faction_get_slot, ":volunteer_troop_castle2", ":center_culture", slot_faction_tier_6_troop),
(else_try),
(faction_get_slot, ":volunteer_troop", ":center_culture", slot_faction_tier_1_troop),
(try_end),
#------------------------------------------
(assign, ":volunteer_troop_tier", 1),
(store_div, ":tier_upgrades", ":player_relation", 10),
(try_for_range, ":unused", 0, ":tier_upgrades"),
(store_random_in_range, ":random_no", 0, 100),
(lt, ":random_no", 10),
(store_random_in_range, ":random_no", 0, 2),
(troop_get_upgrade_troop, ":upgrade_troop_no", ":volunteer_troop", ":random_no"),
(try_begin),
(le, ":upgrade_troop_no", 0),
(troop_get_upgrade_troop, ":upgrade_troop_no", ":volunteer_troop", 0),
(try_end),
(gt, ":upgrade_troop_no", 0),
(val_add, ":volunteer_troop_tier", 1),
(assign, ":volunteer_troop", ":upgrade_troop_no"),
(try_end),
(assign, ":upper_limit", 7),
(try_begin),
(ge, ":player_relation", 5),
(assign, ":upper_limit", ":player_relation"),
(val_div, ":upper_limit", 2),
(val_add, ":upper_limit", 10),
(else_try),
(lt, ":player_relation", 0),
(assign, ":upper_limit", 0),
(try_end),
(val_mul, ":upper_limit", 3),
(store_add, ":amount_random_divider", 2, ":volunteer_troop_tier"),
(val_div, ":upper_limit", ":amount_random_divider"),
(store_random_in_range, ":amount", 0, ":upper_limit"),
#------------------------------------------
#hispania 1200, reclutamiento en castillos
(try_begin),
(party_slot_eq,":center_no",slot_party_type, spt_castle),
(val_div, ":amount", 1), #reducir voluntarios disponibles
# (try_begin),
# (le, ":player_relation", 0),
# (assign, ":amount", 0),
# (try_end),
(party_set_slot, ":center_no", slot_center_volunteer_troop_type, ":volunteer_troop_castle1"),
(party_set_slot, ":center_no", slot_center_volunteer_troop_type2, ":volunteer_troop_castle2"),
(party_set_slot, ":center_no", slot_center_volunteer_troop_amount, ":amount"),
(else_try),
(party_set_slot, ":center_no", slot_center_volunteer_troop_type, ":volunteer_troop"),
(party_set_slot, ":center_no", slot_center_volunteer_troop_amount, ":amount"),
(try_end),
#------------------------------------------
]),
#################################
Por último añadimos este script al final del documento:
#################################
#script_center_relation_is_lord_relation
#por JBJ
#Descripcion: Iguala la relacion del asentamiento->jugador a la relacion del propietario->jugador)
#Entradas: arg1 = center_no
#Salidas: ninguna
("center_relation_is_lord_relation",
[
(store_script_param_1, ":center_no"),
(party_get_slot, ":center_lord", ":center_no", slot_town_lord),
(try_begin), #Si el asentamiento pertence al jugador
(eq, ":center_lord", "trp_player"),
(assign, reg0, 100),
(else_try), #Si el asentamiento pertenece a un lord
(ge, ":center_lord", 0),
(call_script, "script_troop_get_player_relation", ":center_lord"),
(else_try),
(assign, reg0, 0), #Si el asentamiento no tiene lord
(try_end),
(party_set_slot, ":center_no", slot_center_player_relation, reg0),
#Otros scripts de cambio de relaciones
#script_change_player_relation_with_troop
#script_change_player_relation_with_center
]),
#################################
Sino olvidé nada esto debe funcionar perfectamente, recuerda que este código está incluido en el MS liberado junto a Hispania 1200, con el tag 'reclutamiento', puede encontrar fácilmente el código referente a este tema. Los nuevos textos que hemos incluido están en inglés, si quieres traducirlos a otro idioma debes generar nuevos documentos de idiomas y traducir las frases.
| Opción de reclutar nuevos soldados en el menú del castillo propio |
| Opciones de reclutamiento disponibles tras el menú de la anterior imagen |
sábado, 1 de octubre de 2016
Armorum&Basis - Imperivm III mods
Ambas modificaciones eliminan los elementos de fantasía del juego, pero Armorum lo lleva más allá sustituyendo los 'objetos de las ruinas' y modificando los valores y las habilidades de las unidades.
Toda la información aquí.
sábado, 23 de julio de 2016
Creando un modelo estático para M&BW
También puedes ver este tutorial aquí.
Para seguir el tutorial necesitas tener nociones de modelado 3D (usaremos Blender), diseño gráfico (usaremos GIMP) y programación del Module System de M&BW.
Antecedentes
Debemos tener en cuenta que todos los objetos que puedes encontrar en M&B se dividen en tres grupos según su forma de comportarse en el entorno. Tendremos diferentes tipos de archivos según los tipos de objetos:
- Modelos estáticos (.obj): yelmos, armas, escudos, alimentos, edificios...
- Modelos de animación por vértices (.md3): modelos de animación por vértices: caras, arcos, ballestas, fundas de espadas... (consiste en una animación por fotogramas de varios modelos estáticos).
- Modelos de animación (.smd): animaciones, armaduras, caballos, botas, guantes... (también se conoce por animación por esqueleto)
*Notas:
-Este tutorial no trata sobre el aprendizaje y manejo de las herramientas usadas, se da por sentado que tienes cierto nivel en su uso.
-En el tutorial nos centraremos en los objetos de tipo estático .obj y .md3. El otro tipo de objetos son los .smd, que llevan asociados esqueletos y animaciones, haré un tutorial de ellos más adelante.
-En general el modelo de cada objeto está contenido en un único archivo (existen excepciones con objetos muy grandes como edificios, pero esto también queda fuera del tutorial).
-De aquí en adelante cuando haga referencia a la palabra 'modelo' quiero decir la malla 3D diseñada en Blender y cuando diga 'objeto' me refiero al item, edificio o cualquier otro ente que puedes ver mientras juegas.
Modelado
Existe gran cantidad de software especializado el modelado 3D, en nuestro caso por ser gratuito, vamos a usar el polifacético Blender. Otra buena opción, con menos capacidades, pero más que suficiente para nuestro propósito es Windg3D.
Texturizado
De igual modo puedes usar cualquier editor de imágenes para trabajar con las texturas, nosotros usaremos GIMP. Necesitaras también alguna herramienta que genere mapas de normales y otra que exporte archivos de imagen en formato .dds, existen plugins para GIMP que hacen todo esto.
Empaquetado
M&B necesita usar un "contenedor" para empaquetar los modelos de los objetos y enlazarlos con el motor de juego, otros modelos, texturas etc..., en este paso también aplicaremos los materiales simulados para conseguir un mayor realismo en los objetos, usaremos OpenBRF.
Programación
Este paso consiste en crear el código de nuestro nuevo objeto para que esté disponible en el mod, necesitaras tener instalado Python 2.7 y descargado el 'Module System' para más detalle ve aquí o aquí, si quieres optar por la simplicidad también puedes usar Morgh's.
Descripción del proyecto
Solución paso a paso
Antes de hacer nada vamos a organizarnos creando una nueva carpeta llamada 'MiItem', estará alojada en el escritorio y contendrá todos los archivos con los que trabajemos.
1º Modelado
En esta étapa nos centraremos en el diseño del "cuerpo físico" de nuestra espada.
1.1º
La primera característica a definir en nuestra espada es su tamaño, estableciendo las dimensiones que va a tener, podría no preocuparnos esto ya que en cualquier momento podríamos hacer retoques con OpenBRF o con Blender, pero lo mejor es trabajar seguros desde el primer momento. Así que vamos a usar un patrón. Como nuesto 'item' es una espada bastarda vamos a buscar una espada semejante en los archivos de M&B que nos sirva de guía. Encontramos 'bastard_sword_a.obj' que se encuentra en 'weapons_e.brf' de 'CommonsRes' la exportaremos mediante OpenBrf como modelo estático.
Como también vamos a hacer la funda tomaremos como patrón 'bastard_sword_a_scabbard.md3' en el mismo .brf, tienes que recordar que un archivo .md3 no es más que varios archivos .obj unidos, cada .obj es un cuadro o fotograma de la animación. Las fundas tienen 3 cuadros (puedes verlos en el campo 'línea temporal'), el nº0 y el nº1 son idénticos y muestran al espada enfundada y el cuadro nº2 muestra solo la funda, exportamos como modelos estáticos los cuadros nº1 y nº2.
| Los dos patrones que usaremos |
1.2º
Ahora empezamos a modelar en Blender nuestro nuevo diseño de espada, debe ser similar en dimensiones al patrón, para ello puedes importar a Blender los .obj del patrón o colocar una imagen de base sobre la que trabajar.
Si no sabes usar Blender puedes acudir a la inmensidad de tutoriales que ofrece la web.
Debemos tener en cuenta algunos puntos importantes a la hora de comenzar a modelar:
- Al terminar, el modelo debe estar compuesto de una única malla.
- Todas las caras deben ser triangulares.
- Las normales deben quedar hacia fuera.
- No es necesario aplicar materiales.
- No dejes activo ningún modificador de mallas.
- A menos vértices más rendimiento en el juego.
- Eliminar los vértices repetidos
- El origen de la nueva malla debe tener la misma posición que el de la malla patrón. En el caso de las espadas es el mango.
- A la hora de exportar las mallas, el origen de la misma debe coincidir con el origen absoluto, posición (0,0).
- Hay partes de la malla que deben estar irremediablemente en una posición determinada. Como las correas al cinturón de las fundas de espada, de los escudos, de los carcaj etc... Esto es así para que en el juego cada 'item' quede alineado con el cuerpo del personaje.
Este proceso es delicado y depende de la pericia del modelador obtener unos buenos resultados. Tras un ratito de modelaje:
| Los tres modelos de la izquierda son los patrones, los tres de la derecha nuestros modelos |
Recordad: En los detalles está la diferencia.
Hemos llamado a nuestras mallas: 'miespada', miespadafunda1', 'miespadaCCfunda2' pero aún no la exportamos.
En esta etapa aplicaremos color a nuestros modelos mediante la aplicación de texturas.
Podemos trabajar según tres modos diferentes. El primero consiste en diseñar la textura para posteriormente 'desenrollar' la malla encima, el segundo método 'desenrolla' la malla primero y luego aplicar la textura y por último está el término medio, que es un poco de una y un poco de otra. Yo trabajaré según el primer método.
2.1º
Abrimos GIMP y creamos un nuevo archivo que llamaremos 'textura_miespada'.
Debemos tener en cuenta algunos puntos importantes a la hora de comenzar a crear la textura:
-El tamaño de la textura dependerá de la relación rendimiento/detalle que desees en el juego. Es aconsejable que tengan una relación 1:1 en las dimensiones (para el caso de la espada un 1024x1024px es más que aceptable)
-Aprovecha al máximo el área de la imagen/textura. Intentar no encoger el tamaño de las proyecciones originales, es preferible girar objetos, llevar al límite de la imagen las proyecciones, no dejar huecos vacíos...
Nuestra espada no requiere ninguna textura compleja, así que después de poco tiempo:
| Textura de color para el modelo |
2.2º
Exportamos la imagen en formato .dds y elegimos el tipo deseado según la relación peso/detalle que aceptamos y del uso del canal alfa, el tipo DXT1 es suficiente para nuestra espada. Debemso activar siempre la opción 'Generate mipmaps' o mapas MIP que consiguen una mayor fluidez en el juego, los mipmaps son imágenes de mapa de bits que acompañan a la textura en diferentes niveles de detalle, esto significa que una vez en el juego, si la espada está muy lejos de la cámara del jugador se utilizaran los mapas de bits de menor resolución y solo cuando nos vamos acercando se muestran las más detalladas, mejorando así el el rendimiento.
2.3º
Este punto debería estar en el apartado Modelado pero es necesario llevar a cabo el paso anterior para poder realizarlo, así que aquí o colocamos.
Ahora llega un trabajo laborioso: hacer unwrap a las mallas o lo que es lo mismo 'desenrrollar' las mallas.
Esto consiste básicamente en proyectar en un plano 2D (la textura) la superficie de la malla 3D (el modelo). Podemos usar muy diversas técnicas atendiendo principalmente a la complejidad de nuestro modelo. La espada es muy sencilla y no necesitaremos siquiera usar zonas de corte. Desenrollamos por las vistas: alzado, planta y perfil.
Así que importamos la imagen 'textura_miespada' a Blender y procedemos.
En nuestro caso solo es necesario desenrollar 2 de las 3 mallas, la espada desenfundada y la funda, la otra malla es solo una combinación de ambas. Los tres modelos deben desenrollarse en la misma textura para que compartan origen de coordenadas.
Así nos quedó:
| Modelos de la espada con la textura aplicada |
Exportamos los tres modelos en formato .obj y sin modificaciones con los nombres: 'miespada.obj', 'miespadafunda1.obj', 'miespadafunda2.obj' (recuerda, sus orígenes de coordenadas deben estar en el la posición (0,0)).
2.4º
Elegir y editar las texturas de forma correcta es el método más importante (además de la aplicación de materiales y de los detalles del modelo) para dar realismo al objeto en el juego, por esto hay que poner mucho empeño en ello. Con realismo no me refiero a que nuestros objetos luzcan en le juego como lo harían en la vida real, ya que si diseñamos unos pocos objetos que así fuesen, si el resto de objetos en el juego no lo son la heterogeneidad resultante da un aspecto extraño a nuestro mod. Debemos elegir que mundo queremos representar. Por esta razón, es muy probable que una vez hayamos llegado al final del tutorial, diseñado nuestro objeto y probado dentro del motor de juego, tengamos que volver a repetir algunos pasos para retocar la textura o el modelo y conseguir así que se vea lo más en sintonía posible con su mundo virtual.
Muchos modders no lo hacen así, lo que conlleva tener una calidad gráfica pobre y dificulta a los jugadores la inmersión en el mundo virtual.
Muchos modders no lo hacen así, lo que conlleva tener una calidad gráfica pobre y dificulta a los jugadores la inmersión en el mundo virtual.
2.5º
La textura que hemos diseñado en los pasos anteriores da color al objeto, es necesaria pero no suficiente en la mayoría de los casos para obtener un buen grado de realismo. Vamos a diseñar dos texturas más, así que tendremos tres en total:
- Textura difusa o RGB. Contiene la información del color. Ya la tenemos hecha.
- Textura de mapa de normales. Ofrece información sobre el relieve (con esta técnica podemos añadir pequeños detalles en el modelo sin tener que modelarlos en la malla)
- Textura especular. Contiene información sobre la reflexión de luz en el objeto.
Para el mapa de normales o normalmap podemos hacer uso del plugin de GIMP, tan solo hay que aplicar la función del plugin sobre nuestra primera textura.
Para la textura especular podemos seguir varios procedimientos, pero lo más sencillo es retocar la primera textura. Debemos tener una imagen saturada con colores grises planos, donde el blanco indica reflexión máxima de la luz sobre la superficie del objeto y el negro mínima.
Exportamos como .dds, DXT1 y con mipmaps
Estos son los resultados de las tres texturas:
| De izquierda a derecha: textura difusa, mapa de normales y especular |
3º Empaquetado
En este paso 'empaquetaremos' los modelos en el formato .brf, que ayuda al motor de juego de M&B a asociar un modelo con su textura, material, cuerpo de colisión, esqueleto...
3.1º
Resumamos:
Dentro de la carpeta 'MiItem' tenemos los siguientes archivos:
Dentro de la carpeta 'MiItem' tenemos los siguientes archivos:
- Archivos .obj: 'miespada.obj', 'miespadafunda1.obj', 'miespadafunda2.obj'
- Archivos .dds: 'textura_miespada.dds', 'normalmap_miespada.dds', 'especular_miespada.dds'
Ahora creamos un nuevo archivo .brf en la carpeta gracias OpenBRF, e importaremos la malla 'espadaCC.obj' como modelo estático; después creamos el modelo de animación por vértices con dos frames, la espada enfundada y desenfundad, al igual que aparecía en el modelo de la espada bastarda que usamos como patrón al comienzo del tutorial.
Os explicamos como crear esta animación por vértices: importamos 'miespadafunda1.obj' como modelo estático y ahora manteniendolo seleccionado importamos un cuadro o fotograma de animación por vértices y seleccionamos 'miespadafunda1.obj', vemos como ha aparecido la línea temporal, avanzamos un frame y con el objeto seleccionado añadimos un nuevo cuadro que será 'miespadafunda2.obj', listo, ya tenemos la animación por vértices, en caso de necesidad podría ser exportado con formato .md3. En la línea temporal debemos indicar los tiempos 0, 0 y 10 para los cuadros 0, 1 y 2 respectivamente tal cual aparece en el modelo patrón.
Os explicamos como crear esta animación por vértices: importamos 'miespadafunda1.obj' como modelo estático y ahora manteniendolo seleccionado importamos un cuadro o fotograma de animación por vértices y seleccionamos 'miespadafunda1.obj', vemos como ha aparecido la línea temporal, avanzamos un frame y con el objeto seleccionado añadimos un nuevo cuadro que será 'miespadafunda2.obj', listo, ya tenemos la animación por vértices, en caso de necesidad podría ser exportado con formato .md3. En la línea temporal debemos indicar los tiempos 0, 0 y 10 para los cuadros 0, 1 y 2 respectivamente tal cual aparece en el modelo patrón.
3.2º
Debemos ahora cambiar de directorio de trabajo. Vamos a llevarnos los archivos a la carpeta del mod que supuestamente estas desarrollando. Copiamos nuestras 3 texturas dentro de la carpeta 'Textures' de tu mod y nuestro recién creado archivo .brf al que hemos llamado 'mistitems.brf' dentro de 'Resource'.
Abrimos el .brf e importamos un nuevo material vacío con el nombre 'material_miespada' y también importamos 3 referencias a texturas a las que les pondremos los nombres 'textura_miespada.dds', 'normalmap_miespada.dds', 'especular_miespada.dds', justo en el instante de ponerle esos nombre, idénticos a nuestras texturas, estas quedan vinculadas y deben poder verse desde OpenBRF.
Nuestro propósito ahora es configurar correctamente los elementos que aparecen en las pestañas 'Mod' (modelos), 'Mat' (materiales) y 'Text' (texturas).
Texturas dentro del .brf
Podemos apreciar como en cada una de las tres texturas se pude modificar un campo llamado 'Indicad', su funcionalidad es confusa y mi consejo es que a cada textura, en este campo, le coloquéis el mismo valor que tienen las texturas del objeto patrón en su .brf.
Materiales dentro del .brf
Nuestro propósito ahora es configurar correctamente los elementos que aparecen en las pestañas 'Mod' (modelos), 'Mat' (materiales) y 'Text' (texturas).
Texturas dentro del .brf
Podemos apreciar como en cada una de las tres texturas se pude modificar un campo llamado 'Indicad', su funcionalidad es confusa y mi consejo es que a cada textura, en este campo, le coloquéis el mismo valor que tienen las texturas del objeto patrón en su .brf.
Materiales dentro del .brf
La pestaña 'Mat' es de vital importancia para conseguir realismo dentro del juego y si no se modifica adecuadamente pueden ocurrir errores en el momento de cargar el juego, se cuidadoso. Lo mejor, al igual que con las texturas, es tener a mano el .brf del objeto patrón y guiarnos, en este caso, por la configuración de sus materiales.
Los campos disponibles y los valores que hemos dado son:
Los campos disponibles y los valores que hemos dado son:
- Sombreado: envmap_shader_Instanced (básicamente significa que nuestro objeto tiene un sombreado de environment map, abajo lo explico)
- Difuso A: textura_miespada (el nombre de la textura que da color. No poner .dds)
- Difuso A: none (seré sincero, no se para que vale esto, jamás lo use ni lo vi en M&B nativo. Parece ser otra textura de color, pero no se cual es la relación A-B. Lo dejamos en none)
- Desplazamiento: normalmap_miespada (el nombre de la textura que contiene el mapa de normales. No poner .dds)
- Entorno: earthenvmap (aquí debemos poner una textura que simule el entorno en el que se encuentra el objeto, pera que la reflexión de luz sea lo más realista posible. M&B usa por defecto esa textura que simula un paisaje exterior, podríamos poner cualquier otra. Solo debemos usarlo para objetos que reflejen luz, metales pulidos sobre todo)
- Especular: especular_miespada (el nombre de la textura que contiene la información especular o de reflejo de luz No poner .dds)
- Espectro RGB: indica como se comportan los diferentes componentes de color ante la reflexión. Practicante solo para metales.
- Coeficiente: Coeficiente que indica el tamaño de las zonas que reflejan. Practicante solo para metales.
- Insignia: Este valor es un conjunto de bits que contienen información avanzada del material, si no sabes usarlo lo mejor es dejarlo con el mismo valor que el modelo patrón.
- Recuerda que a materiales más complejos más realismo y menos rendimiento.
Modelos dentro de .brf
En la pestaña 'Modelo' indicamos el material asociado a cada modelo. El valor insignia mantelo siempre en 0.
También podemos hacer uso de algunas herramientas muy útiles como el sombreado oclusión ambiental, el re-cálculo de normales y por supuesto lo que debemos hacer siempre es el cálculo de niveles de detalle (level of detail - LOD) para cada malla. Esto crea mallas adicionales con un detalle menor a la original, funciona de modo similar a los mipmaps de las texturas, mejoran el rendimiento si el objeto se encuentra lejos de la cámara.
Descárgate los archivos que adjunto al final de la entrada para ver con detalle como ha quedado configurado el archivo .brf
*Nota:
Si nuestro objeto fuera un edificio, piedra, árbol, valla o cualquier tipo de objeto que los NPC's y caballos deban considerar en el juego como objetos sólidos que no deben traspasarse, es necesario crear objetos de colisión.
Si nuestro objeto fuera un edificio, piedra, árbol, valla o cualquier tipo de objeto que los NPC's y caballos deban considerar en el juego como objetos sólidos que no deben traspasarse, es necesario crear objetos de colisión.
Este es el último paso, añadiremos los códigos al 'Module_System', para que nuestra espada esté disponible en el juego. Como nuestro objeto es un arma nos dirigimos a definirla en 'module_items.py'. De nuevo vamos a usar usaremos un patrón que nos sirva de guía. Buscamos el código de nuestro patrón, la espada bastarda, es éste:
["bastard_sword_a", "Bastard Sword", [("bastard_sword_a",0),("bastard_sword_a_scabbard", ixmesh_carry)], itp_type_two_handed_wpn|itp_merchandise| itp_primary, itc_bastardsword|itcf_carry_sword_left_hip|itcf_show_holster_when_drawn,
294 , weight(2.0)|difficulty(9)|spd_rtng(98) | weapon_length(101)|swing_damage(35 , cut) | thrust_damage(26 , pierce),imodbits_sword_high ],
Lo copiamos y los añadimos al final del archivo justo antes de la línea:
["items_end", "Items End", [("shield_round_a",0)], 0, 0, 1, 0, 0],
Ahora lo modificamos a nuestro gusto.
Cuidado, no se permiten letras mayúsculas en los identificadores.
Cuidado, no se permiten letras mayúsculas en los identificadores.
Ya que nuestra espada ha sido forjada por el mismísimo Hefesto en su forja para unos héroes como nosotros, le aumentaremos los valores de daño y le ponemos el modificador 'imodbits_none' para que siempre sea una espada perfecta.
Guardamos y compilamos.
Este es nuestro código:
Guardamos y compilamos.
Este es nuestro código:
["miespada", "Mi Espada", [("miespada",0),("miespadafunda", ixmesh_carry)], itp_type_two_handed_wpn|itp_merchandise| itp_primary, itc_bastardsword|itcf_carry_sword_left_hip|itcf_show_holster_when_drawn,
494 , weight(3.0)|difficulty(9)|spd_rtng(96) | weapon_length(101)|swing_damage(45 , cut) | thrust_damage(28 , pierce),imodbits_none],
No se nos puede olvidar que debemos indicarle al juego que tiene disponible un nuevo archivo .brf que cargar en el arranque. Abrimos 'module.ini' en la carpeta del mod y añadimos la línea load_mod_resource = misitems
El lugar no importa, pero es conveniente ponerlo justo después de la carga de los otros .brf.
El lugar no importa, pero es conveniente ponerlo justo después de la carga de los otros .brf.
Y ya hemos finalizado. Ahora 'MiEspada' estará disponibles en los mercados para su compra, ya depende de ti modificar el código para hacer el uso de ella que más te convenga.
Resultado
Como un soldado no solo merece una espada sino también un escudo, trabajé en uno, no lo modelé tan solo le cambié las texturas. Espero que más de uno de vosotros juegue con ellos.
Aquí una impresión de pantalla del resultado.
| Nuestros modelos en el juego |
martes, 19 de julio de 2016
Hispania 1200 - M&BW mod
Hipania 1200 es un mod histórico para Mount&Blade Warband basado en la España del siglo XIII. Ha sido desarrollado por El Xabeo de la Cova con la estrecha colaboración de JBJ.Toda la información aquí.
domingo, 17 de julio de 2016
CoEx - M&BW mod
Algunas de sus novedades son: nuevos items, mejoras gráficas y mejoras de jugabilidad
Toda la información aquí.