Мой первый мод

Всем привет!
Я занимаюсь модостроением под The Fall относительно недавно, были различные попытки сделать под него мод,
и все не доходили руки. Поскольку информации на русском языке по модостроению относительно мало, я решил 
документировать свои фиксы, так сказать, для тех, кто хочет, но не может разобраться. За основу я взял версию 
от Руссобита 1.10 с установленными  Derfflinger v.7.4 и Freedom 2.0

В данной заметке я попробую одеть на персонажа пояс!
Все мы знаем, что пояс персонаж одеть не может, ибо некуда.
Итак, берем за основу самый простой пояс: http://fall.pro-d.ru/db/other/belt/

Его код в scripts/itemdata/items.py:

create_item_type(typeid='SET_BELT')
objects.set_attribute(object='SET_BELT', attribute="name", value=globaltext.SET_BELT_NAME)
objects.set_attribute(object='SET_BELT', attribute="hint", value=globaltext.SET_BELT_HINT)
objects.set_attribute(object='SET_BELT', attribute="resourceui", value='RES_ITEM65X32_MISCITEM_BELT')
objects.set_attribute(object='SET_BELT', attribute="resource3d", value='RES3D_BELT')
objects.set_attribute(object='SET_BELT', attribute="value", value=2.0)
objects.set_attribute(object='SET_BELT', attribute="weight", value=0.2)
objects.set_attribute(object='SET_BELT', attribute="stacking", value=1)

Следующей строкой указываем на какой слот он будет одеваться:
objects.set_attribute(object='SET_BELT', attribute="occupied_slots", value=["belt"])

И теперь можно в игре его одеть. Но что нам толку от пояса, если никаких полезностей он не несет?
Пусть он нам дает хотя бы +10 силы, +5 ловкости и 30 медицины. Странный пояс, да-да. :)

Придумал что-то отбалдовое:
objects.set_attribute(object='SET_BELT', attribute="eq_effect", value= { "strength" : 10, "agility": 5, "medicine": 30 })

в scripts/object_events.py есть две замечательные функции: on_equip и on_unequip. Первая срабатывает когда вещь
одеваем, вторая - когда снимаем.

Сначало хотел написать свой обработчик, после понял что можно модифицировать существующий DR_recalculate_bonus.
Вешаем обработчик в on_equip в самый конец:

if objects.get_attribute(itemtype, "eq_effect"):
DR_recalculate_bonus(objectid, "eq_effect", itemtype )
И в on_unequip тоже в самый конец:
if objects.get_attribute(itemtype, "eq_effect"):
DR_recalculate_bonus(objectid, "eq_effect", None )

Модифицируем ф-ю DR_recalculate_bonus:
def DR_recalculate_bonus ( character_id, object_type, itemtype ):
if character_id == None or object_type == None:
return
bonus.remove_temp_bonus( character_id, object_type )
if object_type == "armor_effect":
properity_table = DR_armor_bonus_calculator ( character_id )
elif object_type == "implantant":
properity_table = objects.get_att ( itemtype, "implantant_effect" )
elif object_type == "eq_effect":
properity_table = objects.get_att ( itemtype, "eq_effect" )
else:
properity_table = None
if properity_table:
bonus.add_temp_bonuses( character_id, properity_table, object_type )

Наш "eq_effect" будет относится не только к поясу, а к любому итему, имеющему атрибут "eq_effect".



Никогда в игре не повышал параметр телосложения. Считал его бесполезным. Действительно, с хорошей пушкой
наши персонажи практически не огребают. Появились идеи хоть немного сделать его полезным. 
В scripts/skill_tables.py модифицруем расчет грузоподъемности:

def strength_max_load(strength, constitution):
"""Returns max load (i.e., max. added weight of all inventory items) in kg.

Chars can carry more than max load, but they get penalties.

Parameters:
strength - Strength value.
constitution - Constitution value.
"""
assert strength >= 1
assert constitution >= 1

weight = ( strength * 3 )
weight += ( constitution * 1.5 )

return weight
Поскольку аргументов функции у нас поприбавилось, нужно добавить второй там, где ф-я вызывается,
в частности в scripts/object_events.py:

def update_speed( character_id ):
...
strength = objects.get_attribute( object=character_id, attribute="strength" )
constitution = objects.get_attribute( object=character_id, attribute="constitution" )
...
if strength == 0: rel_load = 0
else: rel_load = load / skill_tables.strength_max_load(strength, constitution)



def get_load_text( character_id ):
...
constitution = objects.get_attribute( object=character_id, attribute="constitution" )

if strength>0:
relload = load / skill_tables.strength_max_load(strength, constitution)

Тем же путем, можно сделать интелект более полезным, в частности влияющем на механику, разговор,
торговлю. Пока над этим не думал :)



Вот что мне не нравится в коктеле молотова, точнее в его крафте - ветошь к нему нужно поискать.
В своем моде я хочу повысить значение кидающихся взрывчатых итемов - отсюда следует, что их нужно в игре 
где-то взять в достаточном количестве. 
Первое: нужно где-то обжиться ветошью под коктель, а поскольку ветошь это тряпка, то будем резать одежду. 
Ту самую, обычную. Например: http://fall.pro-d.ru/db/armor/vest/normal_clothes_2/   

Во что превратился код ветоши в scripts/itemdata/items.py:
create_item_type(typeid='SET_RAGS')
objects.set_attribute(object='SET_RAGS', attribute="name", value=globaltext.SET_RAGS_NAME)
objects.set_attribute(object='SET_RAGS', attribute="hint", value=globaltext.SET_RAGS_HINT)
objects.set_attribute(object='SET_RAGS', attribute="resourceui", value='RES_ITEM65X32_MISCITEM_RAGS')
objects.set_attribute(object='SET_RAGS', attribute="resource3d", value='RES3D_RAGS')
objects.set_attribute(object='SET_RAGS', attribute="value", value=1.0)
objects.set_attribute(object='SET_RAGS', attribute="weight", value=0.1)
objects.set_attribute(object='SET_RAGS', attribute="stacking", value=10)
objects.set_attribute(object='SET_RAGS', attribute="item_combination", value={
"difficulty_assemble" : COMBO_EVERYBODY,
"assemble_function" : "assemble_rags",
"combination_list" :
cutting(['SET_NORMAL_CLOTHES_1', 'SET_NORMAL_CLOTHES_2', 'SET_NORMAL_CLOTHES_3', 'SET_NORMAL_CLOTHES_4', 'SET_NORMAL_CLOTHES_5', 'SET_NORMAL_CLOTHES_6', 'SET_LOW_SHOES']) })
 
Что я с ней сделал? Я увеличил количество в пачке ( у нас же ее будет много! ) и написал функцию (см ниже). 
Суть функции в том, что она возвращает пачку массивов, состоящую из режущих предметов и предметов, 
которые необходимо порезать. У меня в планах еще порезка разного мяса, шитье и мн др, и копировать везде 
режущие предметы утомительно - сейчас можно в одном месте только добавлять их.
 
Режем мы всю обычную одежду и кросовки. В коде я указал функцию, которой буду обрабатывать данные 
наборы крафта:
"assemble_function"                :       "assemble_rags",

Данная функция определяется в файле scripts/combos.py:
def assemble_rags(character_id, items, item):

new_count = 0
exp = 0

for act_item in items:
# Не удаляем наши инструменты
if objects.get_att ( act_item, 'typeid' ) not in CUTTING_TOOLS:
              # Ботинки меньше по размеру - получим меньше тряпок
if objects.get_att ( act_item, 'typeid' ) == 'SET_LOW_SHOES':
new_count += 3
else:
new_count += 5

# С каждой порезанной вещью персонаж получает единичку опыта.
exp += 1
objects.remove_item_from_inventory(character_id, act_item)

while new_count > 0:
objects.create_item_in_inventory(object=character_id, equipment=item)
new_count -= 1

character.add_experience(character_id, exp)
return True

В файле scripts/define_globals.py:
# Список режущих предметов
CUTTING_TOOLS = ['SET_KNIFE','SET_THROWING_KNIFE','SET_KATANA','SET_MACHETE','SET_SHURIKEN','SET_AXE', 'SET_BIG_KNIFE', 'SET_GIANT_KNIFE', 'SET_PLANT_SHEARS']
 
def cutting(array_of_objects):
objs = []
for item in array_of_objects:
for tool in CUTTING_TOOLS:
objs.append([item, tool])

return objs
 
    
Расчитывал сделать, чтобы за раз можно было резать сразу несколько вещей, но пока не разобрался как :)
Точнее, можно сделать как-то так в определении итема:
['SET_MACHETE', 'SET_NORMAL_CLOTHES_3'], ['SET_MACHETE', 'SET_NORMAL_CLOTHES_3', 'SET_NORMAL_CLOTHES_1'],
['SET_MACHETE', 'SET_NORMAL_CLOTHES_2', 'SET_NORMAL_CLOTHES_6'] и мн.др. 
Только это мне кажется каким-то кривокодьем и я так делать не буду :) 
Хотя выковырял код комбинирования в object_events.py, хотел сделать все через словари (python), 
но ругается при загрузке итемов в память. Думаю обойдем, со временем. 

Тряпками мы себя обеспечили, осталось добавить комбинаций самому коктелю:
create_throw_object_type(typeid='SET_MOLOTOV_COCKTAIL')
...
"combination_list" : [
['SET_RAGS','SET_BOTTLE_OF_HOOCH'],
['SET_RAGS','SET_BOTTLE_OF_BOOZE'],
['SET_RAGS','SET_BOTTLE_OF_WHISKEY'],
['SET_RAGS','SET_TIN_WITH_ALCOHOL'],
['SET_RAGS','SET_BOTTLE_OF_GAS']]})



Ища идеи что можно сотворить в моде полезного - вычитал, что в RT mod была такая фишка,
как экспа за применение навыков ( не за первое, а вообще ). Хорошая фишка, сейчас ее реализуем в нашем. 
Приведу пример кражи из карманов. В scripts/object_scripts.py:
В def on_steal(target, operator) вместо give_first_use_exp(operator, "steal_item") пишем следующее, 
хотя и первую кражу оставить можно :)
character.add_experience(operator, 10)
В RT мод так же экспа зависит от навыка, но если у всех подрят все воровать - не вижу смысла,
ибо экспа растет и так очень быстро даже при мелких значениях. 


 

comAT0Zz 16.01.2015 | Комментарии (15)













Разработка Sergey A.Zhukov 2007-2012