Merge: From default to build_pipeline_v3

--HG--
branch : build_pipeline_v3
hg/feature/build_pipeline_v3
kaetemi 13 years ago
commit e1d4f16939

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

@ -0,0 +1,190 @@
-- create the webig namespace without reseting if already created in an other file.
if (webig==nil) then
webig= {}
end
if (webig.sheetLists==nil) then
webig.sheetLists = {}
end
function webig:addSheet(dst, sheet, quality, quantity, worned, user_color, rm_class_type, rm_faber_stat_type)
if quality == nil then quality=0 end
if quantity == nil then quantity=0 end
if worned == nil then worned=0 end
if user_color == nil then user_color=0 end
if rm_class_type == nil then rm_class_type=0 end
if rm_faber_stat_type == nil then rm_faber_stat_type=0 end
addDbProp(dst..":SHEET", sheet)
addDbProp(dst..":WORNED", worned)
addDbProp(dst..":QUALITY", quality)
addDbProp(dst..":QUANTITY", quantity)
addDbProp(dst..":USER_COLOR", user_color)
addDbProp(dst..":RM_CLASS_TYPE", rm_class_type)
addDbProp(dst..":RM_FABER_STAT_TYPE", rm_faber_stat_type)
end
function webig:cleanSheets(db)
delDbProp(db)
end
function webig:addSheetList(name, ctrl, db, size)
webig.sheetLists[name] = {}
webig.sheetLists[name].ctrl = ctrl
webig.sheetLists[name].db = db
webig.sheetLists[name].selection = ""
webig.sheetLists[name].size = size
end
function webig:copyItems(src, dst)
addDbProp(dst..":SHEET", getDbProp(src..":SHEET"))
addDbProp(dst..":WORNED", getDbProp(src..":WORNED"))
addDbProp(dst..":QUALITY", getDbProp(src..":QUALITY"))
addDbProp(dst..":QUANTITY", getDbProp(src..":QUANTITY"))
addDbProp(dst..":USER_COLOR", getDbProp(src..":USER_COLOR"))
addDbProp(dst..":RM_CLASS_TYPE", getDbProp(src..":RM_CLASS_TYPE"))
addDbProp(dst..":RM_FABER_STAT_TYPE", getDbProp(src..":RM_FABER_STAT_TYPE"))
end
function webig:swapItems(src, dst)
local sheet = getDbProp(dst..":SHEET")
local worned = getDbProp(dst..":WORNED")
local quality = getDbProp(dst..":QUALITY")
local quantity = getDbProp(dst..":QUANTITY")
local user_color = getDbProp(dst..":USER_COLOR")
local rm_class_type = getDbProp(dst..":RM_CLASS_TYPE")
local rm_faber_stat_type = getDbProp(dst..":RM_FABER_STAT_TYPE")
addDbProp(dst..":SHEET", getDbProp(src..":SHEET"))
addDbProp(dst..":WORNED", getDbProp(src..":WORNED"))
addDbProp(dst..":QUALITY", getDbProp(src..":QUALITY"))
addDbProp(dst..":QUANTITY", getDbProp(src..":QUANTITY"))
addDbProp(dst..":USER_COLOR", getDbProp(src..":USER_COLOR"))
addDbProp(dst..":RM_CLASS_TYPE", getDbProp(src..":RM_CLASS_TYPE"))
addDbProp(dst..":RM_FABER_STAT_TYPE", getDbProp(src..":RM_FABER_STAT_TYPE"))
addDbProp(src..":SHEET", sheet)
addDbProp(src..":WORNED", worned)
addDbProp(src..":QUALITY", quality)
addDbProp(src..":QUANTITY", quantity)
addDbProp(src..":USER_COLOR", user_color)
addDbProp(src..":RM_CLASS_TYPE", rm_class_type)
addDbProp(src..":RM_FABER_STAT_TYPE", rm_faber_stat_type)
end
function webig:deleteItem(src)
addDbProp(src..":SHEET", 0)
addDbProp(src..":WORNED", 0)
addDbProp(src..":QUALITY", 0)
addDbProp(src..":QUANTITY", 0)
addDbProp(src..":USER_COLOR", 0)
addDbProp(src..":RM_CLASS_TYPE", 0)
addDbProp(src..":RM_FABER_STAT_TYPE", 0)
end
function webig:paramDbSheetSlot(sheet_list, ctrl)
local ctrlSheet = webig.sheetLists[sheet_list].ctrl:find("list:"..ctrl)
if ctrlSheet ~= nil then
ctrlSheet.left_click="lua"
ctrlSheet.left_click_params="webig:addOrRemoveDbSheet(\'"..sheet_list.."\', \'"..ctrl.."\')"
ctrlSheet.dragable=true
ctrlSheet.can_drop=true
ctrlSheet.on_drop="lua"
ctrlSheet.on_drop_params="webig:dropDbSheet(\'"..sheet_list.."\', \'"..ctrl.."\', \'%src\')"
ctrlSheet.on_can_drop="lua"
ctrlSheet.on_can_drop_params="webig:canDropDbSheet(\'"..sheet_list.."\', \'"..ctrl.."\', \'%src\')"
end
end
function webig:paramDbSheetSelect(sheet_list, ctrl, lua_function)
local ctrlSheet = webig.sheetLists[sheet_list].ctrl:find("list:"..ctrl)
if ctrlSheet ~= nil then
ctrlSheet.left_click="lua"
ctrlSheet.left_click_params=lua_function.."(\'"..sheet_list.."\', \'"..ctrl.."\')"
ctrlSheet.dragable=false
ctrlSheet.can_drop=false
end
end
function webig:canDropDbSheet(sheet_list, ctrl, src)
webig.sheetLists[sheet_list].ctrl:find("list:"..ctrl).can_drop=true
end
function webig:dropDbSheet(sheet_list, ctrl, src)
local db = webig.sheetLists[sheet_list].db
local sl_id = webig.sheetLists[sheet_list].ctrl.id
if (string.sub(src, 1, string.len(sl_id)) == sl_id) then -- copy from same list sheet
local pos=nil
for i=1, string.len(src) do
if string.sub(src, i, i) == ":" then
pos = i+1
end
end
id = string.sub(src, pos, string.len(src))
webig:swapItems(db..":"..id, db..":"..ctrl)
else
slot = getUI(src)
if slot ~= nil then
id = findReplaceAll(src, slot.parent.id..":", "")
webig:copyItems("LOCAL:INVENTORY:BAG:"..id, db..":"..ctrl)
end
end
end
function webig:addOrRemoveDbSheet(sheet_list, ctrl)
local db = webig.sheetLists[sheet_list].db
if getDbProp(db..":"..ctrl..":SHEET") == 0 then -- Add item
webig:AddDbSheet(sheet_list, ctrl)
else
webig:removeDbSheetQuantity(sheet_list, ctrl)
end
end
function webig:AddDbSheet(sheet_list, ctrl)
runAH(nil, "enter_modal", "group=ui:interface:webig_html_modal")
local whm = getUI("ui:interface:webig_html_modal")
whm.child_resize_h=false
whm.h = 44*webig.sheetLists[sheet_list].size
whm.w = 224
whm = getUI("ui:interface:webig_html_modal:html")
if whm ~= nil then
whm:refresh() -- url need be setted before
end
webig.sheetLists[sheet_list].selection = ctrl
end
function webig:removeDbSheetQuantity(sheet_list, ctrl)
local db = webig.sheetLists[sheet_list].db
webig:copyItems(db..":"..ctrl, "UI:DROP_DESTROY_ITEM:ITEM")
runAH(nil, "set_keyboard_focus", "select_all=true|target=ui:interface:webig_drop_destroy_item_quantity_modal:edit:eb")
getUI("ui:interface:webig_drop_destroy_item_quantity_modal:ok_cancel:ok").onclick_l="lua"
getUI("ui:interface:webig_drop_destroy_item_quantity_modal:ok_cancel:ok").params_l="webig:doRemoveDbSheetQuantity(\'"..sheet_list.."\', \'"..ctrl.."\')"
getUI("ui:interface:webig_drop_destroy_item_quantity_modal:edit:eb").on_enter="lua"
getUI("ui:interface:webig_drop_destroy_item_quantity_modal:edit:eb").on_enter_params="webig:doRemoveDbSheetQuantity(\'"..sheet_list.."\', \'"..ctrl.."\')"
runAH(nil, "enter_modal", "group=ui:interface:webig_drop_destroy_item_quantity_modal")
setDbProp("UI:DROP_DESTROY_ITEM:ITEM:QUANTITY", getDbProp(db..":"..ctrl..":QUANTITY"))
getUI("ui:interface:webig_drop_destroy_item_quantity_modal:edit:eb").input_string=tostring(getDbProp(db..":"..ctrl..":QUANTITY"))
end
function webig:doRemoveDbSheetQuantity(sheet_list, ctrl)
local db = webig.sheetLists[sheet_list].db
runAH(nil, "leave_modal", "group=ui:interface:webig_drop_destroy_item_quantity_modal")
local new_quantity = tonumber(getUI("ui:interface:webig_drop_destroy_item_quantity_modal:edit:eb").input_string)
local current_quantity = getDbProp(db..":"..ctrl..":QUANTITY")
if new_quantity >= current_quantity then
webig:deleteItem(db..":"..ctrl)
else
addDbProp(db..":"..ctrl..":QUANTITY", current_quantity-new_quantity)
end
end
--assert(nil, "RELOADABLE SCRIPT");

@ -0,0 +1,120 @@
<!-- ****************************************** -->
<!-- * WEBIG WIDGETS * -->
<!-- ****************************************** -->
<interface_config>
<root id="interface" x="0" y="0" w="800" h="600" active="true" />
<lua file="webig.lua" />
<!-- //////////// STYLE : webigchat_desc /////////// -->
<style style="webigchat_desc" type="text" fontsize="12" justification="dont_clip_word" color="0 0 0 255" global_color="false" multi_line="true" multi_line_space="0" line_maxw="320" multi_line_maxw_only="true" />
<!-- //////////// STYLE : webigchat_option /////////// -->
<style style="webigchat_option" type="text" format_taged="true" fontsize="10" justification="dont_clip_word" color="0 0 64 255" underlined="true" global_color="false" multi_line="true" multi_line_space="0" line_maxw="320" multi_line_maxw_only="true" />
<!-- //////////// STYLE : webigchat_option_but /////////// -->
<style style="webigchat_option_but" type="button_link" posref="TL TL" x="0" y="0" sizeref="wh" w="0" h="0" onclick_l="proc" params_l="proc_browse_faq" />
<!-- //////////// TEMPLATE : webig_3dbulle_L /////////// -->
<template name="webig_3dbulle_L" id="" keep="true">
<group id="#id" type="in_scene_bubble" header_active="false" options="no_bordure" openable="false" savable="false" resizer="true" movable="false" right_button="false" opened="true" child_resize_w="true" w="0" max_w="512" min_w="48" child_resize_h="true" in_scene_offset_x="-95" win_priority="%win_priority_world_space" posref="BL BR" use_cursor="true">
<group id="header_opened" x="0" y="0" child_resize_w="true" w="0" child_resize_h="true" h="0" max_w="512" min_w="48" max_h="256" min_h="48" posref="TL TL">
<group id="window" x="0" y="0" child_resize_w="true" child_resize_wmargin="10" child_resize_h="true" child_resize_hmargin="10" posref="TL TL">
<group id="back" x="0" y="0" w="0" h="0" sizeref="wh" posref="TL TL">
<view type="bitmap" id="win_M" posref="MM MM" scale="true" sizeref="wh" w="-10" h="-10" texture="Bulle_M.tga" global_color="false" />
<view type="bitmap" id="win_T" posparent="win_M" posref="TL BL" scale="true" sizeref="w" w="0" h="5" texture="Bulle_T.tga" global_color="false" />
<view type="bitmap" id="win_B" posparent="win_M" posref="BL TL" scale="true" sizeref="w" w="0" h="5" texture="Bulle_B.tga" global_color="false" />
<view type="bitmap" id="win_L" posparent="win_M" posref="TL TR" scale="true" sizeref="h" w="5" h="0" texture="Bulle_L.tga" global_color="false" />
<view type="bitmap" id="win_R" posparent="win_M" posref="TR TL" scale="true" sizeref="h" w="5" h="0" texture="Bulle_R.tga" global_color="false" />
<view type="bitmap" id="win_TL" posref="TL TL" texture="Bulle_TL.tga" global_color="false" />
<view type="bitmap" id="win_TR" posref="TR TR" texture="Bulle_TR.tga" global_color="false" />
<view type="bitmap" id="win_BL" posref="BL BL" texture="Bulle_BL.tga" global_color="false" />
<view type="bitmap" id="win_BR" posref="BR BR" texture="Bulle_BR.tga" global_color="false" />
</group>
<view style="webigchat_desc" id="text" posref="TL TL" x="5" y="-24" />
<ctrl type="button" button_type="push_button" tx_normal="Bulle_next.tga" tx_pushed="Bulle_next.tga" tx_over="Bulle_next.tga" color="255 255 255 255" col_over="255 255 255 0" col_pushed="255 255 255 255" global_color_normal="false" global_color_over="false" global_color_pushed="false" tooltip="uiNext" id="but_next" posref="TR TR" x="-5" y="-5" onclick_l="bubble_next" active="false" />
<ctrl type="button" button_type="push_button" tx_normal="Bulle_quit.tga" tx_pushed="Bulle_quit.tga" tx_over="Bulle_quit.tga" color="255 255 255 255" col_over="255 255 255 0" col_pushed="255 255 255 255" global_color_normal="false" global_color_over="false" global_color_pushed="false" tooltip="uiSkip" id="but_skip" posref="TL TR" posparent="but_next" x="-4" y="0" onclick_l="bubble_skip" active="false" />
<!-- Yoyo: Fake to have minimum bubble size -->
<group id="min_w" posparent="text" posref="TL TL" x="0" y="0" w="48" h="14" />
<view style="webigchat_option" id="opt0" posparent="text" posref="BL TL" x="16" y="-4" />
<view style="webigchat_option" id="opt1" posparent="opt0" posref="BL TL" x="0" y="-4" />
<view style="webigchat_option" id="opt2" posparent="opt1" posref="BL TL" x="0" y="-5" />
<view style="webigchat_option" id="opt3" posparent="opt2" posref="BL TL" x="0" y="-5" />
<view style="webigchat_option" id="opt4" posparent="opt3" posref="BL TL" x="0" y="-5" />
<view style="webigchat_option" id="opt5" posparent="opt4" posref="BL TL" x="0" y="-5" />
<view style="webigchat_option" id="opt6" posparent="opt5" posref="BL TL" x="0" y="-5" />
<view style="webigchat_option" id="opt7" posparent="opt6" posref="BL TL" x="0" y="-5" />
<ctrl style="webigchat_option_but" id="optb0" posparent="opt0" params_l="0" />
<ctrl style="webigchat_option_but" id="optb1" posparent="opt1" params_l="1" />
<ctrl style="webigchat_option_but" id="optb2" posparent="opt2" params_l="2" />
<ctrl style="webigchat_option_but" id="optb3" posparent="opt3" params_l="3" />
<ctrl style="webigchat_option_but" id="optb4" posparent="opt4" params_l="4" />
<ctrl style="webigchat_option_but" id="optb5" posparent="opt5" params_l="5" />
<ctrl style="webigchat_option_but" id="optb6" posparent="opt6" params_l="6" />
<ctrl style="webigchat_option_but" id="optb7" posparent="opt7" params_l="7" />
</group>
<view type="bitmap" id="win_talk" posref="BR TR" x="-24" y="2" posparent="window" texture="Bulle_Say_L.tga" global_color="false" />
</group>
</group>
</template>
<!-- //////////// TEMPLATE : webig_modal /////////// -->
<group type="modal" id="webig_html_modal" w="360" posref="TL TL" child_resize_hmargin="8" child_resize_h="true" x="0" y="0" active="false" options="skin_modal" escapable="true" global_color="true">
<group id="html" type="html" posref="MM MM" url="" title_prefix="uiQuickhelpTitle" sizeref="wh" x="0" y="0" w="0" h="0" background_color="0 0 0 0" error_color="255 240 48 255" link_color="240 155 100 255" text_color="210 210 210 255" h1_color="255 255 255 255" h2_color="255 255 255 255" h3_color="255 255 255 255" h4_color="255 255 255 255" h5_color="255 255 255 255" h6_color="255 255 255 255" text_font_size="10" h1_font_size="16" h2_font_size="14" h3_font_size="13" h4_font_size="12" h5_font_size="11" h6_font_size="11" paragraph_begin_space="12" multi_line_space_factor="0.25" td_begin_space="0" li_begin_space="4" ul_begin_space="12" li_indent="-10" ul_indent="30" checkbox_bitmap_normal="patch_off.tga" checkbox_bitmap_pushed="patch_on.tga" checkbox_bitmap_over="" background_bitmap_view="" home="" browse_next_time="false" timeout="0" form_text_area_group="edit_box_widget_multiline" >
<group id="black" posref="BR BR" sizeref="hw" w="-16" h="-12" inherit_gc_alpha="true"/>
<view type="bitmap" id="black2" posparent="black" posref="MM MM" sizeref="wh" w="-2" h="-2" inherit_gc_alpha="true" scale="true" texture="blank.tga" global_color="false"/>
<group type="list" id="text_list" fontsize="9" posref="TL TL" posparent="black" x="2" y="-2" space="0" sizeref="hw" w="-4" h="-4" maxelements="2000"/>
<ctrl style="skin_scroll" id="scroll_bar" />
</group>
</group>
<!-- //////////// MODAL : webig_exchange_choose_in_bag /////////// -->
<group type="modal" id="webig_exchange_choose_in_bag" w="360" child_resize_hmargin="8" child_resize_h="true" x="0" y="0" active="false" options="skin_modal" escapable="true" global_color="true">
<view type="text" id="title" posref="TL TL" x="6" y="-8" color="255 255 255 255" global_color="false" fontsize="10" shadow="true" hardtext="uiBCTitleMPItemType"/>
<group type="list_sheet" id="list" nature="item" posref="TL TL" x="4" y="-20" value="UI:VARIABLES:BOTCHAT:FILTER_ITEM_TYPE_SELECTED" force_item_background_generic="true" wspace="2" hspace="2" array="false" w="350" lmargin="0" rmargin="0" tmargin="2" bmargin="2" child_resize_h="true" onclick_l="confirm_change_botchat_buy_filter_item_type" on_tooltip="botchat_tt_item_type" use_quantity="false" use_quality="false" display_empty_slot="true"/>
<view type="text" id="no_filter" posparent="ctrl" posref="TL MM" x="24" y="-46" fontsize="12" shadow="true" case_mode="%case_upper" global_color="false" hardtext="uiBCNoItemTypeFilter"/>
</group>
<!-- //////////// MODAL : webig_drop_destroy_item_quantity_modal /////////// -->
<group type="modal" id="webig_drop_destroy_item_quantity_modal" exit_click_out="true" posref="TL TL" w="180" h="80" x="-8" y="8" options="skin_modal">
<ctrl type="sheet" id="sheet" value="UI:DROP_DESTROY_ITEM:ITEM" posparent="parent" posref="MM MM" x="-26" y="0"/>
<view type="text" id="x" posparent="sheet" posref="MR MM" x="8" y="0" color="255 255 255 255" fontsize="12" shadow="true" hardtext="X"/>
<instance template="edit_box_widget" entry_type="positive_integer" id="edit" text_ref="TR TR" text_y="-1" fontsize="12" posparent="sheet" posref="MR ML" x="16" text_x="-2" w="32" prompt="" enter_loose_focus="false" multi_line="false" max_num_chars="3" onchange="editbox_number" onchange_params="value=UI:DROP_DESTROY_ITEM:ITEM:QUANTITY|update_text=false" onenter="proc" params="webig_drop_destroy_item_quantity_modal_ok" max_historic="0"/>
<instance template="button_ok_cancel" posref="BR BR" x="-4" y="4" onclick_ok="" onclick_ok_param="" onclick_cancel="leave_modal" onclick_cancel_param=""/>
<link expr="eq(@UI:DROP_DESTROY_ITEM:DROP_MODE,1)" target="drop_text:active"/>
<link expr="ne(@UI:DROP_DESTROY_ITEM:DROP_MODE,1)" target="destroy_text:active"/>
</group>
<!-- //////////// TEMPLATE : webig_list_sheet /////////// -->
<template name="webig_list_sheet" keep="true" db="" w="200" y="-10" x="10">
<group id="list_group" w="#w" y="#y" x="#x" posref="TL TL" child_resize_h="true" >
<group type="list_sheet" nature="item" id="list" posref="TL TL" x="0" y="0" child_resize_h="true" wspace="8" hspace="8" value="#db" array="true" auto_grayed="true" onclick_r="open_item_help" tooltip="uittSelectMp" />
</group>
</template>
<!-- //////////// TEMPLATE : webig_frame_borderless /////////// -->
<template name="webig_frame_borderless" keep="true" w="200" h="200" x="0" y="0" movable="true">
<group id="content" w="#w" h="#h" x="#x" y="#y" posref="MM MM" >
<group id="html" type="html" posref="TL TL" url="" title_prefix="uiQuickhelpTitle" sizeref="wh" x="0" y="0" w="0" h="0" background_color="0 0 0 0" error_color="255 240 48 255" link_color="240 155 100 255" text_color="210 210 210 255" h1_color="255 255 255 255" h2_color="255 255 255 255" h3_color="255 255 255 255" h4_color="255 255 255 255" h5_color="255 255 255 255" h6_color="255 255 255 255" text_font_size="10" h1_font_size="16" h2_font_size="14" h3_font_size="13" h4_font_size="12" h5_font_size="11" h6_font_size="11" paragraph_begin_space="12" multi_line_space_factor="0.25" td_begin_space="0" li_begin_space="4" ul_begin_space="12" li_indent="-10" ul_indent="30" checkbox_bitmap_normal="patch_off.tga" checkbox_bitmap_pushed="patch_on.tga" checkbox_bitmap_over="" background_bitmap_view="" home="" browse_next_time="false" timeout="0" form_text_area_group="edit_box_widget_multiline" >
<group id="black" posref="BR BR" sizeref="hw" w="-16" h="-12" inherit_gc_alpha="true"/>
<view type="bitmap" id="black2" posparent="black" posref="MM MM" sizeref="wh" w="-2" h="-2" inherit_gc_alpha="true" scale="true" texture="blank.tga" global_color="false"/>
<group type="list" id="text_list" fontsize="9" posref="TL TL" posparent="black" x="2" y="-2" space="0" sizeref="hw" w="-4" h="-4" maxelements="2000"/>
<ctrl style="skin_scroll" id="scroll_bar" />
</group>
</group>
</template>
<!-- //////////// TEMPLATE : webig_frame_skin_modal /////////// -->
<template name="webig_frame_skin_modal" keep="true" w="200" h="200" x="0" y="0">
<group id="group" type="container" active="true" w="#w" h="#h" x="#x" y="#y" posref="MM MM" options="skin_modal" opened="true" openable="true" movable="true" header_color="UI:SAVE:WIN:COLORS:COM">
<group id="header_closed" x="0" y="0" w="#w" h="16" posref="TL TL"></group>
<group id="header_opened" x="0" y="0" w="#w" h="16" posref="TL TL"></group>
<group id="content" x="0" y="0" w="0" h="0" posref="TL TL ">
<group id="html" type="html" posref="MM MM" url="" title_prefix="uiQuickhelpTitle" sizeref="wh" x="0" y="0" w="0" h="0" background_color="0 0 0 0" error_color="255 240 48 255" link_color="240 155 100 255" text_color="210 210 210 255" h1_color="255 255 255 255" h2_color="255 255 255 255" h3_color="255 255 255 255" h4_color="255 255 255 255" h5_color="255 255 255 255" h6_color="255 255 255 255" text_font_size="10" h1_font_size="16" h2_font_size="14" h3_font_size="13" h4_font_size="12" h5_font_size="11" h6_font_size="11" paragraph_begin_space="12" multi_line_space_factor="0.25" td_begin_space="0" li_begin_space="4" ul_begin_space="12" li_indent="-10" ul_indent="30" checkbox_bitmap_normal="patch_off.tga" checkbox_bitmap_pushed="patch_on.tga" checkbox_bitmap_over="" background_bitmap_view="" home="" browse_next_time="false" timeout="0" form_text_area_group="edit_box_widget_multiline" >
<group id="black" posref="BR BR" sizeref="hw" w="-16" h="-12" inherit_gc_alpha="true"/>
<view type="bitmap" id="black2" posparent="black" posref="MM MM" sizeref="wh" w="-2" h="-2" inherit_gc_alpha="true" scale="true" texture="blank.tga" global_color="false"/>
<group type="list" id="text_list" fontsize="9" posref="TL TL" posparent="black" x="2" y="-2" space="0" sizeref="hw" w="-4" h="-4" maxelements="2000"/>
<ctrl style="skin_scroll" id="scroll_bar" />
</group>
</group>
</group>
</template>
</interface_config>

@ -997,7 +997,7 @@ void CBotChatPageTrade::startSellDialog(CDBCtrlSheet *sheet, CCtrlBase * /* pCal
CCtrlTextButton *confirmButton = dynamic_cast<CCtrlTextButton*>(ig->getCtrl("ok"));
if (confirmButton)
{
confirmButton->setActive( sheet->getLockedByOwner() );
confirmButton->setActive( !sheet->getLockedByOwner() );
confirmButton->setText(CI18N::get("uiSellImmediately"));
confirmButton->setDefaultContextHelp(CI18N::get("uittDirectSellButton"));
}

@ -2088,7 +2088,7 @@ public:
if(GenericMsgHeaderMngr.pushNameToStream(msgName, out))
{
uint8 teamMember = (uint8) peopleIndex;
out.serialEnum(teamMember);
out.serial(teamMember);
NetMngr.push(out);
//nlinfo("impulseCallBack : %s %d sent", msgName.c_str(), teamMember);
}

@ -1108,9 +1108,7 @@ namespace CHARSYNC
void setResult(TCharacterNameResult value)
{
_Result = value;
}
//
uint32 getUserId() const
@ -1120,9 +1118,7 @@ namespace CHARSYNC
void setUserId(uint32 value)
{
_UserId = value;
}
//
uint8 getCharIndex() const
@ -1132,9 +1128,7 @@ namespace CHARSYNC
void setCharIndex(uint8 value)
{
_CharIndex = value;
}
//
const ucstring& getFullName() const
@ -1144,9 +1138,7 @@ namespace CHARSYNC
void setFullName(const ucstring &value)
{
_FullName = value;
}
bool operator == (const CValidateNameResult &other) const
@ -1161,7 +1153,6 @@ namespace CHARSYNC
// constructor
CValidateNameResult()
{
}
void serial(NLMISC::IStream &s)
@ -1170,7 +1161,6 @@ namespace CHARSYNC
s.serial(_UserId);
s.serial(_CharIndex);
s.serial(_FullName);
}

@ -884,6 +884,7 @@ namespace RYMSG
std::vector< NLMISC::CSheetId > _LootList;
//
NLMISC::CSheetId _Outpost;
uint32 _Organization;
//
float _MaxHitRangeForPC;
//
@ -1336,6 +1337,21 @@ namespace RYMSG
_Outpost = value;
}
//
uint32 getOrganization() const
{
return _Organization;
}
void setOrganization(uint32 value)
{
_Organization = value;
}
//
float getMaxHitRangeForPC() const
@ -1431,6 +1447,7 @@ namespace RYMSG
&& _ContextOptions == other._ContextOptions
&& _LootList == other._LootList
&& _Outpost == other._Outpost
&& _Organization == other._Organization
&& _MaxHitRangeForPC == other._MaxHitRangeForPC
&& _UserModelId == other._UserModelId
&& _CustomLootTableId == other._CustomLootTableId
@ -1489,6 +1506,7 @@ namespace RYMSG
s.serialCont(_ContextOptions);
s.serialCont(_LootList);
s.serial(_Outpost);
s.serial(_Organization);
s.serial(_MaxHitRangeForPC);
s.serial(_UserModelId);
s.serial(_CustomLootTableId);

@ -175,6 +175,42 @@
#include "nel/misc/hierarchical_timer.h"
inline uint32 saveGameCycleToSecond(NLMISC::TGameCycle tick)
{
// Evaluate the UTC of this event (with the current date of save). Suppose that 1 second==10 tick
// NB: result should be positive since no event should have been launched before 1970!
if (tick < CTickEventHandler::getGameCycle())
{
NLMISC::TGameCycle tick_dt = CTickEventHandler::getGameCycle() - tick;
uint32 s_dt = tick_dt / 10;
return NLMISC::CTime::getSecondsSince1970() - s_dt;
}
else
{
NLMISC::TGameCycle tick_dt = tick - CTickEventHandler::getGameCycle();
uint32 s_dt = tick_dt / 10;
return NLMISC::CTime::getSecondsSince1970() + s_dt;
}
}
inline NLMISC::TGameCycle loadSecondToGameCycle(uint32 second)
{
if (second < NLMISC::CTime::getSecondsSince1970())
{
uint32 s_dt = NLMISC::CTime::getSecondsSince1970() - second;
NLMISC::TGameCycle tick_dt = s_dt * 10;
return CTickEventHandler::getGameCycle() - tick_dt;
}
else
{
uint32 s_dt = second - NLMISC::CTime::getSecondsSince1970();
NLMISC::TGameCycle tick_dt = s_dt * 10;
return CTickEventHandler::getGameCycle() + tick_dt;
}
}
/*inline uint32 saveGameCycleToSecond(NLMISC::TGameCycle tick)
{
sint32 dt = CTickEventHandler::getGameCycle() - tick;
// Evaluate the UTC of this event (with the current date of save). Suppose that 1 second==10 tick
if (tick < CTickEventHandler::getGameCycle())
return NLMISC::CTime::getSecondsSince1970();
@ -190,7 +226,7 @@ inline NLMISC::TGameCycle loadSecondToGameCycle(uint32 second)
// Convert UTC of the event to game cycle. Suppose that 1 second==10 tick
return CTickEventHandler::getGameCycle() + (second - NLMISC::CTime::getSecondsSince1970())*10;
}
}*/
#endif
// GameCycle property (saved as a UTC of the current game cycle, support server migration)

@ -423,6 +423,15 @@ void CAIS::update()
_CreatureChangeHPList.Entities.clear();
_CreatureChangeHPList.DeltaHp.clear();
}
if (!_CreatureChangeMaxHPList.Entities.empty())
{
nlassert(_CreatureChangeMaxHPList.Entities.size()==_CreatureChangeMaxHPList.MaxHp.size());
nlassert(_CreatureChangeMaxHPList.Entities.size()==_CreatureChangeMaxHPList.SetFull.size());
_CreatureChangeMaxHPList.send("EGS");
_CreatureChangeMaxHPList.Entities.clear();
_CreatureChangeMaxHPList.MaxHp.clear();
_CreatureChangeMaxHPList.SetFull.clear();
}
}
//

@ -222,6 +222,11 @@ public:
return _CreatureChangeHPList;
}
CChangeCreatureMaxHPMsg &getCreatureChangeMaxHP()
{
return _CreatureChangeMaxHPList;
}
enum TSearchType
{
AI_INSTANCE = 0,
@ -288,6 +293,7 @@ private:
// Faunas descriptions to be sent each frame
CFaunaBotDescription _FaunaDescriptionList;
CChangeCreatureHPMsg _CreatureChangeHPList;
CChangeCreatureMaxHPMsg _CreatureChangeMaxHPList;
/// The emot identifiers
std::map<std::string, uint32> _EmotNames;

@ -61,7 +61,7 @@ CAIInstance* CSpawnBot::getAIInstance() const
void CSpawnBot::setVisualPropertiesName()
{
CBot& botRef = CSpawnBot::getPersistent();
std::string name = botRef.getName();
ucstring name = botRef.getName();
if (CVisualPropertiesInterface::UseIdForName)
{
@ -403,8 +403,8 @@ std::vector<std::string> CBot::getMultiLineInfoString() const
pushTitle(container, "CBot");
pushEntry(container, "id=" + getIndexString());
container.back() += " eid=" + getEntityIdString();
container.back() += " alias=" + getAliasTreeOwner()->getAliasString();
container.back() += " name=" + getName();
container.back() += " alias=" + getAliasTreeOwner()->getAliasString() + " raw alias=" + NLMISC::toString(getAliasTreeOwner()->getAlias());
pushEntry(container, " name=" + getName());
if (isSheetValid())
container.back() += " sheet=" + NLMISC::CFile::getFilenameWithoutExtension(getSheet()->SheetId().toString());
pushEntry(container, "fullname=" + getFullName());

@ -95,7 +95,7 @@ public:
virtual float getAggroPropagationRadius() const;
//@}
void setVisualPropertiesName();
virtual void setVisualPropertiesName();
// as there not a lot of prop (1 or 2, maybe 3) stores in this comportment, we don't need hash.
bool getProp(size_t Id, uint32& value) const;
@ -241,8 +241,8 @@ public:
NLMISC::CEntityId createEntityId() const;
const std::string& getCustomName() const { return _CustomName; }
void setCustomName(const std::string &name) { _CustomName = name; }
const ucstring& getCustomName() const { return _CustomName; }
void setCustomName(const ucstring &name) { _CustomName = name; }
virtual void setClientSheet(const std::string & clientSheetName);
@ -272,7 +272,7 @@ private:
bool _IgnoreOffensiveActions;
bool _Healer;
bool _BuildingBot;
std::string _CustomName;
ucstring _CustomName;
CTimer _SetSheetTimer;
struct CSetSheetData
{

@ -274,9 +274,12 @@ std::vector<std::string> CSpawnBotNpc::getMultiLineInfoString() const
else
{
vector<uint32> const& missions = _CurrentChatProfile.getMissions();
pushEntry(container, "missions: " + NLMISC::toString("%u", missions[0]));
for (size_t i=1; i<missions.size(); ++i)
container.back() += ", " + NLMISC::toString("%u", missions[i]);
pushEntry(container, "missions:");
for (size_t i=0; i<missions.size(); ++i)
{
string name = getAIInstance()->findMissionName(missions[i]);
pushEntry(container, NLMISC::toString(" %u (%s)", missions[i], name.c_str()));
}
}
pushFooter(container);

@ -16,6 +16,7 @@
#include "stdpch.h"
#include "ai_bot_pet.h"
#include "visual_properties_interface.h"
#include "nel/misc/random.h"
#include "ai_grp_pet.h"
@ -92,3 +93,28 @@ CSpawnGroupPet& CSpawnBotPet::spawnGrp()
{
return static_cast<CSpawnGroupPet&>(CSpawnBot::spawnGrp());
}
void CSpawnBotPet::setVisualPropertiesName()
{
CBotPet& botRef = CSpawnBotPet::getPersistent();
ucstring name = botRef.getName();
if (CVisualPropertiesInterface::UseIdForName)
{
name = NLMISC::toString("AI:%s", botRef.getIndexString().c_str());
}
if (name.empty() && CVisualPropertiesInterface::ForceNames)
{
name = NLMISC::CFile::getFilenameWithoutExtension(botRef.getSheet()->SheetId().toString().c_str());
}
if (!botRef.getCustomName().empty())
name = botRef.getCustomName();
// no name the bot will appear without name on the client.
if (name.empty())
return;
CVisualPropertiesInterface::setName(dataSetRow(), name);
}

@ -66,6 +66,8 @@ public:
uint32 _DeathTime;
void setVisualPropertiesName();
private:
CPathPosition _PathPos;

@ -653,7 +653,7 @@ static float randomAngle()
return val;
}
CGroupNpc* CAIInstance::eventCreateNpcGroup(uint nbBots, NLMISC::CSheetId const& sheetId, CAIVector const& pos, double dispersionRadius, bool spawnBots, double orientation, const std::string &botsName)
CGroupNpc* CAIInstance::eventCreateNpcGroup(uint nbBots, NLMISC::CSheetId const& sheetId, CAIVector const& pos, double dispersionRadius, bool spawnBots, double orientation, const std::string &botsName, const std::string &look)
{
if (!_EventNpcManager)
return NULL;
@ -689,10 +689,13 @@ CGroupNpc* CAIInstance::eventCreateNpcGroup(uint nbBots, NLMISC::CSheetId const&
CBotNpc* const bot = NLMISC::safe_cast<CBotNpc*>(grp->bots()[i]);
bot->setSheet(sheet);
if (!look.empty())
bot->setClientSheet(look);
bot->equipmentInit();
bot->initEnergy(/*groupEnergyCoef()*/0);
CAIVector rpos(pos);
if (i!=0)
// Spawn all randomly except if only 1 bot
if (nbBots > 1)
{
RYAI_MAP_CRUNCH::CWorldMap const& worldMap = CWorldContainer::getWorldMap();
RYAI_MAP_CRUNCH::CWorldPosition wp;
@ -857,6 +860,7 @@ void cbEventCreateNpcGroup( NLNET::CMessage& msgin, const std::string &serviceNa
double dispersionRadius;
bool spawnBots;
std::string botsName;
std::string look;
msgin.serial(messageVersion);
nlassert(messageVersion==1);
msgin.serial(instanceNumber);
@ -869,10 +873,11 @@ void cbEventCreateNpcGroup( NLNET::CMessage& msgin, const std::string &serviceNa
msgin.serial(dispersionRadius);
msgin.serial(spawnBots);
msgin.serial(botsName);
msgin.serial(look);
CAIInstance* instance = CAIS::instance().getAIInstance(instanceNumber);
if (instance)
{
CGroupNpc* npcGroup = instance->eventCreateNpcGroup(nbBots, sheetId, CAIVector((double)x/1000., (double)y/1000.), dispersionRadius, spawnBots, (double)orientation/1000., botsName);
CGroupNpc* npcGroup = instance->eventCreateNpcGroup(nbBots, sheetId, CAIVector((double)x/1000., (double)y/1000.), dispersionRadius, spawnBots, (double)orientation/1000., botsName, look);
if (npcGroup != NULL)
{
_PlayersLastCreatedNpcGroup[playerId] = npcGroup->getName();

@ -207,7 +207,7 @@ public:
return NULL;
}
CGroupNpc* eventCreateNpcGroup(uint nbBots, NLMISC::CSheetId const& sheetId, CAIVector const& pos, double dispersionRadius, bool spawnBots, double orientation, const std::string &botsName);
CGroupNpc* eventCreateNpcGroup(uint nbBots, NLMISC::CSheetId const& sheetId, CAIVector const& pos, double dispersionRadius, bool spawnBots, double orientation, const std::string &botsName, const std::string &look);
/// create a new easter egg
CBotEasterEgg* createEasterEgg(uint32 easterEggId, NLMISC::CSheetId const& sheetId, std::string const& botName, double x, double y, double z, double heading, const std::string& look);

@ -291,6 +291,11 @@ void CPetSpawnMsgImp::callback(std::string const& name, NLNET::TServiceId id)
botPet->setSheet(sheet);
if (!CustomName.empty())
{
botPet->setCustomName(CustomName);
}
if (!botPet->spawn())
{
confirmMsg.SpawnError = CPetSpawnConfirmationMsg::INTERNAL_ERROR;

@ -873,14 +873,20 @@ void COutpost::createSquad(CGroupDesc<COutpostSquadFamily> const* groupDesc, COu
// Attack only the declared ennemies of the outpost
if (side==OUTPOSTENUMS::OutpostOwner)
{
// grp->faction ().addProperty(NLMISC::toString("outpost:%s:defender", getAliasString().c_str()));
// grp->friendFaction().addProperty(NLMISC::toString("outpost:%s:defender", getAliasString().c_str()));
// Bots factions
grp->faction ().addProperty(NLMISC::toString("outpost:%s:bot_defender", getAliasString().c_str()));
grp->friendFaction().addProperty(NLMISC::toString("outpost:%s:bot_defender", getAliasString().c_str()));
grp->ennemyFaction().addProperty(NLMISC::toString("outpost:%s:bot_attacker", getAliasString().c_str()));
// Players faction
grp->ennemyFaction().addProperty(NLMISC::toString("outpost:%s:attacker", getAliasString().c_str()));
}
if (side==OUTPOSTENUMS::OutpostAttacker)
{
// grp->faction ().addProperty(NLMISC::toString("outpost:%s:attacker", getAliasString().c_str()));
// grp->friendFaction().addProperty(NLMISC::toString("outpost:%s:attacker", getAliasString().c_str()));
// Bots factions
grp->faction ().addProperty(NLMISC::toString("outpost:%s:bot_attacker", getAliasString().c_str()));
grp->friendFaction().addProperty(NLMISC::toString("outpost:%s:bot_attacker", getAliasString().c_str()));
grp->ennemyFaction().addProperty(NLMISC::toString("outpost:%s:bot_defender", getAliasString().c_str()));
// Players faction
grp->ennemyFaction().addProperty(NLMISC::toString("outpost:%s:defender", getAliasString().c_str()));
}
grp->_AggroRange = 25;

@ -1562,7 +1562,7 @@ void CGrpProfileGoToPoint::updateProfile(uint ticksSinceLastUpdate)
dx+=dir.x;
dy+=dir.y;
// 4 rangées.
// 4 rows
CAIVector idealPos=groupPosition;
if (botIndex>=_NbBotInNormalShape)
{
@ -2054,7 +2054,7 @@ void CGrpProfileFollowRoute::updateProfile(uint ticksSinceLastUpdate)
dx+=dir.x;
dy+=dir.y;
// 4 rangées.
// 4 rows
CAIVector idealPos=groupPosition;
if (botIndex>=_NbBotInNormalShape)
{
@ -2299,6 +2299,94 @@ void CGrpProfileStandOnVertices::updateProfile(uint ticksSinceLastUpdate)
}
}
//////////////////////////////////////////////////////////////////////////////
// CGrpProfileFollowPlayer //
//////////////////////////////////////////////////////////////////////////////
CGrpProfileFollowPlayer::CGrpProfileFollowPlayer(CProfileOwner* owner, TDataSetRow const& playerRow, uint32 dispersionRadius)
: CMoveProfile(owner)
, _PlayerRow(playerRow)
, _DispersionRadius(dispersionRadius)
, _PathPos(CAngle(0))
, _PathCont(NLMISC::safe_cast<CSpawnBotNpc*>(owner)->getAStarFlag())
{
PROFILE_LOG("group", "follow player", "ctor", "");
_Status = CFollowPath::FOLLOWING;
}
bool CGrpProfileFollowPlayer::destinationReach() const
{
return _Status == CFollowPath::FOLLOW_ARRIVED
|| _Status==CFollowPath::FOLLOW_NO_PATH;
}
void CGrpProfileFollowPlayer::beginProfile()
{
_Status = CFollowPath::FOLLOWING;
}
// TODO: this doesn't work very well at all...
void CGrpProfileFollowPlayer::updateProfile(uint ticksSinceLastUpdate)
{
H_AUTO(CGrpProfileFollowPlayerUpdate);
CFollowPathContext fpcGrpFollowPlayerUpdate("CGrpProfileFollowPlayerUpdate");
// check all bot to see if there need to move
CSpawnGroupNpc* grp = static_cast<CSpawnGroupNpc*>(static_cast<CSpawnGroup*>(_Grp));
CGroupNpc &pgrp = grp->getPersistent();
CBotPlayer* plrPtr = dynamic_cast<CBotPlayer*>(CAIS::instance().getEntityPhysical(_PlayerRow));
if ( ! plrPtr) {
nlwarning("CGrpProfileFollowPlayer: No valid player position to follow");
return;
}
_PathCont.setDestination(plrPtr->wpos());
_PathPos._Angle = plrPtr->theta();
for (uint i = 0; i < pgrp.bots().size(); ++i)
{
CBotNpc* bot = static_cast<CBotNpc*>(pgrp.bots()[i]);
if (!bot)
continue;
// check current bot state
CSpawnBotNpc *sbot = bot->getSpawn();
if (!sbot)
continue;
// Need to wait for a correct position before moving?
CAIVector const& dest = _PathCont.getDestination();
if (dest.x()==0 || dest.y()==0)
return;
static const std::string runParameter("running");
float dist;
if (sbot->getPersistent().getOwner()->getSpawnObj()->checkProfileParameter(runParameter))
dist = sbot->runSpeed()*ticksSinceLastUpdate;
else
dist = sbot->walkSpeed()*ticksSinceLastUpdate;
// Move
CFollowPath::TFollowStatus const status = CFollowPath::getInstance()->followPath(
sbot,
_PathPos,
_PathCont,
dist,
0.f,
0.5f);
if (status==CFollowPath::FOLLOW_NO_PATH)
{
nlwarning("Problem with following player");
}
}
}
//////////////////////////////////////////////////////////////////////////////
// CGrpProfileIdle //
//////////////////////////////////////////////////////////////////////////////
@ -3687,10 +3775,14 @@ bool CGrpProfileFaction::entityHavePartOfFactions(CAIEntityPhysical const* entit
std::set<TStringId>::const_iterator it, end = factionsSet.end();
for (it=factionsSet.begin(); it!=end; ++it)
{
std::string fameFaction = scriptFactionToFameFaction(CStringMapper::unmap(*it));
string factionInfos = CStringMapper::unmap(*it);
string fameFaction = scriptFactionToFameFaction(factionInfos);
// sint32 fame = CFameInterface::getInstance().getFameOrCivilisationFame(entity->getEntityId(), CStringMapper::map(fameFaction));
sint32 const fame = entity->getFame(fameFaction);
if (fame!=NO_FAME && fame>0)
sint32 const value = scriptFactionToFameFactionValue(factionInfos);
bool gt = scriptFactionToFameFactionGreaterThan(factionInfos);
if ((fame != NO_FAME && gt && fame > value) ||
(fame != NO_FAME && !gt && fame < value))
{
// nldebug("Entity has faction %s", CStringMapper::unmap(*it).c_str());
return true;
@ -3731,12 +3823,41 @@ std::string CGrpProfileFaction::scriptFactionToFameFaction(std::string name)
ret += "_";
ret += name[i]-'A'+'a';
}
else if (name[i] == '>' || name[i] == '<')
{
return ret;
}
else
{
ret += name[i];
}
}
return ret;
}
bool CGrpProfileFaction::scriptFactionToFameFactionGreaterThan(string name)
{
if (name.find("<") != string::npos)
return false;
return true;
}
sint32 CGrpProfileFaction::scriptFactionToFameFactionValue(string name)
{
size_t start = name.find(">");
if (start == string::npos)
{
start = name.find("<");
if (start == string::npos)
return 0;
}
sint32 value;
NLMISC::fromString(name.substr(start+1), value);
return value*6000;
}
std::string CGrpProfileFaction::fameFactionToScriptFaction(std::string name)
{
std::string ret = "Famous";
@ -3772,9 +3893,9 @@ void CGrpProfileFaction::checkTargetsAround()
CPropertySetWithExtraList<TAllianceId> const& thisEnnemyFactions = thisGrpNpc.ennemyFaction();
// We don't assist or attack players if our friends/ennemies are not in factions
bool const assistPlayers = thisFriendFactions.containsPartOfStrict(_FameFactions);
bool const assistPlayers = (thisFriendFactions.containsPartOfStrictFilter("Famous*") || thisFriendFactions.have(AITYPES::CPropertyId("Player")));
bool const assistBots = !thisFriendFactions.empty() && !bNoAssist;
bool const attackPlayers = (!thisEnnemyFactions.extraSetEmpty()) || thisEnnemyFactions.containsPartOfStrict(_FameFactions) || thisEnnemyFactions.containsPartOfStrictFilter("outpost:*");
bool const attackPlayers = (!thisEnnemyFactions.extraSetEmpty()) || thisEnnemyFactions.containsPartOfStrictFilter("Famous*") || thisEnnemyFactions.have(AITYPES::CPropertyId("Player")) || thisEnnemyFactions.containsPartOfStrictFilter("outpost:*");
bool const attackBots = !thisEnnemyFactions.empty();
CAIVision<CPersistentOfPhysical> Vision;

@ -628,6 +628,49 @@ private:
CAITimer _Timer;
};
class CGrpProfileFollowPlayer :
public CMoveProfile
{
public:
CGrpProfileFollowPlayer(CProfileOwner* owner, TDataSetRow const& playerRow, uint32 dispersionRadius);
virtual ~CGrpProfileFollowPlayer() {};
void setBotStandProfile(AITYPES::TProfiles botStandProfileType, IAIProfileFactory* botStandProfileFactory);
/// @name IAIProfile implementation
//@{
virtual void beginProfile();
virtual void updateProfile(uint ticksSinceLastUpdate);
virtual void endProfile() {};
virtual AITYPES::TProfiles getAIProfileType() const { return AITYPES::BOT_FOLLOW_POS; }
virtual std::string getOneLineInfoString() const { return std::string("follow_player group profile"); }
//@}
void stateChangeProfile() {};
bool destinationReach() const;
void addBot (CBot* bot) {};
void removeBot (CBot* bot) {};
CPathCont* getPathCont (CBot const* bot) { return NULL; };
protected:
private:
/// the profile type to apply to bot standing between two deplacement
AITYPES::TProfiles _BotStandProfileType;
/// the profile factory to apply to bot standing between two deplacement
IAIProfileFactory*_BotStandProfileFactory;
CFollowPath::TFollowStatus _Status;
CPathPosition _PathPos;
CPathCont _PathCont;
CAIVector _LastPos;
TDataSetRow _PlayerRow;
uint32 _DispersionRadius;
};
//////////////////////////////////////////////////////////////////////////////
// CGrpProfileIdle //
//////////////////////////////////////////////////////////////////////////////
@ -792,6 +835,10 @@ public:
static std::string scriptFactionToFameFaction(std::string name);
static std::string fameFactionToScriptFaction(std::string name);
static bool scriptFactionToFameFactionGreaterThan(std::string name);
static sint32 scriptFactionToFameFactionValue(std::string name);
private:
CAITimer _checkTargetTimer;
bool bNoAssist;

@ -259,7 +259,7 @@ NLMISC_COMMAND(eventCreateNpcGroup, "create an event npc group", "<aiInstanceId>
std::string botsName;
if (args.size()>8) botsName = args[8];
aiInstance->eventCreateNpcGroup(nbBots, sheetId, CAIVector(x, y), dispersionRadius, spawnBots, orientation, botsName);
aiInstance->eventCreateNpcGroup(nbBots, sheetId, CAIVector(x, y), dispersionRadius, spawnBots, orientation, botsName, "");
return true;
}

@ -3013,7 +3013,10 @@ public:
}
if(!_Id)
npcChatToChannelSentence(bot->dataSetRow(),CChatGroup::say,_Sentence);
{
ucstring ucstr = _Sentence;
npcChatToChannelSentence(bot->dataSetRow(),CChatGroup::say, ucstr);
}
else
{
if(!_Arg)

@ -697,7 +697,8 @@ void CMessages::init()
TRANSPORT_CLASS_REGISTER (CReportStaticAIInstanceMsg);
TRANSPORT_CLASS_REGISTER (CReportAIInstanceDespawnMsg);
TRANSPORT_CLASS_REGISTER (CWarnBadInstanceMsgImp);
TRANSPORT_CLASS_REGISTER (CCreatureSetUrlMsg);
TRANSPORT_CLASS_REGISTER (CChangeCreatureMaxHPMsg)
TRANSPORT_CLASS_REGISTER (CChangeCreatureHPMsg);
TRANSPORT_CLASS_REGISTER (CChangeCreatureModeMsgImp);
TRANSPORT_CLASS_REGISTER (CQueryEgs);
@ -770,10 +771,10 @@ void CAIAskForInfosOnEntityImp::callback (const std::string &name, NLNET::TServi
}
break;
default:
break;
}
std::vector<std::string> strings = phys->getMultiLineInfoString();
msg.Infos.insert(msg.Infos.end(), strings.begin(), strings.end());
break;
}
}
else
{

@ -1497,6 +1497,41 @@ void setAutoSpawn_f_(CStateInstance* entity, CScriptStack& stack)
// HP related methods
/** @page code
@subsection setMaxHP_ff_
Sets the Max HP level of each bot of the group.
Arguments: f(MaxHp) f(SetFull) ->
@param[in] MaxHP is the new maximum HP for each bot
@param[in] SetFull if not 0, will set the HP to the new maximum
@code
()setMaxHP(50000,1);
@endcode
*/
// CGroup
void setMaxHP_ff_(CStateInstance* entity, CScriptStack& stack)
{
bool setFull = ((float)stack.top() != 0.f); stack.pop();
float maxHp = ((float)stack.top()); stack.pop();
CChangeCreatureMaxHPMsg& msgList = CAIS::instance().getCreatureChangeMaxHP();
FOREACH(bot, CCont<CBot>, entity->getGroup()->bots())
{
if (!bot->isSpawned())
continue;
CSpawnBot* const sbot = bot->getSpawnObj();
msgList.Entities.push_back(sbot->dataSetRow());
msgList.MaxHp.push_back((uint32)(maxHp));
msgList.SetFull.push_back((uint8)(setFull?1:0));
}
}
/** @page code
@subsection setHPLevel_f_
Sets the current HP level of each bot of the group.
@ -1573,10 +1608,42 @@ void setHPScale_f_(CStateInstance* entity, CScriptStack& stack)
}
}
//----------------------------------------------------------------------------
// Url related method
/** @page code
@subsection setUrl_ss_
Sets the name and url of right-click action
Arguments: s(actionName),s(url) ->
@param[in] actionName of action when player mouse over
@param[in] url of action when player mouse over
@code
()setUrl("Click on Me", "http://www.domain.com/script.php");
@endcode
*/
// CGroup
void setUrl_ss_(CStateInstance* entity, CScriptStack& stack)
{
std::string url = (std::string)stack.top();stack.pop();
std::string actionName = (std::string)stack.top();stack.pop();
CCreatureSetUrlMsg msg;
FOREACH(botIt, CCont<CBot>, entity->getGroup()->bots())
{
CSpawnBot* pbot = botIt->getSpawnObj();
if (pbot!=NULL)
{
msg.Entities.push_back(pbot->dataSetRow());
}
}
msg.ActionName = actionName;
msg.Url = url;
msg.send(egsString);
}
@ -1870,7 +1937,7 @@ Arguments: s(parameterName) ->
@param[in] parameterName is a the id of the parameter to add
@code
()addProfileParameter("running"); // équivalent à un parameter "running" dans la primitive du groupe
()addProfileParameter("running"); // equivalent to "running" parameter in group primitive
@endcode
*/
@ -1898,7 +1965,7 @@ Arguments: s(parameterName),s(parameterContent) ->
@param[in] parameterContent is the value of the parameter
@code
()addProfileParameter("foo", "bar"); // équivalent à un parameter "foo:bar" dans la primitive du groupe
()addProfileParameter("foo", "bar"); // equivalent to "foo:bar" parameter in group primitive
@endcode
*/
@ -1927,7 +1994,7 @@ Arguments: s(parameterName),f(parameterContent) ->
@param[in] parameterContent is the value of the parameter
@code
()addProfileParameter("foo", 0.5); // équivalent à un parameter "foo:0.5" dans la primitive du groupe
()addProfileParameter("foo", 0.5); // equivalent to "foo:0.5" parameter in group primitive
@endcode
*/
@ -4456,6 +4523,37 @@ void setSheet_s_(CStateInstance* entity, CScriptStack& stack)
}
}
//----------------------------------------------------------------------------
/** @page code
@subsection setClientSheet_s_
Change the client sheet of a creature
Arguments: -> s(sheetName)
@code
()setClientSheet('ccdeb2');
@endcode
*/
void setClientSheet_s_(CStateInstance* entity, CScriptStack& stack)
{
string sheetname = stack.top();
stack.pop();
if (sheetname.find(".creature") == string::npos)
sheetname += ".creature";
FOREACH(itBot, CCont<CBot>, entity->getGroup()->bots())
{
CBot* bot = *itBot;
if (bot)
{
bot->setClientSheet(sheetname);
}
}
}
/****************************************************************************/
@ -4581,6 +4679,62 @@ void setConditionSuccess_f_(CStateInstance* entity, CScriptStack& stack)
CAILogicDynamicIfHelper::setConditionSuccess(conditionState);
}
inline
static float randomAngle()
{
uint32 const maxLimit = CAngle::PI*2;
float val = (float)CAIS::rand32(maxLimit);
return val;
}
//----------------------------------------------------------------------------
/** @page code
@subsection facing_f_
The npc will face the given direction
Arguments: f(direction)
@param[in] direction is the new angle of the bot in radians
@code
()facing(3.14);
@endcode
*/
// CStateInstance
void facing_f_(CStateInstance* entity, CScriptStack& stack)
{
float const theta = (float)stack.top(); stack.pop();
CGroup* group = entity->getGroup();
bool bRandomAngle = false;
if (theta > (NLMISC::Pi * 2.0) || theta < (-NLMISC::Pi * 2.0))
bRandomAngle = true;
if (group->isSpawned())
{
FOREACH(itBot, CCont<CBot>, group->bots())
{
CBot* bot = *itBot;
if (bot)
{
if (bot->isSpawned())
{
CSpawnBot *spawnBot = bot->getSpawnObj();
if (bRandomAngle)
spawnBot->setTheta(randomAngle());
else
spawnBot->setTheta(theta);
}
}
}
}
}
std::map<std::string, FScrptNativeFunc> nfGetGroupNativeFunctions()
{
@ -4628,6 +4782,7 @@ std::map<std::string, FScrptNativeFunc> nfGetGroupNativeFunctions()
REGISTER_NATIVE_FUNC(functions, clearAggroList__);
REGISTER_NATIVE_FUNC(functions, setMode_s_);
REGISTER_NATIVE_FUNC(functions, setAutoSpawn_f_);
REGISTER_NATIVE_FUNC(functions, setMaxHP_ff_);
REGISTER_NATIVE_FUNC(functions, setHPLevel_f_);
REGISTER_NATIVE_FUNC(functions, setHPScale_f_);
REGISTER_NATIVE_FUNC(functions, scaleHP_f_);
@ -4651,10 +4806,11 @@ std::map<std::string, FScrptNativeFunc> nfGetGroupNativeFunctions()
REGISTER_NATIVE_FUNC(functions, getEventParam_f_f);
REGISTER_NATIVE_FUNC(functions, getEventParam_f_s);
REGISTER_NATIVE_FUNC(functions, setSheet_s_);
REGISTER_NATIVE_FUNC(functions, setClientSheet_s_);
REGISTER_NATIVE_FUNC(functions, setHealer_f_);
REGISTER_NATIVE_FUNC(functions, setConditionSuccess_f_);
REGISTER_NATIVE_FUNC(functions, facing_f_);
REGISTER_NATIVE_FUNC(functions, setUrl_ss_);
// Boss functions (custom text)
REGISTER_NATIVE_FUNC(functions, phraseBegin__);
@ -4700,9 +4856,6 @@ std::map<std::string, FScrptNativeFunc> nfGetGroupNativeFunctions()
REGISTER_NATIVE_FUNC(functions, summonPlayer_fs_);
#undef REGISTER_NATIVE_FUNC
return functions;

@ -462,7 +462,7 @@ Arguments: f(Radius) ->
@param[in] Radius dispersion of wander activity
@code
()startWander(100); // Gives a wander activity to the group with dispersion of 100
()startMoving(100,-100,10); // Moves the group to 100,-100 with radius of 10
@endcode
*/
@ -501,6 +501,56 @@ void startMoving_fff_(CStateInstance* entity, CScriptStack& stack)
return;
}
//----------------------------------------------------------------------------
/** @page code
@subsection followPlayer_sf_
Set activity to follow the given player
Arguments: s(PlayerEid) f(Radius) ->
@param[in] PlayerEid id of player to follow
@param[in] Radius dispersion of wander activity
@code
()followPlayer("(0x0002015bb4:01:88:88)",10);
@endcode
*/
// Spawned CGroupNpc not in a family behaviour
void followPlayer_sf_(CStateInstance* entity, CScriptStack& stack)
{
uint32 dispersionRadius = (uint32)(float&)stack.top(); stack.pop();
NLMISC::CEntityId playerId = NLMISC::CEntityId((std::string)stack.top());
IManagerParent* const managerParent = entity->getGroup()->getOwner()->getOwner();
CAIInstance* const aiInstance = dynamic_cast<CAIInstance*>(managerParent);
if (!aiInstance)
return;
if (!entity) { nlwarning("followPlayer failed!"); return; }
CGroupNpc* group = dynamic_cast<CGroupNpc*>(entity->getGroup());
if (!group)
{ nlwarning("followPlayer failed: no NPC group");
return;
}
CSpawnGroupNpc* spawnGroup = group->getSpawnObj();
if (!spawnGroup)
{ nlwarning("followPlayer failed: no spawned group");
return;
}
if (playerId == CEntityId::Unknown)
{
nlwarning("followPlayer failed: unknown player");
DEBUG_STOP;
return;
}
spawnGroup->movingProfile().setAIProfile(new CGrpProfileFollowPlayer(spawnGroup, TheDataset.getDataSetRow(playerId), dispersionRadius));
return;
}
//----------------------------------------------------------------------------
@ -2179,14 +2229,11 @@ void facing_cscs_(CStateInstance* entity, CScriptStack& stack)
// bot1->setTheta(bot1->pos().angleTo(bot2->pos()));
}
//----------------------------------------------------------------------------
/** @page code
@subsection npcSay_css_
A new entry of the npc contextual menu will propose to the targeter player to talk to the npc.
Make a npc say a text
There are 3 type of text
@ -2201,9 +2248,9 @@ Arguments: c(group), s(botname), s(text), ->
@code
(@group)group_name.context();
()emote(@group, "bob", "DSS_1601 RtEntryText_6") ;// Send To dss
()emote(@group, "bob", "RAW Ca farte?"); // phrase direcly send to IOS as raw (for debug)
()emote(@group, "bob", "answer_group_no_m"); //phrase id
()npcSay(@group, "bob", "DSS_1601 RtEntryText_6") ;// Send To dss
()npcSay(@group, "bob", "RAW Ca farte?"); // phrase direcly send to IOS as raw (for debug)
()npcSay(@group, "bob", "answer_group_no_m"); //phrase id
@endcode
@ -2214,6 +2261,34 @@ Arguments: c(group), s(botname), s(text), ->
#include "game_share/chat_group.h"
#include "game_share/send_chat.h"
void execSayHelper(CSpawnBot *spawnBot, NLMISC::CSString text, CChatGroup::TGroupType mode = CChatGroup::say)
{
if (spawnBot)
{
NLMISC::CSString prefix = text.left(4);
if (prefix=="DSS_")
{
NLMISC::CSString phrase = text.right(text.length() - 4);
NLMISC::CSString idStr = phrase.strtok(" ",false,false,false,false);
uint32 scenarioId = atoi(idStr.c_str());
forwardToDss(spawnBot->dataSetRow(), mode, phrase, scenarioId);
return;
}
if (prefix=="RAW ")
{
std::string phrase = text.right(text.length()-4);
ucstring ucstr = phrase;
npcChatToChannelSentence(spawnBot->dataSetRow(), mode, ucstr);
return;
}
//Classic phrase ID
npcChatToChannel(spawnBot->dataSetRow(), mode, text);
}
}
void npcSay_css_(CStateInstance* entity, CScriptStack& stack)
{
string text = (string)stack.top(); stack.pop();
@ -2224,29 +2299,58 @@ void npcSay_css_(CStateInstance* entity, CScriptStack& stack)
if (!spawnBot) { return; }
execSayHelper(spawnBot, text);
}
std::string prefix =NLMISC::CSString (text).left(4);
if(prefix=="DSS_")
{
//----------------------------------------------------------------------------
/** @page code
NLMISC::CSString phrase = NLMISC::CSString (text).right((uint)text.length()-4);
NLMISC::CSString idStr = phrase.strtok(" ",false,false,false,false);
uint32 scenarioId;
NLMISC::fromString(idStr, scenarioId);
forwardToDss(spawnBot->dataSetRow(), CChatGroup::say, phrase, scenarioId);
return;
}
@subsection npcSay_ss_
if (prefix=="RAW ")
Make a npc say a text
Arguments: s(text), s(mode) ->
@param[in] text is the text to say. prefix with ID: to use an id
@param[in] mode is the mode to use (say, shout)
@code
()npcSay("Hello!","say"); // phrase direcly send to IOS as raw
()npcSay("ID:answer_group_no_m","shout"); // phrase id
@endcode
*/
void npcSay_ss_(CStateInstance* entity, CScriptStack& stack)
{
std::string sMode = (std::string)stack.top(); stack.pop();
std::string text = (std::string)stack.top(); stack.pop();
CChatGroup::TGroupType mode = CChatGroup::say;
mode = CChatGroup::stringToGroupType(sMode);
CGroup* group = entity->getGroup();
if (group->isSpawned())
{
NLMISC::CSString phrase = NLMISC::CSString (text).right((uint)text.length()-4);
npcChatToChannelSentence(spawnBot->dataSetRow(),CChatGroup::say, phrase);
return;
FOREACH(itBot, CCont<CBot>, group->bots())
{
CBot* bot = *itBot;
if (bot)
{
if (bot->isSpawned())
{
CSpawnBot *spawnBot = bot->getSpawnObj();
std::string prefix = NLMISC::CSString(text).left(3);
if (NLMISC::nlstricmp(prefix.c_str(), "id:") == 0) {
text = NLMISC::CSString(text).right(text.length()-3);
execSayHelper(spawnBot, text, mode);
}
else {
execSayHelper(spawnBot, "RAW " + text, mode);
}
}
}
}
}
//Classic phrase ID
npcChatToChannel(spawnBot->dataSetRow(), CChatGroup::say, text);
return;
}
@ -2514,6 +2618,7 @@ void rename_s_(CStateInstance* entity, CScriptStack& stack)
msgout.serial(row);
msgout.serial(name);
sendMessageViaMirror("IOS", msgout);
bot->setCustomName(name);
}
}
}
@ -2650,6 +2755,7 @@ std::map<std::string, FScrptNativeFunc> nfGetNpcGroupNativeFunctions()
REGISTER_NATIVE_FUNC(functions, startMoving_fff_);
REGISTER_NATIVE_FUNC(functions, waitInZone_s_);
REGISTER_NATIVE_FUNC(functions, stopMoving__);
REGISTER_NATIVE_FUNC(functions, followPlayer_sf_);
REGISTER_NATIVE_FUNC(functions, wander__);
REGISTER_NATIVE_FUNC(functions, setAttackable_f_);
REGISTER_NATIVE_FUNC(functions, setPlayerAttackable_f_);
@ -2687,6 +2793,7 @@ std::map<std::string, FScrptNativeFunc> nfGetNpcGroupNativeFunctions()
REGISTER_NATIVE_FUNC(functions, rename_s_);
REGISTER_NATIVE_FUNC(functions, vpx_s_);
REGISTER_NATIVE_FUNC(functions, npcSay_css_);
REGISTER_NATIVE_FUNC(functions, npcSay_ss_);
REGISTER_NATIVE_FUNC(functions, dssMessage_fsss_);
REGISTER_NATIVE_FUNC(functions, despawnBotByAlias_s_);
REGISTER_NATIVE_FUNC(functions, giveReward_ssssc_);

@ -1000,8 +1000,8 @@ void setSimplePhrase_ss_(CStateInstance* entity, CScriptStack& stack)
phraseContent2 += "]}";
ucstring ucPhraseContent;
// ucPhraseContent.fromUtf8(phraseContent2); // utf-8 version
ucPhraseContent = phraseContent2; // iso-8859-1 version
ucPhraseContent.fromUtf8(phraseContent2); // utf-8 version
//ucPhraseContent = phraseContent2; // iso-8859-1 version
NLNET::CMessage msgout("SET_PHRASE");
msgout.serial(phraseName);
@ -1009,6 +1009,33 @@ void setSimplePhrase_ss_(CStateInstance* entity, CScriptStack& stack)
sendMessageViaMirror("IOS", msgout);
}
void setSimplePhrase_sss_(CStateInstance* entity, CScriptStack& stack)
{
std::string lang = (std::string)stack.top();
stack.pop();
std::string phraseContent = (std::string)stack.top();
stack.pop();
std::string phraseName = (std::string)stack.top();
stack.pop();
std::string phraseContent2;
phraseContent2 += phraseName;
phraseContent2 += "(){[";
phraseContent2 += phraseContent;
phraseContent2 += "]}";
ucstring ucPhraseContent;
ucPhraseContent.fromUtf8(phraseContent2); // utf-8 version
//ucPhraseContent = phraseContent2; // iso-8859-1 version
NLNET::CMessage msgout("SET_PHRASE_LANG");
msgout.serial(phraseName);
msgout.serial(ucPhraseContent);
msgout.serial(lang);
sendMessageViaMirror("IOS", msgout);
}
//----------------------------------------------------------------------------
/** @page code
@ -1330,6 +1357,7 @@ std::map<std::string, FScrptNativeFunc> nfGetStaticNativeFunctions()
REGISTER_NATIVE_FUNC(functions, getNamedEntityProp_ss_s);
REGISTER_NATIVE_FUNC(functions, destroyNamedEntity_s_);
REGISTER_NATIVE_FUNC(functions, setSimplePhrase_ss_);
REGISTER_NATIVE_FUNC(functions, setSimplePhrase_sss_);
REGISTER_NATIVE_FUNC(functions, dataGetVar_s_s);
REGISTER_NATIVE_FUNC(functions, dataGetVar_s_f);
REGISTER_NATIVE_FUNC(functions, dataSetVar_ss_);

@ -788,6 +788,13 @@ bool CNpcChatProfileImp::parseChatArgs(CAIInstance *aiInstance, const std::strin
return true;
}
// organization entry
if (NLMISC::nlstricmp(keyword, "organization") == 0)
{
NLMISC::fromString(tail, _Organization);
return true;
}
// if no match found throw an error
return false;
}
@ -830,4 +837,5 @@ void TGenNpcDescMsgImp::setChat(const CNpcChatProfileImp& chatProfile)
_OptionalProperties = chatProfile.getOptionalProperties();
_Outpost = chatProfile.getOutpost();
_Organization = chatProfile.getOrganization();
}

@ -36,7 +36,7 @@ public:
CNpcChatProfileImp(const CNpcChatProfileImp &other0,const CNpcChatProfileImp &other1);
// interface for setting up chat info
void clear() { clearShopInfo(); clearMissions(); clearCellZones(); clearContextOption(); _OptionalProperties.clear(); }
void clear() { clearShopInfo(); clearMissions(); clearCellZones(); clearContextOption(); clearWeb(); _OptionalProperties.clear(); }
void clearShopInfo()
{
_ShopTypes.clear();
@ -56,6 +56,11 @@ public:
}
void clearCellZones() { _CellZones.clear(); }
void clearMissions() { _Missions.clear(); }
void clearWeb()
{
_WebPage.clear();
_WebPageName.clear();
}
bool add(CAIInstance *aiInstance, const std::string &chatArgs) { return parseChatArgs(aiInstance, chatArgs); }
void addMission(uint32 mission) { _Missions.push_back(mission); }
void clearContextOption() { _ContextOptions.clear(); }

@ -1083,25 +1083,33 @@ CSmartPtr<const AIVM::CByteCode> CCompiler::compileCode (const std::vector<std::
FOREACHC(itArg, TList, sourceCodeLines)
{
const string &str=*itArg;
size_t firstIndex=str.find_first_of("/",0);
while (firstIndex!=string::npos)
{
firstIndex++;
if (firstIndex>=str.size())
{
firstIndex=string::npos;
size_t index = str.find("//",0);
if (index == string::npos)
code += str;
else {
// We have a potential comment. Now check if it is quoted or not
bool inQuote = false;
uint i = 0;
for (;;)
{
if ('"' == str[i])
inQuote = !inQuote;
if ( !inQuote && ('/' == str[i]) )
{
++i;
if ('/' == str[i])
break;
}
if (str.at(firstIndex)=='/')
{
code+=str.substr(0, firstIndex-1);
code += '/';
}
code += str[i];
++i;
if (str.size() == i)
break;
}
firstIndex=str.find_first_of("/",firstIndex);
}
if (firstIndex==string::npos)
code+=str;
code+="\n "; // additional ..
}
code+="}";

@ -221,10 +221,12 @@ arguments.
- @ref moveToZone_ss_
- @ref waitInZone_s_
- @ref stopMoving__
- @ref followPlayer_sf_
- @ref wander__
- @ref downScaleHP_f_
- @ref upScaleHP_f_
- @ref scaleHP_f_
- @ref setMaxHP_ff_
- @ref setHPLevel_f_
- @ref addHP_f_
- @ref aiAction_s_

@ -69,7 +69,7 @@ void CVisualPropertiesInterface::release()
}
// set different visual properties for a bot.
void CVisualPropertiesInterface::setName(const TDataSetRow& dataSetRow,std::string name)
void CVisualPropertiesInterface::setName(const TDataSetRow& dataSetRow, ucstring name)
{
if (!IOSHasMirrorReady)
return;
@ -77,8 +77,6 @@ void CVisualPropertiesInterface::setName(const TDataSetRow& dataSetRow,std::stri
NLNET::CMessage msgout("CHARACTER_NAME");
CEntityId eid=CMirrors::DataSet->getEntityId(dataSetRow);
msgout.serial (const_cast<TDataSetRow&>(dataSetRow));
ucstring uname;
uname.fromUtf8(name);
msgout.serial (uname); // Daniel: TODO update all name dependencies to ucstring in your service.
msgout.serial (name);
sendMessageViaMirror("IOS",msgout);
}

@ -39,7 +39,7 @@ public:
static void release();
// set different visual properties for an entity
static void setName(const TDataSetRow& dataSetRow,std::string name);
static void setName(const TDataSetRow& dataSetRow, ucstring name);
// static void setMode(CAIEntityId id,MBEHAV::EMode mode);
// static void setBehaviour(CAIEntityId id,MBEHAV::EBehaviour behaviour);

File diff suppressed because it is too large Load Diff

@ -43,6 +43,8 @@ struct CAdminCommand
void initAdmin ();
void initCommandsPrivileges(const std::string & fileName);
void initPositionFlags(const std::string & fileName);
void initSalt();
const std::string &getSalt();
CAdminCommand * findAdminCommand(const std::string & name);

@ -268,6 +268,7 @@ bool CBuildingManager::parsePhysicalBuildings( const NLLIGO::IPrimitive* prim, C
else
{
_BuildingPhysicals.insert( make_pair( alias, building ) );
_BuildingPhysicalsName.insert( make_pair( building->getName(), building));
return true;
}
}
@ -853,18 +854,18 @@ IBuildingPhysical * CBuildingManager::getBuildingPhysicalsByAlias( TAIAlias alia
//----------------------------------------------------------------------------
IBuildingPhysical* CBuildingManager::getBuildingPhysicalsByName( const std::string & name )
{
for ( std::map<TAIAlias,IBuildingPhysical*>::iterator it = _BuildingPhysicals.begin(); it != _BuildingPhysicals.end(); ++it )
std::map<std::string,IBuildingPhysical*>::iterator it = _BuildingPhysicalsName.find( name );
if ( it != _BuildingPhysicalsName.end() )
{
if( (*it).second == NULL )
{
nlwarning("<BUILDING> NULL building in building maps. Checks should be done at init time");
return NULL;
}
if ( (*it).second->getName() == name )
return (*it).second;
}
return NULL;
return NULL;
}
//----------------------------------------------------------------------------
@ -1134,3 +1135,9 @@ void CBuildingManager::buyBuildingOption(const NLMISC::CEntityId & userId, uint8
}
}
//----------------------------------------------------------------------------
void CBuildingManager::buyBuilding(const NLMISC::CEntityId & userId, TAIAlias alias)
{
CCharacter * user = PlayerManager.getChar(userId);
user->getRoomInterface().init( user, dynamic_cast<CBuildingPhysicalPlayer*>(getBuildingPhysicalsByAlias(alias)) );
}

@ -86,7 +86,7 @@ public:
void registerPlayer( CCharacter * user );
/// get a building destination from its alias.
IBuildingPhysical* getBuildingPhysicalsByAlias( TAIAlias Alias );
/// get a building destination from its name. WARNING : slow
/// get a building destination from its name.
IBuildingPhysical* getBuildingPhysicalsByName( const std::string & name );
/// remove a player from a room
void removePlayerFromRoom( CCharacter * user );
@ -122,6 +122,7 @@ public:
void buildBuildingTradeList(const NLMISC::CEntityId & userId, uint16 session);
/// buy a player flat option
void buyBuildingOption(const NLMISC::CEntityId & userId, uint8 idx);
void buyBuilding(const NLMISC::CEntityId & userId, TAIAlias alias);
//@}
private:
@ -201,9 +202,12 @@ private:
typedef CHashMap< TDataSetRow , CTriggerRequest , TDataSetRow::CHashCode > TTriggerRequestCont;
TTriggerRequestCont _TriggerRequests;
/// physical buildings by name
/// physical buildings by Alias
std::map<TAIAlias,IBuildingPhysical*> _BuildingPhysicals;
/// physical buildings by name
std::map<std::string,IBuildingPhysical*> _BuildingPhysicalsName;
/// room instances
struct CRoomInstanceEntry
{

@ -109,7 +109,6 @@ void CBuildingPhysicalGuild::addGuild( uint32 guildId )
{
if ( std::find(_Guilds.begin(), _Guilds.end(), guildId) != _Guilds.end() )
{
nlwarning("<BUILDING> trying to add a guild that is already present in the building, guild id = %u", guildId);
return;
}

@ -815,6 +815,34 @@ void cbClientCombatDodge( NLNET::CMessage& msgin, const std::string &serviceName
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
// CLIENT:LEAGUE
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
//
void cbClientLeagueJoin( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId)
{
cbJoinLeague(msgin, serviceName, serviceId);
}
//
void cbClientLeagueJoinProposal( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId)
{
cbJoinLeagueProposal(msgin, serviceName, serviceId);
}
//
void cbClientLeagueJoinProposalDecline( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId)
{
cbJoinLeagueDecline(msgin, serviceName, serviceId);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
// CLIENT:TEAM
@ -857,7 +885,8 @@ void cbClientTeamSetSuccessor( NLNET::CMessage& msgin, const std::string &servic
CEntityId id;
uint8 idx;
msgin.serial( id,idx );
msgin.serial(id);
msgin.serial(idx);
CCharacter* user = PlayerManager.getChar( id );
if ( !user )
{
@ -872,9 +901,17 @@ void cbClientTeamSetSuccessor( NLNET::CMessage& msgin, const std::string &servic
}
if ( team->getLeader() != id )
{
nlwarning("<TEAM> user %s is not leader : cant set successor",id.toString().c_str() );
nlwarning("<TEAM> user %s is not leader: cant set successor",id.toString().c_str() );
return;
}
if (team->getSuccessor() == id)
{
nlwarning("<TEAM> user %s already is successor", id.toString().c_str() );
return;
}
// increment the target index as the leader is not in its team list
++idx;
team->setSuccessor( idx );
}
@ -2370,7 +2407,6 @@ void cbClientWhere( NLNET::CMessage& msgin, const std::string &serviceName, NLNE
}\
}
// Send list of connected character name / account to client
void cbClientWho( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId )
{
@ -2381,6 +2417,11 @@ void cbClientWho( NLNET::CMessage& msgin, const std::string &serviceName, NLNET:
msgin.serial( id,opt );
const std::vector<CEntityId> * gms = NULL;
// Make sure opt is not like "A(c)" for "é"
ucstring ucopt;
ucopt.fromUtf8(opt);
opt = ucopt.toString();
uint nbAnswers = 0;
// standard who
@ -2420,7 +2461,7 @@ void cbClientWho( NLNET::CMessage& msgin, const std::string &serviceName, NLNET:
&& user->getInstanceNumber() == ch->getInstanceNumber())
{
params[0].setEId( (*it) );
CCharacter::sendDynamicSystemMessage( id,"WHO_REGION_LIST",params );
CCharacter::sendDynamicSystemMessage( id,"WHO_REGION_LIST", params );
nbAnswers++;
}
}
@ -2429,7 +2470,7 @@ void cbClientWho( NLNET::CMessage& msgin, const std::string &serviceName, NLNET:
}
// GM who
else if ( NLMISC::nlstricmp( opt.c_str() , "GM" ) == 0)
else if ( NLMISC::nlstricmp( opt.c_str(), "GM" ) == 0)
{
TVectorParamCheck params(1);
params[0].Type = STRING_MANAGER::player;
@ -2476,6 +2517,75 @@ void cbClientWho( NLNET::CMessage& msgin, const std::string &serviceName, NLNET:
}
}
}
else
{
TChanID chanID;
CCharacter * user = PlayerManager.getChar( id );
if ( !user )
{
nlwarning("<WHO>'%s' is invalid", id.toString().c_str() );
return;
}
CPlayer *p = PlayerManager.getPlayer(PlayerManager.getPlayerId(user->getId()));
if (NLMISC::nlstricmp( opt.c_str(), "league" ) == 0)
{
chanID = user->getLeagueId();
}
else
{
chanID = DynChatEGS.getChanIDFromName(opt);
}
if (chanID == DYN_CHAT_INVALID_CHAN)
{
CCharacter::sendDynamicSystemMessage( id, "WHO_CHANNEL_NOT_FOUND" );
return;
}
bool havePriv = p->havePriv(":DEV:SGM:GM:");
bool hasChannel = false;
nbAnswers = 0;
vector<NLMISC::CEntityId> players;
DynChatEGS.getPlayersInChan(chanID, players);
ucstring playerNames("");
uint32 shardId = CEntityIdTranslator::getInstance()->getEntityShardId(id);
for (uint i = 0; i < players.size(); i++)
{
if (players[i] == id)
hasChannel = true;
ucstring name = CEntityIdTranslator::getInstance()->getByEntity(players[i]);
if (shardId == CEntityIdTranslator::getInstance()->getEntityShardId(players[i]))
{
// Same shard, remove shard from name
CEntityIdTranslator::removeShardFromName(name);
}
playerNames += ((i > 0) ? "\n" : "") + name ;
}
if (!hasChannel && !havePriv)
{
SM_STATIC_PARAMS_1(params, STRING_MANAGER::literal);
params[0].Literal = opt;
CCharacter::sendDynamicSystemMessage( id, "WHO_CHANNEL_NOT_CONNECTED", params );
return;
}
if (!playerNames.empty())
{
CCharacter::sendDynamicSystemMessage( id, "WHO_CHANNEL_INTRO" );
//playerNames = "Players in channel \"" + opt + "\":" + playerNames;
SM_STATIC_PARAMS_1(params, STRING_MANAGER::literal);
params[0].Literal = playerNames;
CCharacter::sendDynamicSystemMessage( id, "LITERAL", params );
return;
}
}
if ( nbAnswers == 0 )
{
@ -3508,9 +3618,9 @@ TUnifiedCallbackItem CbClientArray[]=
{ "CLIENT:DUEL:REFUSE", cbClientDuelRefuse },
{ "CLIENT:DUEL:ABANDON", cbClientDuelAbandon },
{ "CLIENT:PVP_CHALLENGE:ASK", cbClientPVPChallengeAsked },
{ "CLIENT:PVP_CHALLENGE:ACCEPT", cbClientPVPChallengeAccept },
{ "CLIENT:PVP_CHALLENGE:REFUSE", cbClientPVPChallengeRefuse },
{ "CLIENT:PVP_CHALLENGE:ASK", cbClientLeagueJoinProposal },
{ "CLIENT:PVP_CHALLENGE:ACCEPT", cbClientLeagueJoin },
{ "CLIENT:PVP_CHALLENGE:REFUSE", cbClientLeagueJoinProposalDecline },
{ "CLIENT:PVP_CHALLENGE:ABANDON", cbClientPVPChallengeAbandon },
// { "CLIENT:PVP_VERSUS:CLAN", cbClientPvpChooseClan },

@ -145,6 +145,7 @@ CCreature::CCreature() : CEntityBase(true)
_TicketFameRestrictionValue = 0;
_MaxHitRangeForPC = -1.f;
_Organization = 0;
// _MissionIconFlags.IsMissionStepIconDisplayable = true;
// _MissionIconFlags.IsMissionGiverIconDisplayable = true;
}
@ -941,6 +942,8 @@ void CCreature::setBotDescription( const CGenNpcDescMsgImp& description )
_BotChatOutpost = description.getOutpost();
_Organization = description.getOrganization();
bool cosmeticCategory = false;
bool tradeCategory = false;
bool tpCategory = false;

@ -496,6 +496,8 @@ public:
const std::string &getWebPage() const {return _WebPage;}
const std::string &getWebPageName() const {return _WebPageName;}
const uint32 getOrganization() const { return _Organization; }
const NLMISC::CSheetId &getBotChatOutpost() const {return _BotChatOutpost;}
const std::vector<NLMISC::CSheetId> &getExplicitActionTradeList() const {return _ExplicitActionTradeList;}
@ -590,6 +592,7 @@ private:
NLMISC::CSmartPtr<CMerchant> _Merchant; // smart pointer on CMerchant class of creature
uint32 _BotChatProgram; // Program enabled for bot chat
uint32 _Organization; // Organization for bot
TDataSetRow _CharacterLeaderIndex; // The data set row of the beast's leader character if it's in a pack/train
std::string _WelcomePhrase; // welcome message id of the bot

@ -195,6 +195,28 @@ void CCreatureCompleteHealImp::callback(const string &, NLNET::TServiceId sid)
}
}
//--------------------------------------------------------------
// CChangeCreatureMaxHPImp ::callback()
//--------------------------------------------------------------
void CChangeCreatureMaxHPImp::callback(const string &, NLNET::TServiceId sid)
{
H_AUTO(CChangeCreatureMaxHPImp);
// for each creature, restore full HP
for ( uint i = 0; i < Entities.size(); ++i )
{
CCreature * c = CreatureManager.getCreature( Entities[i] );
if ( c )
{
c->getScores()._PhysicalScores[SCORES::hit_points].Max = MaxHp[i];
if (SetFull[i] != 0)
c->changeCurrentHp( c->maxHp() - c->currentHp() );
}
}
}
//--------------------------------------------------------------
// CChangeCreatureHPImp ::callback()
//--------------------------------------------------------------
@ -229,6 +251,50 @@ void CChangeCreatureHPImp::callback(const string &, NLNET::TServiceId sid)
}
}
//--------------------------------------------------------------
// CChangeCreatureMaxHPImp ::callback()
//--------------------------------------------------------------
void CCreatureSetUrlImp::callback(const string &, NLNET::TServiceId sid)
{
H_AUTO(CCreatureSetUrlImp);
// for each creature set url
for ( uint i = 0; i < Entities.size(); ++i )
{
CCreature * c = CreatureManager.getCreature( Entities[i] );
if ( c )
{
uint32 program = c->getBotChatProgram();
if(!(program & (1<<BOTCHATTYPE::WebPageFlag)))
{
if(program != 0)
{
return;
}
program |= 1 << BOTCHATTYPE::WebPageFlag;
c->setBotChatProgram(program);
}
const string &wp = c->getWebPage();
if(Url == "*") {
(string &)wp = "";
program &= ~(1 << BOTCHATTYPE::WebPageFlag);
c->setBotChatProgram(program);
return;
}
else
(string &)wp = Url;
const string &wpn = c->getWebPageName();
(string &)wpn = ActionName;
return;
}
}
}
//---------------------------------------------------
// Constructor
//

@ -71,6 +71,15 @@ public:
virtual void callback (const std::string &name, NLNET::TServiceId id);
};
/**
* Implementation of the set Max HP message for creatures
*/
class CChangeCreatureMaxHPImp : public CChangeCreatureMaxHPMsg
{
public:
virtual void callback (const std::string &name, NLNET::TServiceId id);
};
/**
* Implementation of the change HP message for creatures
*/
@ -81,6 +90,16 @@ public:
};
/**
* Implementation of the change setUrl message for creatures
*/
class CCreatureSetUrlImp : public CCreatureSetUrlMsg
{
public:
virtual void callback (const std::string &name, NLNET::TServiceId id);
};
typedef CHashMap< NLMISC::CEntityId, CCreature *, NLMISC::CEntityIdHashMapTraits> TMapCreatures;
/**

@ -3140,6 +3140,9 @@ void CBankAccessor_PLR::TPACK_ANIMAL::TBEAST::init(ICDBStructNode *parent, uint
nlassert(node != NULL);
_DESPAWN = node;
node = parent->getNode( ICDBStructNode::CTextId("NAME"), true );
nlassert(node != NULL);
_NAME = node;
// branch init

@ -8855,7 +8855,7 @@ inline void _getProp(const CCDBSynchronised &db, ICDBStructNode *node, NLMISC::C
ICDBStructNode *_POS;
ICDBStructNode *_HUNGER;
ICDBStructNode *_DESPAWN;
ICDBStructNode *_NAME;
public:
void init(ICDBStructNode *parent, uint index);
@ -9045,6 +9045,23 @@ inline void _getProp(const CCDBSynchronised &db, ICDBStructNode *node, NLMISC::C
return _DESPAWN;
}
void setNAME(CCDBSynchronised &dbGroup, uint32 value, bool forceSending = false)
{
_setProp(dbGroup, _NAME, value, forceSending);
}
uint32 getNAME(const CCDBSynchronised &dbGroup)
{
uint32 value;
_getProp(dbGroup, _NAME, value);
return value;
}
ICDBStructNode *getNAMECDBNode()
{
return _NAME;
}
};

@ -248,6 +248,23 @@ bool CDynChatEGS::removeSession(TChanID chan,const TDataSetRow &client)
return true;
}
//============================================================================================================
bool CDynChatEGS::getPlayersInChan(TChanID chanID, std::vector<NLMISC::CEntityId> &players)
{
CDynChatChan *chan = _DynChat.getChan(chanID);
if (!chan) return false;
CDynChatSession *currSession = chan->getFirstSession();
bool havePlayers = false;
while (currSession)
{
players.push_back(TheDataset.getEntityId(currSession->getClient()->getID()));
havePlayers = true;
currSession = currSession->getNextChannelSession();
}
return havePlayers;
}
//============================================================================================================
void CDynChatEGS::iosSetHistoricSize(TChanID chan, uint32 size)

@ -76,6 +76,9 @@ public:
bool setWriteRight(TChanID chan, const TDataSetRow &client, bool writeRight);
// Set size of historic for a given channel
void setHistoricSize(TChanID chan, uint32 size);
// Get list of players in channel
bool getPlayersInChan(TChanID chanID, std::vector<NLMISC::CEntityId> &players);
// Resend all channel / sessions to the IOS
void iosConnection();
// Get all channel names (for read only)
@ -83,6 +86,7 @@ public:
const TChanIDToName &getChanIDToNameMap() const { return _ChanNames.getAToBMap(); }
// Get pointer on all channels
void getChans(std::vector<CDynChatChan *> &channels) { _DynChat.getChans(channels); }
const TChanID getNextChanID() const { return _NextChanID; }
/// Message from a service that need to create a new dynamic channel
static void cbServiceAddChan(NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId);

@ -1382,7 +1382,9 @@ void CPlayerService::init()
TRANSPORT_CLASS_REGISTER (CReportAIInstanceDespawnMsgImp);
TRANSPORT_CLASS_REGISTER (CWarnBadInstanceMsg);
TRANSPORT_CLASS_REGISTER (CCreatureCompleteHealImp);
TRANSPORT_CLASS_REGISTER (CChangeCreatureMaxHPImp);
TRANSPORT_CLASS_REGISTER (CChangeCreatureHPImp);
TRANSPORT_CLASS_REGISTER (CCreatureSetUrlImp);
TRANSPORT_CLASS_REGISTER (CChangeCreatureModeMsg);
TRANSPORT_CLASS_REGISTER (CGiveItemRequestMsgImp);
TRANSPORT_CLASS_REGISTER (CReceiveItemRequestMsgImp);

@ -446,6 +446,8 @@ void cbClientReady( CMessage& msgin, const std::string &serviceName, NLNET::TSer
c->initAnimalHungerDb();
c->initFactionPointDb();
c->initPvpPointDb();
c->initOrganizationInfos();
c->updateOutpostAdminFlagInDB();
@ -516,17 +518,6 @@ void cbClientReady( CMessage& msgin, const std::string &serviceName, NLNET::TSer
// ask backup for offline commands file
COfflineCharacterCommand::getInstance()->characterOnline( characterId );
if( CGameEventManager::getInstance().getChannelEventId() != TChanID::Unknown )
{
if( c->haveAnyPrivilege() )
{
DynChatEGS.addSession(CGameEventManager::getInstance().getChannelEventId(), entityIndex, true);
}
else
{
DynChatEGS.addSession(CGameEventManager::getInstance().getChannelEventId(), entityIndex, false);
}
}
c->onConnection();
} // cbClientReady //
@ -680,6 +671,9 @@ void finalizeClientReady( uint32 userId, uint32 index )
CPVPManager2::getInstance()->setPVPModeInMirror( c );
c->updatePVPClanVP();
// Add character to event channel if event is active
CGameEventManager::getInstance().addCharacterToChannelEvent( c );
// for GM player, trigger a 'infos' command to remember their persistent state
if (!PlayerManager.getPlayer(uint32(c->getId().getShortId())>>4)->getUserPriv().empty())
CCommandRegistry::getInstance().execute(toString("infos %s", c->getId().toString().c_str()).c_str(), InfoLog(), true);
@ -1596,6 +1590,53 @@ void cbJoinTeamProposal( NLNET::CMessage& msgin, const std::string &serviceName,
} // cbJoinTeamProposal //
//---------------------------------------------------
// cbJoinLeague: join specified League
//---------------------------------------------------
void cbJoinLeague( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId)
{
H_AUTO(cbJoinLeague);
CEntityId charId;
msgin.serial( charId );
TeamManager.joinLeagueAccept( charId );
} // cbJoinLeague //
//---------------------------------------------------
// cbJoinLeagueDecline: player decline the proposition
//---------------------------------------------------
void cbJoinLeagueDecline( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId)
{
H_AUTO(cbJoinLeagueDecline);
CEntityId charId;
msgin.serial( charId );
TeamManager.joinLeagueDecline( charId );
} // cbJoinLeagueDecline //
//---------------------------------------------------
// cbJoinLeagueProposal: propose a player (current target) to enter the League
//---------------------------------------------------
void cbJoinLeagueProposal( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId)
{
H_AUTO(cbJoinLeagueProposal);
CEntityId charId;
msgin.serial( charId );
CCharacter *character = PlayerManager.getChar( charId );
if (character == NULL || !character->getEnterFlag())
{
nlwarning("<cbJoinLeagueProposal> Invalid player Id %s", charId.toString().c_str() );
return;
}
character->setAfkState(false);
TeamManager.joinLeagueProposal( character, character->getTarget() );
} // cbJoinLeagueProposal //
//---------------------------------------------------
// cbKickTeammate: kick your target from your team
//---------------------------------------------------

@ -82,6 +82,15 @@ void cbJoinTeamProposal( NLNET::CMessage& msgin, const std::string &serviceName,
// kick your target from your team
void cbKickTeammate( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId);
/// callback for JOIN_LEAGUE message
void cbJoinLeague( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId);
/// callback for JOIN_LEAGUE_DECLINE message
void cbJoinLeagueDecline( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId);
/// callback for JOIN_LEAGUE_PROPOSAL message
void cbJoinLeagueProposal( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId);
// toogle god mode on / off for testing
//void cbGodMode( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId);

@ -791,6 +791,7 @@ void CGameItem::ctor( const CSheetId& sheetId, uint32 recommended, bool destroya
// SlotCount = slotCount;
_Recommended = recommended;
_TotalSaleCycle = 0;
_PetIndex = MAX_INVENTORY_ANIMAL;
_Form = CSheets::getForm( sheetId );
if (_Form)
@ -1146,6 +1147,14 @@ uint32 CGameItem::getNonLockedStackSize()
return _StackSize - _LockCount;
}
void CGameItem::setLockedByOwner(bool value)
{
if (value != _LockedByOwner)
{
_LockedByOwner = value;
callItemChanged(INVENTORIES::TItemChangeFlags(INVENTORIES::itc_lock_state));
}
}
//-----------------------------------------------
// getCopy :
@ -1362,6 +1371,8 @@ void CGameItem::clear()
_RequiredCharacLevel = 0;
_HasPrerequisit= false;
_LockedByOwner = false;
_TypeSkillMods.clear();
_PhraseId.clear();
_CustomText.clear();

@ -679,6 +679,9 @@ public :
/// set required skill level
inline void setRequiredSkillLevel2( uint16 l ) { _RequiredSkillLevel2 = l; }
bool getLockedByOwner() const { return _LockedByOwner; }
void setLockedByOwner(bool value);
/// get required stat
inline CHARACTERISTICS::TCharacteristics getRequiredCharac() const { return _RequiredCharac; }
/// set required stat
@ -702,9 +705,16 @@ public :
const CItemCraftParameters * getCraftParameters() const { return _CraftParameters; }
/// get custom string (for scroll-like items)
const ucstring& getCustomText() const { return _CustomText; }
ucstring getCustomText() const { return _CustomText; }
/// set custom string (for scroll-like items)
void setCustomText(const ucstring &val);
void setCustomText(ucstring val);
uint8 getPetIndex() const { return _PetIndex; }
void setPetIndex(uint8 val) { _PetIndex = val; }
ucstring getCustomName() const { return _CustomName; }
void setCustomName(ucstring val) { _CustomName = val; }
protected:
friend class CFaberPhrase;
@ -947,6 +957,9 @@ private:
std::vector<CTypeSkillMod> _TypeSkillMods;
ucstring _CustomText;
bool _LockedByOwner;
uint8 _PetIndex;
ucstring _CustomName;
};
/**

@ -84,6 +84,10 @@ bool CExchangeView::putItemInExchange(uint32 bagSlot, uint32 exchangeSlot, uint3
if (_InterlocutorView != NULL && (!form->DropOrSell && form->Family != ITEMFAMILY::PET_ANIMAL_TICKET))
return false;
// Can't trade items locked by owner
if (item->getLockedByOwner())
return false;
if( getCharacter()->isAnActiveXpCatalyser(item) )
return false;

@ -1066,6 +1066,12 @@ void CCharacterInvView::updateClientSlot(uint32 slot, const CGameItemPtr item)
getCharacter()->queryItemPrice( item, price );
itemBestStat = item->getCraftParameters() == 0 ? RM_FABER_STAT_TYPE::Unknown : item->getCraftParameters()->getBestItemStat();
BOTCHATTYPE::TBotChatResaleFlag resaleFlag = (item->durability() == item->maxDurability() ? BOTCHATTYPE::ResaleOk : BOTCHATTYPE::ResaleKOBroken);
if (item->getLockedByOwner())
{
resaleFlag = BOTCHATTYPE::ResaleKOLockedByOwner;
}
INVENTORIES::CItemSlot itemSlot( slot );
itemSlot.setItemProp( INVENTORIES::Sheet, item->getSheetId().asInt() );
itemSlot.setItemProp( INVENTORIES::Quality, item->quality() );
@ -1076,7 +1082,7 @@ void CCharacterInvView::updateClientSlot(uint32 slot, const CGameItemPtr item)
itemSlot.setItemProp( INVENTORIES::NameId, item->sendNameId(getCharacter()) );
itemSlot.setItemProp( INVENTORIES::Enchant, item->getClientEnchantValue() );
itemSlot.setItemProp( INVENTORIES::Price, price );
itemSlot.setItemProp( INVENTORIES::ResaleFlag, item->durability() == item->maxDurability() ? BOTCHATTYPE::ResaleOk : BOTCHATTYPE::ResaleKOBroken );
itemSlot.setItemProp( INVENTORIES::ResaleFlag, resaleFlag );
itemSlot.setItemProp( INVENTORIES::ItemClass, item->getItemClass() );
itemSlot.setItemProp( INVENTORIES::ItemBestStat, itemBestStat );
itemSlot.setItemProp( INVENTORIES::PrerequisitValid, getCharacter()->checkPreRequired( item ) );

@ -217,7 +217,7 @@ void CGuild::setBuilding(TAIAlias buildingAlias)
if (getBuilding() != CAIAliasTranslator::Invalid)
{
CBuildingManager::getInstance()->removeGuildBuilding( getId() );
_Inventory->clearInventory();
//_Inventory->clearInventory();
}
// set the new guild building
@ -1298,23 +1298,34 @@ uint16 CGuild::getMaxGradeCount(EGSPD::CGuildGrade::TGuildGrade grade)const
for ( uint i = 0; i < size; ++i )
count+=_GradeCounts[i];
if ( grade == EGSPD::CGuildGrade::Leader )
switch (grade)
{
case EGSPD::CGuildGrade::Leader:
return 1;
if ( grade == EGSPD::CGuildGrade::HighOfficer )
break;
case EGSPD::CGuildGrade::HighOfficer:
{
return GuildMaxMemberCount;
/*
count *= 5;
if ( count %100 == 0 )
return count/100;
else
return count/100 + 1;
*/
}
if ( grade == EGSPD::CGuildGrade::Officer )
break;
case EGSPD::CGuildGrade::Officer:
{
return GuildMaxMemberCount;
/*
count *= 10;
if ( count %100 == 0 )
return count/100;
else
return count/100 + 1;
*/
}
}
return 0xFFFF;
}
@ -2238,7 +2249,7 @@ void IGuild::updateMembersStringIds()
//-----------------------------------------------------------------------------
/**
* This class is used to load old guild inventory, DO NOT BREAK IT!
* \author Sébastien 'kxu' Guignot
* \author Sebastien 'kxu' Guignot
* \author Nevrax France
* \date 2005
*/

@ -100,7 +100,7 @@ void CGuildLeaderModule::quitGuild()
CGuildMember * member = EGS_PD_CAST<CGuildMember*>( (*it).second );
EGS_PD_AST( member );
// ignore current leader
if ( member->getGrade() == EGSPD::CGuildGrade::Leader )
if ( _GuildMemberCore->getId() == member->getId() )
continue;
// check if the current member is the successor

@ -230,7 +230,6 @@ void cbClientGroupAbandonMission( NLNET::CMessage& msgin, const std::string &ser
if (index < MaxGroupMissionCount)
{
// Team
CTeam * team = TeamManager.getRealTeam( user->getTeamId() );
if ( !team )
{
@ -250,7 +249,6 @@ void cbClientGroupAbandonMission( NLNET::CMessage& msgin, const std::string &ser
return;
}
CMissionTeam* mission = team->getMissions()[index];
nlassert(mission);
@ -301,7 +299,6 @@ void cbClientGroupAbandonMission( NLNET::CMessage& msgin, const std::string &ser
return;
}
CMissionGuild* mission = guild->getMissions()[index];
nlassert(mission);

@ -1961,7 +1961,6 @@ class CMissionActionRecvMoney : public IMissionAction
PHRASE_UTILITIES::sendDynamicSystemMessage(user->getEntityRowId(),"MIS_GUILD_RECV_MONEY",params);
}
}
}
};
uint _Amount;

@ -48,6 +48,7 @@ class CMissionStepKillFauna : public IMissionStepTemplate
{
struct CSubStep
{
string Dynamic;
CSheetId Sheet;
uint16 Quantity;
};
@ -56,7 +57,7 @@ class CMissionStepKillFauna : public IMissionStepTemplate
_SourceLine = line;
_Place = 0xFFFF;
bool ret = true;
if ( script.size() < 2 || script.size() > 3)
if (script.size() < 2 || script.size() > 3)
{
MISLOGSYNTAXERROR("<creature> <quantity> *[; <creature> <quantity>] [: <place>]");
return false;
@ -68,15 +69,28 @@ class CMissionStepKillFauna : public IMissionStepTemplate
_SubSteps.reserve( subs.size() );
for ( uint i = 0; i < subs.size(); i++ )
{
CSubStep subStep;
std::vector< std::string > args;
CMissionParser::tokenizeString( subs[i]," \t", args );
//// Dynamic Mission Args : #dynamic# <quantity>
if ((args.size() == 2) && (args[0] == "#dynamic#"))
{
subStep.Dynamic = missionData.Name;
subStep.Quantity = atoi(args[1].c_str());
}
////
else
{
if ( args.size() != 2 )
{
MISLOGSYNTAXERROR("<creature> <quantity> *[; <creature> <quantity>] [: <place>]");
return false;
}
missionData.ChatParams.push_back( make_pair(args[0],STRING_MANAGER::creature_model) );
CSubStep subStep;
subStep.Dynamic = "";
subStep.Sheet = CSheetId( args[0] + ".creature");
if ( subStep.Sheet == CSheetId::Unknown )
{
@ -84,6 +98,7 @@ class CMissionStepKillFauna : public IMissionStepTemplate
MISLOGERROR1("invalid sheet '%s'", args[0].c_str());
}
NLMISC::fromString(args[1], subStep.Quantity);
}
_SubSteps.push_back(subStep);
}
if ( script.size() == 3 )
@ -104,15 +119,54 @@ class CMissionStepKillFauna : public IMissionStepTemplate
}
uint processEvent( const TDataSetRow & userRow, const CMissionEvent & event,uint subStepIndex,const TDataSetRow & giverRow )
{
nlinfo("Process Event");
string webAppUrl;
bool ret = true;
_User = PlayerManager.getChar(getEntityIdFromRow(userRow));
if ( event.Type == CMissionEvent::Kill )
{
CMissionEventKill & eventSpe = (CMissionEventKill&)event;
CCreature * c = CreatureManager.getCreature( event.TargetEntity );
CSheetId faunaSheet;
//// Dynamic Mission Args
if (_SubSteps[subStepIndex].Dynamic.empty()) {
faunaSheet = _SubSteps[subStepIndex].Sheet;
}
else
{
vector<string> params = _User->getCustomMissionParams(_SubSteps[subStepIndex].Dynamic);
if (params.size() < 2)
{
LOGMISSIONSTEPERROR("kill_fauna : invalid dynamic creature");
return 0;
}
else
{
webAppUrl = params[0];
faunaSheet = CSheetId(params[1]);
if (params.size() > 2) {
string placeStr = CMissionParser::getNoBlankString( params[2] );
CPlace * place = CZoneManager::getInstance().getPlaceFromName( placeStr );
if ( !place )
{
ret = false;
LOGMISSIONSTEPERROR("kill_fauna : invalid place "+params[2]);
}
else
_Place = place->getId();
}
}
////
}
if ( !c )
{
LOGMISSIONSTEPERROR("kill_fauna : invalid creature " + toString(event.TargetEntity.getIndex()));
}
else if ( _SubSteps[subStepIndex].Sheet == c->getType() )
else if ( faunaSheet == c->getType() )
{
if ( _Place != 0xFFFF )
{
@ -126,6 +180,8 @@ class CMissionStepKillFauna : public IMissionStepTemplate
if ( region && region->getId() == _Place )
{
if (!webAppUrl.empty())
_User->validateDynamicMissionStep(webAppUrl);
LOGMISSIONSTEPSUCCESS("kill_fauna");
return 1;
}
@ -134,6 +190,8 @@ class CMissionStepKillFauna : public IMissionStepTemplate
{
if ( places[i] && places[i]->getId() == _Place )
{
if (!webAppUrl.empty())
_User->validateDynamicMissionStep(webAppUrl);
LOGMISSIONSTEPSUCCESS("kill_fauna");
return 1;
}
@ -142,11 +200,14 @@ class CMissionStepKillFauna : public IMissionStepTemplate
}
else
{
if (!webAppUrl.empty())
_User->validateDynamicMissionStep(webAppUrl);
LOGMISSIONSTEPSUCCESS("kill_fauna");
return 1;
}
}
}
return 0;
}
@ -162,23 +223,61 @@ class CMissionStepKillFauna : public IMissionStepTemplate
virtual void getTextParams( uint & nbSubSteps,const std::string* & textPtr,TVectorParamCheck& retParams, const std::vector<uint32>& subStepStates)
{
static const std::string stepTextReact = "MIS_NEED_REACTIVATION";
static const std::string stepText = "MIS_KILL_FAUNA_";
static const std::string stepTextLoc = "MIS_KILL_FAUNA_LOC_";
nlassert( _SubSteps.size() == subStepStates.size() );
CSheetId faunaSheet;
for ( uint i = 0; i < subStepStates.size(); i++ )
{
if( subStepStates[i] != 0 )
{
if (_SubSteps[i].Dynamic.empty())
{
faunaSheet = _SubSteps[i].Sheet;
}
else
{
//// Dynamic Mission Args
vector<string> params = _User->getCustomMissionParams(_SubSteps[i].Dynamic);
if (params.size() < 2)
{
faunaSheet = CSheetId::Unknown;
}
else
{
faunaSheet = CSheetId(params[1]);
}
if ((_Place == 0xFFFF) && (params.size() > 2))
{
string placeStr = CMissionParser::getNoBlankString( params[2] );
CPlace * place = CZoneManager::getInstance().getPlaceFromName( placeStr );
if ( !place )
{
MISLOG("sline:%u ERROR : kill_fauna : Invalid place %u", _SourceLine, _Place);
}
else
_Place = place->getId();
}
////
}
nbSubSteps++;
if (faunaSheet != CSheetId::Unknown)
{
retParams.push_back(STRING_MANAGER::TParam());
retParams.back().Type = STRING_MANAGER::creature_model;
retParams.back().SheetId = _SubSteps[i].Sheet;
retParams.back().SheetId = faunaSheet;
retParams.push_back(STRING_MANAGER::TParam());
retParams.back().Type = STRING_MANAGER::integer;
retParams.back().Int = subStepStates[i];
}
}
}
if (faunaSheet != CSheetId::Unknown)
{
if ( _Place != 0xFFFF )
{
STRING_MANAGER::TParam param;
@ -198,6 +297,9 @@ class CMissionStepKillFauna : public IMissionStepTemplate
else
textPtr = &stepText;
}
else
textPtr = &stepTextReact;
}
std::vector< CSubStep > _SubSteps;
uint16 _Place;
@ -329,6 +431,7 @@ class CMissionStepKillRace : public IMissionStepTemplate
virtual void getTextParams( uint & nbSubSteps, const std::string* & textPtr,TVectorParamCheck& retParams, const std::vector<uint32>& subStepStates)
{
static const std::string stepTextReact = "MIS_NEED_REACTIVATION";
static const std::string stepText = "MIS_KILL_RACE_";
static const std::string stepTextLoc = "MIS_KILL_RACE_LOC_";
@ -380,6 +483,7 @@ class CMissionStepKillNpc : public IMissionStepTemplate
{
struct CSubStep
{
string Dynamic;
TAIAlias Alias;
// NLMISC::TStringId NpcName;
};
@ -400,9 +504,17 @@ class CMissionStepKillNpc : public IMissionStepTemplate
for ( uint i = 0; i < subs.size(); i++ )
{
CSubStep subStep;
//// Dynamic Mission Args : #dynamic#
if (trim(subs[i]) == "#dynamic#") {
subStep.Dynamic = missionData.Name;
}
////
else
{
subStep.Alias = CAIAliasTranslator::Invalid;
if ( !CMissionParser::parseBotName(subs[i],subStep.Alias,missionData) )
ret = false;
}
_SubSteps.push_back( subStep );
}
return ret;
@ -410,6 +522,9 @@ class CMissionStepKillNpc : public IMissionStepTemplate
}
uint processEvent( const TDataSetRow & userRow, const CMissionEvent & event,uint subStepIndex,const TDataSetRow & giverRow )
{
string webAppUrl;
CCharacter * user = PlayerManager.getChar(getEntityIdFromRow(userRow));
if ( event.Type == CMissionEvent::Kill )
{
CMissionEventKill & eventSpe = (CMissionEventKill&)event;
@ -419,6 +534,8 @@ class CMissionStepKillNpc : public IMissionStepTemplate
LOGMISSIONSTEPERROR("kill_npc : invalid creature " + toString(event.TargetEntity.getIndex()));
}
else
{
if (_SubSteps[subStepIndex].Dynamic.empty())
{
if ( _SubSteps[subStepIndex].Alias != CAIAliasTranslator::Invalid )
{
@ -434,6 +551,30 @@ class CMissionStepKillNpc : public IMissionStepTemplate
return 1;
}
}
else
{
//// Dynamic Mission Args
vector<string> params = user->getCustomMissionParams(_SubSteps[subStepIndex].Dynamic);
if (params.size() < 2) {
LOGMISSIONSTEPERROR("kill_npc : invalid dynamic npc");
return 0;
}
else
{
webAppUrl = params[0];
string name;
CAIAliasTranslator::getInstance()->getNPCNameFromAlias(c->getAlias(), name);
if ( name == params[1] )
{
user->validateDynamicMissionStep(webAppUrl);
LOGMISSIONSTEPSUCCESS("kill_npc");
return 1;
}
}
////
}
}
}
return 0;
}
@ -450,6 +591,7 @@ class CMissionStepKillNpc : public IMissionStepTemplate
virtual void getTextParams( uint & nbSubSteps, const std::string* & textPtr,TVectorParamCheck& retParams, const std::vector<uint32>& subStepStates)
{
static const std::string stepTextReact = "MIS_NEED_REACTIVATION";
static const std::string stepText = "MIS_KILL_NPC_";
textPtr = &stepText;
nlassert( _SubSteps.size() == subStepStates.size() );
@ -460,11 +602,35 @@ class CMissionStepKillNpc : public IMissionStepTemplate
nbSubSteps++;
retParams.push_back(STRING_MANAGER::TParam());
retParams.back().Type = STRING_MANAGER::bot;
if (_SubSteps[i].Dynamic.empty())
{
if ( _SubSteps[i].Alias != CAIAliasTranslator::Invalid )
retParams.back().Int = _SubSteps[i].Alias;
else
retParams.back().Identifier = "giver";
}
else
{
vector<string> params = _User->getCustomMissionParams(_SubSteps[i].Dynamic);
if (params.size() < 2)
{
nlinfo("kill_npc : invalid dynamic npc");
textPtr = &stepTextReact;
return;
}
else
{
vector<TAIAlias> aliases;
CAIAliasTranslator::getInstance()->getNPCAliasesFromName( params[1] , aliases );
if ( aliases.empty() )
{
retParams.back().Int = CAIAliasTranslator::Invalid;
return;
}
retParams.back().Int = aliases[0];
}
}
}
}
}
@ -891,10 +1057,6 @@ class CMissionStepKillByName : public IMissionStepTemplate
MISSION_REGISTER_STEP(CMissionStepKillByName,"kill_npc_by_name");
// ----------------------------------------------------------------------------
class CMissionStepKillPlayer : public IMissionStepTemplate
{

@ -22,6 +22,7 @@
#include "mission_manager/mission_parser.h"
#include "mission_manager/ai_alias_translator.h"
#include "player_manager/character.h"
#include "player_manager/player_manager.h"
#include "creature_manager/creature_manager.h"
#include "mission_manager/mission_manager.h"
#include "game_item_manager/player_inv_xchg.h"
@ -49,18 +50,29 @@ class CMissionStepTalk : public IMissionStepTemplate
bool buildStep( uint32 line, const std::vector< std::string > & script, CMissionGlobalParsingData & globalData, CMissionSpecificParsingData & missionData )
{
_SourceLine = line;
if ( script.size() < 3 )
if ( script.size() < 2 )
{
MISLOGSYNTAXERROR("<npc_name> [: <phrase_id>*[;<param>]]");
return false;
}
bool ret = true;
//// Dynamic Mission Args : #dynamic#
if (trim(script[1]) == "#dynamic#")
{
_Dynamic = missionData.Name;
_PhraseId = _Dynamic+"_ACTION";
_IsDynamic = true;
}
else
{
_IsDynamic = false;
// parse bot
if ( !CMissionParser::parseBotName(script[1], _Bot, missionData) )
{
MISLOGERROR1("invalid npc '%s'", script[1].c_str());
return false;
}
// parse phrase and params
if (script.size() > 2)
{
@ -80,12 +92,13 @@ class CMissionStepTalk : public IMissionStepTemplate
// add a first default param (the name of the bot we talk to)
_Params.insert(_Params.begin(), STRING_MANAGER::TParam());
_Params[0].Identifier = CMissionParser::getNoBlankString(script[1]);
}
return true;
}
uint processEvent( const TDataSetRow & userRow, const CMissionEvent & event,uint subStepIndex,const TDataSetRow & giverRow )
{
_User = PlayerManager.getChar(getEntityIdFromRow(userRow));
// not check here : they are done befor. If a talk event comes here, the step is complete
if( event.Type == CMissionEvent::Talk )
{
@ -102,9 +115,50 @@ class CMissionStepTalk : public IMissionStepTemplate
ret[0] = 1;
}
bool getDynamicBot(TAIAlias & aliasRet)
{
if (_User != NULL)
{
vector<string> params = _User->getCustomMissionParams(_Dynamic);
if (params.size() < 2)
{
MISLOG("sline:%u ERROR : talk_to (sendContextText) : invalid bot", _SourceLine);
return false;
}
else
{
vector<TAIAlias> aliases;
CAIAliasTranslator::getInstance()->getNPCAliasesFromName(params[1], aliases);
if ( aliases.empty() )
{
MISLOG("sline:%u ERROR : talk_to (sendContextText) : invalid bot", _SourceLine);
return false;
}
aliasRet = aliases[0];
return true;
}
}
return false;
}
virtual uint32 sendContextText(const TDataSetRow& user, const TDataSetRow& interlocutor, CMission * instance, bool & gift, const NLMISC::CEntityId & giver )
{
if (_IsDynamic)
{
if (!getDynamicBot(_Bot) || _User == NULL)
{
MISLOG("sline:%u ERROR : talk_to (sendContextText) : invalid bot", _SourceLine);
return 0;
}
TVectorParamCheck params;
return STRING_MANAGER::sendStringToClient( user, _PhraseId, params );
}
CCreature * bot = CreatureManager.getCreature( interlocutor );
if ( bot )
{
if ( ( _Bot != CAIAliasTranslator::Invalid && _Bot == bot->getAlias() ) ||
@ -124,6 +178,12 @@ class CMissionStepTalk : public IMissionStepTemplate
virtual bool hasBotChatOption(const TDataSetRow & interlocutor, CMission * instance, bool & gift)
{
if (_IsDynamic && !getDynamicBot(_Bot))
{
MISLOG("sline:%u ERROR : talk_to (sendContextText) : invalid bot", _SourceLine);
return 0;
}
CCreature * bot = CreatureManager.getCreature( interlocutor );
if ( bot )
{
@ -140,6 +200,27 @@ class CMissionStepTalk : public IMissionStepTemplate
virtual void getTextParams( uint & nbSubSteps,const std::string* & textPtr,TVectorParamCheck& retParams, const std::vector<uint32>& subStepStates)
{
if (_IsDynamic && !getDynamicBot(_Bot))
{
MISLOG("sline:%u ERROR : talk_to (sendContextText) : invalid bot", _SourceLine);
static const std::string stepText = "DEBUG_CRASH_P_SMG_CRASH2";
textPtr = &stepText;
return;
}
if (_IsDynamic && _User != NULL)
{
vector<string> params = _User->getCustomMissionParams(_Dynamic);
if (params.size() < 2)
{
MISLOG("sline:%u ERROR : talk_to (sendContextText) : invalid bot", _SourceLine);
return;
}
_Params.insert(_Params.begin(), STRING_MANAGER::TParam());
_Params[0].Identifier = params[1];
}
nbSubSteps = 1;
static const std::string stepText = "MIS_TALK_TO";
textPtr = &stepText;
@ -151,16 +232,23 @@ class CMissionStepTalk : public IMissionStepTemplate
else
retParams[0].Identifier = "giver";
}
bool solveTextsParams( CMissionSpecificParsingData & missionData,CMissionTemplate * templ )
{
if (!_IsDynamic)
{
bool ret = IMissionStepTemplate::solveTextsParams(missionData,templ);
if ( !CMissionParser::solveTextsParams(_SourceLine, _Params,missionData ) )
ret = false;
return ret;
}
return true;
}
virtual TAIAlias getInvolvedBot(bool& invalidIsGiver) const { invalidIsGiver=true; return _Bot; }
bool _IsDynamic;
std::string _Dynamic;
std::string _PhraseId;
TVectorParamCheck _Params;
TAIAlias _Bot;

@ -102,6 +102,8 @@ uint32 IMissionStepTemplate::sendRpStepText(CCharacter * user,const std::vector<
uint nbSteps = 0;
const std::string* textPtr = NULL;
_User = user;
if ( !_RoleplayText.empty() )
{
// build the param list
@ -143,6 +145,8 @@ uint32 IMissionStepTemplate::sendStepText(CCharacter * user,const std::vector<ui
uint nbSteps = 0;
const std::string* textPtr = NULL;
_User = user;
// build the param list
getTextParams(nbSteps,(const std::string *&)textPtr,params,stepStates);

@ -41,7 +41,7 @@ public:
//@{
/// ctor
inline IMissionStepTemplate()
:_OOOStepIndex(0xFFFFFFFF),_Any(false),_Displayed(true),_IconDisplayedOnStepNPC(true),_IsInOverridenOOO(false) {}
:_OOOStepIndex(0xFFFFFFFF),_Any(false),_Displayed(true),_IconDisplayedOnStepNPC(true),_IsInOverridenOOO(false),_User(NULL) {}
//BRIANCODE my appologies, need access to this data from CMissionStepGiveItem
struct CSubStep
@ -164,7 +164,8 @@ protected:
bool _AddDefaultParams;
/// flag set to true if the step is in an OOO block which text wad overriden
bool _IsInOverridenOOO;
/// Player running the mission
CCharacter * _User;
};

@ -1357,7 +1357,6 @@ uint32 CMissionTemplate::testPrerequisits( CCharacter * user, CPrerequisitInfos
returnValue = MISSION_DESC::PreReqFail;
logOnFail = false;*/
}
}
// check non replayable missions
if( !Tags.Replayable )
@ -1387,7 +1386,6 @@ uint32 CMissionTemplate::testPrerequisits( CCharacter * user, CPrerequisitInfos
logOnFail = false;*/
}
}
}
else
{
@ -1474,7 +1472,6 @@ uint32 CMissionTemplate::testPrerequisits( CCharacter * user, CPrerequisitInfos
}
if (guild->isMissionSuccessfull(templ->Alias))
break;
}
else if ( templ->Type == MISSION_DESC::Solo )
{
@ -1534,7 +1531,6 @@ uint32 CMissionTemplate::testPrerequisits( CCharacter * user, CPrerequisitInfos
break;
/*if (!guild || !guild->isMissionSuccessfull(templ->Alias))
break;*/
}
else if ( templ->Type == MISSION_DESC::Solo )
{
@ -1590,7 +1586,6 @@ uint32 CMissionTemplate::testPrerequisits( CCharacter * user, CPrerequisitInfos
{
/// todo guild mission
CGuild* guild = CGuildManager::getInstance()->getGuildFromId( user->getGuildId() );
if ( !guild )
{
@ -1606,7 +1601,6 @@ uint32 CMissionTemplate::testPrerequisits( CCharacter * user, CPrerequisitInfos
}
if (k != guild->getMissions().size())
break;
}
else if ( templ->Type == MISSION_DESC::Solo )
{
@ -1702,9 +1696,7 @@ uint32 CMissionTemplate::testPrerequisits( CCharacter * user, CPrerequisitInfos
if ( templ->Type == MISSION_DESC::Guild )
{
/// todo guild mission
CGuild* guild = CGuildManager::getInstance()->getGuildFromId( user->getGuildId() );
if(!guild)
break;
@ -1717,7 +1709,6 @@ uint32 CMissionTemplate::testPrerequisits( CCharacter * user, CPrerequisitInfos
}
if (k == guild->getMissions().size())
break;
}
else if ( templ->Type == MISSION_DESC::Solo )
{

@ -1096,10 +1096,22 @@ public:
// this is a special user, store it in the appropriate container
_OnlineSpecialEntities[cci.getPrivilege()].insert(charEid);
}
// Update LastPlayedDate
ICharacter *character = ICharacter::getInterface(IPlayerManager::getInstance().getActiveChar(uint32(charEid.getShortId()>>4)), true);
if (character)
character->setLastConnectionDate(cci.getlastConnectionDate());
}
else
{
nldebug(" Char %s has disconnected", charEid.toString().c_str());
// Update LastPlayedDate
ICharacter *character = ICharacter::getInterface(IPlayerManager::getInstance().getActiveChar(uint32(charEid.getShortId()>>4)), true);
if (character)
character->setLastConnectionDate(0);
// this character disconnected
_OnlineEntities.erase(charEid);

@ -84,7 +84,7 @@ CVariable<bool> UseProxyMoneyForOutpostCosts("egs", "UseProxyMoneyForOutpostCost
CVariable<uint32> OutpostStateTimeOverride("egs", "OutpostStateTimeOverride", "Each state can be set to a shorter time in seconds, 0 means default computed value", true, 0, true );
CVariable<uint32> OutpostJoinPvpTimer("egs", "OutpostJoinPvpTimer", "Max time the player has to answer the JoinPvp Window, in seconds", 10, 0, true );
CVariable<uint32> NumberDayFactorGuildNeedForChallengeOutpost("egs","NumberDayFactorGuildNeedForChallengeOutpost","Nombre de 'level outpost / factor' jours d'existance que la guilde doit avoir pour pouvoir challenger un outpost",10,0,true);
CVariable<sint32> NumberDaysMinusOutpostLevelForChallenge("egs","NumberDaysMinusOutpostLevelForChallenge", "Nombre à enlever au level du oupost pour avoir l'ancieneté requise pour challenger un outpost",50,0,true);
CVariable<sint32> NumberDaysMinusOutpostLevelForChallenge("egs","NumberDaysMinusOutpostLevelForChallenge", "Number to substract from outpost level to get oldness required to challenge an outpost",50,0,true);
extern CPlayerManager PlayerManager;
@ -1463,49 +1463,54 @@ PVP_RELATION::TPVPRelation COutpost::getPVPRelation( CCharacter * user, CEntityB
if( IsRingShard )
return PVP_RELATION::Neutral;
bool targetSafe = false;
bool actorSafe = false;
if( target->getOutpostAlias() == 0 )
{
return PVP_RELATION::Neutral;
}
else
{
CCharacter * pTarget = dynamic_cast<CCharacter*>(target);
if(pTarget)
{
if( CPVPManager2::getInstance()->inSafeZone( pTarget->getPosition() ) )
{
if( pTarget->getSafeInPvPSafeZone() )
if (pTarget == 0)
return PVP_RELATION::Unknown;
if (CPVPManager2::getInstance()->inSafeZone(pTarget->getPosition()))
{
return PVP_RELATION::NeutralPVP;
if (pTarget->getSafeInPvPSafeZone())
targetSafe = true;
}
}
}
if( CPVPManager2::getInstance()->inSafeZone( user->getPosition() ) )
{
if( user->getSafeInPvPSafeZone() )
if( CPVPManager2::getInstance()->inSafeZone(user->getPosition()))
{
return PVP_RELATION::NeutralPVP;
}
if( user->getSafeInPvPSafeZone())
actorSafe = true;
}
if( user->getOutpostAlias() != target->getOutpostAlias() )
{
// One is safe but not other => NeutralPVP
if ((targetSafe && !actorSafe) || (actorSafe && !targetSafe)) {
return PVP_RELATION::NeutralPVP;
}
else
if( user->getOutpostAlias() == target->getOutpostAlias() )
{
if( user->getOutpostSide() != target->getOutpostSide() )
{
if (!targetSafe && !actorSafe)
{
CPVPManager2::getInstance()->setPVPOutpostEnemyReminder( true );
return PVP_RELATION::Ennemy;
}
}
else
{
CPVPManager2::getInstance()->setPVPOutpostAllyReminder( true );
return PVP_RELATION::Ally;
}
}
}
return PVP_RELATION::NeutralPVP;
} // getPVPRelation //

@ -1528,6 +1528,9 @@ bool testOffensiveActionAllowed( const NLMISC::CEntityId &actorId, const NLMISC:
return false;
}
// AI
if (actorId.getType() != RYZOMID::player)
{
// test target isn't invulnerable
if (target->getContextualProperty().directAccessForStructMembers().invulnerable())
{
@ -1540,9 +1543,6 @@ bool testOffensiveActionAllowed( const NLMISC::CEntityId &actorId, const NLMISC:
}
}
// AI
if (actorId.getType() != RYZOMID::player)
{
if (mainTarget == true)
return true;
else

@ -210,7 +210,7 @@ CVariable<uint32> SpawnedDeadMektoubDelay("egs","SpawnedDeadMektoubDelay", "nb
CVariable<bool> ForceQuarteringRight("egs","ForceQuarteringRight", "Allow anyone to quarter a dead creature", false, 0, true );
CVariable<bool> AllowAnimalInventoryAccessFromAnyStable("egs", "AllowAnimalInventoryAccessFromAnyStable", "If true a player can access to his animal inventory (if the animal is inside a stable) from any stable over the world", true, 0, true );
CVariable<uint32> FreeTrialSkillLimit("egs", "FreeTrialSkillLimit", "Level limit for characters belonging to free trial accounts", 125,0,true);
CVariable<uint32> CraftFailureProbaMpLost("egs", "CraftFailureProbaMpLost", "Probabilité de destruction de chaque MP en cas d'echec du craft", 50,0,true);
CVariable<uint32> CraftFailureProbaMpLost("egs", "CraftFailureProbaMpLost", "Probability de destruction de chaque MP en cas d'echec du craft", 50,0,true);
// Number of login stats kept for a character
@ -411,6 +411,8 @@ CCharacter::CCharacter(): CEntityBase(false),
// pvp for player with privilege inactive
_PriviledgePvp = false;
// full pvp
_FullPvp = false;
// aggroable undefined
_Aggroable = true;
_AggroableOverride = -1;
@ -421,12 +423,17 @@ CCharacter::CCharacter(): CEntityBase(false),
for (uint i = 0 ; i < (PVP_CLAN::EndClans-PVP_CLAN::BeginClans+1); ++i)
_FactionPoint[i] = 0;
_PvpPoint = 0;
_PVPFlagLastTimeChange = 0;
_PVPFlagTimeSettedOn = 0;
_PvPDatabaseCounter = 0;
_PVPFlag = false;
_PVPRecentActionTime = 0;
_Organization = 0;
_OrganizationStatus = 0;
_OrganizationPoints = 0;
// do not start berserk
_IsBerserk = false;
@ -493,6 +500,9 @@ CCharacter::CCharacter(): CEntityBase(false),
///init teamId
_TeamId= CTEAM::InvalidTeamId;
///init LeagueId
_LeagueId = TChanID::Unknown;
// init combat flags
_CombatEventFlagTicks.resize(32);
for( uint i=0; i<32; ++i )
@ -641,6 +651,10 @@ CCharacter::CCharacter(): CEntityBase(false),
_CurrentSessionId = _SessionId;
_PvPSafeZoneActive = false;
_PVPSafeLastTimeChange = CTickEventHandler::getGameCycle();
_PVPSafeLastTime = false;
_PVPInSafeZoneLastTime = false;
// For client/server contact list communication
_ContactIdPool= 0;
@ -653,6 +667,10 @@ CCharacter::CCharacter(): CEntityBase(false),
_LastTickNpcControlUpdated = CTickEventHandler::getGameCycle();
_LastWebCommandIndex = 0;
_CustomMissionsParams.clear();
initDatabase();
} // CCharacter //
@ -773,55 +791,20 @@ void CCharacter::initPDStructs()
void CCharacter::updatePVPClanVP() const
{
TYPE_PVP_CLAN propPvpClanTemp = 0;
uint32 maxFameCiv = 0;
uint8 civOfMaxFame = 255;
uint32 maxFameCult = 0;
uint8 cultOfMaxFame = 255;
for (uint8 fameIdx = 0; fameIdx < 7; fameIdx++)
{
sint32 fame = CFameInterface::getInstance().getFameIndexed(_Id, fameIdx);
if (fameIdx < 4)
{
if ((uint32)abs(fame) >= maxFameCiv)
{
civOfMaxFame = fameIdx;
maxFameCiv = abs(fame);
}
}
if (_LeagueId != DYN_CHAT_INVALID_CHAN)
propPvpClanTemp = 1+(uint32)(_LeagueId.getShortId());
else
{
if ((uint32)abs(fame) >= maxFameCult)
{
cultOfMaxFame = fameIdx - 4;
maxFameCult = abs(fame);
}
}
propPvpClanTemp = 0;
if (fame >= PVPFameRequired*6000)
{
propPvpClanTemp |= (TYPE_PVP_CLAN(1) << (2*TYPE_PVP_CLAN(fameIdx)));
}
else if (fame <= -PVPFameRequired*6000)
{
propPvpClanTemp |= (TYPE_PVP_CLAN(1) << ((2*TYPE_PVP_CLAN(fameIdx))+1));
}
if (getPvPRecentActionFlag())
CMirrorPropValue<TYPE_PVP_CLAN> propPvpClan( TheDataset, TheDataset.getDataSetRow(_Id), DSPropertyPVP_CLAN );
if (propPvpClan.getValue() != propPvpClanTemp)
{
uint8 flagAlly = (_PVPFlagAlly & (1 << TYPE_PVP_CLAN(fameIdx))) >> TYPE_PVP_CLAN(fameIdx);
uint8 flagEnemy = (_PVPFlagEnemy & (1 << TYPE_PVP_CLAN(fameIdx))) >> TYPE_PVP_CLAN(fameIdx);
propPvpClanTemp |= flagAlly << (2*TYPE_PVP_CLAN(fameIdx));
propPvpClanTemp |= flagEnemy << ((2*TYPE_PVP_CLAN(fameIdx))+1);
propPvpClan = propPvpClanTemp;
propPvpClan.setChanged();
}
}
propPvpClanTemp |= TYPE_PVP_CLAN(civOfMaxFame) << (2*TYPE_PVP_CLAN(7));
propPvpClanTemp |= TYPE_PVP_CLAN(cultOfMaxFame) << (2*TYPE_PVP_CLAN(8));
CMirrorPropValue<TYPE_PVP_CLAN> propPvpClan( TheDataset, TheDataset.getDataSetRow(_Id), DSPropertyPVP_CLAN );
propPvpClan = (uint32)propPvpClanTemp;
}
/*
TYPE_PVP_CLAN CCharacter::getPVPFamesAllies()
{
TYPE_PVP_CLAN propPvpClanTemp = 0;
@ -843,7 +826,7 @@ TYPE_PVP_CLAN CCharacter::getPVPFamesEnemies()
return propPvpClanTemp | _PVPFlagEnemy;
return propPvpClanTemp;
}
*/
//-----------------------------------------------
// addPropertiesToMirror :
@ -1464,6 +1447,29 @@ uint32 CCharacter::tickUpdate()
{
H_AUTO(CharacterUpdatePVPMode);
if (_PVPSafeLastTimeChange + 20 < CTickEventHandler::getGameCycle())
{
bool update = false;
_PVPSafeLastTimeChange = CTickEventHandler::getGameCycle();
if (_PVPSafeLastTime != getSafeInPvPSafeZone())
{
_PVPSafeLastTime = !_PVPSafeLastTime;
update = true;
}
if (_PVPInSafeZoneLastTime != CPVPManager2::getInstance()->inSafeZone(getPosition()))
{
_PVPInSafeZoneLastTime = !_PVPInSafeZoneLastTime;
update = true;
}
if (update) {
CPVPManager2::getInstance()->setPVPModeInMirror(this);
updatePVPClanVP();
}
}
if( _HaveToUpdatePVPMode )
{
const TGameCycle waitTime = _PVPFlag ? TimeForSetPVPFlag.get() : TimeForPVPFlagOff.get();
@ -2865,7 +2871,9 @@ void CCharacter::postLoadTreatment()
{
_PlayerPets[ i ].Slot = INVENTORIES::INVALID_INVENTORY_SLOT;
}
uint32 slot = _PlayerPets[ i ].initLinkAnimalToTicket( this );
sendPetCustomNameToClient(i);
uint32 slot = _PlayerPets[ i ].initLinkAnimalToTicket( this, i );
if( slot < INVENTORIES::NbPackerSlots )
{
tickets[ slot ] = true;
@ -3625,7 +3633,7 @@ void CCharacter::setTargetBotchatProgramm( CEntityBase * target, const CEntityId
// _PropertyDatabase.setProp( toString("TARGET:CONTEXT_MENU:MISSIONS_OPTIONS:%u:PLAYER_GIFT_NEEDED",i) , 0 );
CBankAccessor_PLR::getTARGET().getCONTEXT_MENU().getMISSIONS_OPTIONS().getArray(i).setPLAYER_GIFT_NEEDED(_PropertyDatabase, 0 );
// _PropertyDatabase.setProp( toString("TARGET:CONTEXT_MENU:MISSIONS_OPTIONS:%u:PRIORITY",i), 0 );
CBankAccessor_PLR::getTARGET().getCONTEXT_MENU().getMISSIONS_OPTIONS().getArray(i).setPRIORITY(_PropertyDatabase, 0 );
CBankAccessor_PLR::getTARGET().getCONTEXT_MENU().getMISSIONS_OPTIONS().getArray(i).setPRIORITY(_PropertyDatabase, 2 );
i++;
}
}
@ -4563,13 +4571,31 @@ bool CCharacter::fillFaberMaterialArray( vector<CFaberMsgItem>& materialsSelecte
lowerMaterialQuality = USHRT_MAX;
for( uint s = 0; s < materialsSelectedForFaber.size(); ++s )
{
bool bOk = false;
CInventoryPtr pInv = NULL;
if( materialsSelectedForFaber[ s ].getInvId() >= INVENTORIES::NUM_INVENTORY )
{
// Also allow crafting from player's room
if (materialsSelectedForFaber[ s ].getInvId() == INVENTORIES::player_room)
{
if (getRoomInterface().isValid() && getRoomInterface().canUseInventory(this, this))
{
pInv = getRoomInterface().getInventory();
bOk = true;
}
}
if ( ! bOk)
{
nlwarning("<CCharacter::fillFaberMaterialArray> CFaberMsgItem[%d] sended by client contains an invalid inventory index %d", s, materialsSelectedForFaber[ s ].getInvId() );
return false;
}
}
else
{
pInv = _Inventory[ materialsSelectedForFaber[ s ].getInvId() ];
}
CInventoryPtr pInv = _Inventory[ materialsSelectedForFaber[ s ].getInvId() ];
if( materialsSelectedForFaber[ s ].IndexInInv >= pInv->getSlotCount() )
{
nlwarning("<CCharacter::fillFaberMaterialArray> CFaberMsgItem[%d] sended by client contains an invalid index %d for inventory %d", s, materialsSelectedForFaber[ s ].IndexInInv, materialsSelectedForFaber[ s ].getInvId() );
@ -5170,6 +5196,9 @@ bool CCharacter::addCharacterAnimal( const CSheetId& PetTicket, uint32 Price, CG
{
_PlayerPets[ i ] = pet;
pet.ItemPtr->setPetIndex(i);
pet.Slot = ptr->getInventorySlot();
// init pet inventory
const uint32 petMaxWeight = 0xFFFFFFFF; // no weight limit
const uint32 petMaxBulk = _PlayerPets[ i ].getAnimalMaxBulk();
@ -5433,6 +5462,7 @@ bool CCharacter::spawnWaitingCharacterAnimalNear( uint index, const SGameCoordin
msg.CharacterMirrorRow = _EntityRowId;
msg.PetSheetId = _PlayerPets[ index ].PetSheetId;
msg.PetIdx = index;
msg.CustomName = _PlayerPets[ index ].CustomName;
msg.AIInstanceId = (uint16)destAIInstance;
CWorldInstances::instance().msgToAIInstance( msg.AIInstanceId, msg);
// The row will be received in AnimalSpawned()
@ -5544,6 +5574,7 @@ bool CCharacter::spawnCharacterAnimal(uint index )
msg.CharacterMirrorRow = _EntityRowId;
msg.PetSheetId = _PlayerPets[ index ].PetSheetId;
msg.PetIdx = index;
msg.CustomName = _PlayerPets[ index ].CustomName;
CVector pos;
pos.x = msg.Coordinate_X * 0.001f;
@ -6723,6 +6754,38 @@ void CCharacter::sendAnimalCommand( uint8 petIndexCode, uint8 command )
}
}
void CCharacter::setAnimalName( uint8 petIndex, ucstring customName )
{
if (petIndex < 0 || petIndex >= MAX_INVENTORY_ANIMAL)
{
nlwarning("<CCharacter::setAnimalName> Incorect animal index '%d'.", petIndex);
return;
}
CPetAnimal& animal = _PlayerPets[petIndex];
animal.setCustomName(customName);
sendPetCustomNameToClient(petIndex);
TDataSetRow row = animal.SpawnedPets;
NLNET::CMessage msgout("CHARACTER_NAME");
msgout.serial(row);
msgout.serial(customName);
sendMessageViaMirror("IOS", msgout);
}
//-----------------------------------------------------------------------------
void CCharacter::sendPetCustomNameToClient(uint8 petIndex)
{
uint32 textId = 0;
if (_PlayerPets[petIndex].CustomName.length() > 0)
{
SM_STATIC_PARAMS_1(params, STRING_MANAGER::literal);
params[0].Literal= _PlayerPets[petIndex].CustomName;
uint32 userId = PlayerManager.getPlayerId(_Id);
textId = STRING_MANAGER::sendStringToUser(userId, "LITERAL", params);
}
CBankAccessor_PLR::getPACK_ANIMAL().getBEAST(petIndex).setNAME(_PropertyDatabase, textId);
}
//-----------------------------------------------
@ -6842,6 +6905,7 @@ double CCharacter::addXpToSkillInternal( double XpGain, const std::string& ContS
}
// check whether this character is on a free trial account
bool bFreeTrialLimitReached = false;
CPlayer * p = PlayerManager.getPlayer(PlayerManager.getPlayerId( getId() ));
BOMB_IF(p == NULL,"Failed to find player record for character: "<<getId().toString(),return 0.0);
if (p->isTrialPlayer())
@ -6853,7 +6917,7 @@ double CCharacter::addXpToSkillInternal( double XpGain, const std::string& ContS
SM_STATIC_PARAMS_1(params, STRING_MANAGER::skill);
params[0].Enum = skillEnum;
PHRASE_UTILITIES::sendDynamicSystemMessage(getEntityRowId(), "PROGRESS_FREE_TRIAL_LIMIT", params);
return 0.0;
bFreeTrialLimitReached = true;
}
}
@ -6893,6 +6957,11 @@ double CCharacter::addXpToSkillInternal( double XpGain, const std::string& ContS
// update death penalty
_DeathPenalties->addXP( *this, skillEnum, XpGain);
if (bFreeTrialLimitReached)
{
return 0.0;
}
// if no remaining XPGain, return
if (XpGain == 0.0f)
return 0.0;
@ -8800,7 +8869,7 @@ void CCharacter::setDatabase()
_IneffectiveAuras.activate();
_ConsumableOverdoseEndDates.activate();
// init the RRPs
RingRewardPoints.initDb();
//RingRewarsdPoints.initDb();
}// setDatabase //
@ -8862,7 +8931,7 @@ void CCharacter::startTradeItemSession( uint16 session )
nlwarning("fame %u is INVALID",(uint)bot->getRace() );
fame = MinFameToTrade;
}
else if ( fame < MinFameToTrade )
else if ( fame < MinFameToTrade && bot->getOrganization() != getOrganization() )
{
SM_STATIC_PARAMS_1(params, STRING_MANAGER::bot);
params[0].setEIdAIAlias( _CurrentInterlocutor, CAIAliasTranslator::getInstance()->getAIAlias(_CurrentInterlocutor) );
@ -8961,14 +9030,13 @@ void CCharacter::startTradePhrases(uint16 session)
return;
}
// *** Check the player has sufficient fame to Trade with Bot.
sint32 fame = CFameInterface::getInstance().getFameIndexed( _Id, bot->getForm()->getFaction() );
if ( fame == NO_FAME )
{
nlwarning("fame %u is INVALID",(uint)bot->getRace() );
}
if ( fame < MinFameToTrade )
if ( fame < MinFameToTrade && bot->getOrganization() != getOrganization() )
{
SM_STATIC_PARAMS_1(params, STRING_MANAGER::bot);
params[0].setEIdAIAlias( _CurrentInterlocutor, CAIAliasTranslator::getInstance()->getAIAlias(_CurrentInterlocutor) );
@ -9738,7 +9806,7 @@ void CCharacter::sellItem( INVENTORIES::TInventory inv, uint32 slot, uint32 quan
nlwarning("fame %u is INVALID",(uint)bot->getRace() );
fame = MinFameToTrade;
}
else if ( fame < MinFameToTrade )
else if ( fame < MinFameToTrade && bot->getOrganization() != getOrganization() )
{
SM_STATIC_PARAMS_1(params, STRING_MANAGER::bot);
params[0].setEIdAIAlias( _CurrentInterlocutor, CAIAliasTranslator::getInstance()->getAIAlias(_CurrentInterlocutor) );
@ -10087,6 +10155,84 @@ void CCharacter::initFactionPointDb()
}
}
//-----------------------------------------------
// setPvpPoint : set the number of pvp point
//
//-----------------------------------------------
void CCharacter::setPvpPoint(uint32 nbPt)
{
_PvpPoint = nbPt;
CBankAccessor_PLR::getUSER().getRRPS_LEVELS(0).setVALUE(_PropertyDatabase, nbPt );
}
//-----------------------------------------------
// getPvpPoint : get the number of pvp point
//
//-----------------------------------------------
uint32 CCharacter::getPvpPoint()
{
return _PvpPoint;
}
//-----------------------------------------------------------------------------
void CCharacter::initPvpPointDb()
{
CBankAccessor_PLR::getUSER().getRRPS_LEVELS(0).setVALUE(_PropertyDatabase, _PvpPoint );
}
//-----------------------------------------------------------------------------
void CCharacter::setOrganization(uint32 org)
{
if (org == _Organization)
return;
_Organization = org;
_OrganizationStatus = 0;
_OrganizationPoints = 0;
CBankAccessor_PLR::getUSER().getRRPS_LEVELS(1).setVALUE(_PropertyDatabase, _Organization );
CBankAccessor_PLR::getUSER().getRRPS_LEVELS(2).setVALUE(_PropertyDatabase, _OrganizationStatus );
CBankAccessor_PLR::getUSER().getRRPS_LEVELS(3).setVALUE(_PropertyDatabase, _OrganizationPoints );
}
//-----------------------------------------------------------------------------
void CCharacter::setOrganizationStatus(uint32 status)
{
_OrganizationStatus = status;
CBankAccessor_PLR::getUSER().getRRPS_LEVELS(2).setVALUE(_PropertyDatabase, _OrganizationStatus );
}
//-----------------------------------------------------------------------------
void CCharacter::changeOrganizationStatus(sint32 status)
{
if (status < 0 && abs(status) > _OrganizationStatus)
_OrganizationStatus = 0;
else
_OrganizationStatus += status;
CBankAccessor_PLR::getUSER().getRRPS_LEVELS(2).setVALUE(_PropertyDatabase, _OrganizationStatus );
}
//-----------------------------------------------------------------------------
void CCharacter::changeOrganizationPoints(sint32 points)
{
if (points < 0 && abs(points) > _OrganizationPoints)
_OrganizationPoints = 0;
else
_OrganizationPoints += points;
CBankAccessor_PLR::getUSER().getRRPS_LEVELS(3).setVALUE(_PropertyDatabase, _OrganizationPoints );
}
//-----------------------------------------------------------------------------
void CCharacter::initOrganizationInfos()
{
CBankAccessor_PLR::getUSER().getRRPS_LEVELS(1).setVALUE(_PropertyDatabase, _Organization );
CBankAccessor_PLR::getUSER().getRRPS_LEVELS(2).setVALUE(_PropertyDatabase, _OrganizationStatus );
CBankAccessor_PLR::getUSER().getRRPS_LEVELS(3).setVALUE(_PropertyDatabase, _OrganizationPoints );
}
//-----------------------------------------------------------------------------
void CCharacter::sendFactionPointGainMessage(PVP_CLAN::TPVPClan clan, uint32 fpGain)
{
@ -10176,6 +10322,16 @@ void CCharacter::exchangeProposal()
return;
}
// If not a privileged player and in ignorelist, don't trade
if ( !haveAnyPrivilege() && c->hasInIgnoreList( getId() ) )
{
params.resize(1);
params[0].Type = STRING_MANAGER::player;
params[0].setEIdAIAlias( c->getId(), CAIAliasTranslator::getInstance()->getAIAlias(c->getId()) );
CCharacter::sendDynamicSystemMessage(_EntityRowId, "EXCHANGE_DECLINE", params);
return;
}
//set the target's exchange asker, and inform the target
c->_ExchangeAsker = _Id;
@ -11666,7 +11822,7 @@ bool CCharacter::processMissionEventList( std::list< CMissionEvent* > & eventLis
// If the mission is not for guild members we just instanciate it
if (!missionForGuild)
CMissionManager::getInstance()->instanciateMission(this, mission, giver ,eventList, mainMission);
CMissionManager::getInstance()->instanciateMission(this, mission, giver, eventList, mainMission);
else
{
// We find the guild and each guild members and we instanciate the mission for them
@ -11681,7 +11837,7 @@ bool CCharacter::processMissionEventList( std::list< CMissionEvent* > & eventLis
nlwarning( "<MISSIONS>cant find user %s", it->first.toString().c_str() );
continue;
}
CMissionManager::getInstance()->instanciateMission(guildUser, mission, giver ,eventList, mainMission);
CMissionManager::getInstance()->instanciateMission(guildUser, mission, giver, eventList, mainMission);
}
}
}
@ -13430,7 +13586,45 @@ void CCharacter::sendUrl(const string &url, const string &salt)
PlayerManager.sendImpulseToClient(getId(), "USER:POPUP", titleId, textId);
}
void CCharacter::validateDynamicMissionStep(const string &url)
{
sendUrl(url+"&player_eid="+getId().toString()+"&event=mission_step_finished", getSalt());
}
/// set custom mission param
void CCharacter::setCustomMissionParams(const string &missionName, const string &params)
{
_CustomMissionsParams[missionName] = params;
}
/// add custom mission param
void CCharacter::addCustomMissionParam(const string &missionName, const string &param)
{
if (!_CustomMissionsParams.empty() && _CustomMissionsParams.find(missionName) != _CustomMissionsParams.end())
_CustomMissionsParams[missionName] += ","+param;
else
_CustomMissionsParams[missionName] = param;
}
/// get custom mission params
vector<string> CCharacter::getCustomMissionParams(const string &missionName)
{
vector<string> params;
if (_CustomMissionsParams.empty())
{
return params;
}
if (!_CustomMissionsParams.empty() && _CustomMissionsParams.find(missionName) != _CustomMissionsParams.end())
{
if (!_CustomMissionsParams[missionName].empty())
NLMISC::splitString(_CustomMissionsParams[missionName], ",", params);
}
return params;
}
// !!! Deprecated !!!
void CCharacter::addWebCommandCheck(const string &url, const string &data, const string &salt)
{
uint webCommand = getWebCommandCheck(url);
@ -13494,6 +13688,7 @@ void CCharacter::addWebCommandCheck(const string &url, const string &data, const
}
}
// !!! Deprecated !!!
uint CCharacter::getWebCommandCheck(const string &url)
{
CInventoryPtr inv = getInventory(INVENTORIES::bag);
@ -13528,6 +13723,7 @@ uint CCharacter::getWebCommandCheck(const string &url)
return INVENTORIES::NbBagSlots;
}
// !!! Deprecated !!!
uint CCharacter::checkWebCommand(const string &url, const string &data, const string &hmac, const string &salt)
{
if (salt.empty())
@ -14650,7 +14846,7 @@ void CCharacter::addRoomAccessToPlayer(const NLMISC::CEntityId &id)
//--------------------------------------------------------------
void CCharacter::addPlayerToFriendList(const NLMISC::CEntityId &id)
{
// if player not found
/*// if player not found
if (id == CEntityId::Unknown || PlayerManager.getChar(id)==NULL)
{
if ( ! (IShardUnifierEvent::getInstance() && IShardUnifierEvent::getInstance()->isCharacterOnlineAbroad(id)))
@ -14659,7 +14855,7 @@ void CCharacter::addPlayerToFriendList(const NLMISC::CEntityId &id)
PHRASE_UTILITIES::sendDynamicSystemMessage( _EntityRowId, "OPERATION_OFFLINE");
return;
}
}
}*/
// check not already in list
const uint size = (uint)_FriendsList.size();
@ -14721,6 +14917,82 @@ void CCharacter::addPlayerToFriendList(const NLMISC::CEntityId &id)
}
//--------------------------------------------------------------
// CCharacter::addPlayerToLeagueList() // unused, need more tests
//--------------------------------------------------------------
void CCharacter::addPlayerToLeagueList(const NLMISC::CEntityId &id)
{
// if player not found
/*if (id == CEntityId::Unknown || PlayerManager.getChar(id)==NULL)
{
if ( ! (IShardUnifierEvent::getInstance() && IShardUnifierEvent::getInstance()->isCharacterOnlineAbroad(id)))
{
// player not found => message
PHRASE_UTILITIES::sendDynamicSystemMessage( _EntityRowId, "OPERATION_OFFLINE");
return;
}
}*/
// check not already in list
const uint size = _LeagueList.size();
for ( uint i =0 ; i < size ; ++i)
{
if ( _LeagueList[i].EntityId.getShortId() == id.getShortId())
{
return;
}
}
if(haveAnyPrivilege() == false && PlayerManager.haveAnyPriv(id))
return; // a character without privilege can't add one with privilege.
uint32 playerId = PlayerManager.getPlayerId(id);
// check the two char aren't from the same account
if (playerId == PlayerManager.getPlayerId(_Id))
{
egs_chinfo("Char %s tried to add %s in his friend list but they are from the same account->return", _Id.toString().c_str(), id.toString().c_str());
return;
}
// reference count
contactListRefChange( id, AddedAsLeague);
// add the char to friends
CContactId contactId;
contactId.EntityId= id;
contactId.ContactId= _ContactIdPool++; // create a new Id for client/server communication
_LeagueList.push_back(contactId);
// send create message to client
CMessage msgout( "IMPULSION_ID" );
msgout.serial( _Id );
CBitMemStream bms;
if ( ! GenericMsgManager.pushNameToStream( "TEAM:CONTACT_CREATE", bms) )
{
nlwarning("<CEntityBase::addPlayerToFriendList> Msg name TEAM:CONTACT_CREATE not found");
return;
}
TCharConnectionState onlineStatus = ccs_online;
uint32 nameId = CEntityIdTranslator::getInstance()->getEntityNameStringId(id);
uint8 listIndex = 2;
bms.serial(contactId.ContactId);
bms.serial(nameId);
bms.serialShortEnum(onlineStatus);
bms.serial(listIndex);
msgout.serialBufferWithSize((uint8*)bms.buffer(), bms.length());
CUnifiedNetwork::getInstance()->send( NLNET::TServiceId(_Id.getDynamicId()), msgout );
}
//--------------------------------------------------------------
// CCharacter::addPlayerToIgnoreList()
//--------------------------------------------------------------
@ -14822,6 +15094,23 @@ void CCharacter::removePlayerFromFriendListByIndex(uint16 index)
contactListRefChange( id, RemovedFromFriends);
}
//--------------------------------------------------------------
// CCharacter::removePlayerFromFriendListByIndex() // unused, need more tests
//--------------------------------------------------------------
void CCharacter::removePlayerFromLeagueListByIndex(uint16 index)
{
if (index >= _LeagueList.size())
return;
const CEntityId id = _LeagueList[index].EntityId;
uint32 contactId= _LeagueList[index].ContactId;
// remove entry
_LeagueList.erase(_LeagueList.begin() + index);
sendRemoveContactMessage(contactId, 2);
contactListRefChange( id, RemovedFromLeague);
}
//--------------------------------------------------------------
// CCharacter::removePlayerFromIgnoreListByIndex()
//--------------------------------------------------------------
@ -14901,6 +15190,25 @@ void CCharacter::removePlayerFromFriendListByEntityId(const NLMISC::CEntityId &i
}
}
//--------------------------------------------------------------
// CCharacter::removePlayerFromLeagueListByEntityId() // unused, need more tests
//--------------------------------------------------------------
void CCharacter::removePlayerFromLeagueListByEntityId(const NLMISC::CEntityId &id)
{
if (id == NLMISC::CEntityId::Unknown)
return;
for ( uint i = 0 ; i < _LeagueList.size() ; ++i)
{
if ( _LeagueList[i].EntityId.getShortId() == id.getShortId() )
{
removePlayerFromLeagueListByIndex(i);
break;
}
}
}
//--------------------------------------------------------------
// CCharacter::removePlayerFromIgnoreListByEntityId()
//--------------------------------------------------------------
@ -14934,6 +15242,22 @@ void CCharacter::removePlayerFromFriendListByContactId(uint32 contactId)
}
}
//--------------------------------------------------------------
// CCharacter::removePlayerFromFriendListByContactId() unused, need more tests
//--------------------------------------------------------------
void CCharacter::removePlayerFromLeagueListByContactId(uint32 contactId)
{
for ( uint i = 0 ; i < _LeagueList.size() ; ++i)
{
if ( _LeagueList[i].ContactId == contactId )
{
removePlayerFromLeagueListByIndex(i);
break;
}
}
}
//--------------------------------------------------------------
// CCharacter::removePlayerFromIgnoreListByContactId()
//--------------------------------------------------------------
@ -15329,6 +15653,15 @@ void CCharacter::sendRemoveContactMessage(uint32 contactId, uint8 listNumber)
CUnifiedNetwork::getInstance()->send( NLNET::TServiceId(_Id.getDynamicId()), msgout );
} // sendRemoveContactMessage //
//--------------------------------------------------------------
// CCharacter::setLastConnectionDate()
//--------------------------------------------------------------
void CCharacter::setLastConnectionDate(uint32 date)
{
_LastConnectedDate = date;
}
//--------------------------------------------------------------
// CCharacter::destroyCharacter()
//--------------------------------------------------------------
@ -15476,8 +15809,6 @@ void CCharacter::onConnection()
{
// Add all handledAIGroups for all missions of the player
spawnAllHandledAIGroup();
// add character to event channel if event occurs
CGameEventManager::getInstance().addCharacterToChannelEvent( this );
// update for the unified entity locator
if (IShardUnifierEvent::getInstance() != NULL)
@ -15874,6 +16205,7 @@ void CCharacter::sendEmote( const NLMISC::CEntityId& id, MBEHAV::EBehaviour beha
uint32 txtId = STRING_MANAGER::sendStringToClient( targetRow, phraseCont->TargetTarget, params );
// send emote message to IOS
NLNET::CMessage msgout("EMOTE_PLAYER");
msgout.serial( const_cast<TDataSetRow&>( getEntityRowId() ) );
msgout.serial( targetRow );
msgout.serial(txtId);
sendMessageViaMirror("IOS", msgout);
@ -15884,7 +16216,8 @@ void CCharacter::sendEmote( const NLMISC::CEntityId& id, MBEHAV::EBehaviour beha
uint32 txtId = STRING_MANAGER::sendStringToClient(getEntityRowId(), *self, params );
// send emote message to IOS
NLNET::CMessage msgout("EMOTE_PLAYER");
msgout.serial( const_cast<TDataSetRow&>( getEntityRowId() ) );
msgout.serial( const_cast<TDataSetRow&>( getEntityRowId() ) ); // sender
msgout.serial( const_cast<TDataSetRow&>( getEntityRowId() ) ); // receiver
msgout.serial(txtId);
sendMessageViaMirror("IOS", msgout);
@ -16226,7 +16559,14 @@ NLMISC::TGameCycle CCharacter::getMissionLastSuccess(const CMissionTemplate & te
{
std::map< TAIAlias, TMissionHistory >::iterator it(_MissionHistories.find(templ.Alias));
if (it != _MissionHistories.end())
{
TGameCycle lastSuccessDate = it->second.LastSuccessDate;
if (lastSuccessDate > CTickEventHandler::getGameCycle())
return 0;
return it->second.LastSuccessDate;
}
return 0;
}
@ -17049,6 +17389,9 @@ void CCharacter::setPVPFlag( bool pvpFlag )
// set the new pvp flag and time last change for apply timer delay before this change become effective
if( pvpFlag == false )
{
if (_PVPFlagTimeSettedOn > CTickEventHandler::getGameCycle())
_PVPFlagTimeSettedOn = CTickEventHandler::getGameCycle() - TimeForResetPVPFlag;
if( _PVPFlagTimeSettedOn + TimeForResetPVPFlag > CTickEventHandler::getGameCycle() )
{
// we need wait a minimal of time before reset your pvp tag
@ -17146,13 +17489,6 @@ void CCharacter::setPVPRecentActionFlag(CCharacter *target)
_PVPRecentActionTime = CTickEventHandler::getGameCycle();
if (target != NULL)
{
_PVPFlagAlly |= target->getPVPFamesAllies();
_PVPFlagEnemy |= target->getPVPFamesEnemies();
updatePVPClanVP();
}
// _PropertyDatabase.setProp("CHARACTER_INFO:PVP_FACTION_TAG:FLAG_PVP_TIME_LEFT", _PVPRecentActionTime + PVPActionTimer );
CBankAccessor_PLR::getCHARACTER_INFO().getPVP_FACTION_TAG().setFLAG_PVP_TIME_LEFT(_PropertyDatabase, _PVPRecentActionTime + PVPActionTimer );
@ -17880,7 +18216,7 @@ void CPetAnimal::serial(NLMISC::IStream &f) throw(NLMISC::EStream)
}
//-----------------------------------------------------------------------------
uint32 CPetAnimal::initLinkAnimalToTicket( CCharacter * c )
uint32 CPetAnimal::initLinkAnimalToTicket( CCharacter * c, uint8 index )
{
if( c )
{
@ -17888,6 +18224,8 @@ uint32 CPetAnimal::initLinkAnimalToTicket( CCharacter * c )
if( ( ItemPtr != 0 ) && ( ItemPtr->getStaticForm() != NULL ) && ( ItemPtr->getStaticForm()->Family == ITEMFAMILY::PET_ANIMAL_TICKET ) )
{
// Slot = ItemPtr->getLocSlot();
ItemPtr->setPetIndex(index);
ItemPtr->setCustomName(CustomName);
Slot = ItemPtr->getInventorySlot();
return Slot;
}
@ -17900,6 +18238,8 @@ uint32 CPetAnimal::initLinkAnimalToTicket( CCharacter * c )
{
// Slot = ItemPtr->getLocSlot();
Slot = ItemPtr->getInventorySlot();
ItemPtr->setPetIndex(index);
ItemPtr->setCustomName(CustomName);
return Slot;
}
else
@ -17916,7 +18256,6 @@ uint32 CPetAnimal::initLinkAnimalToTicket( CCharacter * c )
return INVENTORIES::INVALID_INVENTORY_SLOT;
}
//-----------------------------------------------
// getAnimalMaxBulk
//-----------------------------------------------
@ -18697,8 +19036,42 @@ void CCharacter::teleportCharacter( sint32 x, sint32 y)
void CCharacter::setTeamId(uint16 id)
{
_TeamId = id;
updatePVPClanVP();
}
void CCharacter::setLeagueId(TChanID id, bool removeIfEmpty)
{
ucstring name = CEntityIdTranslator::getInstance()->getByEntity(getId());
CEntityIdTranslator::removeShardFromName(name);
// Remove old dynamic channel
if (_LeagueId != DYN_CHAT_INVALID_CHAN)
{
CPVPManager2::getInstance()->broadcastMessage(_LeagueId, string("<INFO>"), name+" -->[]");
PHRASE_UTILITIES::sendDynamicSystemMessage(getEntityRowId(), "TEAM_QUIT_LEAGUE");
DynChatEGS.removeSession(_LeagueId, getEntityRowId());
vector<CEntityId> players;
bool isEmpty = DynChatEGS.getPlayersInChan(_LeagueId, players);
if (isEmpty)
{
if (removeIfEmpty)
DynChatEGS.removeChan(_LeagueId);
}
}
if (id != DYN_CHAT_INVALID_CHAN)
{
PHRASE_UTILITIES::sendDynamicSystemMessage(getEntityRowId(), "TEAM_JOIN_LEAGUE");
DynChatEGS.addSession(id, getEntityRowId(), true);
CPVPManager2::getInstance()->broadcastMessage(id, string("<INFO>"), "<-- "+name);
}
_LeagueId = id;
updatePVPClanVP();
}
//------------------------------------------------------------------------------
@ -18707,6 +19080,12 @@ void CCharacter::setTeamInvitor(const NLMISC::CEntityId & invitorId)
_TeamInvitor = invitorId;
}
//------------------------------------------------------------------------------
void CCharacter::setLeagueInvitor(const NLMISC::CEntityId & invitorId)
{
_LeagueInvitor = invitorId;
}
//------------------------------------------------------------------------------
@ -19871,6 +20250,13 @@ void CCharacter::setPriviledgePVP( bool b )
_PriviledgePvp = b;
}
//------------------------------------------------------------------------------
void CCharacter::setFullPVP( bool b )
{
_FullPvp = b;
}
//------------------------------------------------------------------------------

@ -21,6 +21,7 @@
// Game Share
#include "game_share/bot_chat_types.h"
#include "game_share/brick_flags.h"
#include "server_share/pet_interface_msg.h"
#include "game_share/power_types.h"
#include "game_share/roles.h"
#include "game_share/temp_inventory_mode.h"
@ -297,6 +298,7 @@ struct CPetAnimal
bool IsMounted;
bool IsTpAllowed;
bool spawnFlag;
ucstring CustomName;
// ctor
CPetAnimal();
@ -305,10 +307,12 @@ struct CPetAnimal
void serial(NLMISC::IStream &f) throw(NLMISC::EStream);
// init found ticket item pointer with slot
uint32 initLinkAnimalToTicket( CCharacter * c );
uint32 initLinkAnimalToTicket( CCharacter * c, uint8 index);
// get the max bulk of the animal inventory
uint32 getAnimalMaxBulk();
void setCustomName(const ucstring& customName) { CustomName = customName; }
};
/**
@ -416,6 +420,10 @@ private:
RemoveFriend,
RemoveIgnored,
AddedAsLeague,
RemovedFromLeague,
RemoveLeague,
NB_CONTACT_LIST_ACTIONS,
UnknownContactListAction= NB_CONTACT_LIST_ACTIONS,
};
@ -738,6 +746,9 @@ public:
// return the season in which is the current character
uint8 getRingSeason() const { return _RingSeason;}
/// get the League id
TChanID getLeagueId() const { return _LeagueId;}
// \name Team related methods
@ -746,10 +757,16 @@ public:
uint16 getTeamId() const;
/// set the team Id of this player
void setTeamId(uint16 id);
/// set the League id
void setLeagueId(TChanID id, bool removeIfEmpty=false);
/// get team invitor
const NLMISC::CEntityId & getTeamInvitor() const;
/// set team invitor
void setTeamInvitor(const NLMISC::CEntityId & invitorId);
/// get League invitor
const NLMISC::CEntityId & getLeagueInvitor() const;
/// set League invitor
void setLeagueInvitor(const NLMISC::CEntityId & invitorId);
//@}
/// Set fighting target
@ -975,6 +992,11 @@ public:
// return the index of a player pet, or -1 if not found
sint32 getPlayerPet( const TDataSetRow& petRowId ) const;
// Set the name of the animal
void setAnimalName( uint8 petIndex, ucstring customName );
void sendPetCustomNameToClient(uint8 petIndex);
// near character's pets are TP with player (continent tp)
void allowNearPetTp();
bool isNearPetTpIsAllowed() const;
@ -1151,6 +1173,12 @@ public:
/// get the number of faction point given a faction
uint32 getFactionPoint(PVP_CLAN::TPVPClan clan);
/// set the number of pvp point
void setPvpPoint(uint32 nbPt);
/// get the number of pvp point given a faction
uint32 getPvpPoint();
/// set the SDB path where player wins HoF points in PvP (if not empty)
void setSDBPvPPath(const std::string & sdbPvPPath);
@ -1160,6 +1188,15 @@ public:
/// init faction point in client database
void initFactionPointDb();
/// init pvp point in client database
void initPvpPointDb();
void initOrganizationInfos();
void setOrganization(uint32 org);
void setOrganizationStatus(uint32 status);
void changeOrganizationStatus(sint32 status);
void changeOrganizationPoints(sint32 points);
/// send faction point gain phrase to the client
void sendFactionPointGainMessage(PVP_CLAN::TPVPClan clan, uint32 fpGain);
/// send faction point gain kill phrase to the client
@ -1614,6 +1651,18 @@ public:
/// send custom url
void sendUrl(const std::string &url, const std::string &salt);
/// set custom mission param
void setCustomMissionParams(const std::string &missionName, const std::string &params);
/// add custom mission param
void addCustomMissionParam(const std::string &missionName, const std::string &param);
/// get custom mission params
std::vector<std::string> getCustomMissionParams(const std::string &missionName);
/// validate dynamic mission step sending url
void validateDynamicMissionStep(const std::string &url);
/// add web command validation check
void addWebCommandCheck(const std::string &url, const std::string &data, const std::string &salt);
@ -1856,15 +1905,18 @@ public:
/// add a player to friend list by name
void addPlayerToFriendList(const ucstring &name);
/// add a player to friend list by id
void addPlayerToFriendList(const NLMISC::CEntityId &id);
/// add a player to ignore list by name
void addPlayerToIgnoreList(const ucstring &name);
/// add a player to ignore list by Id
void addPlayerToIgnoreList(const NLMISC::CEntityId &id);
/// add a player to league list by id
void addPlayerToLeagueList(const NLMISC::CEntityId &id);
/// add a player to friend list by id
void addPlayerToFriendList(const NLMISC::CEntityId &id);
/// get a player from friend or ignore list, by contact id
const NLMISC::CEntityId &getFriendByContactId(uint32 contactId);
const NLMISC::CEntityId &getIgnoreByContactId(uint32 contactId);
@ -1885,6 +1937,9 @@ public:
/// remove room acces to player
void removeRoomAccesToPlayer(const NLMISC::CEntityId &id, bool kick);
/// remove player from league list
void removePlayerFromLeagueListByContactId(uint32 contactId);
void removePlayerFromLeagueListByEntityId(const NLMISC::CEntityId &id);
/// remove player from ignore list
void removePlayerFromIgnoreListByContactId(uint32 contactId);
@ -1923,6 +1978,9 @@ public:
/// player is going online or offline
void online(bool onlineStatus);
/// player last connection date (from SU, exactly like on mysql db)
void setLastConnectionDate(uint32 date);
/// player is permanently erased, unreferenced it from all contact lists
void destroyCharacter();
@ -2230,6 +2288,8 @@ public:
// priviledge PVP mode
void setPriviledgePVP( bool b );
bool priviledgePVP();
// full PVP mode
void setFullPVP( bool b );
/// set the current PVP zone where the player is
void setCurrentPVPZone(TAIAlias alias);
/// get the current PVP zone where the player is
@ -2246,6 +2306,8 @@ public:
void openPVPVersusDialog() const;
/// get priviledgePvp
bool getPriviledgePVP() const {return _PriviledgePvp;};
/// get fullPvp
bool getFullPVP() const {return _FullPvp;};
/// get character pvp flag
bool getPVPFlag( bool updatePVPModeInMirror = true ) const;
/// change pvp flag
@ -2274,7 +2336,7 @@ public:
/// Set an allegiance to neutral from indetermined status, used for process message from client want set it's allegiance to neutral when it's idetermined, over case are managed by missions.
void setAllegianceFromIndeterminedStatus(PVP_CLAN::TPVPClan allegiance);
/// true if pvp safe zone active for character
bool getSafeInPvPSafeZone();
bool getSafeInPvPSafeZone() const;
/// set pvp safe zone to true
void setPvPSafeZoneActive();
/// clear pvp zone safe flag
@ -2316,7 +2378,9 @@ public:
/// character log stats accessors
uint32 getFirstConnectedTime() const;
uint32 getLastConnectedTime() const;
uint32 getLastConnectedDate() const;
uint32 getPlayedTime() const;
uint32 getOrganization() const;
const std::list<TCharacterLogTime>& getLastLogStats() const;
void updateConnexionStat();
void setDisconnexionTime();
@ -2339,7 +2403,7 @@ public:
bool isAnActiveXpCatalyser( CGameItemPtr item );
void setShowFactionChannelsMode(TChanID channel, bool s);
bool showFactionChannelsMode(TChanID channel) const;
bool showFactionChannelsMode(TChanID channel);
// from offline command
void contactListRefChangeFromCommand(const NLMISC::CEntityId &id, const std::string &operation);
@ -2635,6 +2699,8 @@ private:
/// remove player from friend list
void removePlayerFromFriendListByIndex(uint16 index);
/// remove player from league list
void removePlayerFromLeagueListByIndex(uint16 index);
/// remove player from ignore list
void removePlayerFromIgnoreListByIndex(uint16 index);
@ -2934,6 +3000,12 @@ private:
uint32 _FactionPoint[PVP_CLAN::EndClans-PVP_CLAN::BeginClans+1];
uint32 _PvpPoint;
uint32 _Organization;
uint32 _OrganizationStatus;
uint32 _OrganizationPoints;
/// SDB path where player wins HoF points in PvP (if not empty)
std::string _SDBPvPPath;
@ -2944,9 +3016,14 @@ private:
/// if this player has an invitation for another team, keep the team here
NLMISC::CEntityId _TeamInvitor;
/// if this player has an invitation for League, keep the invitor here
NLMISC::CEntityId _LeagueInvitor;
// id of the current team
CMirrorPropValueAlice< uint16, CPropLocationPacked<2> > _TeamId;
TChanID _LeagueId;
/// temp values used to test if team bars need an update or not
mutable uint8 _OldHpBarSentToTeam;
mutable uint8 _OldSapBarSentToTeam;
@ -3178,6 +3255,11 @@ private:
/// nb of users channels
uint8 _NbUserChannels;
/// last webcommand index
uint32 _LastWebCommandIndex;
std::map<std::string, std::string> _CustomMissionsParams;
// for a power/combat event, stores start and end ticks
struct CFlagTickRange {
@ -3243,6 +3325,8 @@ private:
// friends list
std::vector<CContactId> _FriendsList;
// league list
std::vector<CContactId> _LeagueList;
// ignore list
std::vector<CContactId> _IgnoreList;
// list of players for whom this player is in the friendlist (to update online status and to remove from players list if this char is permanently deleted)
@ -3380,8 +3464,14 @@ private:
CPVPInterface *_PVPInterface;
// set pvp mode for priviledge player
bool _PriviledgePvp;
// set full pvp mode for player
bool _FullPvp;
// flag PVP, true for player involved in Faction PVP and other PVP
bool _PVPFlag;
// time of last change in pvp safe
NLMISC::TGameCycle _PVPSafeLastTimeChange;
bool _PVPSafeLastTime;
bool _PVPInSafeZoneLastTime;
// time of last change in pvp flag (for prevent change PVP flag exploits)
NLMISC::TGameCycle _PVPFlagLastTimeChange;
// time of pvp flag are setted to on (for prevent change PVP flag exploits)
@ -3571,7 +3661,8 @@ private:
std::set<NLMISC::CEntityId> _EntitiesToSaveWithMe;
uint32 _FirstConnectedTime; //first connected time in second since midnight (00:00:00), January 1, 1970
uint32 _LastConnectedTime; //last connected time in second since midnight (00:00:00), January 1, 1970
uint32 _LastConnectedTime; //last connected time in second since midnight (00:00:00), January 1, 1970 (change each tick update)
uint32 _LastConnectedDate; //last connected time in second since midnight (00:00:00), January 1, 1970 (never change after login, exactly like in mysql db)
uint32 _PlayedTime; //cumulated played time in second
mutable std::list<TCharacterLogTime> _LastLogStats; //keep n login/duration/logoff time
@ -3625,6 +3716,11 @@ private:
/// General god flag for persistence
bool _GodModeSave;
public:
void setWebCommandIndex(uint32 index) { _LastWebCommandIndex = index;}
uint32 getWebCommandIndex() const { return _LastWebCommandIndex;}
bool getInvisibility() const { return _Invisibility;}
/// Set the invisibility flag, NB : just for persistence, do not change nothing.
void setInvisibility(bool invisible)

@ -131,6 +131,13 @@ inline const NLMISC::CEntityId & CCharacter::getTeamInvitor() const
//------------------------------------------------------------------------------
inline const NLMISC::CEntityId & CCharacter::getLeagueInvitor() const
{
return _LeagueInvitor;
}
//------------------------------------------------------------------------------
inline const NLMISC::CEntityId &CCharacter::harvestedEntity() const
{
return _MpSourceId;
@ -847,7 +854,7 @@ inline uint16 CCharacter::getKilledPvPRegion()
//------------------------------------------------------------------------------
inline bool CCharacter::getSafeInPvPSafeZone()
inline bool CCharacter::getSafeInPvPSafeZone() const
{
return _PvPSafeZoneActive;
}
@ -875,11 +882,26 @@ inline uint32 CCharacter::getLastConnectedTime() const
//------------------------------------------------------------------------------
inline uint32 CCharacter::getLastConnectedDate() const
{
return _LastConnectedDate;
}
//------------------------------------------------------------------------------
inline uint32 CCharacter::getPlayedTime() const
{
return _PlayedTime;
}
//------------------------------------------------------------------------------
inline uint32 CCharacter::getOrganization() const
{
return _Organization;
}
//------------------------------------------------------------------------------
inline const std::list<TCharacterLogTime>& CCharacter::getLastLogStats() const

@ -126,6 +126,9 @@ public:
virtual void setContactOnlineStatus(const NLMISC::CEntityId &charEid, bool connection) =0;
virtual void setLastConnectionDate(uint32 date) =0;
virtual void syncContactListWithCharNameChanges(const std::vector<NLMISC::CEntityId> &charNameChanges)=0;
virtual void updateTargetingChars()=0;

@ -2443,7 +2443,7 @@ void CCharacter::sendItemInfos( uint16 slotId )
infos.TypeSkillMods = item->getTypeSkillMods();
// Special case of web missions items
if (item->getStaticForm()->Name == "Web Transaction" || item->getStaticForm()->Family == ITEMFAMILY::SCROLL)
if (item->getStaticForm()->Name == "Web Transaction")
{
string cText = item->getCustomText().toString();
string::size_type sPos = cText.find(" ");
@ -2453,11 +2453,16 @@ void CCharacter::sendItemInfos( uint16 slotId )
string cUrl = cText.substr(sPos, ePos-sPos);
infos.CustomText = ucstring("@WEBIG "+cUrl);
}
else
infos.CustomText = "";
}
else
{
infos.CustomText = item->getCustomText();
}
if (item->getPetIndex() < MAX_INVENTORY_ANIMAL)
{
infos.PetNumber = item->getPetIndex() + 1;
}
CMessage msgout( "IMPULSION_ID" );
CBitMemStream bms;
@ -2912,7 +2917,8 @@ void CCharacter::useItem(uint32 slot)
{
pair<PVP_CLAN::TPVPClan, PVP_CLAN::TPVPClan> allegeance = getAllegiance();
if ((form->TpType == TELEPORT_TYPES::KAMI) && (allegeance.first == PVP_CLAN::Karavan)
|| (form->TpType == TELEPORT_TYPES::KARAVAN) && (allegeance.first == PVP_CLAN::Kami))
|| (form->TpType == TELEPORT_TYPES::KARAVAN) && (allegeance.first == PVP_CLAN::Kami)
|| getOrganization() == 5 ) //marauder
{
CCharacter::sendDynamicSystemMessage(_Id, "ALTAR_RESTRICTION");
return;

@ -414,6 +414,10 @@ static void prepareCharacterPositionForStore ( COfflineEntityState & state, cons
_FactionPoint[i],\
PVP_CLAN::TPVPClan k=PVP_CLAN::fromString(key); if ((k>=PVP_CLAN::BeginClans) && (k<=PVP_CLAN::EndClans)) _FactionPoint[k-PVP_CLAN::BeginClans]=val)\
\
PROP(uint32,_PvpPoint)\
PROP(uint32,_Organization)\
PROP(uint32,_OrganizationStatus)\
PROP(uint32,_OrganizationPoints)\
PROP2(DeclaredCult,string,PVP_CLAN::toString(_DeclaredCult),_DeclaredCult=PVP_CLAN::fromString(val))\
PROP2(DeclaredCiv,string,PVP_CLAN::toString(_DeclaredCiv),_DeclaredCiv=PVP_CLAN::fromString(val))\
\
@ -688,6 +692,7 @@ static void prepareCharacterPositionForStore ( COfflineEntityState & state, cons
LPROP(bool,IsMounted,if(IsMounted))\
PROP(bool,IsTpAllowed)\
PROP(TSatiety,Satiety)\
PROP2(CustomName, ucstring, CustomName, CustomName = val)\
//#pragma message( PERSISTENT_GENERATION_MESSAGE )
#include "game_share/persistent_data_template.h"
@ -1183,7 +1188,7 @@ static void displayWarning(const std::string& s)
//-----------------------------------------------------------------------------
/**
* This class is used to load old player room inventory, DO NOT BREAK IT!
* \author Sébastien 'kxu' Guignot
* \author Sebastien 'kxu' Guignot
* \author Nevrax France
* \date 2005
*/
@ -1345,6 +1350,7 @@ private:
STRUCT_VECT(_TypeSkillMods)\
LPROP_VECT(CSheetId, _Enchantment, VECT_LOGIC(_Enchantment) if (_Enchantment[i]!=CSheetId::Unknown))\
PROP2(_CustomText, ucstring, _CustomText, _CustomText=val)\
PROP(bool, _LockedByOwner)\
//#pragma message( PERSISTENT_GENERATION_MESSAGE )
#include "game_share/persistent_data_template.h"

@ -2357,7 +2357,7 @@ void CPlayerManager::broadcastMessageUpdate()
msg= msg.replace("$seconds$",secondsStr.c_str());
msg= msg.replace("$minutes$",minutesStr.c_str());
msg= msg.replace("$hours$",hoursStr.c_str());
nlinfo("braodcasting message: %s",msg.c_str());
nlinfo("broadcasting message: %s",msg.c_str());
SM_STATIC_PARAMS_1(params, STRING_MANAGER::literal);
params[0].Literal.fromUtf8(msg);

@ -1095,14 +1095,14 @@ void CDamageScoreManager::playerDeath(CCharacter * victimChar, const CCharacter
nlassert(victimChar != NULL);
PVP_CLAN::TPVPClan victimFaction;
bool victimLosesFactionPoints;
if (!playerInFactionPvP(victimChar, &victimFaction, &victimLosesFactionPoints))
return;
// PVP_CLAN::TPVPClan victimFaction;
bool victimLosesFactionPoints = false;
// if (!playerInFactionPvP(victimChar, &victimFaction, &victimLosesFactionPoints))
// return;
PVP_CLAN::TPVPClan finalBlowerFaction;
if (!playerInFactionPvP(finalBlower, &finalBlowerFaction))
return;
// PVP_CLAN::TPVPClan finalBlowerFaction;
// if (!playerInFactionPvP(finalBlower, &finalBlowerFaction))
// return;
// check if victim and final blower are in PvP Faction (by tag or by a pvp versus zone)
/* if(!CPVPManager2::getInstance()->factionWarOccurs(victimFaction, finalBlowerFaction))
@ -1204,9 +1204,13 @@ void CDamageScoreManager::playerDeath(CCharacter * victimChar, const CCharacter
BOMB_IF(winnerChar == NULL, "invalid winner!", continue);
PVP_CLAN::TPVPClan winnerFaction;
bool winnerGainFactionPoints;
if(!playerInFactionPvP(winnerChar, &winnerFaction, &winnerGainFactionPoints))
continue; // can be in Duel or in other pvp mode.
bool winnerGainFactionPoints = true;
if (!canPlayerWinPoints(winnerChar, victimChar))
continue;
//if(!playerInFactionPvP(winnerChar, &winnerFaction, &winnerGainFactionPoints))
// continue; // can be in Duel or in other pvp mode.
CRewardedKills::CRewardedKiller * noPointPlayer = getRewardedKiller(winnerChar->getId(), noPointPlayers);
if (noPointPlayer != NULL)
@ -1227,9 +1231,27 @@ void CDamageScoreManager::playerDeath(CCharacter * victimChar, const CCharacter
if (winnerGainFactionPoints)
{
// Compute Fames delta
sint32 fameFactor = 0;
for (uint8 fameIdx = 0; fameIdx < 7; fameIdx++)
{
sint32 victimFame = CFameInterface::getInstance().getFameIndexed(victimChar->getId(), fameIdx);
sint32 winnerFame = CFameInterface::getInstance().getFameIndexed(winnerChar->getId(), fameIdx);
if ( (victimFame >= 25*6000 && winnerFame <= -25*6000) ||
(winnerFame >= 25*6000 && victimFame <= -25*6000) )
fameFactor++;
if ( (victimFame >= 25*6000 && winnerFame >= 25*6000) ||
(victimFame <= -25*6000 && winnerFame <= -25*6000) )
fameFactor--;
}
clamp(fameFactor, 0, 3);
nlinfo("points = %d * %d", fpPerPlayer, fameFactor);
// player gains faction points
changePlayerFactionPoints(winnerChar, winnerFaction, sint32(fpPerPlayer));
winnerChar->sendFactionPointGainKillMessage(winnerFaction, fpPerPlayer, victimChar->getId());
changePlayerPvpPoints(winnerChar, sint32(fpPerPlayer) * fameFactor);
winnerChar->sendFactionPointGainKillMessage(winnerFaction, fpPerPlayer * fameFactor, victimChar->getId());
}
// player gains HoF points
@ -1237,13 +1259,14 @@ void CDamageScoreManager::playerDeath(CCharacter * victimChar, const CCharacter
// and a way for known if an episode occurs (and specs for known if other episode pemrti to win HoF point...)
//changePlayerHoFPoints(winnerChar, sint32(hofpPerPlayer));
/*
// PvP faction winner HOF reward
CPVPManager2::getInstance()->characterKillerInPvPFaction( winnerChar, winnerFaction, (sint32)fpPerPlayer );
if( finalBlower == winnerChar )
{
CPVPManager2::getInstance()->finalBlowerKillerInPvPFaction( winnerChar, winnerFaction, victimChar );
}
*/
rewardedKillers.push_back(winnerChar->getId());
nbRewardedMembers++;
}
@ -1273,7 +1296,7 @@ void CDamageScoreManager::playerDeath(CCharacter * victimChar, const CCharacter
hofpLoss = uint32(double(hofpLoss) * PVPHoFPointLossFactor.get() + 0.5);
// keep the point loss to apply if the victim respawn
CPointLoss pointLoss;
/*CPointLoss pointLoss;
pointLoss.PlayerLosesFactionPoints = victimLosesFactionPoints;
pointLoss.PlayerFaction = victimFaction;
pointLoss.FactionPointLoss = fpLoss;
@ -1282,8 +1305,8 @@ void CDamageScoreManager::playerDeath(CCharacter * victimChar, const CCharacter
_PointLossByPlayer[victimChar->getId()] = pointLoss;
// PvP faction looser lost
CPVPManager2::getInstance()->characterKilledInPvPFaction( victimChar, victimFaction, -(sint32) fpLoss );
//CPVPManager2::getInstance()->characterKilledInPvPFaction( victimChar, victimFaction, -(sint32) fpLoss );
*/
// delete the score table of the victim
removeDamageScoreTable(victimChar->getEntityRowId());
}
@ -1429,6 +1452,7 @@ void CDamageScoreManager::playerRespawn(CCharacter * victimChar)
const CPointLoss & pointLoss = (*it).second;
/*
if (pointLoss.PlayerLosesFactionPoints)
{
// victim loses faction points
@ -1438,6 +1462,7 @@ void CDamageScoreManager::playerRespawn(CCharacter * victimChar)
// victim loses HoF points
changePlayerHoFPoints(victimChar, -sint32(pointLoss.HoFPointLoss));
*/
// remove the applied entry
_PointLossByPlayer.erase(it);
@ -1684,9 +1709,9 @@ bool CDamageScoreManager::playerInFactionPvP(const CCharacter * playerChar, PVP_
return true;
}
}
else if( playerChar->getPVPFlag() )
else if( playerChar->getPVPFlag(false) )
{
pair<PVP_CLAN::TPVPClan, PVP_CLAN::TPVPClan> allegiance = playerChar->getAllegiance();
/*pair<PVP_CLAN::TPVPClan, PVP_CLAN::TPVPClan> allegiance = playerChar->getAllegiance();
if( (allegiance.first != PVP_CLAN::Neutral) && (allegiance.first != PVP_CLAN::None) )
{
if (faction)
@ -1695,7 +1720,7 @@ bool CDamageScoreManager::playerInFactionPvP(const CCharacter * playerChar, PVP_
*withFactionPoints = true;
return true;
}
/*if ( allegiance.second != PVP_CLAN::Neutral)
if ( allegiance.second != PVP_CLAN::Neutral)
{
if (faction)
*faction = allegiance.second;
@ -1703,7 +1728,42 @@ bool CDamageScoreManager::playerInFactionPvP(const CCharacter * playerChar, PVP_
*withFactionPoints = true;
return true;
}*/
return true;
}
return false;
}
bool CDamageScoreManager::canPlayerWinPoints(const CCharacter * winnerChar, CCharacter * victimeChar) const
{
// Don't win points if in duel
if ( winnerChar->getDuelOpponent() && (winnerChar->getDuelOpponent()->getId() == victimeChar->getId()) )
return false;
if (victimeChar->getPVPRecentActionFlag())
nlinfo("PVP recent flag");
// Only win points if victime is Flag
if( winnerChar->getPVPFlag(false))
{
if ( true/*victimeChar->getPVPRecentActionFlag()*/ )
{
nlinfo("Teams : %d, %d", winnerChar->getTeamId(), victimeChar->getTeamId());
// Don't win points if in same Team
if ( winnerChar->getTeamId() != CTEAM::InvalidTeamId && victimeChar->getTeamId() != CTEAM::InvalidTeamId && (winnerChar->getTeamId() == victimeChar->getTeamId()) )
return false;
// Don't win points if in same Guild
nlinfo("Guild : %d, %d", winnerChar->getGuildId(), victimeChar->getGuildId());
if ( winnerChar->getGuildId() != 0 && victimeChar->getGuildId() != 0 && (winnerChar->getGuildId() == victimeChar->getGuildId()) )
return false;
// Don't win points if in same League
if ( winnerChar->getLeagueId() != DYN_CHAT_INVALID_CHAN && victimeChar->getLeagueId() != DYN_CHAT_INVALID_CHAN && (winnerChar->getLeagueId() == victimeChar->getLeagueId()) )
return false;
return true;
}
}
return false;
}
@ -1795,6 +1855,28 @@ sint32 CDamageScoreManager::changePlayerFactionPoints(CCharacter * playerChar, P
return fpDelta;
}
//-----------------------------------------------------------------------------
sint32 CDamageScoreManager::changePlayerPvpPoints(CCharacter * playerChar, sint32 fpDelta)
{
nlassert(playerChar != NULL);
if (fpDelta == 0)
return 0;
uint32 points = playerChar->getPvpPoint();
// player cannot have negative pvp points
fpDelta = max(fpDelta, -sint32(points));
points += fpDelta;
// set the new pvp points
playerChar->setPvpPoint(points);
return fpDelta;
}
//-----------------------------------------------------------------------------
void CDamageScoreManager::changePlayerHoFPoints(CCharacter * playerChar, sint32 hofpDelta)
{

@ -42,7 +42,7 @@ typedef uint16 TTeamId;
/**
* A damage score table keeps all damages done by a player/team/creature on a player
*
* \author Sébastien 'kxu' Guignot
* \author Sebastien 'kxu' Guignot
* \author Nevrax France
* \date 2005
*/
@ -193,7 +193,7 @@ private:
* It permits to find all players wounded by an entity (player/team/creature)
* ie to find all players on which the entity has a damage score.
*
* \author Sébastien 'kxu' Guignot
* \author Sebastien 'kxu' Guignot
* \author Nevrax France
* \date 2005
*/
@ -229,7 +229,7 @@ private:
/**
* It keeps kills that have been rewarded and which cannot be rewarded again for a lapse of time.
*
* \author Sébastien 'kxu' Guignot
* \author Sebastien 'kxu' Guignot
* \author Nevrax France
* \date 2005
*/
@ -273,7 +273,7 @@ private:
* and keeps their damage scores on each attacked player.
* It also gives faction and HoF points to players.
*
* \author Sébastien 'kxu' Guignot
* \author Sebastien 'kxu' Guignot
* \author Nevrax France
* \date 2005
*/
@ -342,6 +342,8 @@ private:
/// return true if the given action is curative
bool isCurativeAction(const TReportAction & action) const;
bool canPlayerWinPoints(const CCharacter * winnerChar, CCharacter * victimeChar) const;
/// return true if the given player is in 'faction PvP' (in a faction PvP zone)
/// \param faction : if not NULL return the faction of the player in the PvP zone where he is
/// \param gainFactionPoints : if not NULL return true if the zone gives faction points or not
@ -357,6 +359,10 @@ private:
/// \return the applied delta (a negative delta may have been modified up to zero to keep faction points positive)
sint32 changePlayerFactionPoints(CCharacter * playerChar, PVP_CLAN::TPVPClan faction, sint32 fpDelta);
/// add/remove pvp points to a player
/// \return the applied delta (a negative delta may have been modified up to zero to keep pvp points positive)
sint32 changePlayerPvpPoints(CCharacter * playerChar, sint32 fpDelta);
/// add/remove HoF points to a player and his guild if his SDB PvP path is defined
void changePlayerHoFPoints(CCharacter * playerChar, sint32 hofpDelta);
@ -388,7 +394,7 @@ private:
/**
* This is the interface for the character progression in PvP
*
* \author Sébastien 'kxu' Guignot
* \author Sebastien 'kxu' Guignot
* \author Nevrax France
* \date 2005
*/

@ -39,6 +39,13 @@ PVP_RELATION::TPVPRelation CPVPFaction::getPVPRelation( CCharacter * actor, CEnt
CPVPManager2::getInstance()->setPVPFactionAllyReminder( false );
CPVPManager2::getInstance()->setPVPFactionEnemyReminder( false );
bool isAlly = false;
bool targetSafe = false;
bool actorSafe = false;
bool targetInSafeZone = false;
bool actorInSafeZone = false;
// Check actor and target validity
if (actor == 0 || target == 0)
{
@ -50,70 +57,85 @@ PVP_RELATION::TPVPRelation CPVPFaction::getPVPRelation( CCharacter * actor, CEnt
if (pTarget == 0)
return PVP_RELATION::Unknown;
// if target is not tagged then he's neutral
if (!pTarget->getPVPFlag() && !pTarget->getPvPRecentActionFlag())
return PVP_RELATION::Neutral;
// Check safe zones
if (CPVPManager2::getInstance()->inSafeZone(pTarget->getPosition()))
{
targetInSafeZone = true;
if (pTarget->getSafeInPvPSafeZone())
return PVP_RELATION::NeutralPVP;
targetSafe = true;
}
if( CPVPManager2::getInstance()->inSafeZone(actor->getPosition()))
{
actorInSafeZone = true;
if( actor->getSafeInPvPSafeZone())
return PVP_RELATION::NeutralPVP;
actorSafe = true;
}
// Check fames
if( actor->getPVPFlag() || actor->getPvPRecentActionFlag() )
// Target is not tagged => Neutral
if (!pTarget->getPVPFlag() && !pTarget->getPvPRecentActionFlag())
return PVP_RELATION::Neutral;
// Actor is not tagged => Check target
if (!actor->getPVPFlag() && !actor->getPvPRecentActionFlag())
{
// In same Team
// Target flag => NeutralPVP
if (pTarget->getPvPRecentActionFlag())
return PVP_RELATION::NeutralPVP;
else
return PVP_RELATION::Neutral;
}
// In same Team => Ally
if ((pTarget->getTeamId() != CTEAM::InvalidTeamId) && (actor->getTeamId() != CTEAM::InvalidTeamId) && (actor->getTeamId() == pTarget->getTeamId()))
{
CPVPManager2::getInstance()->setPVPFactionAllyReminder( true );
return PVP_RELATION::Ally;
isAlly = true;
}
// In same Guild
if ((pTarget->getGuildId() != 0) && (actor->getGuildId() != 0) && (actor->getGuildId() == pTarget->getGuildId()))
// In Same League => Ally
if ((pTarget->getLeagueId() != DYN_CHAT_INVALID_CHAN) && (actor->getLeagueId() != DYN_CHAT_INVALID_CHAN) && (actor->getLeagueId() == pTarget->getLeagueId()))
{
CPVPManager2::getInstance()->setPVPFactionAllyReminder( true );
return PVP_RELATION::Ally;
isAlly = true;
}
// check if he's an ennemy
if ((actor->getPVPFamesAllies() & pTarget->getPVPFamesEnemies()) || (actor->getPVPFamesEnemies() & pTarget->getPVPFamesAllies()))
// In same Guild and not Leagued => Ally
if ((pTarget->getGuildId() != 0) && (actor->getGuildId() != 0) && (actor->getGuildId() == pTarget->getGuildId()) && (pTarget->getLeagueId() == DYN_CHAT_INVALID_CHAN) && (actor->getLeagueId() == DYN_CHAT_INVALID_CHAN))
{
// Actor can heal an ennemi if not PvPRecentActionFlaged
if (curative && !pTarget->getPvPRecentActionFlag())
{
return PVP_RELATION::Neutral;
isAlly = true;
}
else
if (isAlly)
{
CPVPManager2::getInstance()->setPVPFactionEnemyReminder(true);
return PVP_RELATION::Ennemy;
}
// One is in safe zone but not other => NeutralPVP
if ((targetInSafeZone && !actorInSafeZone) || (actorInSafeZone && !targetInSafeZone))
{
return PVP_RELATION::NeutralPVP;
}
// check if he's an ally
else if ((actor->getPVPFamesAllies() & pTarget->getPVPFamesAllies()) || (actor->getPVPFamesEnemies() & pTarget->getPVPFamesEnemies()))
// One is safe but not other => NeutralPVP
if (targetSafe != actorSafe)
{
return PVP_RELATION::NeutralPVP;
}
CPVPManager2::getInstance()->setPVPFactionAllyReminder(true);
return PVP_RELATION::Ally;
}
// If one is safe => NeutralPVP
if (targetSafe || actorSafe)
{
return PVP_RELATION::NeutralPVP;
}
else
//
if ((targetInSafeZone && !pTarget->getPvPRecentActionFlag()) || (actorInSafeZone && !actor->getPvPRecentActionFlag()))
{
// Check if actor is not PvPFlag and try to heal a PvPRecentActionFlag
if (curative && pTarget->getPvPRecentActionFlag())
return PVP_RELATION::NeutralPVP;
}
// default is neutral
return PVP_RELATION::Neutral;
CPVPManager2::getInstance()->setPVPFactionEnemyReminder(true);
return PVP_RELATION::Ennemy;
}

@ -26,6 +26,7 @@
#include "game_share/utils.h"
#include "game_share/msg_client_server.h"
#include "game_share/fame.h"
#include "game_share/send_chat.h"
#include "pvp_manager/pvp_manager_2.h"
#include "pvp_manager/pvp_manager.h"
@ -176,6 +177,21 @@ TChanID CPVPManager2::getUserDynChannel( const std::string& channelName)
return DYN_CHAT_INVALID_CHAN;
}
std::string CPVPManager2::getUserDynChannel(const TChanID& channelId)
{
TMAPExtraFactionChannel::iterator it;
for (it = _UserChannel.begin(); it != _UserChannel.end(); ++it)
{
if ((*it).second == channelId)
{
return (*it).first;
}
}
// should not get here
nlassert(false);
return "";
}
const std::string & CPVPManager2::getPassUserChannel( TChanID channelId)
{
// Search in user channels
@ -353,7 +369,7 @@ void CPVPManager2::broadcastMessage(TChanID channel, const ucstring& speakerName
sendMessageViaMirror("IOS", msgout);
}
void CPVPManager2::sendChannelUsers(TChanID channel, CCharacter * user)
void CPVPManager2::sendChannelUsers(TChanID channel, CCharacter * user, bool outputToSys)
{
std::vector<NLMISC::CEntityId> lst;
@ -361,21 +377,40 @@ void CPVPManager2::sendChannelUsers(TChanID channel, CCharacter * user)
if(it != _UserChannelCharacters.end())
{
lst = (*it).second;
string players = "";
ucstring players;
uint32 shardId = CEntityIdTranslator::getInstance()->getEntityShardId(user->getId());
for (uint i = 0; i < lst.size(); i++)
{
players += "\n"+CEntityIdTranslator::getInstance()->getByEntity(lst[i]).toString();
ucstring name = CEntityIdTranslator::getInstance()->getByEntity(lst[i]);
if (shardId == CEntityIdTranslator::getInstance()->getEntityShardId(lst[i]))
{
// Same shard, remove shard from name
CEntityIdTranslator::removeShardFromName(name);
}
players += "\n" + name ;
}
TDataSetRow senderRow = TheDataset.getDataSetRow(user->getId());
if (outputToSys)
{
CCharacter::sendDynamicSystemMessage( user->getId(), "WHO_CHANNEL_INTRO" );
//players = "Players in channel \"" + getUserDynChannel(channel) + "\": " + players;
SM_STATIC_PARAMS_1(params, STRING_MANAGER::literal);
params[0].Literal = players;
CCharacter::sendDynamicSystemMessage( user->getId(), "LITERAL", params );
}
else
{
CMessage msgout("DYN_CHAT:SERVICE_TELL");
msgout.serial(channel);
ucstring users = ucstring("<USERS>");
msgout.serial(const_cast<ucstring&>(users));
TDataSetRow senderRow = TheDataset.getDataSetRow(user->getId());
msgout.serial(senderRow);
ucstring txt = ucstring(players);
msgout.serial(const_cast<ucstring&>(txt));
sendMessageViaMirror( "IOS", msgout);
sendMessageViaMirror("IOS", msgout);
}
}
}
@ -559,10 +594,10 @@ void CPVPManager2::playerTeleports(CCharacter * user)
void CPVPManager2::setPVPModeInMirror( const CCharacter * user ) const
{
nlassert(user);
uint8 pvpMode = 0;
TYPE_PVP_MODE pvpMode = 0;
// Full pvp
if ( user->getPriviledgePVP() )
if ( user->getFullPVP() )
{
pvpMode |= PVP_MODE::PvpChallenge;
}
@ -588,6 +623,16 @@ void CPVPManager2::setPVPModeInMirror( const CCharacter * user ) const
pvpMode |= PVP_MODE::PvpDuel;
}
}
// in Safe zone
{
if (CPVPManager2::getInstance()->inSafeZone(user->getPosition()))
{
pvpMode |= PVP_MODE::PvpZoneSafe;
if (user->getSafeInPvPSafeZone())
pvpMode |= PVP_MODE::PvpSafe;
}
}
// pvp session (i.e everything else)
{
if ( user->getPVPInterface().isValid() )
@ -598,7 +643,13 @@ void CPVPManager2::setPVPModeInMirror( const CCharacter * user ) const
}
CMirrorPropValue<TYPE_PVP_MODE> propPvpMode( TheDataset, user->getEntityRowId(), DSPropertyPVP_MODE );
CMirrorPropValue<TYPE_EVENT_FACTION_ID> propPvpMode2( TheDataset, user->getEntityRowId(), DSPropertyEVENT_FACTION_ID );
if (propPvpMode.getValue() != pvpMode)
{
nlinfo("New pvp Mode : %d", pvpMode);
propPvpMode = pvpMode;
propPvpMode2 = pvpMode;
}
}
//----------------------------------------------------------------------------
@ -648,22 +699,16 @@ PVP_RELATION::TPVPRelation CPVPManager2::getPVPRelation( CCharacter * actor, CEn
CCharacter * pTarget = dynamic_cast<CCharacter*>(target);
if( pTarget )
{
// priviledgePVP is Full PVP, only ally of teammates anf guildmates
if (pTarget->priviledgePVP() || actor->priviledgePVP())
// Full PVP is ennemy of everybody
if (pTarget->getFullPVP() || actor->getFullPVP())
{
if ((pTarget->getTeamId() != CTEAM::InvalidTeamId) && (actor->getTeamId() != CTEAM::InvalidTeamId) && (actor->getTeamId() == pTarget->getTeamId()))
return PVP_RELATION::Ally;
if ((pTarget->getGuildId() != 0) && (actor->getGuildId() != 0) && (actor->getGuildId() == pTarget->getGuildId()))
return PVP_RELATION::Ally;
return PVP_RELATION::Ennemy;
}
if( IsRingShard )
return relation; // disable PVP on Ring shards (only if target is a CCharacter, because we must let attack NPCs)
// //////////////////////////////////////////////////////
////////////////////////////////////////////////////////
// temp : until new manager is finished we have to check the char pvp session too
IPVP * pvpSession = pTarget->getPVPInterface().getPVPSession();
if( pvpSession )
@ -713,8 +758,8 @@ PVP_RELATION::TPVPRelation CPVPManager2::getPVPRelation( CCharacter * actor, CEn
if( relationTmp == PVP_RELATION::NeutralPVP )
relation = PVP_RELATION::NeutralPVP;
// Check if ally (neutralpvp has priority over ally)
if( relationTmp == PVP_RELATION::Ally && relation != PVP_RELATION::NeutralPVP )
// Check if ally (neutralpvp and active has priority over ally)
if (relationTmp == PVP_RELATION::Ally && relation != PVP_RELATION::NeutralPVP)
relation = PVP_RELATION::Ally;
}
@ -730,6 +775,7 @@ bool CPVPManager2::isCurativeActionValid( CCharacter * actor, CEntityBase * targ
PVP_RELATION::TPVPRelation pvpRelation = getPVPRelation( actor, target, true );
bool actionValid;
nlinfo("Pvp relation = %d", pvpRelation);
switch( pvpRelation )
{
case PVP_RELATION::Ally :
@ -757,11 +803,12 @@ bool CPVPManager2::isCurativeActionValid( CCharacter * actor, CEntityBase * targ
if( actionValid && !checkMode )
{
CCharacter * pTarget = dynamic_cast<CCharacter*>(target);
if(pTarget)
actor->clearSafeInPvPSafeZone();
//if(pTarget)
// actor->clearSafeInPvPSafeZone();
// propagate faction pvp flag
if( pvpRelation == PVP_RELATION::Ally )
if( pvpRelation == PVP_RELATION::Ally)
{
if( _PVPFactionAllyReminder )
{
@ -782,10 +829,6 @@ bool CPVPManager2::isCurativeActionValid( CCharacter * actor, CEntityBase * targ
{
actor->refreshOutpostLeavingTimer();
}
// propagate full pvp
if( pTarget->priviledgePVP() )
actor->setPriviledgePVP(true);
}
}
return actionValid;
@ -832,7 +875,13 @@ bool CPVPManager2::isOffensiveActionValid( CCharacter * actor, CEntityBase * tar
{
CCharacter * pTarget = dynamic_cast<CCharacter*>(target);
if(pTarget)
{
if (actor->getDuelOpponent() == pTarget) // No _PVPFactionEnemyReminder when in duel
CPVPManager2::getInstance()->setPVPFactionAllyReminder(false);
else
actor->clearSafeInPvPSafeZone();
}
if( _PVPFactionEnemyReminder )
{
actor->setPVPRecentActionFlag();
@ -886,10 +935,20 @@ bool CPVPManager2::canApplyAreaEffect(CCharacter* actor, CEntityBase * areaTarge
if( actionValid )
{
/* if ((pTarget->getGuildId() != 0) && (actor->getGuildId() != 0) && (actor->getGuildId() != pTarget->getGuildId()))
return false;
*/
if( areaTarget->getId().getType() == RYZOMID::player )
{
CCharacter * pTarget = dynamic_cast<CCharacter*>(areaTarget);
if(pTarget)
if (!offensive)
{
if (actor->getTeamId() != pTarget->getTeamId() && actor->getLeagueId() != pTarget->getLeagueId() )
return false;
}
if(pTarget && offensive)
actor->clearSafeInPvPSafeZone();
// set faction flag
if( offensive && _PVPFactionEnemyReminder )
@ -1096,6 +1155,11 @@ void CPVPManager2::createExtraFactionChannel(const std::string & channelName)
TChanID CPVPManager2::createUserChannel(const std::string & channelName, const std::string & pass)
{
// Don't allow channels called "GM" (to not clash with the /who gm command)
if (NLMISC::nlstricmp( channelName.c_str() , "GM" ) == 0)
{
return DYN_CHAT_INVALID_CHAN;
}
TMAPExtraFactionChannel::iterator it = _UserChannel.find(channelName);
if( it == _UserChannel.end() )
@ -1244,6 +1308,14 @@ void CPVPManager2::askForDuel( const NLMISC::CEntityId & userId )
return;
}
// If not a privileged player and in ignorelist, cannot duel
if ( !user->haveAnyPrivilege() && target->hasInIgnoreList( user->getId() ) )
{
params[0].setEIdAIAlias( target->getId(), CAIAliasTranslator::getInstance()->getAIAlias(target->getId()) );
CCharacter::sendDynamicSystemMessage(userId, "DUEL_REFUSE_INVITATION", params);
return;
}
// remove previous invitation, and check that user is not invited
bool problem = false;

@ -76,10 +76,12 @@ public:
void onIOSMirrorUp();
/// callback called at each tick
void tickUpdate();
/// return dynamic channel TChanID attribued to a faction
/// return dynamic channel TChanID attributed to a faction
TChanID getFactionDynChannel( const std::string& channelName );
/// return dynamic channel TChanID attribued to an user
/// return user dynamic channel TChanID
TChanID getUserDynChannel( const std::string& channelName);
/// return user dynamic channel name
std::string getUserDynChannel(const TChanID& channelId);
/// return dynamic channel TChanID attribued to a faction
const std::string &getPassUserChannel( TChanID channelId);
/// return dynamic channel TChanID character must have, DYN_CHAT_INVALID_CHAN if he must don't have faction channel
@ -91,7 +93,7 @@ public:
// brodcast message to channel
void broadcastMessage(TChanID channel, const ucstring& speakerName ,const ucstring& txt);
// send list of users to player
void sendChannelUsers(TChanID channel, CCharacter * user);
void sendChannelUsers(TChanID channel, CCharacter * user, bool outputToSys = false);
// add faction channel to character if needed
void addFactionChannelToCharacter(TChanID channel, CCharacter * user, bool writeRight = true, bool userChannel = false);
// remove faction channel for character

@ -63,6 +63,15 @@ namespace PVP_ZONE_TYPE
} // namespace PVP_ZONE_TYPE
//----------------------------------------------------------------------------
static inline bool inSameLeague(CCharacter * c1, CCharacter * c2)
{
if (c1 == NULL || c2 == NULL)
return false;
return ( c1 == c2 ) || ( c1->getLeagueId() != DYN_CHAT_INVALID_CHAN && c1->getLeagueId() == c2->getLeagueId() );
}
//----------------------------------------------------------------------------
static inline bool inSameTeam(CCharacter * c1, CCharacter * c2)
{
@ -372,35 +381,47 @@ PVP_RELATION::TPVPRelation CPVPFreeZone::getPVPRelation( CCharacter * user, CEnt
nlassert(user);
nlassert(target);
if( target->getId().getType() != RYZOMID::player )
CCharacter * pTarget = dynamic_cast<CCharacter*>(target);
bool targetSafe = false;
bool actorSafe = false;
if (target->getId().getType() != RYZOMID::player)
{
return PVP_RELATION::Unknown;
}
// if target is in same zone then he's an ennemy or ally
if ( _Users.find( target->getEntityRowId() ) != _Users.end() )
{
if( inSameTeam( user, (CCharacter *)target ) )
if (CPVPManager2::getInstance()->inSafeZone(pTarget->getPosition()))
{
return PVP_RELATION::Ally;
if (pTarget->getSafeInPvPSafeZone())
targetSafe = true;
}
else
if (CPVPManager2::getInstance()->inSafeZone(user->getPosition()))
{
return PVP_RELATION::Ennemy;
if( user->getSafeInPvPSafeZone())
actorSafe = true;
}
if ((targetSafe && !actorSafe) || (actorSafe && !targetSafe)) {
return PVP_RELATION::NeutralPVP;
}
// if target is in free pvp then he's neutral pvp
const CCharacter * targetChar = static_cast<const CCharacter*>(target);
if( targetChar->getPVPInterface().isValid() )
// In same Zone
if (_Users.find( target->getEntityRowId() ) != _Users.end())
{
if( targetChar->getPVPInterface().getPVPSession()->getPVPMode() == PVP_MODE::PvpZoneFree );
// In Same Team or League => Ally
if (inSameTeam( user, pTarget ) || inSameLeague( user, pTarget ))
{
return PVP_RELATION::NeutralPVP;
return PVP_RELATION::Ally;
}
// If both not in safe zone => Ennemy
if (!targetSafe && !actorSafe)
return PVP_RELATION::Ennemy;
}
return PVP_RELATION::Neutral;
return PVP_RELATION::NeutralPVP;
}
//----------------------------------------------------------------------------
@ -1135,36 +1156,53 @@ PVP_RELATION::TPVPRelation CPVPGuildZone::getPVPRelation( CCharacter * user, CEn
nlassert(user);
nlassert(target);
// target has to be a char
CCharacter *targetChar = dynamic_cast<CCharacter*>(target);
if ( !targetChar )
CCharacter * pTarget = dynamic_cast<CCharacter*>(target);
bool targetSafe = false;
bool actorSafe = false;
if( target->getId().getType() != RYZOMID::player )
{
return PVP_RELATION::Unknown;
}
// check that target is in the same zone than user (discards bots)
if ( _Users.find( target->getEntityRowId() ) != _Users.end() )
{
if ( inSameGuild(targetChar,user) || inSameTeam( targetChar, user) )
if (CPVPManager2::getInstance()->inSafeZone(pTarget->getPosition()))
{
return PVP_RELATION::Ally;
if (pTarget->getSafeInPvPSafeZone())
targetSafe = true;
}
else
if( CPVPManager2::getInstance()->inSafeZone(user->getPosition()))
{
return PVP_RELATION::Ennemy;
if( user->getSafeInPvPSafeZone())
actorSafe = true;
}
if ((targetSafe && !actorSafe) || (actorSafe && !targetSafe)) {
return PVP_RELATION::NeutralPVP;
}
// if target is in guild pvp then he's neutral pvp
if( targetChar->getPVPInterface().isValid() )
// if target is in same zone then he's an ennemy or ally
if ( _Users.find( target->getEntityRowId() ) != _Users.end() )
{
if( targetChar->getPVPInterface().getPVPSession()->getPVPMode() == PVP_MODE::PvpZoneGuild )
// In Same Team or League => Ally
if (inSameTeam( user, pTarget ) || inSameLeague( user, pTarget ))
{
return PVP_RELATION::NeutralPVP;
return PVP_RELATION::Ally;
}
// in same Guild and not in Leagues => Ally
if (inSameGuild( user, pTarget ) && user->getLeagueId() == DYN_CHAT_INVALID_CHAN && pTarget->getLeagueId() == DYN_CHAT_INVALID_CHAN)
{
return PVP_RELATION::Ally;
}
return PVP_RELATION::Neutral;
// If both not in safe zone => Ennemy
if (!targetSafe && !actorSafe)
return PVP_RELATION::Ennemy;
}
return PVP_RELATION::NeutralPVP;
}
/*

@ -155,6 +155,12 @@ void CTradeBase::copy( IItemTrade * itt )
else _ItemPtr = 0;
}
TGameCycle CItemForSale::getGameCycleLeft() const
{
TGameCycle dt = CTickEventHandler::getGameCycle() - _StartSaleCycle;
return (TGameCycle) ( (sint32) std::max( (sint32)0, (sint32)( ((sint32) MaxGameCycleSaleStore) - (sint32)( dt + _ItemPtr->getTotalSaleCycle() ) ) ) );
}
//-----------------------------------------------------------------------------
//uint32 CTradeBase::getFactionPointPrice() const
//{

@ -202,7 +202,8 @@ public:
void setAvailable( bool a );
// return game cycle left for item in store
NLMISC::TGameCycle getGameCycleLeft() const { return (NLMISC::TGameCycle) ( (sint32) std::max( (sint32)0, (sint32)( ((sint32) MaxGameCycleSaleStore) - ( ( CTickEventHandler::getGameCycle() - _StartSaleCycle ) + _ItemPtr->getTotalSaleCycle() ) ) ) ); }
// NLMISC::TGameCycle getGameCycleLeft() const { return (NLMISC::TGameCycle) ( (sint32) std::max( (sint32)0, (sint32)( ((sint32) MaxGameCycleSaleStore) - ( ( CTickEventHandler::getGameCycle() - _StartSaleCycle ) + _ItemPtr->getTotalSaleCycle() ) ) ) ); }
NLMISC::TGameCycle getGameCycleLeft() const;
// get quantity
uint32 getQuantity() const { return _Quantity; }

@ -57,6 +57,7 @@ void CTeam::init( CCharacter* leader, uint16 teamId )
_ValidityFlags.Fake = false;
_NbMembers = 1;
_TeamId = teamId;
_LeagueId = leader->getLeagueId();
_LeaderId = leader->getId();
_TeamMembers.push_back(_LeaderId);
// init the team chat group
@ -120,6 +121,12 @@ void CTeam::release()
PROGRESSIONPVE::CCharacterProgressionPVE::getInstance()->disbandTeam(_TeamId, _TeamMembers);
PROGRESSIONPVP::CCharacterProgressionPVP::getInstance()->disbandTeam(_TeamId, _TeamMembers);
if (_LeagueId != DYN_CHAT_INVALID_CHAN)
{
DynChatEGS.removeChan(_LeagueId);
}
_LeagueId = DYN_CHAT_INVALID_CHAN;
_TeamId = CTEAM::InvalidTeamId;
_TeamMembers.clear();
_NbMembers = 0;
@ -167,7 +174,8 @@ void CTeam::addCharacter(CCharacter *newCharacter)
else
{
// newCharacter->_PropertyDatabase.setProp( "GROUP:SUCCESSOR_INDEX", 1 );
CBankAccessor_PLR::getGROUP().setSUCCESSOR_INDEX(newCharacter->_PropertyDatabase, 1);
uint8 index = getSuccessorIndex();
CBankAccessor_PLR::getGROUP().setSUCCESSOR_INDEX(newCharacter->_PropertyDatabase, index);
}
// update all member's DB
@ -283,6 +291,9 @@ void CTeam::addCharacter(CCharacter *newCharacter)
// set the character team
newCharacter->setTeamId(_TeamId);
// set the character alliance
newCharacter->setLeagueId(_LeagueId);
// Add character to chat group
TGroupId idGroupe = CHAT_GROUPS_IDS::getTeamChatGroupId(_TeamId);
CMessage msgout("ADD_TO_GROUP");
@ -383,6 +394,7 @@ void CTeam::removeCharacter( CCharacter * player )
///\todo give him a player team Id
player->setTeamId( CTEAM::InvalidTeamId );
player->setLeagueId(DYN_CHAT_INVALID_CHAN);
player->updateTargetingChars();
// tell progression system this player has been removed from his team
@ -410,13 +422,19 @@ void CTeam::removeCharacter( CCharacter * player )
clearPlayerTeamDB( *_TeamMembers.begin() );
CCharacter * lastPlayer = PlayerManager.getOnlineChar( *_TeamMembers.begin() );
if ( lastPlayer )
{
lastPlayer->setTeamId( CTEAM::InvalidTeamId );
lastPlayer->setLeagueId(DYN_CHAT_INVALID_CHAN);
}
else
{
nlwarning("<CTeam removeCharacter> charId %s not found in the team", (*_TeamMembers.begin()).toString().c_str() );
return;
}
// remove league
setLeague("");
// remove the team chat group
TGroupId idGroupe = CHAT_GROUPS_IDS::getTeamChatGroupId(_TeamId);
CMessage msgRemoveGroup("REMOVE_GROUP");
@ -437,80 +455,26 @@ void CTeam::removeCharacter( CCharacter * player )
// if that was the leader, get another one
else if ( _LeaderId == charId )
{
_LeaderId = _SuccessorId;
_SuccessorId = CEntityId::Unknown;
for (list<CEntityId>::const_iterator it = _TeamMembers.begin(); it != _TeamMembers.end(); ++it)
{
if ( (*it) != _LeaderId )
{
_SuccessorId = (*it );
break;
}
}
// switch dyn chat speaker
CMissionManager::getInstance()->switchDynChatSpeaker(player,_LeaderId);
// inform the new leader
SM_STATIC_PARAMS_1(params1, STRING_MANAGER::player);
params1[0].setEId( charId );
PHRASE_UTILITIES::sendDynamicSystemMessage(TheDataset.getDataSetRow(_LeaderId), "TEAM_YOU_NEW_LEADER", params1);
// inform the group
SM_STATIC_PARAMS_2(params, STRING_MANAGER::player, STRING_MANAGER::player);
params[0].setEId( charId );
params[1].setEId( _LeaderId );
set<CEntityId> exclude;
exclude.insert( _LeaderId );
exclude.insert( charId );
sendDynamicMessageToMembers("TEAM_NEW_LEADER", params, exclude);
// update leader DB
CCharacter *leader = PlayerManager.getOnlineChar( _LeaderId );
if (leader)
{
// leader->_PropertyDatabase.setProp( "GROUP:LEADER_INDEX", -1 );
CBankAccessor_PLR::getGROUP().setLEADER_INDEX(leader->_PropertyDatabase, 0xf);
// leader->_PropertyDatabase.setProp( "GROUP:SUCCESSOR_INDEX", 0 );
CBankAccessor_PLR::getGROUP().setSUCCESSOR_INDEX(leader->_PropertyDatabase, 0);
}
else
nlwarning("<CTeam removeCharacter> invalid new leader %s", _LeaderId.toString().c_str() );
setLeader(_SuccessorId);
}
// if that was the successor, inform the new one
/* else if ( formerPos == 1 && _NbMembers > 2)
{
list<CEntityId>::iterator itTmp = _TeamMembers.begin();
++itTmp;
const CEntityId & successorId = *(itTmp);
CCharacter *successor = PlayerManager.getOnlineChar( successorId );
if (successor)
else if ( _SuccessorId == charId )
{
successor->_PropertyDatabase.setProp( "GROUP:SUCCESSOR_INDEX", -1 );
// The current successor dropped from team; set it to the next in line after leader
setSuccessor(1);
}
else
nlwarning("<CTeam removeCharacter> invalid new successor %s", successorId.toString().c_str() );
}
*/
else if ( _SuccessorId == charId )
{
for (list<CEntityId>::const_iterator it = _TeamMembers.begin(); it != _TeamMembers.end(); ++it)
{
if ( (*it) != _LeaderId )
{
_SuccessorId = (*it );
CCharacter *successor = PlayerManager.getOnlineChar( _SuccessorId );
if (successor)
// A random member dropped from team; make sure the current successor is shown currectly
// in all team lists.
uint8 index = 0;
for (std::list<NLMISC::CEntityId>::iterator it = _TeamMembers.begin() ; it != _TeamMembers.end() ; ++it)
{
// successor->_PropertyDatabase.setProp( "GROUP:SUCCESSOR_INDEX", -1 );
CBankAccessor_PLR::getGROUP().setSUCCESSOR_INDEX(successor->_PropertyDatabase, 0xf);
}
if (_SuccessorId == (*it))
break;
++index;
}
}
// Don't show a message because the successor hasn't actually changed.
setSuccessor(index, false);
}
for (std::list<NLMISC::CEntityId>::iterator it = _TeamMembers.begin() ; it != _TeamMembers.end() ; ++it)
@ -607,114 +571,171 @@ void CTeam::removeCharacter( CCharacter * player )
}// CTeam removeCharacter
void CTeam::setSuccessor( uint8 memberIdx )
void CTeam::setLeague(const string &leagueName)
{
/*
list<CEntityId>::const_iterator it = _TeamMembers.begin();
uint8 i = 0;
for (; it != _TeamMembers.end(); ++it)
TChanID chanId = _LeagueId;
if (_LeagueId != DYN_CHAT_INVALID_CHAN)
{
if ( i == memberIdx )
break;
++i;
// Remove players from previous channel
_LeagueId = DYN_CHAT_INVALID_CHAN;
updateLeague();
// Remove channel if empty
vector<CEntityId> players;
if (!DynChatEGS.getPlayersInChan(chanId, players))
DynChatEGS.removeChan(chanId);
}
if ( it == _TeamMembers.end() )
if (!leagueName.empty())
{
nlwarning("invalid team member %u : count is %u", memberIdx,_TeamMembers.size() );
_LeagueId = DynChatEGS.addChan("league_"+toString(DynChatEGS.getNextChanID()), leagueName);
if (_LeagueId == DYN_CHAT_INVALID_CHAN)
{
nlinfo("Error channel creation !!!");
return;
}
_SuccessorId = (*it);
SM_STATIC_PARAMS_1( params,STRING_MANAGER::player );
params[0].EId = (*it );
sendDynamicMessageToMembers("TEAM_NEW_SUCCESSOR",params);
// set historic size of the newly created channel
DynChatEGS.setHistoricSize(_LeagueId, 100);
}
for (std::list<CEntityId>::const_iterator it = _TeamMembers.begin() ; it != _TeamMembers.end() ; ++it)
updateLeague();
}
void CTeam::updateLeague()
{
for (list<CEntityId>::iterator it = _TeamMembers.begin() ; it != _TeamMembers.end() ; ++it)
{
uint8 hp, sap, stamina;
uint32 nameId;
CCharacter* character = PlayerManager.getOnlineChar( (*it) );
if (character != NULL)
CCharacter * ch = PlayerManager.getOnlineChar((*it));
if (ch != NULL && ch->getLeagueId() != _LeagueId)
{
// update the current character team slot
///\todo: can be done outside the loop
if ( newCharacter->getPhysScores()._PhysicalScores[ SCORES::hit_points ].Max != 0)
hp = (uint8) ( ( float(TeamMembersStatusMaxValue) * ( newCharacter->getPhysScores()._PhysicalScores[ SCORES::hit_points ].Current ) ) / ( newCharacter->getPhysScores()._PhysicalScores[ SCORES::hit_points ].Max ) );
else
hp = 0;
if ( newCharacter->getPhysScores()._PhysicalScores[ SCORES::sap ].Max != 0)
sap = (uint8) ( ( float(TeamMembersStatusMaxValue) * ( newCharacter->getPhysScores()._PhysicalScores[ SCORES::sap ].Current ) ) / ( newCharacter->getPhysScores()._PhysicalScores[ SCORES::sap ].Max ) );
else
sap = 0;
if ( newCharacter->getPhysScores()._PhysicalScores[ SCORES::stamina ].Max != 0)
stamina = (uint8) ( ( float(TeamMembersStatusMaxValue) * ( newCharacter->getPhysScores()._PhysicalScores[ SCORES::stamina ].Current ) ) / ( newCharacter->getPhysScores()._PhysicalScores[ SCORES::stamina ].Max ) );
else
stamina = 0;
CMirrorPropValueRO<uint32> nameIndexValue1( TheDataset, newCharacter->getId(), "NameIndex" );
nameId = nameIndexValue1();
ch->setLeagueId(_LeagueId);
}
}
}
sprintf(buffer, "GROUP:%d:HP",position );
character->_PropertyDatabase.setProp( buffer, hp );
uint8 CTeam::getSuccessorIndex()
{
list<CEntityId>::const_iterator it = _TeamMembers.begin();
uint8 i = 0;
for (; it != _TeamMembers.end(); ++it)
{
if ( (*it) == _SuccessorId )
break;
++i;
}
return i;
}
sprintf(buffer, "GROUP:%d:SAP",position );
character->_PropertyDatabase.setProp( buffer, sap );
void CTeam::setLeader(CEntityId id, bool bMessage)
{
_LeaderId = id;
sprintf(buffer, "GROUP:%d:STA",position );
character->_PropertyDatabase.setProp( buffer, stamina );
// Move new leader to top of list
_TeamMembers.remove(_LeaderId);
_TeamMembers.insert(_TeamMembers.begin(), _LeaderId);
sprintf(buffer, "GROUP:%d:NAME",position );
character->_PropertyDatabase.setProp( buffer, nameId );
// inform the new leader
SM_STATIC_PARAMS_1(params1, STRING_MANAGER::player);
params1[0].setEId( id );
PHRASE_UTILITIES::sendDynamicSystemMessage(TheDataset.getDataSetRow(_LeaderId), "TEAM_YOU_NEW_LEADER", params1);
sprintf(buffer, "GROUP:%d:UID",position );
character->_PropertyDatabase.setProp( buffer, newCharacter->getEntityRowId().getCompressedIndex() );
// inform the group
SM_STATIC_PARAMS_2(params, STRING_MANAGER::player, STRING_MANAGER::player);
params[0].setEId( id );
params[1].setEId( _LeaderId );
sprintf(buffer, "GROUP:%d:PRESENT",position );
character->_PropertyDatabase.setProp( buffer, (uint8)1 );
set<CEntityId> exclude;
exclude.insert( _LeaderId );
exclude.insert( id );
sendDynamicMessageToMembers("TEAM_NEW_LEADER", params, exclude);
// update the new character team slot corresponding to character
if ( character->getPhysScores()._PhysicalScores[ SCORES::hit_points ].Max != 0)
hp = (uint8) ( ( float(TeamMembersStatusMaxValue) * ( character->getPhysScores()._PhysicalScores[ SCORES::hit_points ].Current ) ) / ( character->getPhysScores()._PhysicalScores[ SCORES::hit_points ].Max ) );
else
hp = 0;
// New leader was successor, choose a new successor
if (id == _SuccessorId)
{
_SuccessorId = CEntityId::Unknown;
// Set the new successor to next in line
setSuccessor(1);
}
if ( character->getPhysScores()._PhysicalScores[ SCORES::sap ].Max != 0)
sap = (uint8) ( ( float(TeamMembersStatusMaxValue) * ( character->getPhysScores()._PhysicalScores[ SCORES::sap ].Current ) ) / ( character->getPhysScores()._PhysicalScores[ SCORES::sap ].Max ) );
else
sap = 0;
// update leader DB
CCharacter *leader = PlayerManager.getOnlineChar( _LeaderId );
if (leader)
{
// switch dyn chat speaker
CMissionManager::getInstance()->switchDynChatSpeaker(leader, _LeaderId);
if ( character->getPhysScores()._PhysicalScores[ SCORES::stamina ].Max != 0)
stamina = (uint8) ( ( float(TeamMembersStatusMaxValue) * ( character->getPhysScores()._PhysicalScores[ SCORES::stamina ].Current ) ) / ( character->getPhysScores()._PhysicalScores[ SCORES::stamina ].Max ) );
CBankAccessor_PLR::getGROUP().setLEADER_INDEX(leader->_PropertyDatabase, 0xf);
}
else
stamina = 0;
CMirrorPropValueRO<uint32> nameIndexValue2( TheDataset, character->getId(), "NameIndex" );
nameId = nameIndexValue2();
sprintf(buffer, "GROUP:%d:HP",i );
newCharacter->_PropertyDatabase.setProp( buffer, hp );
sprintf(buffer, "GROUP:%d:SAP",i );
newCharacter->_PropertyDatabase.setProp( buffer, sap );
sprintf(buffer, "GROUP:%d:STA",i );
newCharacter->_PropertyDatabase.setProp( buffer, stamina );
nlwarning("<CTeam setLeader> invalid new leader %s", _LeaderId.toString().c_str() );
}
sprintf(buffer, "GROUP:%d:NAME",i );
newCharacter->_PropertyDatabase.setProp( buffer, nameId );
void CTeam::setLeader(uint8 memberIdx, bool bMessage)
{
list<CEntityId>::const_iterator it = _TeamMembers.begin();
uint8 i = 0;
for (; it != _TeamMembers.end(); ++it)
{
if ( i == memberIdx )
break;
++i;
}
if ( it == _TeamMembers.end() )
{
nlwarning("invalid team member %u : count is %u", memberIdx,_TeamMembers.size() );
return;
}
CEntityId newLeaderId = (*it);
setLeader(newLeaderId, bMessage);
}
sprintf(buffer, "GROUP:%d:UID",i );
newCharacter->_PropertyDatabase.setProp( buffer, character->getEntityRowId().getCompressedIndex() );
void CTeam::setSuccessor( uint8 memberIdx, bool bMessage)
{
list<CEntityId>::const_iterator it = _TeamMembers.begin();
uint8 i = 0;
for (; it != _TeamMembers.end(); ++it)
{
if ( i == memberIdx )
break;
++i;
}
if ( it == _TeamMembers.end() )
{
nlwarning("invalid team member %u : count is %u", memberIdx,_TeamMembers.size() );
return;
}
sprintf(buffer, "GROUP:%d:PRESENT",i );
newCharacter->_PropertyDatabase.setProp( buffer, (uint8)1 );
_SuccessorId = (*it);
i = 0;
for (it = _TeamMembers.begin() ; it != _TeamMembers.end() ; ++it)
{
CCharacter * ch = PlayerManager.getOnlineChar( (*it) );
if (ch)
{
// If this char is the successor, don't show
if (i == memberIdx)
{
CBankAccessor_PLR::getGROUP().setSUCCESSOR_INDEX(ch->_PropertyDatabase, 0xf);
}
else if (i < memberIdx)
{
// If the successor comes after this player in the list,
// bump it up one.
CBankAccessor_PLR::getGROUP().setSUCCESSOR_INDEX(ch->_PropertyDatabase, memberIdx - 1);
}
else
nlwarning("<CTeam::addCharacter> Unknown character %s", (*it).toString().c_str() );
{
CBankAccessor_PLR::getGROUP().setSUCCESSOR_INDEX(ch->_PropertyDatabase, memberIdx);
}
}
++i;
}
*/
if (bMessage)
{
SM_STATIC_PARAMS_1( params,STRING_MANAGER::player );
params[0].setEIdAIAlias(_SuccessorId, CAIAliasTranslator::getInstance()->getAIAlias(_SuccessorId));
sendDynamicMessageToMembers("TEAM_NEW_SUCCESSOR", params);
}
}
//---------------------------------------------------
@ -1130,22 +1151,65 @@ CMissionTeam* CTeam::getMissionByAlias( TAIAlias missionAlias )
return NULL;
}
void CTeam::updateMembersDb()
{
for (std::list<NLMISC::CEntityId>::iterator it = _TeamMembers.begin() ; it != _TeamMembers.end() ; ++it)
{
uint8 hp, sap, stamina;
uint32 nameId;
uint pos = 0;
CCharacter * ch1 = PlayerManager.getOnlineChar( (*it) );
if (ch1->getId() == _LeaderId)
{
CBankAccessor_PLR::getGROUP().setLEADER_INDEX(ch1->_PropertyDatabase, 0xf);
}
else
{
CBankAccessor_PLR::getGROUP().setLEADER_INDEX(ch1->_PropertyDatabase, 0);
}
///\todo log if nothing
if (ch1)
{
for (std::list<NLMISC::CEntityId>::iterator it2 = _TeamMembers.begin() ; it2 != _TeamMembers.end() ; ++it2)
{
if ( (*it) == (*it2) )
continue;
CBankAccessor_PLR::TGROUP::TArray &groupItem = CBankAccessor_PLR::getGROUP().getArray(pos);
CCharacter * ch2 = PlayerManager.getOnlineChar( (*it2) );
if (ch2 != NULL)
{
// update new char for old char
if ( ch2->getPhysScores()._PhysicalScores[ SCORES::hit_points ].Max != 0)
hp = (uint8) ( ( float(TeamMembersStatusMaxValue) * ( ch2->getPhysScores()._PhysicalScores[ SCORES::hit_points ].Current ) ) / ( ch2->getPhysScores()._PhysicalScores[ SCORES::hit_points ].Max ) );
else
hp = 0;
if ( ch2->getPhysScores()._PhysicalScores[ SCORES::sap ].Max != 0)
sap = (uint8) ( ( float(TeamMembersStatusMaxValue) * ( ch2->getPhysScores()._PhysicalScores[ SCORES::sap ].Current ) ) / ( ch2->getPhysScores()._PhysicalScores[ SCORES::sap ].Max ) );
else
sap = 0;
if ( ch2->getPhysScores()._PhysicalScores[ SCORES::stamina ].Max != 0)
stamina = (uint8) ( ( float(TeamMembersStatusMaxValue) * ( ch2->getPhysScores()._PhysicalScores[ SCORES::stamina ].Current ) ) / ( ch2->getPhysScores()._PhysicalScores[ SCORES::stamina ].Max ) );
else
stamina = 0;
CMirrorPropValueRO<uint32> nameIndexValue( TheDataset, ch2->getId(), "NameIndex" );
nameId = nameIndexValue();
groupItem.setHP(ch1->_PropertyDatabase, hp);
groupItem.setSAP(ch1->_PropertyDatabase, sap);
groupItem.setSTA(ch1->_PropertyDatabase, stamina);
groupItem.setNAME(ch1->_PropertyDatabase, nameId);
groupItem.setUID(ch1->_PropertyDatabase, ch2->getEntityRowId().getCompressedIndex());
groupItem.setPRESENT(ch1->_PropertyDatabase, true);
}
pos++;
}
}
}
}

@ -23,6 +23,7 @@
#include "game_share/misc_const.h"
#include "game_share/string_manager_sender.h"
#include "game_share/scores.h"
#include "game_share/dyn_chat.h"
#include "mission_manager/mission_event.h"
#include "mission_manager/ai_alias_translator.h"
#include "team_manager/reward_sharing.h"
@ -72,11 +73,42 @@ public:
*/
void removeCharacter( CCharacter * newChar );
/**
* return the index of team leader successor
*
*/
uint8 getSuccessorIndex(void);
/**
* set the League
* \param leagueName is the name of League
*/
void setLeague(const std::string &leagueName);
/**
* update the League (set LeagueId to all teammates)
*/
void updateLeague();
/**
* set the team leader
* \param id is the Entity ID of the member in the team
* \param bMessage whether to show the message
*/
void setLeader(NLMISC::CEntityId id, bool bMessage = true);
/**
* set the team leader
* \param memberIdx is the index of the member in the team
* \param bMessage whether to show the message
*/
void setLeader(uint8 memberIdx, bool bMessage = true);
/**
* set the successor of the team leader
* \param memberIdx is the index of the member in hte team
* \param memberIdx is the index of the member in the team
* \param bMessage whether to show the message
*/
void setSuccessor( uint8 memberIdx );
void setSuccessor( uint8 memberIdx, bool bMessage = true );
/**
* get the leader of the team
@ -84,6 +116,12 @@ public:
*/
inline const NLMISC::CEntityId & getLeader() const { return _LeaderId; }
/**
* get the successor of the team
* \return successor Id
*/
inline const NLMISC::CEntityId & getSuccessor() const { return _SuccessorId; }
///\return number of team members
inline uint8 getTeamSize() const { return _NbMembers; }
@ -108,6 +146,12 @@ public:
///\return the team id
inline uint16 getTeamId() const { return _TeamId; }
///\return the League id
inline TChanID getLeagueId() const { return _LeagueId; }
///\return the League id
inline void setLeagueId(TChanID id) { _LeagueId = id; }
/// send a message to the team
void sendDynamicMessageToMembers(const std::string &msgName, const TVectorParamCheck &params, const std::set<NLMISC::CEntityId> &excluded) const;
inline void sendDynamicMessageToMembers(const std::string &msgName, const TVectorParamCheck &params) const
@ -171,7 +215,8 @@ public:
CMissionTeam* getMissionByAlias( TAIAlias missionAlias );
/*
void updateMembersDb();
/*
bool processMissionStepEvent(std::list< const CMissionEvent* > & eventList, uint missionIndex, uint32 stepIndex );
bool processMissionEvent( std::list< const CMissionEvent* > & eventList, uint missionIndex, uint32 stepIndex );
*/
@ -204,6 +249,9 @@ private:
///\id of the team
uint16 _TeamId;
///\id of the League (it's id of channel)
TChanID _LeagueId;
/// Team Members. The index of an entity in the container is its position
std::list<NLMISC::CEntityId> _TeamMembers;
@ -212,6 +260,7 @@ private:
/// id of the team leader
NLMISC::CEntityId _LeaderId;
/// successor id
NLMISC::CEntityId _SuccessorId;

@ -71,6 +71,195 @@ void CTeamManager::addAllTeamsToChatGroup()
}
} // addAllTeamsToChatGroup //
//---------------------------------------------------
// leagueJoinProposal :
//---------------------------------------------------
void CTeamManager::joinLeagueProposal( CCharacter * leader, const CEntityId &targetId)
{
//check already done
nlassert(leader);
const NLMISC::CEntityId &leaderId = leader->getId();
if (targetId == leaderId )
{
CCharacter::sendDynamicSystemMessage( leader->getId(),"INVALID_LEAGUE_TARGET" );
return;
}
// get targeted player
CCharacter *invitedPlayer = PlayerManager.getOnlineChar( targetId );
if ( invitedPlayer == NULL )
{
CCharacter::sendDynamicSystemMessage( leader->getId(),"INVALID_LEAGUE_TARGET" );
return;
}
// god player are forbidden to team
if (leader->godMode() || invitedPlayer->godMode())
{
nlwarning("<CTeamManager joinLeagueProposal> Player %s invited %s, but at least on of them is god, forbidden",
leaderId.toString().c_str(),
targetId.toString().c_str());
CCharacter::sendDynamicSystemMessage( leader->getId(),"TEAM_GOD_FORBIDDEN" );
return;
}
TInviteRetCode code = isLeagueInvitableBy(invitedPlayer,leader);
if ( code == AlreadyInvited )
{
CCharacter::sendDynamicSystemMessage( leader->getId(),"LEAGUE_ALREADY_INVITED" );
return;
}
else if ( code == AlreadyInLeague )
{
CTeam * team = getRealTeam( invitedPlayer->getTeamId() );
CCharacter::sendDynamicSystemMessage( leader->getId(),"LEAGUE_ALREADY_IN_LEAGUE" );
return;
}
else if ( code == NotLeader )
{
CTeam * team = getRealTeam( invitedPlayer->getTeamId() );
joinLeagueProposal(leader, team->getLeader());
return;
}
else if ( code == CantInvite )
{
CCharacter::sendDynamicSystemMessage( leader->getId(),"LEAGUE_INVITOR_NOT_LEADER" );
return;
}
/// the invitor must not be in the ignore list of the target
if(invitedPlayer->hasInIgnoreList(leaderId))
{
SM_STATIC_PARAMS_1( params1, STRING_MANAGER::player );
params1[0].setEIdAIAlias( targetId, CAIAliasTranslator::getInstance()->getAIAlias( targetId) );
// Use the standard "player declines your offer". Don't use specific message because
// maybe not a good idea to inform a player that someone ignores him
CCharacter::sendDynamicSystemMessage( leaderId, "TEAM_DECLINE", params1 );
return;
}
//set the target's invitor
invitedPlayer->setLeagueInvitor(leaderId);
CEntityId msgTargetEId = targetId;
//send the appropriate string to the client
SM_STATIC_PARAMS_1(params, STRING_MANAGER::player);
params[0].setEIdAIAlias( leaderId, CAIAliasTranslator::getInstance()->getAIAlias(leaderId) );
uint32 txt = STRING_MANAGER::sendStringToClient(TheDataset.getDataSetRow(targetId), "LEAGUE_PROPOSAL", params );
CMessage msgout( "IMPULSION_ID" );
msgout.serial( const_cast<CEntityId&>(msgTargetEId) );
CBitMemStream bms;
nlverify ( GenericMsgManager.pushNameToStream( "PVP_CHALLENGE:INVITATION", bms) );
bms.serial( txt );
msgout.serialBufferWithSize((uint8*)bms.buffer(), bms.length());
sendMessageViaMirror( NLNET::TServiceId(msgTargetEId.getDynamicId()), msgout );
params[0].setEIdAIAlias( targetId, CAIAliasTranslator::getInstance()->getAIAlias( targetId ) );
PHRASE_UTILITIES::sendDynamicSystemMessage(leader->getEntityRowId(), "LEAGUE_INVITE", params);
leader->updateTarget();
}
//---------------------------------------------------
// joinLeagueDecline :
//---------------------------------------------------
void CTeamManager::joinLeagueDecline( const NLMISC::CEntityId &charId)
{
CCharacter * invited = PlayerManager.getOnlineChar(charId);
if ( invited == NULL )
{
nlwarning("<CTeamManager joinLeagueDecline>Invalid char %s",charId.toString().c_str());
return;
}
invited->setAfkState(false);
if ( invited->getLeagueInvitor() == CEntityId::Unknown )
{
nlwarning("<CTeamManager joinLeagueDecline>character %s has an Invalid invitor",charId.toString().c_str());
return;
}
//inform both players
SM_STATIC_PARAMS_1(params, STRING_MANAGER::player);
params[0].setEIdAIAlias( charId, CAIAliasTranslator::getInstance()->getAIAlias( charId) );
PHRASE_UTILITIES::sendDynamicSystemMessage(TheDataset.getDataSetRow(invited->getTeamInvitor()), "LEAGUE_DECLINE", params);
params[0].setEIdAIAlias( invited->getTeamInvitor(), CAIAliasTranslator::getInstance()->getAIAlias( invited->getTeamInvitor() ) );
PHRASE_UTILITIES::sendDynamicSystemMessage(invited->getEntityRowId(), "LEAGUE_YOU_DECLINE", params);
//cancel the proposal
invited->setLeagueInvitor( CEntityId::Unknown );
} // joinLeagueDecline //
//---------------------------------------------------
// joinLeagueAccept :
//---------------------------------------------------
void CTeamManager::joinLeagueAccept( const NLMISC::CEntityId &charId)
{
// get the invited char
CCharacter * invited = PlayerManager.getOnlineChar(charId);
if ( invited == NULL )
{
nlwarning("<CTeamManager joinLeagueAccept>Invalid char %s",charId.toString().c_str());
return;
}
// get the invitor id
const NLMISC::CEntityId & invitorId = invited->getLeagueInvitor();
if ( invitorId == CEntityId::Unknown )
{
nlwarning("<CTeamManager joinLeagueAccept>character %s has an Invalid invitor",charId.toString().c_str());
return;
}
//get the invitor char
CCharacter * invitor = PlayerManager.getOnlineChar(invitorId);
if ( invitor == NULL )
{
nlwarning("<CTeamManager joinLeagueAccept>character %s, Invalid invitor id %s",charId.toString().c_str(),invitorId.toString().c_str());
invited->setLeagueInvitor( CEntityId::Unknown );
return;
}
invitor->setAfkState(false);
//cancel the proposal
invited->setLeagueInvitor( CEntityId::Unknown );
CTeam *teamInvitor;
CTeam *teamInvited;
//if the invited player had a fake team, remove it
teamInvited = getRealTeam(invited->getTeamId());
teamInvitor = getRealTeam(invitor->getTeamId());
if ( !teamInvitor )
{
nlwarning("<CTeamManager joinLeagueAccept>character %s, invitor id %s, the invited or invitor player is not in a valid team. ",charId.toString().c_str(),invitor->getId().toString().c_str() );
return;
}
// check that the invitor team have league else create them
if (teamInvitor->getLeagueId() == DYN_CHAT_INVALID_CHAN )
{
teamInvitor->setLeague("League");
}
if (teamInvited) {
const string playerName = CEntityIdTranslator::getInstance()->getByEntity(invited->getId()).toString();
CPVPManager2::getInstance()->broadcastMessage(teamInvitor->getLeagueId(), string("<TEAM>"), "<-- "+playerName);
teamInvited->setLeagueId(teamInvitor->getLeagueId());
teamInvited->updateLeague();
} else {
const string playerName = CEntityIdTranslator::getInstance()->getByEntity(invited->getId()).toString();
CPVPManager2::getInstance()->broadcastMessage(teamInvitor->getLeagueId(), string("<PLAYER>"), "<-- "+playerName);
invited->setLeagueId(teamInvitor->getLeagueId(), true);
}
} // joinLeagueAccept //
//---------------------------------------------------
// joinProposal :
//---------------------------------------------------
@ -90,7 +279,7 @@ void CTeamManager::joinProposal( CCharacter * leader, const CEntityId &targetId)
CCharacter *invitedPlayer = PlayerManager.getOnlineChar( targetId );
if ( invitedPlayer == NULL )
{
CCharacter::sendDynamicSystemMessage( leader->getId(),"INVALID_TEAM_TARGET" );
CCharacter::sendDynamicSystemMessage( leader->getId(),"INVALID_LEAGUE_TARGET" );
return;
}
@ -117,7 +306,7 @@ void CTeamManager::joinProposal( CCharacter * leader, const CEntityId &targetId)
}
else if ( code == CantInviteEnemy )
{
CCharacter::sendDynamicSystemMessage( leader->getId(),"TEAM_CANT_INVITE_ENEMIE" );
CCharacter::sendDynamicSystemMessage( leader->getId(),"TEAM_CANT_INVITE_ENEMY" );
return;
}
else if ( code == CantInvite )
@ -423,7 +612,7 @@ void CTeamManager::removeCharacter( const CEntityId &charId )
{
const list<CEntityId> &members = team->getTeamMembers();
CEntityId eId(*(++members.begin()));
CEntityId eId(team->getSuccessor());
params[0].setEIdAIAlias( eId, CAIAliasTranslator::getInstance()->getAIAlias(eId) );
PHRASE_UTILITIES::sendDynamicSystemMessage(TheDataset.getDataSetRow(charId), "TEAM_YOU_LEAVE_LEADER", params);
}
@ -505,6 +694,48 @@ void CTeamManager::removeFakeTeam(CCharacter * player)
nlwarning("<CTeamManager removeFakeTeam> char %s the team id %d is out of bounds (nb teams = %d)",player->getId().toString().c_str(),player->getTeamId(),_Teams.size());
}// removeFakeTeam
//---------------------------------------------------
// isLeagueInvitableBy :
//---------------------------------------------------
CTeamManager::TInviteRetCode CTeamManager::isLeagueInvitableBy(CCharacter * invited, CCharacter * invitor )
{
// check must be done before
nlassert( invited );
nlassert( invitor );
if ( !TheDataset.isAccessible(invited->getEntityRowId()) || !TheDataset.isAccessible(invitor->getEntityRowId()))
return CantInvite;
// check that the invitor is in team
CTeam * team = getRealTeam( invitor->getTeamId() );
if (!team)
return CantInvite;
// check that the invitor is the leader
if (team->getLeader() != invitor->getId() )
return CantInvite;
// check that the invited don't have league
if (invited->getLeagueId() != DYN_CHAT_INVALID_CHAN)
return AlreadyInLeague;
// check if target is not already invited
if( invited->getLeagueInvitor() != CEntityId::Unknown )
return AlreadyInvited;
// get the target team
team = getRealTeam( invited->getTeamId() );
if (!team)
return NotInTeam;
// check that the invited is the leader
if (team->getLeader() != invited->getId() )
return NotLeader;
return Ok;
}
//---------------------------------------------------
// processMissionTeamEvent :
//---------------------------------------------------
@ -519,6 +750,7 @@ CTeamManager::TInviteRetCode CTeamManager::isInvitableBy(CCharacter * invited, C
{
return AlreadyInvited;
}
// get the target team, which must be fake
CTeam * team = getRealTeam( invited->getTeamId() );
if( team )
@ -528,7 +760,8 @@ CTeamManager::TInviteRetCode CTeamManager::isInvitableBy(CCharacter * invited, C
// check that the invitor is alone or a group leader
team = getRealTeam( invitor->getTeamId() );
if ( team && team->getLeader()!= invitor->getId() )
if (team && team->getLeader()!= invitor->getId())
{
return CantInvite;
}
@ -538,9 +771,9 @@ CTeamManager::TInviteRetCode CTeamManager::isInvitableBy(CCharacter * invited, C
return CantInvite;
// cannot invite enemy in faction PvP zones
if( CPVPManager2::getInstance()->isOffensiveActionValid( invited, invitor, true ) )
/* if( CPVPManager2::getInstance()->isOffensiveActionValid( invited, invitor, true ) )
if( invited->getPvPRecentActionFlag() || invitor->getPvPRecentActionFlag() )
return CantInviteEnemy;
return CantInviteEnemy;*/
return Ok;
}

@ -31,7 +31,7 @@ class CCharacter;
///\todo: avoid team reallocation problems?
///\todo: check if we have to remove team from IOS if crash/shutdown
///\todo successor index sert à rien???
///\todo successor index is useful ?
/**
* CTeamManager
@ -47,9 +47,12 @@ public:
{
AlreadyInvited,
AlreadyInTeam,
AlreadyInLeague,
CantInviteEnemy,
CantInvite,
Ok,
NotInTeam,
NotLeader,
};
/// default constructor
CTeamManager()
@ -58,6 +61,13 @@ public:
/// add all created to chat groups
void addAllTeamsToChatGroup();
/// player leaderId invites player targetId to join his League. Only leaders can invite other leaders
void joinLeagueProposal( CCharacter * leader, const NLMISC::CEntityId &targetId );
/// player charId declines an invitation
void joinLeagueDecline( const NLMISC::CEntityId &charId );
/// player charId accepts an invitation
void joinLeagueAccept( const NLMISC::CEntityId &charId );
/// player leaderId invites plyer targetId to join his team. Only leaders can invite
void joinProposal( CCharacter * leader, const NLMISC::CEntityId &targetId );
@ -104,6 +114,13 @@ public:
*/
TInviteRetCode isInvitableBy(CCharacter * invited, CCharacter * invitor );
/**
* \param invited: character being invited
* \param invitor: character inviting the other one
* \return true if the invited is invitable by the invitor
*/
TInviteRetCode isLeagueInvitableBy(CCharacter * invited, CCharacter * invitor );
/**
* PvP attack occurs in a team
* \param actor is the attacker character

@ -248,9 +248,9 @@ public :
* \param target is the id of the target char
* \param phraseId is the phrase id (uint32)
*/
void sendEmoteTextToPlayer( const TDataSetRow& target,uint32 phraseId )
void sendEmoteTextToPlayer( const TDataSetRow& sender, const TDataSetRow& target, uint32 phraseId )
{
sendChat2Ex( CChatGroup::say, target, phraseId );
sendChat2Ex( CChatGroup::say, target, phraseId, sender );
}
/**

@ -495,8 +495,8 @@ void CInputOutputService::scanMirrorChanges()
if (entityId.getType() == RYZOMID::player)
{
// init event faction ID in mirror
CMirrorPropValue<TYPE_EVENT_FACTION_ID> propEventFactionId( TheDataset, entityIndex, DSPropertyEVENT_FACTION_ID );
propEventFactionId = 0;
//CMirrorPropValue<TYPE_EVENT_FACTION_ID> propEventFactionId( TheDataset, entityIndex, DSPropertyEVENT_FACTION_ID );
//propEventFactionId = 0;
}
entityIndex = DataSet->getNextAddedEntity();
@ -620,7 +620,7 @@ void CInputOutputService::addCharacterName( const TDataSetRow& chId, const ucstr
if( itInfos == _NameToInfos.end() )
{
// New name does not exist
charInfos->ShortName = ucstring(name);
charInfos->ShortName.fromUtf8(name);
}
// Save the old name only if new name is not found (and the player is getting original name back)

@ -709,8 +709,8 @@ static void cbCharacterEventFaction(CMessage& msgin, const string &serviceName,
else
ci->UntranslatedEventFactionId = SM->storeString( eventFaction );
CMirrorPropValue<TYPE_EVENT_FACTION_ID> propEventFactionId( TheDataset, chId, DSPropertyEVENT_FACTION_ID );
propEventFactionId = SM->translateEventFaction( ci->UntranslatedEventFactionId );
// CMirrorPropValue<TYPE_EVENT_FACTION_ID> propEventFactionId( TheDataset, chId, DSPropertyEVENT_FACTION_ID );
// propEventFactionId = SM->translateEventFaction( ci->UntranslatedEventFactionId );
}
else
{
@ -1513,12 +1513,14 @@ void cbEmoteCrowd( CMessage& msgin, const string &serviceName, TServiceId servic
//-----------------------------------------------
void cbEmoteSolePlayer( CMessage& msgin, const string &serviceName, TServiceId serviceId )
{
TDataSetRow sender;
TDataSetRow target;
uint32 phraseId;
msgin.serial(sender);
msgin.serial(target);
msgin.serial(phraseId);
CChatManager &cm = IOS->getChatManager();
cm.sendEmoteTextToPlayer( target,phraseId );
cm.sendEmoteTextToPlayer(sender, target, phraseId );
}
@ -1567,6 +1569,10 @@ void cbSetPhrase( CMessage& msgin, const string &serviceName, TServiceId service
SM->setPhrase(msgin);
}
void cbSetPhraseLang( CMessage& msgin, const string& serviceName, TServiceId serviceId )
{
SM->setPhraseLang(msgin);
}
//-----------------------------------------------
// Add a new channel in the dyn chat
@ -2048,6 +2054,7 @@ TUnifiedCallbackItem CbIOSArray[]=
{ "CUSTOM_EMOTE", cbCustomEmote }, // EGS wants IOS to dispatch an emote custom text to all users around
{ "SET_PHRASE", cbSetPhrase }, // AIS wants IOS to change a phrase content
{ "SET_PHRASE_LANG", cbSetPhraseLang }, // AIS or EGS wants IOS to change a phrase content for a language
{ "UPDATE_AIALIAS", cbUpdateAIAlias},

@ -231,7 +231,8 @@ public:
{
static const string NAME("name");
if (rep.Format != NAME)
CSString format = rep.Format;
if (format.left(4) != NAME)
{
// can't replace this parameter, write a del char
const static string s("\010");
@ -270,7 +271,8 @@ public:
if (playerInfo != 0)
{
static const string NAME("name");
if (rep.Format != NAME)
CSString format = rep.Format;
if (format.left(4) != NAME)
{
// can't replace this parameter, write a del char
const static string s("\010");

@ -1110,6 +1110,30 @@ void CStringManager::setPhrase(NLNET::CMessage &message)
setPhrase(phraseName, phraseContent);
}
/*
* Replace a phrase in specified language (message handler)
*/
void CStringManager::setPhraseLang(NLNET::CMessage &message)
{
std::string phraseName;
ucstring phraseContent;
std::string langString;
try
{
message.serial(phraseName);
message.serial(phraseContent);
message.serial(langString);
}
catch( Exception& e )
{
nlwarning("<setPhrase> %s",e.what());
return;
}
TLanguages lang = checkLanguageCode(langString);
setPhrase(phraseName, phraseContent, lang);
}
/*
* Replace a phrase in default language(s)
*/

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save