Modding Q&A [For Quick Questions and Answers]

正在查看此主题的用户

状态
不接受进一步回复。
Cozur 说:
I need a trigger
I don't think you need a trigger, you can handle it from the same script that the party generates, in this way you avoid creating new global variables, which is what you would need if it were a trigger that handled it, or so I think.
Something fast and as a prototype and example. You will have to adapt it to your script, for example, assigning a correct name to the variable 'party_no'.
插入代码块:
			#Set a random name for the indicated troop
			(assign, ":custom_troop", "trp_custom_bandit"), #select troop
			(assign, ":continue", 0),
			(party_get_num_companion_stacks, ":num_stacks", ":party_no"),
			(try_for_range, ":i_stack", 0, ":num_stacks"),
				(party_stack_get_troop_id, ":stack_troop", ":party_no", ":i_stack"),
				(eq, ":stack_troop", ":custom_troop"),
				(assign, ":continue", 1),
				(assign, ":num_stacks", 0), #break loop
			(try_end),
			
			(try_begin),
				(eq, ":continue", 1),
	
				(str_store_string, s1, "@_default_name"),
				#assign random name
				(store_random_in_range, ":r", 0, 3),
				(try_begin),
					(eq, ":r", 0),
					(str_store_string, s1, "@custon_name_1"),
				(else_try),
					(eq, ":r", 1),
					(str_store_string, s1, "@custon_name_2"),
				(else_try),
					(eq, ":r", 2),
					(str_store_string, s1, "@custon_name_3"),
				(try_end),
				
				#set name
				(troop_set_name, ":custom_troop", s1),
				#reload variable
				(assign, ":continue", 0),
			(try_end),
EDIT: fixes
 
Dj_FRedy 说:
插入代码块:
(store_random_in_range, ":r", 0, 2),
插入代码块:
store_random_in_range      = 2136    # (store_random_in_range, <destination>, <range_low>, <range_high>),
                                     # Stores a random value in the range of <range_low>..<range_high>-1.

its max-1, so above you would have {0,1}, not {0,1,2}
 
Thank you I will look at what you wrote and try my best and I know I am trying to leap before I can walk.
No fear of me getting angry I appreciate all the time and effort you have all given me and how I must be making you all bang your heads against a wall.
 
markfamily 说:
Thank you I will look at what you wrote and try my best and I know I am trying to leap before I can walk.
No fear of me getting angry I appreciate all the time and effort you have all given me and how I must be making you all bang your heads against a wall.
You're so big, buddy.  :wink:
 
Hey guys, can I ask something?
I made a reputation system (or better yet, its framework, the basic stuff). So, the script checks the players renown, stores it in a local variable and then checks that in a number of possibilities, rewards the player for each rank and displays a message. Kinda like the Torchlight system, you know? Ranks of fame, based on renown value, for Mount and Blade. So far, the scripts works as intended, compiles with not even a warning, all good. My problem is a logical error in my thinking. I need this script to check every 2 days(any interval will do for testing, tbh), but I am stuck on the how. Will I call the script at game init? Will I have to make the local variables global and then add a simple trigger? If it is done just in the scripts file, how will I do that? I mean, I know how to check every x amount of hours in simple triggers, but I haven't seen any relative script in the scripts file.

Thank you!
 
Well you have proberly guessed but i am stuck
module.triggers
##spawn barbarian king
( 365 * 24, 0, ti_once, #check trigger after one year and spawn party only once
  [(store_current_day, ":cur_day"), #Store the current day.
  (ge, ":cur_day", 365),], #spawn on day 365
  [(store_random_in_range, ":town_no", towns_begin,towns_end), #Gets 1 random town from the given list.
  (assign, reg1, ":town_no"),#assign random town as town_no
  (set_spawn_radius,4),(spawn_around_party,":town_no","pt_barbarians"),# spawns barbarians party defined in party template around town_no
  (party_set_ai_behavior,"pt_barbarians",ai_bhvr_patrol_location),# barbarians party will patrol around town_no
(display_message, "@Rumours from passing traveller - A large band of barbarians led by Warlord Perus have landed near {reg1}",0x00FF00),#display message and location of enemy party
  ]),
This part has me stumped - Define the operation 'spawn_around_party' correctly, e.g:.
I have been checking through the forum and osp packs for usage of new party and have seen the usage for adding troops to parties or creating new parties but cannot work out how it would be used for my code.
I assume it must be defined somehow with my pt_barbarians but cannot grasp how Im sorry.
Edit ok found a reference in scripts and entered it which compiled and the code makes sense but I do not understand the actual usage of new_party.
##spawn barbarian king
( 365 * 24, 0, ti_once, #check trigger after one year and spawn party only once
  [(store_current_day, ":cur_day"), #Store the current day.
  (ge, ":cur_day", 365),], #spawn on day 365
  [(store_random_in_range, ":town_no", towns_begin,towns_end), #Gets 1 random town from the given list.
(assign, ":new_party", reg0),
(assign, ":new_party", "pt_barbarians"), 
  (assign, reg1, ":town_no"),#assign random town as town_no
  (set_spawn_radius,4),(spawn_around_party,":town_no","pt_barbarians"),# spawns barbarians party defined in party template around town_no
  (party_set_ai_behavior, ":new_party", ai_bhvr_patrol_location),# barbarians party will patrol around town_no
(display_message, "@Rumours from passing traveller - A large band of barbarians led by Warlord Perus have landed near {reg1}",0x00FF00),#display message and location of enemy party
  ]),
 
Antonis 说:
I need this script to check every 2 days(any interval will do for testing, tbh), but I am stuck on the how. Will I call the script at game init? Will I have to make the local variables global and then add a simple trigger? If it is done just in the scripts file, how will I do that? I mean, I know how to check every x amount of hours in simple triggers, but I haven't seen any relative script in the scripts file.

you can use a trigger (not a simple trigger) for 48 hours and global variables to retain the value. Local variables only work inside their current scope. Global variables are stored in the savegame.

插入代码块:
(0, 0, 48, 
[],[]
),

remember that renown goes up and down as well.

use a global like "$current_rank" to store the number that represents the last promotion. Like 0: no promotion, 1:first promotion, 2:second promotion, ... You can then use it on your IF-block for the rewards.

if you want to control the clock/scheduler for a specific time of the day (say 12pm), then you can have a simple trigger and use the clock operations for that as well.
 
Thanks! I think I won't take into account the downs of the renown value, just the ups. Since my logic was that people 'hear' about you based on fame, even if your renown value goes down a bit, they don't magically forget you or your title.

EDIT: Works(basically)! Thank you, again.
 
markfamily 说:
( 365 * 24, 0, ti_once, #check trigger after one year and spawn party only once

wrong. The scheduler will fire at a random time between 0 hours and 365*24, then fire again in 365*24, and again (until the condition block is true and the re-arm is set to "infinite"). This was explained earlier, so you can read the old comments on triggers scheduler.

插入代码块:
party_set_ai_behavior
插入代码块:
party_set_ai_behavior                 = 1640  # (party_set_ai_behavior, <party_id>, <ai_bhvr>),
                                              # Sets AI behavior for the party. See header_parties.py for reference.
party_ID
not party_template_ID
 
One more question, if you please. So, I've put the trigger, turns out I didn't even need global variables. Now, EVERYTHING works as it should. The script triggers, as intended every 48 hourse/days, the correct message is displayed and all is well. However, it gives me some script errors, which seemingly have no real effect. The errors come up only at the time of the trigger.

插入代码块:
SCRIPT ERROR ON OPCODE 2070 Invalid Trigger Parameter ID,0, LINE NO. 0,
At script fame_system

Illegal value in statement; Opcode=520, Lino No. 1
etc.

And a screenshot, to show that a)all works well and b)exactly what the script errors say:
gxincg522yyspjmzg.jpg
It gets pretty annoying, so any help would be welcome. I should also mention that I use Diplomacy with the 1.153 version, as the Diplomacy is on that module system version.
Thanks!
 
Antonis 说:
插入代码块:
SCRIPT ERROR ON OPCODE 2070 Invalid Trigger Parameter ID,0, LINE NO. 0,
At script fame_system

Illegal value in statement; Opcode=520, Lino No. 1
etc.

And a screenshot, to show that a)all works well and b)exactly what the script errors say:
gxincg522yyspjmzg.jpg
It gets pretty annoying, so any help would be welcome. I should also mention that I use Diplomacy with the 1.153 version, as the Diplomacy is on that module system version.
Thanks!

show your code and the entire error message, easier to understand.

opcode you can find on header_operations.py
插入代码块:
store_trigger_param         = 2070  # (store_trigger_param, <destination>, <trigger_param_no>),
                                    # Version 1.153+. Retrieve the value of arbitrary trigger parameter. Parameters are enumerated starting from 1. Note that despite the introduction of this operation, there's not a single trigger with more than 3 parameters.

troop_get_slot                           =  520  # (troop_get_slot, <destination>, <troop_id>, <slot_no>),
 
kalarhan 说:
markfamily 说:
( 365 * 24, 0, ti_once, #check trigger after one year and spawn party only once

wrong. The scheduler will fire at a random time between 0 hours and 365*24, then fire again in 365*24, and again (until the condition block is true and the re-arm is set to "infinite"). This was explained earlier, so you can read the old comments on triggers scheduler.
Im really sorry I thought I had done it all right and followed all the help you have given to me but im starting to think im not capable of doing this.
So I understand my problem is the way I have implemented the numbers, the first number sets when the event is timed for but is random from 0 to the time set, the second number sets the delay when it runs again and the third is the re-arming which I have set so once it does run it will not happen again so my problem lies with the first two numbers, so if I set it to run right away then delay it for the set time then that is right I hope.
 
kalarhan 说:
show your code and the entire error message, easier to understand.

插入代码块:
 #fame system begin
  ("fame_system", [
	
    (store_trigger_param,":player_renown",0),
	(troop_get_slot, "trp_player", ":player_renown", slot_troop_renown),
    (store_trigger_param,":renown_number",":player_renown"),
	
	(try_begin),#renown>250
#	    (ge,":renown_number",250),
#		(lt,":renown_number",500),
		(is_between,":renown_number",250,500),
        (display_message,"@Your fame runs before you! You are known throughout Ellon as Recognized!",0xc3a278),
	(else_try),#renown>500
#		(ge,":renown_number",500),
#		(lt,":renown_number",750),
		(is_between,":renown_number",500,750),
        (display_message,"@Your fame runs before you! You are known throughout Ellon as Respected!",0xa50000),
	(else_try),#renown>750
#		(ge,":renown_number",750),
#		(lt,":renown_number",1000),
		(is_between,":renown_number",750,1000),
        (display_message,"@Your fame runs before you! You are known throughout Ellon as Distinguished!",0x5c8696),
	(else_try),#renown>1000
#	    (ge,":renown_number",1000),
#		(lt,":renown_number",1250), 
		(is_between,":renown_number",1000,1250),
        (display_message,"@Your fame runs before you! You are known throughout Ellon as Acclaimed!",0x04897c),
	(else_try),#renown>1250
#		(ge,":renown_number",1250),
#		(lt,":renown_number",1500),
		(is_between,":renown_number",1250,1500),
        (display_message,"@Your fame runs before you! You are known throughout Ellon as Renowned!",0xffd700),
	(else_try),#renown>1500 
	    (ge,":renown_number",1500),
		(display_message,"@Your fame runs before you! You are known throughout Ellon as Legendary!",0x8e518d),
    (try_end),
 
  ]),   
 #fame system end 

插入代码块:
#Fame System Begin
(0, 0, 48,[],[
    (call_script, "script_fame_system"),
]
),	 
#Fame System Begin
 
Tested it quickly and no errors on my side so far:

插入代码块:
#fame system begin
  ("fame_system", [
	
	(store_trigger_param_1,":player_renown"),
	(troop_get_slot, ":player_renown", "trp_player", slot_troop_renown),	
	
	(try_begin),#renown>250
		(is_between,":player_renown",250,500),
		(display_message,"@Your fame runs before you! You are known throughout Ellon as Recognized!",0xc3a278),
	(else_try),#renown>500
		(is_between,":player_renown",500,750),
		(display_message,"@Your fame runs before you! You are known throughout Ellon as Respected!",0xa50000),
	(else_try),#renown>750
		(is_between,":player_renown",750,1000),
		(display_message,"@Your fame runs before you! You are known throughout Ellon as Distinguished!",0x5c8696),
	(else_try),#renown>1000
		(is_between,":player_renown",1000,1250),
		(display_message,"@Your fame runs before you! You are known throughout Ellon as Acclaimed!",0x04897c),
	(else_try),#renown>1250
		(is_between,":player_renown",1250,1500),
		(display_message,"@Your fame runs before you! You are known throughout Ellon as Renowned!",0xffd700),
	(else_try),#renown>1500
		(ge,":player_renown",1500),
		(display_message,"@Your fame runs before you! You are known throughout Ellon as Legendary!",0x8e518d),
    (try_end),
  ]),   
 #fame system end

插入代码块:
#Fame System Begin
(48, 0, 0,[],[
	(call_script, "script_fame_system"),
]),	
#Fame System Begin

I'd recommend saving the fame rank/tier in a slot so you can check if there was any change in rank/tier before displaying the message so it doesn't get spammed every 48 hours but I imagine you might have that in mind already.
 
Antonis 说:
插入代码块:
 #fame system begin
  ("fame_system", [
	
    (store_trigger_param,":player_renown",0),
	(troop_get_slot, "trp_player", ":player_renown", slot_troop_renown),
    (store_trigger_param,":renown_number",":player_renown"),

What is a trigger parameter? It is a value that the engine has as entry parameter for special cases (like event target is hit by a arrow). See header_triggers.py for that list. A normal scheduler from module_triggers.py, etc, it is not such. Think about this, how would the engine know that you want the arbitrary value of a troop slot as the first parameter of this random trigger?

Variables names are there for us. People. Computer cant use them for reference. ":player_renown" and ":XPTY" are the same thing for the engine.

In short: remove those store_trigger_param as they do nothing (besides throw error messages).

now look at this operation
插入代码块:
troop_get_slot                           =  520  # (troop_get_slot, <destination>, <troop_id>, <slot_no>),
and the order for the parameters. The first one is the destination (the variable that will store the return value). Now look how you tried to use it and see your mistake.

插入代码块:
(is_between,":renown_number",250,500),
this works fine. You can also do a reverse IF to make the code easier to read, but that is just a suggestion.

IF value > 1500
  do this
ELSE IF value > 1200
  do this
...
END IF

as mentioned above you need a way to stop the spam of messages. A global as suggested earlier works fine for this.

IF renown > 1500 AND current_rank = 5
  display_message ...
  current_rank = 6
ELSE IF renown > 1200 AND current_rank = 4
  display_message ...
  current_rank = 5
...
END IF

globals start from zero, or you can use the game_start script to give it a initial value as well.

another suggestion: you can use the message system to display the promotion event. A game_menu/presentation with a cool background image or a display_box like the tutorial one for a pop up window. The display_message can be easily missed by the player as just random spam. VC has a few examples: presentation "game_concepts_tutorial", menu "set_goal_trigger_new_game" and dialog box
插入代码块:
(dialog_box, "str_game_difficulty_warning_desc", "str_game_difficulty_warning"),
 
@Seek n Destroy: As for a slot, the spamming of the message didn't cross my mind. Which is a bit silly of me, to be honest.  :razz:
Something that 'stores' the current rank and activates the script only when the next rank requirements are met might be a wiser idea than mine. Still, I think I should take care of those idiotic script errors first, before adding fluff.

@kalarhan: Wow. You really are a saint. The only thing I can say is it is the first time I tried my hand at an original script, made from scratch, not just edited third party ones. Still, deeply embarrassed by those stupid mistakes on my part.  :facepalm:

Thanks!
 
Hi !

Sorry if it's a dumb question but is it possible to use items variations for multiplayer mods? I've made a lot of colour variations of the same items and to make module_troops.py less cluttered, I would like, if possible, to regroup the different meshes under one same item. I've tried the following code but it always shows the first mesh and not the variations:

插入代码块:
 ["15_hosen", "Hose", [("15_hosen_blue",0),("15_hosen_brown",0),("15_hosen_grey",0),("15_hosen_yellow",0),("15_hosen_green",0),("15_hosen_red",0)], itp_merchandise|itp_type_foot_armor |itp_civilian|itp_attach_armature, 0,
 10 , weight(0.8)|abundance(100)|head_armor(0)|body_armor(0)|leg_armor(2)|difficulty(0) ,imodbits_cloth ],

Thanks in advance :smile:
 
Roudrac 说:
插入代码块:
 ["15_hosen", "Hose", [("15_hosen_blue",0),("15_hosen_brown",0),("15_hosen_grey",0),("15_hosen_yellow",0),("15_hosen_green",0),("15_hosen_red",0)], itp_merchandise|itp_type_foot_armor |itp_civilian|itp_attach_armature, 0,
 10 , weight(0.8)|abundance(100)|head_armor(0)|body_armor(0)|leg_armor(2)|difficulty(0) ,imodbits_cloth ],
An item can only have one base mesh, so you have to create a separate item per mesh variation.

Edit
Alternatively you can set the mesh and/or material of an item on ti_on_init_item
插入代码块:
cur_item_add_mesh                   = 1964  # (cur_item_add_mesh, <mesh_name_string>, [<lod_begin>], [<lod_end>]),
                                            # Version 1.161+. Only call inside ti_on_init_item trigger. Adds another mesh to item, allowing the creation of combined items. Parameter <mesh_name_string> should contain mesh name itself, NOT a mesh reference. LOD values are optional. If <lod_end> is used, it will not be loaded.
cur_item_set_material               = 1978  # (cur_item_set_material, <string_no>, <sub_mesh_no>, [<lod_begin>], [<lod_end>]),
                                            # Version 1.161+. Only call inside ti_on_init_item trigger. Replaces material that will be used to render the item mesh. Use 0 for <sub_mesh_no> to replace material for base mesh. LOD values are optional. If <lod_end> is used, it will not be loaded.
 
状态
不接受进一步回复。
后退
顶部 底部