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")); CCtrlTextButton *confirmButton = dynamic_cast<CCtrlTextButton*>(ig->getCtrl("ok"));
if (confirmButton) if (confirmButton)
{ {
confirmButton->setActive( sheet->getLockedByOwner() ); confirmButton->setActive( !sheet->getLockedByOwner() );
confirmButton->setText(CI18N::get("uiSellImmediately")); confirmButton->setText(CI18N::get("uiSellImmediately"));
confirmButton->setDefaultContextHelp(CI18N::get("uittDirectSellButton")); confirmButton->setDefaultContextHelp(CI18N::get("uittDirectSellButton"));
} }

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

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

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

@ -175,6 +175,42 @@
#include "nel/misc/hierarchical_timer.h" #include "nel/misc/hierarchical_timer.h"
inline uint32 saveGameCycleToSecond(NLMISC::TGameCycle tick) 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 // Evaluate the UTC of this event (with the current date of save). Suppose that 1 second==10 tick
if (tick < CTickEventHandler::getGameCycle()) if (tick < CTickEventHandler::getGameCycle())
return NLMISC::CTime::getSecondsSince1970(); 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 // Convert UTC of the event to game cycle. Suppose that 1 second==10 tick
return CTickEventHandler::getGameCycle() + (second - NLMISC::CTime::getSecondsSince1970())*10; return CTickEventHandler::getGameCycle() + (second - NLMISC::CTime::getSecondsSince1970())*10;
} }*/
#endif #endif
// GameCycle property (saved as a UTC of the current game cycle, support server migration) // GameCycle property (saved as a UTC of the current game cycle, support server migration)

@ -51,4 +51,4 @@ std::map<std::string, CSPType::TSPType> CSPType::_ValueMap;
// End of static implementation of CSPType // End of static implementation of CSPType
} // End of EGSPD } // End of EGSPD

@ -423,6 +423,15 @@ void CAIS::update()
_CreatureChangeHPList.Entities.clear(); _CreatureChangeHPList.Entities.clear();
_CreatureChangeHPList.DeltaHp.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();
}
} }
// //

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

@ -61,7 +61,7 @@ CAIInstance* CSpawnBot::getAIInstance() const
void CSpawnBot::setVisualPropertiesName() void CSpawnBot::setVisualPropertiesName()
{ {
CBot& botRef = CSpawnBot::getPersistent(); CBot& botRef = CSpawnBot::getPersistent();
std::string name = botRef.getName(); ucstring name = botRef.getName();
if (CVisualPropertiesInterface::UseIdForName) if (CVisualPropertiesInterface::UseIdForName)
{ {
@ -85,7 +85,7 @@ void CSpawnBot::setVisualPropertiesName()
if (! botRef.getFaunaBotUseBotName()) //false by default if (! botRef.getFaunaBotUseBotName()) //false by default
{ {
if (botRef.getSheet()->ForceDisplayCreatureName()) if (botRef.getSheet()->ForceDisplayCreatureName())
return; return;
// the npc name is displayed as a fauna // the npc name is displayed as a fauna
} }
@ -403,8 +403,8 @@ std::vector<std::string> CBot::getMultiLineInfoString() const
pushTitle(container, "CBot"); pushTitle(container, "CBot");
pushEntry(container, "id=" + getIndexString()); pushEntry(container, "id=" + getIndexString());
container.back() += " eid=" + getEntityIdString(); container.back() += " eid=" + getEntityIdString();
container.back() += " alias=" + getAliasTreeOwner()->getAliasString(); container.back() += " alias=" + getAliasTreeOwner()->getAliasString() + " raw alias=" + NLMISC::toString(getAliasTreeOwner()->getAlias());
container.back() += " name=" + getName(); pushEntry(container, " name=" + getName());
if (isSheetValid()) if (isSheetValid())
container.back() += " sheet=" + NLMISC::CFile::getFilenameWithoutExtension(getSheet()->SheetId().toString()); container.back() += " sheet=" + NLMISC::CFile::getFilenameWithoutExtension(getSheet()->SheetId().toString());
pushEntry(container, "fullname=" + getFullName()); pushEntry(container, "fullname=" + getFullName());

@ -95,7 +95,7 @@ public:
virtual float getAggroPropagationRadius() const; 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. // 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; bool getProp(size_t Id, uint32& value) const;
@ -241,8 +241,8 @@ public:
NLMISC::CEntityId createEntityId() const; NLMISC::CEntityId createEntityId() const;
const std::string& getCustomName() const { return _CustomName; } const ucstring& getCustomName() const { return _CustomName; }
void setCustomName(const std::string &name) { _CustomName = name; } void setCustomName(const ucstring &name) { _CustomName = name; }
virtual void setClientSheet(const std::string & clientSheetName); virtual void setClientSheet(const std::string & clientSheetName);
@ -272,7 +272,7 @@ private:
bool _IgnoreOffensiveActions; bool _IgnoreOffensiveActions;
bool _Healer; bool _Healer;
bool _BuildingBot; bool _BuildingBot;
std::string _CustomName; ucstring _CustomName;
CTimer _SetSheetTimer; CTimer _SetSheetTimer;
struct CSetSheetData struct CSetSheetData
{ {

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

@ -16,6 +16,7 @@
#include "stdpch.h" #include "stdpch.h"
#include "ai_bot_pet.h" #include "ai_bot_pet.h"
#include "visual_properties_interface.h"
#include "nel/misc/random.h" #include "nel/misc/random.h"
#include "ai_grp_pet.h" #include "ai_grp_pet.h"
@ -92,3 +93,28 @@ CSpawnGroupPet& CSpawnBotPet::spawnGrp()
{ {
return static_cast<CSpawnGroupPet&>(CSpawnBot::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);
}

@ -65,6 +65,8 @@ public:
CPathPosition& pathPos() { return _PathPos; } CPathPosition& pathPos() { return _PathPos; }
uint32 _DeathTime; uint32 _DeathTime;
void setVisualPropertiesName();
private: private:

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

@ -207,7 +207,7 @@ public:
return NULL; 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 /// 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); CBotEasterEgg* createEasterEgg(uint32 easterEggId, NLMISC::CSheetId const& sheetId, std::string const& botName, double x, double y, double z, double heading, const std::string& look);

@ -290,6 +290,11 @@ void CPetSpawnMsgImp::callback(std::string const& name, NLNET::TServiceId id)
} }
botPet->setSheet(sheet); botPet->setSheet(sheet);
if (!CustomName.empty())
{
botPet->setCustomName(CustomName);
}
if (!botPet->spawn()) if (!botPet->spawn())
{ {
@ -314,7 +319,7 @@ void CPetSpawnMsgImp::callback(std::string const& name, NLNET::TServiceId id)
#endif #endif
return; return;
} }
botPet->getSpawn()->setAIProfile(new CAIPetProfileStand(botPet->getSpawn())); botPet->getSpawn()->setAIProfile(new CAIPetProfileStand(botPet->getSpawn()));
confirmMsg.PetMirrorRow = botPet->getSpawn()->dataSetRow(); confirmMsg.PetMirrorRow = botPet->getSpawn()->dataSetRow();

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

@ -1562,7 +1562,7 @@ void CGrpProfileGoToPoint::updateProfile(uint ticksSinceLastUpdate)
dx+=dir.x; dx+=dir.x;
dy+=dir.y; dy+=dir.y;
// 4 rangées. // 4 rows
CAIVector idealPos=groupPosition; CAIVector idealPos=groupPosition;
if (botIndex>=_NbBotInNormalShape) if (botIndex>=_NbBotInNormalShape)
{ {
@ -2054,7 +2054,7 @@ void CGrpProfileFollowRoute::updateProfile(uint ticksSinceLastUpdate)
dx+=dir.x; dx+=dir.x;
dy+=dir.y; dy+=dir.y;
// 4 rangées. // 4 rows
CAIVector idealPos=groupPosition; CAIVector idealPos=groupPosition;
if (botIndex>=_NbBotInNormalShape) 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 // // CGrpProfileIdle //
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@ -3687,10 +3775,14 @@ bool CGrpProfileFaction::entityHavePartOfFactions(CAIEntityPhysical const* entit
std::set<TStringId>::const_iterator it, end = factionsSet.end(); std::set<TStringId>::const_iterator it, end = factionsSet.end();
for (it=factionsSet.begin(); it!=end; ++it) 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 fame = CFameInterface::getInstance().getFameOrCivilisationFame(entity->getEntityId(), CStringMapper::map(fameFaction));
sint32 const fame = entity->getFame(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()); // nldebug("Entity has faction %s", CStringMapper::unmap(*it).c_str());
return true; return true;
@ -3731,12 +3823,41 @@ std::string CGrpProfileFaction::scriptFactionToFameFaction(std::string name)
ret += "_"; ret += "_";
ret += name[i]-'A'+'a'; ret += name[i]-'A'+'a';
} }
else if (name[i] == '>' || name[i] == '<')
{
return ret;
}
else else
{
ret += name[i]; ret += name[i];
}
} }
return ret; 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 CGrpProfileFaction::fameFactionToScriptFaction(std::string name)
{ {
std::string ret = "Famous"; std::string ret = "Famous";
@ -3772,9 +3893,9 @@ void CGrpProfileFaction::checkTargetsAround()
CPropertySetWithExtraList<TAllianceId> const& thisEnnemyFactions = thisGrpNpc.ennemyFaction(); CPropertySetWithExtraList<TAllianceId> const& thisEnnemyFactions = thisGrpNpc.ennemyFaction();
// We don't assist or attack players if our friends/ennemies are not in factions // 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 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(); bool const attackBots = !thisEnnemyFactions.empty();
CAIVision<CPersistentOfPhysical> Vision; CAIVision<CPersistentOfPhysical> Vision;

@ -628,6 +628,49 @@ private:
CAITimer _Timer; 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 // // CGrpProfileIdle //
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@ -792,6 +835,10 @@ public:
static std::string scriptFactionToFameFaction(std::string name); static std::string scriptFactionToFameFaction(std::string name);
static std::string fameFactionToScriptFaction(std::string name); static std::string fameFactionToScriptFaction(std::string name);
static bool scriptFactionToFameFactionGreaterThan(std::string name);
static sint32 scriptFactionToFameFactionValue(std::string name);
private: private:
CAITimer _checkTargetTimer; CAITimer _checkTargetTimer;
bool bNoAssist; bool bNoAssist;

@ -259,7 +259,7 @@ NLMISC_COMMAND(eventCreateNpcGroup, "create an event npc group", "<aiInstanceId>
std::string botsName; std::string botsName;
if (args.size()>8) botsName = args[8]; 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; return true;
} }

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

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

@ -1497,6 +1497,41 @@ void setAutoSpawn_f_(CStateInstance* entity, CScriptStack& stack)
// HP related methods // HP related methods
/** @page code /** @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_ @subsection setHPLevel_f_
Sets the current HP level of each bot of the group. 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 @param[in] parameterName is a the id of the parameter to add
@code @code
()addProfileParameter("running"); // équivalent à un parameter "running" dans la primitive du groupe ()addProfileParameter("running"); // equivalent to "running" parameter in group primitive
@endcode @endcode
*/ */
@ -1898,7 +1965,7 @@ Arguments: s(parameterName),s(parameterContent) ->
@param[in] parameterContent is the value of the parameter @param[in] parameterContent is the value of the parameter
@code @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 @endcode
*/ */
@ -1927,7 +1994,7 @@ Arguments: s(parameterName),f(parameterContent) ->
@param[in] parameterContent is the value of the parameter @param[in] parameterContent is the value of the parameter
@code @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 @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); 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() 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, clearAggroList__);
REGISTER_NATIVE_FUNC(functions, setMode_s_); REGISTER_NATIVE_FUNC(functions, setMode_s_);
REGISTER_NATIVE_FUNC(functions, setAutoSpawn_f_); REGISTER_NATIVE_FUNC(functions, setAutoSpawn_f_);
REGISTER_NATIVE_FUNC(functions, setMaxHP_ff_);
REGISTER_NATIVE_FUNC(functions, setHPLevel_f_); REGISTER_NATIVE_FUNC(functions, setHPLevel_f_);
REGISTER_NATIVE_FUNC(functions, setHPScale_f_); REGISTER_NATIVE_FUNC(functions, setHPScale_f_);
REGISTER_NATIVE_FUNC(functions, scaleHP_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_f);
REGISTER_NATIVE_FUNC(functions, getEventParam_f_s); REGISTER_NATIVE_FUNC(functions, getEventParam_f_s);
REGISTER_NATIVE_FUNC(functions, setSheet_s_); REGISTER_NATIVE_FUNC(functions, setSheet_s_);
REGISTER_NATIVE_FUNC(functions, setClientSheet_s_);
REGISTER_NATIVE_FUNC(functions, setHealer_f_); REGISTER_NATIVE_FUNC(functions, setHealer_f_);
REGISTER_NATIVE_FUNC(functions, setConditionSuccess_f_); REGISTER_NATIVE_FUNC(functions, setConditionSuccess_f_);
REGISTER_NATIVE_FUNC(functions, facing_f_);
REGISTER_NATIVE_FUNC(functions, setUrl_ss_);
// Boss functions (custom text) // Boss functions (custom text)
REGISTER_NATIVE_FUNC(functions, phraseBegin__); REGISTER_NATIVE_FUNC(functions, phraseBegin__);
@ -4699,10 +4855,7 @@ std::map<std::string, FScrptNativeFunc> nfGetGroupNativeFunctions()
REGISTER_NATIVE_FUNC(functions, teleportPlayer_sffff_); REGISTER_NATIVE_FUNC(functions, teleportPlayer_sffff_);
REGISTER_NATIVE_FUNC(functions, summonPlayer_fs_); REGISTER_NATIVE_FUNC(functions, summonPlayer_fs_);
#undef REGISTER_NATIVE_FUNC #undef REGISTER_NATIVE_FUNC
return functions; return functions;

@ -462,7 +462,7 @@ Arguments: f(Radius) ->
@param[in] Radius dispersion of wander activity @param[in] Radius dispersion of wander activity
@code @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 @endcode
*/ */
@ -501,6 +501,56 @@ void startMoving_fff_(CStateInstance* entity, CScriptStack& stack)
return; 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())); // bot1->setTheta(bot1->pos().angleTo(bot2->pos()));
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
/** @page code /** @page code
@subsection npcSay_css_ @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 Make a npc say a text
There are 3 type of text There are 3 type of text
@ -2201,9 +2248,9 @@ Arguments: c(group), s(botname), s(text), ->
@code @code
(@group)group_name.context(); (@group)group_name.context();
()emote(@group, "bob", "DSS_1601 RtEntryText_6") ;// Send To dss ()npcSay(@group, "bob", "DSS_1601 RtEntryText_6") ;// Send To dss
()emote(@group, "bob", "RAW Ca farte?"); // phrase direcly send to IOS as raw (for debug) ()npcSay(@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", "answer_group_no_m"); //phrase id
@endcode @endcode
@ -2214,6 +2261,34 @@ Arguments: c(group), s(botname), s(text), ->
#include "game_share/chat_group.h" #include "game_share/chat_group.h"
#include "game_share/send_chat.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) void npcSay_css_(CStateInstance* entity, CScriptStack& stack)
{ {
string text = (string)stack.top(); stack.pop(); string text = (string)stack.top(); stack.pop();
@ -2224,29 +2299,58 @@ void npcSay_css_(CStateInstance* entity, CScriptStack& stack)
if (!spawnBot) { return; } if (!spawnBot) { return; }
execSayHelper(spawnBot, text);
}
std::string prefix =NLMISC::CSString (text).left(4); //----------------------------------------------------------------------------
if(prefix=="DSS_") /** @page code
{
@subsection npcSay_ss_
NLMISC::CSString phrase = NLMISC::CSString (text).right((uint)text.length()-4);
NLMISC::CSString idStr = phrase.strtok(" ",false,false,false,false); Make a npc say a text
uint32 scenarioId;
NLMISC::fromString(idStr, scenarioId); Arguments: s(text), s(mode) ->
forwardToDss(spawnBot->dataSetRow(), CChatGroup::say, phrase, scenarioId); @param[in] text is the text to say. prefix with ID: to use an id
return; @param[in] mode is the mode to use (say, shout)
}
@code
if (prefix=="RAW ") ()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); FOREACH(itBot, CCont<CBot>, group->bots())
npcChatToChannelSentence(spawnBot->dataSetRow(),CChatGroup::say, phrase); {
return; 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(row);
msgout.serial(name); msgout.serial(name);
sendMessageViaMirror("IOS", msgout); 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, startMoving_fff_);
REGISTER_NATIVE_FUNC(functions, waitInZone_s_); REGISTER_NATIVE_FUNC(functions, waitInZone_s_);
REGISTER_NATIVE_FUNC(functions, stopMoving__); REGISTER_NATIVE_FUNC(functions, stopMoving__);
REGISTER_NATIVE_FUNC(functions, followPlayer_sf_);
REGISTER_NATIVE_FUNC(functions, wander__); REGISTER_NATIVE_FUNC(functions, wander__);
REGISTER_NATIVE_FUNC(functions, setAttackable_f_); REGISTER_NATIVE_FUNC(functions, setAttackable_f_);
REGISTER_NATIVE_FUNC(functions, setPlayerAttackable_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, rename_s_);
REGISTER_NATIVE_FUNC(functions, vpx_s_); REGISTER_NATIVE_FUNC(functions, vpx_s_);
REGISTER_NATIVE_FUNC(functions, npcSay_css_); REGISTER_NATIVE_FUNC(functions, npcSay_css_);
REGISTER_NATIVE_FUNC(functions, npcSay_ss_);
REGISTER_NATIVE_FUNC(functions, dssMessage_fsss_); REGISTER_NATIVE_FUNC(functions, dssMessage_fsss_);
REGISTER_NATIVE_FUNC(functions, despawnBotByAlias_s_); REGISTER_NATIVE_FUNC(functions, despawnBotByAlias_s_);
REGISTER_NATIVE_FUNC(functions, giveReward_ssssc_); REGISTER_NATIVE_FUNC(functions, giveReward_ssssc_);

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

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

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

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

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

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

@ -39,7 +39,7 @@ public:
static void release(); static void release();
// set different visual properties for an entity // 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 setMode(CAIEntityId id,MBEHAV::EMode mode);
// static void setBehaviour(CAIEntityId id,MBEHAV::EBehaviour behaviour); // 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 initAdmin ();
void initCommandsPrivileges(const std::string & fileName); void initCommandsPrivileges(const std::string & fileName);
void initPositionFlags(const std::string & fileName); void initPositionFlags(const std::string & fileName);
void initSalt();
const std::string &getSalt();
CAdminCommand * findAdminCommand(const std::string & name); CAdminCommand * findAdminCommand(const std::string & name);

@ -268,6 +268,7 @@ bool CBuildingManager::parsePhysicalBuildings( const NLLIGO::IPrimitive* prim, C
else else
{ {
_BuildingPhysicals.insert( make_pair( alias, building ) ); _BuildingPhysicals.insert( make_pair( alias, building ) );
_BuildingPhysicalsName.insert( make_pair( building->getName(), building));
return true; return true;
} }
} }
@ -853,18 +854,18 @@ IBuildingPhysical * CBuildingManager::getBuildingPhysicalsByAlias( TAIAlias alia
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
IBuildingPhysical* CBuildingManager::getBuildingPhysicalsByName( const std::string & name ) 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 ) if( (*it).second == NULL )
{ {
nlwarning("<BUILDING> NULL building in building maps. Checks should be done at init time"); nlwarning("<BUILDING> NULL building in building maps. Checks should be done at init time");
return NULL; return NULL;
} }
if ( (*it).second->getName() == name ) return (*it).second;
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 ); void registerPlayer( CCharacter * user );
/// get a building destination from its alias. /// get a building destination from its alias.
IBuildingPhysical* getBuildingPhysicalsByAlias( TAIAlias 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 ); IBuildingPhysical* getBuildingPhysicalsByName( const std::string & name );
/// remove a player from a room /// remove a player from a room
void removePlayerFromRoom( CCharacter * user ); void removePlayerFromRoom( CCharacter * user );
@ -122,6 +122,7 @@ public:
void buildBuildingTradeList(const NLMISC::CEntityId & userId, uint16 session); void buildBuildingTradeList(const NLMISC::CEntityId & userId, uint16 session);
/// buy a player flat option /// buy a player flat option
void buyBuildingOption(const NLMISC::CEntityId & userId, uint8 idx); void buyBuildingOption(const NLMISC::CEntityId & userId, uint8 idx);
void buyBuilding(const NLMISC::CEntityId & userId, TAIAlias alias);
//@} //@}
private: private:
@ -201,9 +202,12 @@ private:
typedef CHashMap< TDataSetRow , CTriggerRequest , TDataSetRow::CHashCode > TTriggerRequestCont; typedef CHashMap< TDataSetRow , CTriggerRequest , TDataSetRow::CHashCode > TTriggerRequestCont;
TTriggerRequestCont _TriggerRequests; TTriggerRequestCont _TriggerRequests;
/// physical buildings by name /// physical buildings by Alias
std::map<TAIAlias,IBuildingPhysical*> _BuildingPhysicals; std::map<TAIAlias,IBuildingPhysical*> _BuildingPhysicals;
/// physical buildings by name
std::map<std::string,IBuildingPhysical*> _BuildingPhysicalsName;
/// room instances /// room instances
struct CRoomInstanceEntry struct CRoomInstanceEntry
{ {

@ -109,7 +109,6 @@ void CBuildingPhysicalGuild::addGuild( uint32 guildId )
{ {
if ( std::find(_Guilds.begin(), _Guilds.end(), guildId) != _Guilds.end() ) 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; 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 // CLIENT:TEAM
@ -857,7 +885,8 @@ void cbClientTeamSetSuccessor( NLNET::CMessage& msgin, const std::string &servic
CEntityId id; CEntityId id;
uint8 idx; uint8 idx;
msgin.serial( id,idx ); msgin.serial(id);
msgin.serial(idx);
CCharacter* user = PlayerManager.getChar( id ); CCharacter* user = PlayerManager.getChar( id );
if ( !user ) if ( !user )
{ {
@ -872,9 +901,17 @@ void cbClientTeamSetSuccessor( NLNET::CMessage& msgin, const std::string &servic
} }
if ( team->getLeader() != id ) 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; return;
} }
// increment the target index as the leader is not in its team list
++idx;
team->setSuccessor( 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 // Send list of connected character name / account to client
void cbClientWho( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId ) 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 ); msgin.serial( id,opt );
const std::vector<CEntityId> * gms = NULL; 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; uint nbAnswers = 0;
// standard who // standard who
@ -2420,7 +2461,7 @@ void cbClientWho( NLNET::CMessage& msgin, const std::string &serviceName, NLNET:
&& user->getInstanceNumber() == ch->getInstanceNumber()) && user->getInstanceNumber() == ch->getInstanceNumber())
{ {
params[0].setEId( (*it) ); params[0].setEId( (*it) );
CCharacter::sendDynamicSystemMessage( id,"WHO_REGION_LIST",params ); CCharacter::sendDynamicSystemMessage( id,"WHO_REGION_LIST", params );
nbAnswers++; nbAnswers++;
} }
} }
@ -2429,7 +2470,7 @@ void cbClientWho( NLNET::CMessage& msgin, const std::string &serviceName, NLNET:
} }
// GM who // GM who
else if ( NLMISC::nlstricmp( opt.c_str() , "GM" ) == 0) else if ( NLMISC::nlstricmp( opt.c_str(), "GM" ) == 0)
{ {
TVectorParamCheck params(1); TVectorParamCheck params(1);
params[0].Type = STRING_MANAGER::player; 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 ) if ( nbAnswers == 0 )
{ {
@ -3508,9 +3618,9 @@ TUnifiedCallbackItem CbClientArray[]=
{ "CLIENT:DUEL:REFUSE", cbClientDuelRefuse }, { "CLIENT:DUEL:REFUSE", cbClientDuelRefuse },
{ "CLIENT:DUEL:ABANDON", cbClientDuelAbandon }, { "CLIENT:DUEL:ABANDON", cbClientDuelAbandon },
{ "CLIENT:PVP_CHALLENGE:ASK", cbClientPVPChallengeAsked }, { "CLIENT:PVP_CHALLENGE:ASK", cbClientLeagueJoinProposal },
{ "CLIENT:PVP_CHALLENGE:ACCEPT", cbClientPVPChallengeAccept }, { "CLIENT:PVP_CHALLENGE:ACCEPT", cbClientLeagueJoin },
{ "CLIENT:PVP_CHALLENGE:REFUSE", cbClientPVPChallengeRefuse }, { "CLIENT:PVP_CHALLENGE:REFUSE", cbClientLeagueJoinProposalDecline },
{ "CLIENT:PVP_CHALLENGE:ABANDON", cbClientPVPChallengeAbandon }, { "CLIENT:PVP_CHALLENGE:ABANDON", cbClientPVPChallengeAbandon },
// { "CLIENT:PVP_VERSUS:CLAN", cbClientPvpChooseClan }, // { "CLIENT:PVP_VERSUS:CLAN", cbClientPvpChooseClan },

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

@ -496,6 +496,8 @@ public:
const std::string &getWebPage() const {return _WebPage;} const std::string &getWebPage() const {return _WebPage;}
const std::string &getWebPageName() const {return _WebPageName;} const std::string &getWebPageName() const {return _WebPageName;}
const uint32 getOrganization() const { return _Organization; }
const NLMISC::CSheetId &getBotChatOutpost() const {return _BotChatOutpost;} const NLMISC::CSheetId &getBotChatOutpost() const {return _BotChatOutpost;}
const std::vector<NLMISC::CSheetId> &getExplicitActionTradeList() const {return _ExplicitActionTradeList;} 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 NLMISC::CSmartPtr<CMerchant> _Merchant; // smart pointer on CMerchant class of creature
uint32 _BotChatProgram; // Program enabled for bot chat 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 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 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() // 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 // Constructor
// //

@ -71,6 +71,15 @@ public:
virtual void callback (const std::string &name, NLNET::TServiceId id); 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 * 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; typedef CHashMap< NLMISC::CEntityId, CCreature *, NLMISC::CEntityIdHashMapTraits> TMapCreatures;
/** /**

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

@ -8855,7 +8855,7 @@ inline void _getProp(const CCDBSynchronised &db, ICDBStructNode *node, NLMISC::C
ICDBStructNode *_POS; ICDBStructNode *_POS;
ICDBStructNode *_HUNGER; ICDBStructNode *_HUNGER;
ICDBStructNode *_DESPAWN; ICDBStructNode *_DESPAWN;
ICDBStructNode *_NAME;
public: public:
void init(ICDBStructNode *parent, uint index); void init(ICDBStructNode *parent, uint index);
@ -9044,7 +9044,24 @@ inline void _getProp(const CCDBSynchronised &db, ICDBStructNode *node, NLMISC::C
{ {
return _DESPAWN; 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; 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) void CDynChatEGS::iosSetHistoricSize(TChanID chan, uint32 size)

@ -76,6 +76,9 @@ public:
bool setWriteRight(TChanID chan, const TDataSetRow &client, bool writeRight); bool setWriteRight(TChanID chan, const TDataSetRow &client, bool writeRight);
// Set size of historic for a given channel // Set size of historic for a given channel
void setHistoricSize(TChanID chan, uint32 size); 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 // Resend all channel / sessions to the IOS
void iosConnection(); void iosConnection();
// Get all channel names (for read only) // Get all channel names (for read only)
@ -83,6 +86,7 @@ public:
const TChanIDToName &getChanIDToNameMap() const { return _ChanNames.getAToBMap(); } const TChanIDToName &getChanIDToNameMap() const { return _ChanNames.getAToBMap(); }
// Get pointer on all channels // Get pointer on all channels
void getChans(std::vector<CDynChatChan *> &channels) { _DynChat.getChans(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 /// 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); 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 (CReportAIInstanceDespawnMsgImp);
TRANSPORT_CLASS_REGISTER (CWarnBadInstanceMsg); TRANSPORT_CLASS_REGISTER (CWarnBadInstanceMsg);
TRANSPORT_CLASS_REGISTER (CCreatureCompleteHealImp); TRANSPORT_CLASS_REGISTER (CCreatureCompleteHealImp);
TRANSPORT_CLASS_REGISTER (CChangeCreatureMaxHPImp);
TRANSPORT_CLASS_REGISTER (CChangeCreatureHPImp); TRANSPORT_CLASS_REGISTER (CChangeCreatureHPImp);
TRANSPORT_CLASS_REGISTER (CCreatureSetUrlImp);
TRANSPORT_CLASS_REGISTER (CChangeCreatureModeMsg); TRANSPORT_CLASS_REGISTER (CChangeCreatureModeMsg);
TRANSPORT_CLASS_REGISTER (CGiveItemRequestMsgImp); TRANSPORT_CLASS_REGISTER (CGiveItemRequestMsgImp);
TRANSPORT_CLASS_REGISTER (CReceiveItemRequestMsgImp); TRANSPORT_CLASS_REGISTER (CReceiveItemRequestMsgImp);

@ -446,6 +446,8 @@ void cbClientReady( CMessage& msgin, const std::string &serviceName, NLNET::TSer
c->initAnimalHungerDb(); c->initAnimalHungerDb();
c->initFactionPointDb(); c->initFactionPointDb();
c->initPvpPointDb();
c->initOrganizationInfos();
c->updateOutpostAdminFlagInDB(); c->updateOutpostAdminFlagInDB();
@ -516,17 +518,6 @@ void cbClientReady( CMessage& msgin, const std::string &serviceName, NLNET::TSer
// ask backup for offline commands file // ask backup for offline commands file
COfflineCharacterCommand::getInstance()->characterOnline( characterId ); 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(); c->onConnection();
} // cbClientReady // } // cbClientReady //
@ -680,6 +671,9 @@ void finalizeClientReady( uint32 userId, uint32 index )
CPVPManager2::getInstance()->setPVPModeInMirror( c ); CPVPManager2::getInstance()->setPVPModeInMirror( c );
c->updatePVPClanVP(); 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 // for GM player, trigger a 'infos' command to remember their persistent state
if (!PlayerManager.getPlayer(uint32(c->getId().getShortId())>>4)->getUserPriv().empty()) 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); 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 // } // 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 // 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 // kick your target from your team
void cbKickTeammate( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId); 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 // toogle god mode on / off for testing
//void cbGodMode( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId); //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; // SlotCount = slotCount;
_Recommended = recommended; _Recommended = recommended;
_TotalSaleCycle = 0; _TotalSaleCycle = 0;
_PetIndex = MAX_INVENTORY_ANIMAL;
_Form = CSheets::getForm( sheetId ); _Form = CSheets::getForm( sheetId );
if (_Form) if (_Form)
@ -1146,6 +1147,14 @@ uint32 CGameItem::getNonLockedStackSize()
return _StackSize - _LockCount; return _StackSize - _LockCount;
} }
void CGameItem::setLockedByOwner(bool value)
{
if (value != _LockedByOwner)
{
_LockedByOwner = value;
callItemChanged(INVENTORIES::TItemChangeFlags(INVENTORIES::itc_lock_state));
}
}
//----------------------------------------------- //-----------------------------------------------
// getCopy : // getCopy :
@ -1362,6 +1371,8 @@ void CGameItem::clear()
_RequiredCharacLevel = 0; _RequiredCharacLevel = 0;
_HasPrerequisit= false; _HasPrerequisit= false;
_LockedByOwner = false;
_TypeSkillMods.clear(); _TypeSkillMods.clear();
_PhraseId.clear(); _PhraseId.clear();
_CustomText.clear(); _CustomText.clear();

@ -679,6 +679,9 @@ public :
/// set required skill level /// set required skill level
inline void setRequiredSkillLevel2( uint16 l ) { _RequiredSkillLevel2 = l; } inline void setRequiredSkillLevel2( uint16 l ) { _RequiredSkillLevel2 = l; }
bool getLockedByOwner() const { return _LockedByOwner; }
void setLockedByOwner(bool value);
/// get required stat /// get required stat
inline CHARACTERISTICS::TCharacteristics getRequiredCharac() const { return _RequiredCharac; } inline CHARACTERISTICS::TCharacteristics getRequiredCharac() const { return _RequiredCharac; }
/// set required stat /// set required stat
@ -702,9 +705,16 @@ public :
const CItemCraftParameters * getCraftParameters() const { return _CraftParameters; } const CItemCraftParameters * getCraftParameters() const { return _CraftParameters; }
/// get custom string (for scroll-like items) /// 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) /// 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: protected:
friend class CFaberPhrase; friend class CFaberPhrase;
@ -947,6 +957,9 @@ private:
std::vector<CTypeSkillMod> _TypeSkillMods; std::vector<CTypeSkillMod> _TypeSkillMods;
ucstring _CustomText; 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)) if (_InterlocutorView != NULL && (!form->DropOrSell && form->Family != ITEMFAMILY::PET_ANIMAL_TICKET))
return false; return false;
// Can't trade items locked by owner
if (item->getLockedByOwner())
return false;
if( getCharacter()->isAnActiveXpCatalyser(item) ) if( getCharacter()->isAnActiveXpCatalyser(item) )
return false; return false;

@ -1066,6 +1066,12 @@ void CCharacterInvView::updateClientSlot(uint32 slot, const CGameItemPtr item)
getCharacter()->queryItemPrice( item, price ); getCharacter()->queryItemPrice( item, price );
itemBestStat = item->getCraftParameters() == 0 ? RM_FABER_STAT_TYPE::Unknown : item->getCraftParameters()->getBestItemStat(); 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 ); INVENTORIES::CItemSlot itemSlot( slot );
itemSlot.setItemProp( INVENTORIES::Sheet, item->getSheetId().asInt() ); itemSlot.setItemProp( INVENTORIES::Sheet, item->getSheetId().asInt() );
itemSlot.setItemProp( INVENTORIES::Quality, item->quality() ); 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::NameId, item->sendNameId(getCharacter()) );
itemSlot.setItemProp( INVENTORIES::Enchant, item->getClientEnchantValue() ); itemSlot.setItemProp( INVENTORIES::Enchant, item->getClientEnchantValue() );
itemSlot.setItemProp( INVENTORIES::Price, price ); 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::ItemClass, item->getItemClass() );
itemSlot.setItemProp( INVENTORIES::ItemBestStat, itemBestStat ); itemSlot.setItemProp( INVENTORIES::ItemBestStat, itemBestStat );
itemSlot.setItemProp( INVENTORIES::PrerequisitValid, getCharacter()->checkPreRequired( item ) ); itemSlot.setItemProp( INVENTORIES::PrerequisitValid, getCharacter()->checkPreRequired( item ) );

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

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

@ -230,7 +230,6 @@ void cbClientGroupAbandonMission( NLNET::CMessage& msgin, const std::string &ser
if (index < MaxGroupMissionCount) if (index < MaxGroupMissionCount)
{ {
// Team // Team
CTeam * team = TeamManager.getRealTeam( user->getTeamId() ); CTeam * team = TeamManager.getRealTeam( user->getTeamId() );
if ( !team ) if ( !team )
{ {
@ -249,11 +248,10 @@ void cbClientGroupAbandonMission( NLNET::CMessage& msgin, const std::string &ser
userId.toString().c_str(), index, team->getMissions().size()); userId.toString().c_str(), index, team->getMissions().size());
return; return;
} }
CMissionTeam* mission = team->getMissions()[index]; CMissionTeam* mission = team->getMissions()[index];
nlassert(mission); nlassert(mission);
if ( mission->getFinished() == false ) if ( mission->getFinished() == false )
{ {
CMissionTemplate * templ = CMissionManager::getInstance()->getTemplate( mission->getTemplateId() ); CMissionTemplate * templ = CMissionManager::getInstance()->getTemplate( mission->getTemplateId() );
@ -271,7 +269,7 @@ void cbClientGroupAbandonMission( NLNET::CMessage& msgin, const std::string &ser
} }
set<CEntityId> excluded; set<CEntityId> excluded;
excluded.insert( userId ); excluded.insert( userId );
team->sendDynamicMessageToMembers( "ABANDON_GROUP_MISSION",TVectorParamCheck(), excluded ); team->sendDynamicMessageToMembers( "ABANDON_GROUP_MISSION",TVectorParamCheck(), excluded );
} }
team->removeMission( index, mr_abandon ); team->removeMission( index, mr_abandon );
@ -301,7 +299,6 @@ void cbClientGroupAbandonMission( NLNET::CMessage& msgin, const std::string &ser
return; return;
} }
CMissionGuild* mission = guild->getMissions()[index]; CMissionGuild* mission = guild->getMissions()[index];
nlassert(mission); nlassert(mission);

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

@ -48,6 +48,7 @@ class CMissionStepKillFauna : public IMissionStepTemplate
{ {
struct CSubStep struct CSubStep
{ {
string Dynamic;
CSheetId Sheet; CSheetId Sheet;
uint16 Quantity; uint16 Quantity;
}; };
@ -56,7 +57,7 @@ class CMissionStepKillFauna : public IMissionStepTemplate
_SourceLine = line; _SourceLine = line;
_Place = 0xFFFF; _Place = 0xFFFF;
bool ret = true; bool ret = true;
if ( script.size() < 2 || script.size() > 3) if (script.size() < 2 || script.size() > 3)
{ {
MISLOGSYNTAXERROR("<creature> <quantity> *[; <creature> <quantity>] [: <place>]"); MISLOGSYNTAXERROR("<creature> <quantity> *[; <creature> <quantity>] [: <place>]");
return false; return false;
@ -68,22 +69,36 @@ class CMissionStepKillFauna : public IMissionStepTemplate
_SubSteps.reserve( subs.size() ); _SubSteps.reserve( subs.size() );
for ( uint i = 0; i < subs.size(); i++ ) for ( uint i = 0; i < subs.size(); i++ )
{ {
CSubStep subStep;
std::vector< std::string > args; std::vector< std::string > args;
CMissionParser::tokenizeString( subs[i]," \t", args ); CMissionParser::tokenizeString( subs[i]," \t", args );
if ( args.size() != 2 )
//// Dynamic Mission Args : #dynamic# <quantity>
if ((args.size() == 2) && (args[0] == "#dynamic#"))
{ {
MISLOGSYNTAXERROR("<creature> <quantity> *[; <creature> <quantity>] [: <place>]"); subStep.Dynamic = missionData.Name;
return false; subStep.Quantity = atoi(args[1].c_str());
} }
missionData.ChatParams.push_back( make_pair(args[0],STRING_MANAGER::creature_model) ); ////
CSubStep subStep; else
subStep.Sheet = CSheetId( args[0] + ".creature");
if ( subStep.Sheet == CSheetId::Unknown )
{ {
ret = false; if ( args.size() != 2 )
MISLOGERROR1("invalid sheet '%s'", args[0].c_str()); {
MISLOGSYNTAXERROR("<creature> <quantity> *[; <creature> <quantity>] [: <place>]");
return false;
}
missionData.ChatParams.push_back( make_pair(args[0],STRING_MANAGER::creature_model) );
subStep.Dynamic = "";
subStep.Sheet = CSheetId( args[0] + ".creature");
if ( subStep.Sheet == CSheetId::Unknown )
{
ret = false;
MISLOGERROR1("invalid sheet '%s'", args[0].c_str());
}
NLMISC::fromString(args[1], subStep.Quantity);
} }
NLMISC::fromString(args[1], subStep.Quantity);
_SubSteps.push_back(subStep); _SubSteps.push_back(subStep);
} }
if ( script.size() == 3 ) 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 ) 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 ) if ( event.Type == CMissionEvent::Kill )
{ {
CMissionEventKill & eventSpe = (CMissionEventKill&)event; CMissionEventKill & eventSpe = (CMissionEventKill&)event;
CCreature * c = CreatureManager.getCreature( event.TargetEntity ); 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 ) if ( !c )
{ {
LOGMISSIONSTEPERROR("kill_fauna : invalid creature " + toString(event.TargetEntity.getIndex())); LOGMISSIONSTEPERROR("kill_fauna : invalid creature " + toString(event.TargetEntity.getIndex()));
} }
else if ( _SubSteps[subStepIndex].Sheet == c->getType() ) else if ( faunaSheet == c->getType() )
{ {
if ( _Place != 0xFFFF ) if ( _Place != 0xFFFF )
{ {
@ -126,6 +180,8 @@ class CMissionStepKillFauna : public IMissionStepTemplate
if ( region && region->getId() == _Place ) if ( region && region->getId() == _Place )
{ {
if (!webAppUrl.empty())
_User->validateDynamicMissionStep(webAppUrl);
LOGMISSIONSTEPSUCCESS("kill_fauna"); LOGMISSIONSTEPSUCCESS("kill_fauna");
return 1; return 1;
} }
@ -134,6 +190,8 @@ class CMissionStepKillFauna : public IMissionStepTemplate
{ {
if ( places[i] && places[i]->getId() == _Place ) if ( places[i] && places[i]->getId() == _Place )
{ {
if (!webAppUrl.empty())
_User->validateDynamicMissionStep(webAppUrl);
LOGMISSIONSTEPSUCCESS("kill_fauna"); LOGMISSIONSTEPSUCCESS("kill_fauna");
return 1; return 1;
} }
@ -142,11 +200,14 @@ class CMissionStepKillFauna : public IMissionStepTemplate
} }
else else
{ {
if (!webAppUrl.empty())
_User->validateDynamicMissionStep(webAppUrl);
LOGMISSIONSTEPSUCCESS("kill_fauna"); LOGMISSIONSTEPSUCCESS("kill_fauna");
return 1; return 1;
} }
} }
} }
return 0; return 0;
} }
@ -162,41 +223,82 @@ class CMissionStepKillFauna : public IMissionStepTemplate
virtual void getTextParams( uint & nbSubSteps,const std::string* & textPtr,TVectorParamCheck& retParams, const std::vector<uint32>& subStepStates) 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 stepText = "MIS_KILL_FAUNA_";
static const std::string stepTextLoc = "MIS_KILL_FAUNA_LOC_"; static const std::string stepTextLoc = "MIS_KILL_FAUNA_LOC_";
nlassert( _SubSteps.size() == subStepStates.size() ); nlassert( _SubSteps.size() == subStepStates.size() );
CSheetId faunaSheet;
for ( uint i = 0; i < subStepStates.size(); i++ ) for ( uint i = 0; i < subStepStates.size(); i++ )
{ {
if( subStepStates[i] != 0 ) if( subStepStates[i] != 0 )
{ {
nbSubSteps++; if (_SubSteps[i].Dynamic.empty())
retParams.push_back(STRING_MANAGER::TParam()); {
retParams.back().Type = STRING_MANAGER::creature_model; faunaSheet = _SubSteps[i].Sheet;
retParams.back().SheetId = _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();
}
////
}
retParams.push_back(STRING_MANAGER::TParam()); nbSubSteps++;
retParams.back().Type = STRING_MANAGER::integer; if (faunaSheet != CSheetId::Unknown)
retParams.back().Int = subStepStates[i]; {
retParams.push_back(STRING_MANAGER::TParam());
retParams.back().Type = STRING_MANAGER::creature_model;
retParams.back().SheetId = faunaSheet;
retParams.push_back(STRING_MANAGER::TParam());
retParams.back().Type = STRING_MANAGER::integer;
retParams.back().Int = subStepStates[i];
}
} }
} }
if ( _Place != 0xFFFF ) if (faunaSheet != CSheetId::Unknown)
{ {
STRING_MANAGER::TParam param; if ( _Place != 0xFFFF )
param.Type = STRING_MANAGER::place;
CPlace * place = CZoneManager::getInstance().getPlaceFromId(_Place);
if ( !place )
{ {
MISLOG("sline:%u ERROR : kill_fauna : Invalid place %u", _SourceLine, _Place); STRING_MANAGER::TParam param;
param.Type = STRING_MANAGER::place;
CPlace * place = CZoneManager::getInstance().getPlaceFromId(_Place);
if ( !place )
{
MISLOG("sline:%u ERROR : kill_fauna : Invalid place %u", _SourceLine, _Place);
}
else
{
param.Identifier = place->getName();
retParams.push_back(param);
}
textPtr = &stepTextLoc;
} }
else else
{ textPtr = &stepText;
param.Identifier = place->getName();
retParams.push_back(param);
}
textPtr = &stepTextLoc;
} }
else else
textPtr = &stepText; textPtr = &stepTextReact;
} }
std::vector< CSubStep > _SubSteps; std::vector< CSubStep > _SubSteps;
@ -329,6 +431,7 @@ class CMissionStepKillRace : public IMissionStepTemplate
virtual void getTextParams( uint & nbSubSteps, const std::string* & textPtr,TVectorParamCheck& retParams, const std::vector<uint32>& subStepStates) 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 stepText = "MIS_KILL_RACE_";
static const std::string stepTextLoc = "MIS_KILL_RACE_LOC_"; static const std::string stepTextLoc = "MIS_KILL_RACE_LOC_";
@ -380,6 +483,7 @@ class CMissionStepKillNpc : public IMissionStepTemplate
{ {
struct CSubStep struct CSubStep
{ {
string Dynamic;
TAIAlias Alias; TAIAlias Alias;
// NLMISC::TStringId NpcName; // NLMISC::TStringId NpcName;
}; };
@ -400,9 +504,17 @@ class CMissionStepKillNpc : public IMissionStepTemplate
for ( uint i = 0; i < subs.size(); i++ ) for ( uint i = 0; i < subs.size(); i++ )
{ {
CSubStep subStep; CSubStep subStep;
subStep.Alias = CAIAliasTranslator::Invalid; //// Dynamic Mission Args : #dynamic#
if ( !CMissionParser::parseBotName(subs[i],subStep.Alias,missionData) ) if (trim(subs[i]) == "#dynamic#") {
ret = false; subStep.Dynamic = missionData.Name;
}
////
else
{
subStep.Alias = CAIAliasTranslator::Invalid;
if ( !CMissionParser::parseBotName(subs[i],subStep.Alias,missionData) )
ret = false;
}
_SubSteps.push_back( subStep ); _SubSteps.push_back( subStep );
} }
return ret; return ret;
@ -410,6 +522,9 @@ class CMissionStepKillNpc : public IMissionStepTemplate
} }
uint processEvent( const TDataSetRow & userRow, const CMissionEvent & event,uint subStepIndex,const TDataSetRow & giverRow ) 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 ) if ( event.Type == CMissionEvent::Kill )
{ {
CMissionEventKill & eventSpe = (CMissionEventKill&)event; CMissionEventKill & eventSpe = (CMissionEventKill&)event;
@ -420,18 +535,44 @@ class CMissionStepKillNpc : public IMissionStepTemplate
} }
else else
{ {
if ( _SubSteps[subStepIndex].Alias != CAIAliasTranslator::Invalid ) if (_SubSteps[subStepIndex].Dynamic.empty())
{ {
if ( _SubSteps[subStepIndex].Alias == c->getAlias() ) if ( _SubSteps[subStepIndex].Alias != CAIAliasTranslator::Invalid )
{
if ( _SubSteps[subStepIndex].Alias == c->getAlias() )
{
LOGMISSIONSTEPSUCCESS("kill_npc");
return 1;
}
}
else if ( event.TargetEntity == giverRow )
{ {
LOGMISSIONSTEPSUCCESS("kill_npc"); LOGMISSIONSTEPSUCCESS("kill_npc");
return 1; return 1;
} }
} }
else if ( event.TargetEntity == giverRow ) else
{ {
LOGMISSIONSTEPSUCCESS("kill_npc"); //// Dynamic Mission Args
return 1; 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;
}
}
////
} }
} }
} }
@ -450,6 +591,7 @@ class CMissionStepKillNpc : public IMissionStepTemplate
virtual void getTextParams( uint & nbSubSteps, const std::string* & textPtr,TVectorParamCheck& retParams, const std::vector<uint32>& subStepStates) 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_"; static const std::string stepText = "MIS_KILL_NPC_";
textPtr = &stepText; textPtr = &stepText;
nlassert( _SubSteps.size() == subStepStates.size() ); nlassert( _SubSteps.size() == subStepStates.size() );
@ -460,10 +602,34 @@ class CMissionStepKillNpc : public IMissionStepTemplate
nbSubSteps++; nbSubSteps++;
retParams.push_back(STRING_MANAGER::TParam()); retParams.push_back(STRING_MANAGER::TParam());
retParams.back().Type = STRING_MANAGER::bot; retParams.back().Type = STRING_MANAGER::bot;
if ( _SubSteps[i].Alias != CAIAliasTranslator::Invalid ) if (_SubSteps[i].Dynamic.empty())
retParams.back().Int = _SubSteps[i].Alias; {
if ( _SubSteps[i].Alias != CAIAliasTranslator::Invalid )
retParams.back().Int = _SubSteps[i].Alias;
else
retParams.back().Identifier = "giver";
}
else else
retParams.back().Identifier = "giver"; {
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"); MISSION_REGISTER_STEP(CMissionStepKillByName,"kill_npc_by_name");
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
class CMissionStepKillPlayer : public IMissionStepTemplate class CMissionStepKillPlayer : public IMissionStepTemplate
{ {

@ -22,6 +22,7 @@
#include "mission_manager/mission_parser.h" #include "mission_manager/mission_parser.h"
#include "mission_manager/ai_alias_translator.h" #include "mission_manager/ai_alias_translator.h"
#include "player_manager/character.h" #include "player_manager/character.h"
#include "player_manager/player_manager.h"
#include "creature_manager/creature_manager.h" #include "creature_manager/creature_manager.h"
#include "mission_manager/mission_manager.h" #include "mission_manager/mission_manager.h"
#include "game_item_manager/player_inv_xchg.h" #include "game_item_manager/player_inv_xchg.h"
@ -49,43 +50,55 @@ class CMissionStepTalk : public IMissionStepTemplate
bool buildStep( uint32 line, const std::vector< std::string > & script, CMissionGlobalParsingData & globalData, CMissionSpecificParsingData & missionData ) bool buildStep( uint32 line, const std::vector< std::string > & script, CMissionGlobalParsingData & globalData, CMissionSpecificParsingData & missionData )
{ {
_SourceLine = line; _SourceLine = line;
if ( script.size() < 3 ) if ( script.size() < 2 )
{ {
MISLOGSYNTAXERROR("<npc_name> [: <phrase_id>*[;<param>]]"); MISLOGSYNTAXERROR("<npc_name> [: <phrase_id>*[;<param>]]");
return false; return false;
} }
bool ret = true; bool ret = true;
// parse bot //// Dynamic Mission Args : #dynamic#
if ( !CMissionParser::parseBotName(script[1], _Bot, missionData) ) if (trim(script[1]) == "#dynamic#")
{ {
MISLOGERROR1("invalid npc '%s'", script[1].c_str()); _Dynamic = missionData.Name;
return false; _PhraseId = _Dynamic+"_ACTION";
_IsDynamic = true;
} }
// parse phrase and params else
if (script.size() > 2)
{ {
// parse a specific phrase _IsDynamic = false;
if (!CMissionParser::parseParamText(line, script[2], _PhraseId, _Params )) // parse bot
if ( !CMissionParser::parseBotName(script[1], _Bot, missionData) )
{ {
MISLOGERROR1("invalid text '%s'", script[2].c_str()); MISLOGERROR1("invalid npc '%s'", script[1].c_str());
return false; return false;
} }
}
else
{
// use the default phrase
_PhraseId = "MIS_TALK_TO_MENU";
}
// add a first default param (the name of the bot we talk to) // parse phrase and params
_Params.insert(_Params.begin(), STRING_MANAGER::TParam()); if (script.size() > 2)
_Params[0].Identifier = CMissionParser::getNoBlankString(script[1]); {
// parse a specific phrase
if (!CMissionParser::parseParamText(line, script[2], _PhraseId, _Params ))
{
MISLOGERROR1("invalid text '%s'", script[2].c_str());
return false;
}
}
else
{
// use the default phrase
_PhraseId = "MIS_TALK_TO_MENU";
}
// 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; return true;
} }
uint processEvent( const TDataSetRow & userRow, const CMissionEvent & event,uint subStepIndex,const TDataSetRow & giverRow ) 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 // not check here : they are done befor. If a talk event comes here, the step is complete
if( event.Type == CMissionEvent::Talk ) if( event.Type == CMissionEvent::Talk )
{ {
@ -102,9 +115,50 @@ class CMissionStepTalk : public IMissionStepTemplate
ret[0] = 1; 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 ) 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 ); CCreature * bot = CreatureManager.getCreature( interlocutor );
if ( bot ) if ( bot )
{ {
if ( ( _Bot != CAIAliasTranslator::Invalid && _Bot == bot->getAlias() ) || 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) 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 ); CCreature * bot = CreatureManager.getCreature( interlocutor );
if ( bot ) 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) 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; nbSubSteps = 1;
static const std::string stepText = "MIS_TALK_TO"; static const std::string stepText = "MIS_TALK_TO";
textPtr = &stepText; textPtr = &stepText;
@ -151,16 +232,23 @@ class CMissionStepTalk : public IMissionStepTemplate
else else
retParams[0].Identifier = "giver"; retParams[0].Identifier = "giver";
} }
bool solveTextsParams( CMissionSpecificParsingData & missionData,CMissionTemplate * templ ) bool solveTextsParams( CMissionSpecificParsingData & missionData,CMissionTemplate * templ )
{ {
bool ret = IMissionStepTemplate::solveTextsParams(missionData,templ); if (!_IsDynamic)
if ( !CMissionParser::solveTextsParams(_SourceLine, _Params,missionData ) ) {
ret = false; bool ret = IMissionStepTemplate::solveTextsParams(missionData,templ);
return ret; if ( !CMissionParser::solveTextsParams(_SourceLine, _Params,missionData ) )
ret = false;
return ret;
}
return true;
} }
virtual TAIAlias getInvolvedBot(bool& invalidIsGiver) const { invalidIsGiver=true; return _Bot; } virtual TAIAlias getInvolvedBot(bool& invalidIsGiver) const { invalidIsGiver=true; return _Bot; }
bool _IsDynamic;
std::string _Dynamic;
std::string _PhraseId; std::string _PhraseId;
TVectorParamCheck _Params; TVectorParamCheck _Params;
TAIAlias _Bot; TAIAlias _Bot;

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

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

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

@ -1096,10 +1096,22 @@ public:
// this is a special user, store it in the appropriate container // this is a special user, store it in the appropriate container
_OnlineSpecialEntities[cci.getPrivilege()].insert(charEid); _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 else
{ {
nldebug(" Char %s has disconnected", charEid.toString().c_str()); 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 // this character disconnected
_OnlineEntities.erase(charEid); _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> 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> 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<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; extern CPlayerManager PlayerManager;
@ -1463,50 +1463,55 @@ PVP_RELATION::TPVPRelation COutpost::getPVPRelation( CCharacter * user, CEntityB
if( IsRingShard ) if( IsRingShard )
return PVP_RELATION::Neutral; return PVP_RELATION::Neutral;
bool targetSafe = false;
bool actorSafe = false;
if( target->getOutpostAlias() == 0 ) if( target->getOutpostAlias() == 0 )
{ {
return PVP_RELATION::Neutral; return PVP_RELATION::Neutral;
} }
else
CCharacter * pTarget = dynamic_cast<CCharacter*>(target);
if (pTarget == 0)
return PVP_RELATION::Unknown;
if (CPVPManager2::getInstance()->inSafeZone(pTarget->getPosition()))
{ {
CCharacter * pTarget = dynamic_cast<CCharacter*>(target); if (pTarget->getSafeInPvPSafeZone())
if(pTarget) targetSafe = true;
{ }
if( CPVPManager2::getInstance()->inSafeZone( pTarget->getPosition() ) )
{
if( pTarget->getSafeInPvPSafeZone() )
{
return PVP_RELATION::NeutralPVP;
}
}
}
if( CPVPManager2::getInstance()->inSafeZone( user->getPosition() ) )
{
if( user->getSafeInPvPSafeZone() )
{
return PVP_RELATION::NeutralPVP;
}
}
if( user->getOutpostAlias() != target->getOutpostAlias() ) if( CPVPManager2::getInstance()->inSafeZone(user->getPosition()))
{ {
return PVP_RELATION::NeutralPVP; if( user->getSafeInPvPSafeZone())
} actorSafe = true;
else }
// One is safe but not other => NeutralPVP
if ((targetSafe && !actorSafe) || (actorSafe && !targetSafe)) {
return PVP_RELATION::NeutralPVP;
}
if( user->getOutpostAlias() == target->getOutpostAlias() )
{
if( user->getOutpostSide() != target->getOutpostSide() )
{ {
if( user->getOutpostSide() != target->getOutpostSide() ) if (!targetSafe && !actorSafe)
{ {
CPVPManager2::getInstance()->setPVPOutpostEnemyReminder( true ); CPVPManager2::getInstance()->setPVPOutpostEnemyReminder( true );
return PVP_RELATION::Ennemy; return PVP_RELATION::Ennemy;
} }
else }
{ else
CPVPManager2::getInstance()->setPVPOutpostAllyReminder( true ); {
return PVP_RELATION::Ally; CPVPManager2::getInstance()->setPVPOutpostAllyReminder( true );
} return PVP_RELATION::Ally;
} }
} }
return PVP_RELATION::NeutralPVP;
} // getPVPRelation // } // getPVPRelation //
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------

@ -1528,21 +1528,21 @@ bool testOffensiveActionAllowed( const NLMISC::CEntityId &actorId, const NLMISC:
return false; return false;
} }
// test target isn't invulnerable // AI
if (target->getContextualProperty().directAccessForStructMembers().invulnerable()) if (actorId.getType() != RYZOMID::player)
{ {
// check target Faction attackable flags // test target isn't invulnerable
CCreature *creature = dynamic_cast<CCreature *> (target); if (target->getContextualProperty().directAccessForStructMembers().invulnerable())
if (!creature || !creature->checkFactionAttackable(actorId))
{ {
errorCode = "BS_TARGET_NOT_ATTACKABLE"; // check target Faction attackable flags
return false; CCreature *creature = dynamic_cast<CCreature *> (target);
if (!creature || !creature->checkFactionAttackable(actorId))
{
errorCode = "BS_TARGET_NOT_ATTACKABLE";
return false;
}
} }
}
// AI
if (actorId.getType() != RYZOMID::player)
{
if (mainTarget == true) if (mainTarget == true)
return true; return true;
else 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> 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<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> 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 // Number of login stats kept for a character
@ -411,6 +411,8 @@ CCharacter::CCharacter(): CEntityBase(false),
// pvp for player with privilege inactive // pvp for player with privilege inactive
_PriviledgePvp = false; _PriviledgePvp = false;
// full pvp
_FullPvp = false;
// aggroable undefined // aggroable undefined
_Aggroable = true; _Aggroable = true;
_AggroableOverride = -1; _AggroableOverride = -1;
@ -421,12 +423,17 @@ CCharacter::CCharacter(): CEntityBase(false),
for (uint i = 0 ; i < (PVP_CLAN::EndClans-PVP_CLAN::BeginClans+1); ++i) for (uint i = 0 ; i < (PVP_CLAN::EndClans-PVP_CLAN::BeginClans+1); ++i)
_FactionPoint[i] = 0; _FactionPoint[i] = 0;
_PvpPoint = 0;
_PVPFlagLastTimeChange = 0; _PVPFlagLastTimeChange = 0;
_PVPFlagTimeSettedOn = 0; _PVPFlagTimeSettedOn = 0;
_PvPDatabaseCounter = 0; _PvPDatabaseCounter = 0;
_PVPFlag = false; _PVPFlag = false;
_PVPRecentActionTime = 0; _PVPRecentActionTime = 0;
_Organization = 0;
_OrganizationStatus = 0;
_OrganizationPoints = 0;
// do not start berserk // do not start berserk
_IsBerserk = false; _IsBerserk = false;
@ -493,6 +500,9 @@ CCharacter::CCharacter(): CEntityBase(false),
///init teamId ///init teamId
_TeamId= CTEAM::InvalidTeamId; _TeamId= CTEAM::InvalidTeamId;
///init LeagueId
_LeagueId = TChanID::Unknown;
// init combat flags // init combat flags
_CombatEventFlagTicks.resize(32); _CombatEventFlagTicks.resize(32);
for( uint i=0; i<32; ++i ) for( uint i=0; i<32; ++i )
@ -641,6 +651,10 @@ CCharacter::CCharacter(): CEntityBase(false),
_CurrentSessionId = _SessionId; _CurrentSessionId = _SessionId;
_PvPSafeZoneActive = false; _PvPSafeZoneActive = false;
_PVPSafeLastTimeChange = CTickEventHandler::getGameCycle();
_PVPSafeLastTime = false;
_PVPInSafeZoneLastTime = false;
// For client/server contact list communication // For client/server contact list communication
_ContactIdPool= 0; _ContactIdPool= 0;
@ -653,6 +667,10 @@ CCharacter::CCharacter(): CEntityBase(false),
_LastTickNpcControlUpdated = CTickEventHandler::getGameCycle(); _LastTickNpcControlUpdated = CTickEventHandler::getGameCycle();
_LastWebCommandIndex = 0;
_CustomMissionsParams.clear();
initDatabase(); initDatabase();
} // CCharacter // } // CCharacter //
@ -773,55 +791,20 @@ void CCharacter::initPDStructs()
void CCharacter::updatePVPClanVP() const void CCharacter::updatePVPClanVP() const
{ {
TYPE_PVP_CLAN propPvpClanTemp = 0; TYPE_PVP_CLAN propPvpClanTemp = 0;
uint32 maxFameCiv = 0;
uint8 civOfMaxFame = 255; if (_LeagueId != DYN_CHAT_INVALID_CHAN)
uint32 maxFameCult = 0; propPvpClanTemp = 1+(uint32)(_LeagueId.getShortId());
uint8 cultOfMaxFame = 255; else
propPvpClanTemp = 0;
for (uint8 fameIdx = 0; fameIdx < 7; fameIdx++) CMirrorPropValue<TYPE_PVP_CLAN> propPvpClan( TheDataset, TheDataset.getDataSetRow(_Id), DSPropertyPVP_CLAN );
if (propPvpClan.getValue() != propPvpClanTemp)
{ {
sint32 fame = CFameInterface::getInstance().getFameIndexed(_Id, fameIdx); propPvpClan = propPvpClanTemp;
if (fameIdx < 4) propPvpClan.setChanged();
{
if ((uint32)abs(fame) >= maxFameCiv)
{
civOfMaxFame = fameIdx;
maxFameCiv = abs(fame);
}
}
else
{
if ((uint32)abs(fame) >= maxFameCult)
{
cultOfMaxFame = fameIdx - 4;
maxFameCult = abs(fame);
}
}
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())
{
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);
}
} }
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 CCharacter::getPVPFamesAllies()
{ {
TYPE_PVP_CLAN propPvpClanTemp = 0; TYPE_PVP_CLAN propPvpClanTemp = 0;
@ -843,7 +826,7 @@ TYPE_PVP_CLAN CCharacter::getPVPFamesEnemies()
return propPvpClanTemp | _PVPFlagEnemy; return propPvpClanTemp | _PVPFlagEnemy;
return propPvpClanTemp; return propPvpClanTemp;
} }
*/
//----------------------------------------------- //-----------------------------------------------
// addPropertiesToMirror : // addPropertiesToMirror :
@ -1464,6 +1447,29 @@ uint32 CCharacter::tickUpdate()
{ {
H_AUTO(CharacterUpdatePVPMode); 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 ) if( _HaveToUpdatePVPMode )
{ {
const TGameCycle waitTime = _PVPFlag ? TimeForSetPVPFlag.get() : TimeForPVPFlagOff.get(); const TGameCycle waitTime = _PVPFlag ? TimeForSetPVPFlag.get() : TimeForPVPFlagOff.get();
@ -2865,7 +2871,9 @@ void CCharacter::postLoadTreatment()
{ {
_PlayerPets[ i ].Slot = INVENTORIES::INVALID_INVENTORY_SLOT; _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 ) if( slot < INVENTORIES::NbPackerSlots )
{ {
tickets[ slot ] = true; 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 ); // _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 ); 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 ); // _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++; i++;
} }
} }
@ -4563,13 +4571,31 @@ bool CCharacter::fillFaberMaterialArray( vector<CFaberMsgItem>& materialsSelecte
lowerMaterialQuality = USHRT_MAX; lowerMaterialQuality = USHRT_MAX;
for( uint s = 0; s < materialsSelectedForFaber.size(); ++s ) for( uint s = 0; s < materialsSelectedForFaber.size(); ++s )
{ {
bool bOk = false;
CInventoryPtr pInv = NULL;
if( materialsSelectedForFaber[ s ].getInvId() >= INVENTORIES::NUM_INVENTORY ) if( materialsSelectedForFaber[ s ].getInvId() >= INVENTORIES::NUM_INVENTORY )
{ {
nlwarning("<CCharacter::fillFaberMaterialArray> CFaberMsgItem[%d] sended by client contains an invalid inventory index %d", s, materialsSelectedForFaber[ s ].getInvId() ); // Also allow crafting from player's room
return false; 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() ) 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() ); 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; _PlayerPets[ i ] = pet;
pet.ItemPtr->setPetIndex(i);
pet.Slot = ptr->getInventorySlot();
// init pet inventory // init pet inventory
const uint32 petMaxWeight = 0xFFFFFFFF; // no weight limit const uint32 petMaxWeight = 0xFFFFFFFF; // no weight limit
const uint32 petMaxBulk = _PlayerPets[ i ].getAnimalMaxBulk(); const uint32 petMaxBulk = _PlayerPets[ i ].getAnimalMaxBulk();
@ -5433,6 +5462,7 @@ bool CCharacter::spawnWaitingCharacterAnimalNear( uint index, const SGameCoordin
msg.CharacterMirrorRow = _EntityRowId; msg.CharacterMirrorRow = _EntityRowId;
msg.PetSheetId = _PlayerPets[ index ].PetSheetId; msg.PetSheetId = _PlayerPets[ index ].PetSheetId;
msg.PetIdx = index; msg.PetIdx = index;
msg.CustomName = _PlayerPets[ index ].CustomName;
msg.AIInstanceId = (uint16)destAIInstance; msg.AIInstanceId = (uint16)destAIInstance;
CWorldInstances::instance().msgToAIInstance( msg.AIInstanceId, msg); CWorldInstances::instance().msgToAIInstance( msg.AIInstanceId, msg);
// The row will be received in AnimalSpawned() // The row will be received in AnimalSpawned()
@ -5544,6 +5574,7 @@ bool CCharacter::spawnCharacterAnimal(uint index )
msg.CharacterMirrorRow = _EntityRowId; msg.CharacterMirrorRow = _EntityRowId;
msg.PetSheetId = _PlayerPets[ index ].PetSheetId; msg.PetSheetId = _PlayerPets[ index ].PetSheetId;
msg.PetIdx = index; msg.PetIdx = index;
msg.CustomName = _PlayerPets[ index ].CustomName;
CVector pos; CVector pos;
pos.x = msg.Coordinate_X * 0.001f; 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 // check whether this character is on a free trial account
bool bFreeTrialLimitReached = false;
CPlayer * p = PlayerManager.getPlayer(PlayerManager.getPlayerId( getId() )); CPlayer * p = PlayerManager.getPlayer(PlayerManager.getPlayerId( getId() ));
BOMB_IF(p == NULL,"Failed to find player record for character: "<<getId().toString(),return 0.0); BOMB_IF(p == NULL,"Failed to find player record for character: "<<getId().toString(),return 0.0);
if (p->isTrialPlayer()) if (p->isTrialPlayer())
@ -6853,7 +6917,7 @@ double CCharacter::addXpToSkillInternal( double XpGain, const std::string& ContS
SM_STATIC_PARAMS_1(params, STRING_MANAGER::skill); SM_STATIC_PARAMS_1(params, STRING_MANAGER::skill);
params[0].Enum = skillEnum; params[0].Enum = skillEnum;
PHRASE_UTILITIES::sendDynamicSystemMessage(getEntityRowId(), "PROGRESS_FREE_TRIAL_LIMIT", params); 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 // update death penalty
_DeathPenalties->addXP( *this, skillEnum, XpGain); _DeathPenalties->addXP( *this, skillEnum, XpGain);
if (bFreeTrialLimitReached)
{
return 0.0;
}
// if no remaining XPGain, return // if no remaining XPGain, return
if (XpGain == 0.0f) if (XpGain == 0.0f)
return 0.0; return 0.0;
@ -8800,7 +8869,7 @@ void CCharacter::setDatabase()
_IneffectiveAuras.activate(); _IneffectiveAuras.activate();
_ConsumableOverdoseEndDates.activate(); _ConsumableOverdoseEndDates.activate();
// init the RRPs // init the RRPs
RingRewardPoints.initDb(); //RingRewarsdPoints.initDb();
}// setDatabase // }// setDatabase //
@ -8862,7 +8931,7 @@ void CCharacter::startTradeItemSession( uint16 session )
nlwarning("fame %u is INVALID",(uint)bot->getRace() ); nlwarning("fame %u is INVALID",(uint)bot->getRace() );
fame = MinFameToTrade; fame = MinFameToTrade;
} }
else if ( fame < MinFameToTrade ) else if ( fame < MinFameToTrade && bot->getOrganization() != getOrganization() )
{ {
SM_STATIC_PARAMS_1(params, STRING_MANAGER::bot); SM_STATIC_PARAMS_1(params, STRING_MANAGER::bot);
params[0].setEIdAIAlias( _CurrentInterlocutor, CAIAliasTranslator::getInstance()->getAIAlias(_CurrentInterlocutor) ); params[0].setEIdAIAlias( _CurrentInterlocutor, CAIAliasTranslator::getInstance()->getAIAlias(_CurrentInterlocutor) );
@ -8961,14 +9030,13 @@ void CCharacter::startTradePhrases(uint16 session)
return; return;
} }
// *** Check the player has sufficient fame to Trade with Bot. // *** Check the player has sufficient fame to Trade with Bot.
sint32 fame = CFameInterface::getInstance().getFameIndexed( _Id, bot->getForm()->getFaction() ); sint32 fame = CFameInterface::getInstance().getFameIndexed( _Id, bot->getForm()->getFaction() );
if ( fame == NO_FAME ) if ( fame == NO_FAME )
{ {
nlwarning("fame %u is INVALID",(uint)bot->getRace() ); 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); SM_STATIC_PARAMS_1(params, STRING_MANAGER::bot);
params[0].setEIdAIAlias( _CurrentInterlocutor, CAIAliasTranslator::getInstance()->getAIAlias(_CurrentInterlocutor) ); 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() ); nlwarning("fame %u is INVALID",(uint)bot->getRace() );
fame = MinFameToTrade; fame = MinFameToTrade;
} }
else if ( fame < MinFameToTrade ) else if ( fame < MinFameToTrade && bot->getOrganization() != getOrganization() )
{ {
SM_STATIC_PARAMS_1(params, STRING_MANAGER::bot); SM_STATIC_PARAMS_1(params, STRING_MANAGER::bot);
params[0].setEIdAIAlias( _CurrentInterlocutor, CAIAliasTranslator::getInstance()->getAIAlias(_CurrentInterlocutor) ); 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) void CCharacter::sendFactionPointGainMessage(PVP_CLAN::TPVPClan clan, uint32 fpGain)
{ {
@ -10176,6 +10322,16 @@ void CCharacter::exchangeProposal()
return; 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 //set the target's exchange asker, and inform the target
c->_ExchangeAsker = _Id; 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 the mission is not for guild members we just instanciate it
if (!missionForGuild) if (!missionForGuild)
CMissionManager::getInstance()->instanciateMission(this, mission, giver ,eventList, mainMission); CMissionManager::getInstance()->instanciateMission(this, mission, giver, eventList, mainMission);
else else
{ {
// We find the guild and each guild members and we instanciate the mission for them // 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() ); nlwarning( "<MISSIONS>cant find user %s", it->first.toString().c_str() );
continue; 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); 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) void CCharacter::addWebCommandCheck(const string &url, const string &data, const string &salt)
{ {
uint webCommand = getWebCommandCheck(url); 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) uint CCharacter::getWebCommandCheck(const string &url)
{ {
CInventoryPtr inv = getInventory(INVENTORIES::bag); CInventoryPtr inv = getInventory(INVENTORIES::bag);
@ -13528,6 +13723,7 @@ uint CCharacter::getWebCommandCheck(const string &url)
return INVENTORIES::NbBagSlots; return INVENTORIES::NbBagSlots;
} }
// !!! Deprecated !!!
uint CCharacter::checkWebCommand(const string &url, const string &data, const string &hmac, const string &salt) uint CCharacter::checkWebCommand(const string &url, const string &data, const string &hmac, const string &salt)
{ {
if (salt.empty()) if (salt.empty())
@ -14650,7 +14846,7 @@ void CCharacter::addRoomAccessToPlayer(const NLMISC::CEntityId &id)
//-------------------------------------------------------------- //--------------------------------------------------------------
void CCharacter::addPlayerToFriendList(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 (id == CEntityId::Unknown || PlayerManager.getChar(id)==NULL)
{ {
if ( ! (IShardUnifierEvent::getInstance() && IShardUnifierEvent::getInstance()->isCharacterOnlineAbroad(id))) if ( ! (IShardUnifierEvent::getInstance() && IShardUnifierEvent::getInstance()->isCharacterOnlineAbroad(id)))
@ -14659,7 +14855,7 @@ void CCharacter::addPlayerToFriendList(const NLMISC::CEntityId &id)
PHRASE_UTILITIES::sendDynamicSystemMessage( _EntityRowId, "OPERATION_OFFLINE"); PHRASE_UTILITIES::sendDynamicSystemMessage( _EntityRowId, "OPERATION_OFFLINE");
return; return;
} }
} }*/
// check not already in list // check not already in list
const uint size = (uint)_FriendsList.size(); 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() // CCharacter::addPlayerToIgnoreList()
//-------------------------------------------------------------- //--------------------------------------------------------------
@ -14822,6 +15094,23 @@ void CCharacter::removePlayerFromFriendListByIndex(uint16 index)
contactListRefChange( id, RemovedFromFriends); 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() // 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() // 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() // CCharacter::removePlayerFromIgnoreListByContactId()
//-------------------------------------------------------------- //--------------------------------------------------------------
@ -15329,6 +15653,15 @@ void CCharacter::sendRemoveContactMessage(uint32 contactId, uint8 listNumber)
CUnifiedNetwork::getInstance()->send( NLNET::TServiceId(_Id.getDynamicId()), msgout ); CUnifiedNetwork::getInstance()->send( NLNET::TServiceId(_Id.getDynamicId()), msgout );
} // sendRemoveContactMessage // } // sendRemoveContactMessage //
//--------------------------------------------------------------
// CCharacter::setLastConnectionDate()
//--------------------------------------------------------------
void CCharacter::setLastConnectionDate(uint32 date)
{
_LastConnectedDate = date;
}
//-------------------------------------------------------------- //--------------------------------------------------------------
// CCharacter::destroyCharacter() // CCharacter::destroyCharacter()
//-------------------------------------------------------------- //--------------------------------------------------------------
@ -15476,8 +15809,6 @@ void CCharacter::onConnection()
{ {
// Add all handledAIGroups for all missions of the player // Add all handledAIGroups for all missions of the player
spawnAllHandledAIGroup(); spawnAllHandledAIGroup();
// add character to event channel if event occurs
CGameEventManager::getInstance().addCharacterToChannelEvent( this );
// update for the unified entity locator // update for the unified entity locator
if (IShardUnifierEvent::getInstance() != NULL) 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 ); uint32 txtId = STRING_MANAGER::sendStringToClient( targetRow, phraseCont->TargetTarget, params );
// send emote message to IOS // send emote message to IOS
NLNET::CMessage msgout("EMOTE_PLAYER"); NLNET::CMessage msgout("EMOTE_PLAYER");
msgout.serial( const_cast<TDataSetRow&>( getEntityRowId() ) );
msgout.serial( targetRow ); msgout.serial( targetRow );
msgout.serial(txtId); msgout.serial(txtId);
sendMessageViaMirror("IOS", msgout); 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 ); uint32 txtId = STRING_MANAGER::sendStringToClient(getEntityRowId(), *self, params );
// send emote message to IOS // send emote message to IOS
NLNET::CMessage msgout("EMOTE_PLAYER"); 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); msgout.serial(txtId);
sendMessageViaMirror("IOS", msgout); sendMessageViaMirror("IOS", msgout);
@ -16226,7 +16559,14 @@ NLMISC::TGameCycle CCharacter::getMissionLastSuccess(const CMissionTemplate & te
{ {
std::map< TAIAlias, TMissionHistory >::iterator it(_MissionHistories.find(templ.Alias)); std::map< TAIAlias, TMissionHistory >::iterator it(_MissionHistories.find(templ.Alias));
if (it != _MissionHistories.end()) if (it != _MissionHistories.end())
{
TGameCycle lastSuccessDate = it->second.LastSuccessDate;
if (lastSuccessDate > CTickEventHandler::getGameCycle())
return 0;
return it->second.LastSuccessDate; return it->second.LastSuccessDate;
}
return 0; 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 // set the new pvp flag and time last change for apply timer delay before this change become effective
if( pvpFlag == false ) if( pvpFlag == false )
{ {
if (_PVPFlagTimeSettedOn > CTickEventHandler::getGameCycle())
_PVPFlagTimeSettedOn = CTickEventHandler::getGameCycle() - TimeForResetPVPFlag;
if( _PVPFlagTimeSettedOn + TimeForResetPVPFlag > CTickEventHandler::getGameCycle() ) if( _PVPFlagTimeSettedOn + TimeForResetPVPFlag > CTickEventHandler::getGameCycle() )
{ {
// we need wait a minimal of time before reset your pvp tag // we need wait a minimal of time before reset your pvp tag
@ -17146,13 +17489,6 @@ void CCharacter::setPVPRecentActionFlag(CCharacter *target)
_PVPRecentActionTime = CTickEventHandler::getGameCycle(); _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 ); // _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 ); 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 ) if( c )
{ {
@ -17888,6 +18224,8 @@ uint32 CPetAnimal::initLinkAnimalToTicket( CCharacter * c )
if( ( ItemPtr != 0 ) && ( ItemPtr->getStaticForm() != NULL ) && ( ItemPtr->getStaticForm()->Family == ITEMFAMILY::PET_ANIMAL_TICKET ) ) if( ( ItemPtr != 0 ) && ( ItemPtr->getStaticForm() != NULL ) && ( ItemPtr->getStaticForm()->Family == ITEMFAMILY::PET_ANIMAL_TICKET ) )
{ {
// Slot = ItemPtr->getLocSlot(); // Slot = ItemPtr->getLocSlot();
ItemPtr->setPetIndex(index);
ItemPtr->setCustomName(CustomName);
Slot = ItemPtr->getInventorySlot(); Slot = ItemPtr->getInventorySlot();
return Slot; return Slot;
} }
@ -17900,6 +18238,8 @@ uint32 CPetAnimal::initLinkAnimalToTicket( CCharacter * c )
{ {
// Slot = ItemPtr->getLocSlot(); // Slot = ItemPtr->getLocSlot();
Slot = ItemPtr->getInventorySlot(); Slot = ItemPtr->getInventorySlot();
ItemPtr->setPetIndex(index);
ItemPtr->setCustomName(CustomName);
return Slot; return Slot;
} }
else else
@ -17916,7 +18256,6 @@ uint32 CPetAnimal::initLinkAnimalToTicket( CCharacter * c )
return INVENTORIES::INVALID_INVENTORY_SLOT; return INVENTORIES::INVALID_INVENTORY_SLOT;
} }
//----------------------------------------------- //-----------------------------------------------
// getAnimalMaxBulk // getAnimalMaxBulk
//----------------------------------------------- //-----------------------------------------------
@ -18697,8 +19036,42 @@ void CCharacter::teleportCharacter( sint32 x, sint32 y)
void CCharacter::setTeamId(uint16 id) void CCharacter::setTeamId(uint16 id)
{ {
_TeamId = 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; _TeamInvitor = invitorId;
} }
//------------------------------------------------------------------------------
void CCharacter::setLeagueInvitor(const NLMISC::CEntityId & invitorId)
{
_LeagueInvitor = invitorId;
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -19871,6 +20250,13 @@ void CCharacter::setPriviledgePVP( bool b )
_PriviledgePvp = b; _PriviledgePvp = b;
} }
//------------------------------------------------------------------------------
void CCharacter::setFullPVP( bool b )
{
_FullPvp = b;
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------

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

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

@ -414,6 +414,10 @@ static void prepareCharacterPositionForStore ( COfflineEntityState & state, cons
_FactionPoint[i],\ _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)\ 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(DeclaredCult,string,PVP_CLAN::toString(_DeclaredCult),_DeclaredCult=PVP_CLAN::fromString(val))\
PROP2(DeclaredCiv,string,PVP_CLAN::toString(_DeclaredCiv),_DeclaredCiv=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))\ LPROP(bool,IsMounted,if(IsMounted))\
PROP(bool,IsTpAllowed)\ PROP(bool,IsTpAllowed)\
PROP(TSatiety,Satiety)\ PROP(TSatiety,Satiety)\
PROP2(CustomName, ucstring, CustomName, CustomName = val)\
//#pragma message( PERSISTENT_GENERATION_MESSAGE ) //#pragma message( PERSISTENT_GENERATION_MESSAGE )
#include "game_share/persistent_data_template.h" #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! * 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 * \author Nevrax France
* \date 2005 * \date 2005
*/ */
@ -1345,6 +1350,7 @@ private:
STRUCT_VECT(_TypeSkillMods)\ STRUCT_VECT(_TypeSkillMods)\
LPROP_VECT(CSheetId, _Enchantment, VECT_LOGIC(_Enchantment) if (_Enchantment[i]!=CSheetId::Unknown))\ LPROP_VECT(CSheetId, _Enchantment, VECT_LOGIC(_Enchantment) if (_Enchantment[i]!=CSheetId::Unknown))\
PROP2(_CustomText, ucstring, _CustomText, _CustomText=val)\ PROP2(_CustomText, ucstring, _CustomText, _CustomText=val)\
PROP(bool, _LockedByOwner)\
//#pragma message( PERSISTENT_GENERATION_MESSAGE ) //#pragma message( PERSISTENT_GENERATION_MESSAGE )
#include "game_share/persistent_data_template.h" #include "game_share/persistent_data_template.h"

@ -2357,7 +2357,7 @@ void CPlayerManager::broadcastMessageUpdate()
msg= msg.replace("$seconds$",secondsStr.c_str()); msg= msg.replace("$seconds$",secondsStr.c_str());
msg= msg.replace("$minutes$",minutesStr.c_str()); msg= msg.replace("$minutes$",minutesStr.c_str());
msg= msg.replace("$hours$",hoursStr.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); SM_STATIC_PARAMS_1(params, STRING_MANAGER::literal);
params[0].Literal.fromUtf8(msg); params[0].Literal.fromUtf8(msg);

@ -1095,14 +1095,14 @@ void CDamageScoreManager::playerDeath(CCharacter * victimChar, const CCharacter
nlassert(victimChar != NULL); nlassert(victimChar != NULL);
PVP_CLAN::TPVPClan victimFaction; // PVP_CLAN::TPVPClan victimFaction;
bool victimLosesFactionPoints; bool victimLosesFactionPoints = false;
if (!playerInFactionPvP(victimChar, &victimFaction, &victimLosesFactionPoints)) // if (!playerInFactionPvP(victimChar, &victimFaction, &victimLosesFactionPoints))
return; // return;
PVP_CLAN::TPVPClan finalBlowerFaction; // PVP_CLAN::TPVPClan finalBlowerFaction;
if (!playerInFactionPvP(finalBlower, &finalBlowerFaction)) // if (!playerInFactionPvP(finalBlower, &finalBlowerFaction))
return; // return;
// check if victim and final blower are in PvP Faction (by tag or by a pvp versus zone) // check if victim and final blower are in PvP Faction (by tag or by a pvp versus zone)
/* if(!CPVPManager2::getInstance()->factionWarOccurs(victimFaction, finalBlowerFaction)) /* if(!CPVPManager2::getInstance()->factionWarOccurs(victimFaction, finalBlowerFaction))
@ -1204,9 +1204,13 @@ void CDamageScoreManager::playerDeath(CCharacter * victimChar, const CCharacter
BOMB_IF(winnerChar == NULL, "invalid winner!", continue); BOMB_IF(winnerChar == NULL, "invalid winner!", continue);
PVP_CLAN::TPVPClan winnerFaction; PVP_CLAN::TPVPClan winnerFaction;
bool winnerGainFactionPoints; bool winnerGainFactionPoints = true;
if(!playerInFactionPvP(winnerChar, &winnerFaction, &winnerGainFactionPoints))
continue; // can be in Duel or in other pvp mode. 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); CRewardedKills::CRewardedKiller * noPointPlayer = getRewardedKiller(winnerChar->getId(), noPointPlayers);
if (noPointPlayer != NULL) if (noPointPlayer != NULL)
@ -1227,9 +1231,27 @@ void CDamageScoreManager::playerDeath(CCharacter * victimChar, const CCharacter
if (winnerGainFactionPoints) 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 // player gains faction points
changePlayerFactionPoints(winnerChar, winnerFaction, sint32(fpPerPlayer)); changePlayerPvpPoints(winnerChar, sint32(fpPerPlayer) * fameFactor);
winnerChar->sendFactionPointGainKillMessage(winnerFaction, fpPerPlayer, victimChar->getId()); winnerChar->sendFactionPointGainKillMessage(winnerFaction, fpPerPlayer * fameFactor, victimChar->getId());
} }
// player gains HoF points // 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...) // 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)); //changePlayerHoFPoints(winnerChar, sint32(hofpPerPlayer));
/*
// PvP faction winner HOF reward // PvP faction winner HOF reward
CPVPManager2::getInstance()->characterKillerInPvPFaction( winnerChar, winnerFaction, (sint32)fpPerPlayer ); CPVPManager2::getInstance()->characterKillerInPvPFaction( winnerChar, winnerFaction, (sint32)fpPerPlayer );
if( finalBlower == winnerChar ) if( finalBlower == winnerChar )
{ {
CPVPManager2::getInstance()->finalBlowerKillerInPvPFaction( winnerChar, winnerFaction, victimChar ); CPVPManager2::getInstance()->finalBlowerKillerInPvPFaction( winnerChar, winnerFaction, victimChar );
} }
*/
rewardedKillers.push_back(winnerChar->getId()); rewardedKillers.push_back(winnerChar->getId());
nbRewardedMembers++; nbRewardedMembers++;
} }
@ -1273,7 +1296,7 @@ void CDamageScoreManager::playerDeath(CCharacter * victimChar, const CCharacter
hofpLoss = uint32(double(hofpLoss) * PVPHoFPointLossFactor.get() + 0.5); hofpLoss = uint32(double(hofpLoss) * PVPHoFPointLossFactor.get() + 0.5);
// keep the point loss to apply if the victim respawn // keep the point loss to apply if the victim respawn
CPointLoss pointLoss; /*CPointLoss pointLoss;
pointLoss.PlayerLosesFactionPoints = victimLosesFactionPoints; pointLoss.PlayerLosesFactionPoints = victimLosesFactionPoints;
pointLoss.PlayerFaction = victimFaction; pointLoss.PlayerFaction = victimFaction;
pointLoss.FactionPointLoss = fpLoss; pointLoss.FactionPointLoss = fpLoss;
@ -1282,8 +1305,8 @@ void CDamageScoreManager::playerDeath(CCharacter * victimChar, const CCharacter
_PointLossByPlayer[victimChar->getId()] = pointLoss; _PointLossByPlayer[victimChar->getId()] = pointLoss;
// PvP faction looser lost // 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 // delete the score table of the victim
removeDamageScoreTable(victimChar->getEntityRowId()); removeDamageScoreTable(victimChar->getEntityRowId());
} }
@ -1429,6 +1452,7 @@ void CDamageScoreManager::playerRespawn(CCharacter * victimChar)
const CPointLoss & pointLoss = (*it).second; const CPointLoss & pointLoss = (*it).second;
/*
if (pointLoss.PlayerLosesFactionPoints) if (pointLoss.PlayerLosesFactionPoints)
{ {
// victim loses faction points // victim loses faction points
@ -1438,6 +1462,7 @@ void CDamageScoreManager::playerRespawn(CCharacter * victimChar)
// victim loses HoF points // victim loses HoF points
changePlayerHoFPoints(victimChar, -sint32(pointLoss.HoFPointLoss)); changePlayerHoFPoints(victimChar, -sint32(pointLoss.HoFPointLoss));
*/
// remove the applied entry // remove the applied entry
_PointLossByPlayer.erase(it); _PointLossByPlayer.erase(it);
@ -1684,9 +1709,9 @@ bool CDamageScoreManager::playerInFactionPvP(const CCharacter * playerChar, PVP_
return true; 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( (allegiance.first != PVP_CLAN::Neutral) && (allegiance.first != PVP_CLAN::None) )
{ {
if (faction) if (faction)
@ -1695,7 +1720,7 @@ bool CDamageScoreManager::playerInFactionPvP(const CCharacter * playerChar, PVP_
*withFactionPoints = true; *withFactionPoints = true;
return true; return true;
} }
/*if ( allegiance.second != PVP_CLAN::Neutral) if ( allegiance.second != PVP_CLAN::Neutral)
{ {
if (faction) if (faction)
*faction = allegiance.second; *faction = allegiance.second;
@ -1703,7 +1728,42 @@ bool CDamageScoreManager::playerInFactionPvP(const CCharacter * playerChar, PVP_
*withFactionPoints = true; *withFactionPoints = true;
return 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; return false;
} }
@ -1795,6 +1855,28 @@ sint32 CDamageScoreManager::changePlayerFactionPoints(CCharacter * playerChar, P
return fpDelta; 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) 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 * 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 * \author Nevrax France
* \date 2005 * \date 2005
*/ */
@ -193,7 +193,7 @@ private:
* It permits to find all players wounded by an entity (player/team/creature) * 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. * 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 * \author Nevrax France
* \date 2005 * \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. * 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 * \author Nevrax France
* \date 2005 * \date 2005
*/ */
@ -273,7 +273,7 @@ private:
* and keeps their damage scores on each attacked player. * and keeps their damage scores on each attacked player.
* It also gives faction and HoF points to players. * It also gives faction and HoF points to players.
* *
* \author Sébastien 'kxu' Guignot * \author Sebastien 'kxu' Guignot
* \author Nevrax France * \author Nevrax France
* \date 2005 * \date 2005
*/ */
@ -342,6 +342,8 @@ private:
/// return true if the given action is curative /// return true if the given action is curative
bool isCurativeAction(const TReportAction & action) const; 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) /// 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 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 /// \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) /// \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); 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 /// add/remove HoF points to a player and his guild if his SDB PvP path is defined
void changePlayerHoFPoints(CCharacter * playerChar, sint32 hofpDelta); void changePlayerHoFPoints(CCharacter * playerChar, sint32 hofpDelta);
@ -388,7 +394,7 @@ private:
/** /**
* This is the interface for the character progression in PvP * This is the interface for the character progression in PvP
* *
* \author Sébastien 'kxu' Guignot * \author Sebastien 'kxu' Guignot
* \author Nevrax France * \author Nevrax France
* \date 2005 * \date 2005
*/ */

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

@ -26,6 +26,7 @@
#include "game_share/utils.h" #include "game_share/utils.h"
#include "game_share/msg_client_server.h" #include "game_share/msg_client_server.h"
#include "game_share/fame.h" #include "game_share/fame.h"
#include "game_share/send_chat.h"
#include "pvp_manager/pvp_manager_2.h" #include "pvp_manager/pvp_manager_2.h"
#include "pvp_manager/pvp_manager.h" #include "pvp_manager/pvp_manager.h"
@ -176,6 +177,21 @@ TChanID CPVPManager2::getUserDynChannel( const std::string& channelName)
return DYN_CHAT_INVALID_CHAN; 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) const std::string & CPVPManager2::getPassUserChannel( TChanID channelId)
{ {
// Search in user channels // Search in user channels
@ -353,7 +369,7 @@ void CPVPManager2::broadcastMessage(TChanID channel, const ucstring& speakerName
sendMessageViaMirror("IOS", msgout); sendMessageViaMirror("IOS", msgout);
} }
void CPVPManager2::sendChannelUsers(TChanID channel, CCharacter * user) void CPVPManager2::sendChannelUsers(TChanID channel, CCharacter * user, bool outputToSys)
{ {
std::vector<NLMISC::CEntityId> lst; std::vector<NLMISC::CEntityId> lst;
@ -361,21 +377,40 @@ void CPVPManager2::sendChannelUsers(TChanID channel, CCharacter * user)
if(it != _UserChannelCharacters.end()) if(it != _UserChannelCharacters.end())
{ {
lst = (*it).second; lst = (*it).second;
string players = ""; ucstring players;
uint32 shardId = CEntityIdTranslator::getInstance()->getEntityShardId(user->getId());
for (uint i = 0; i < lst.size(); i++) 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 ;
} }
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()); TDataSetRow senderRow = TheDataset.getDataSetRow(user->getId());
msgout.serial(senderRow); if (outputToSys)
ucstring txt = ucstring(players); {
msgout.serial(const_cast<ucstring&>(txt)); CCharacter::sendDynamicSystemMessage( user->getId(), "WHO_CHANNEL_INTRO" );
sendMessageViaMirror( "IOS", msgout); //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));
msgout.serial(senderRow);
ucstring txt = ucstring(players);
msgout.serial(const_cast<ucstring&>(txt));
sendMessageViaMirror("IOS", msgout);
}
} }
} }
@ -559,10 +594,10 @@ void CPVPManager2::playerTeleports(CCharacter * user)
void CPVPManager2::setPVPModeInMirror( const CCharacter * user ) const void CPVPManager2::setPVPModeInMirror( const CCharacter * user ) const
{ {
nlassert(user); nlassert(user);
uint8 pvpMode = 0; TYPE_PVP_MODE pvpMode = 0;
// Full pvp // Full pvp
if ( user->getPriviledgePVP() ) if ( user->getFullPVP() )
{ {
pvpMode |= PVP_MODE::PvpChallenge; pvpMode |= PVP_MODE::PvpChallenge;
} }
@ -588,6 +623,16 @@ void CPVPManager2::setPVPModeInMirror( const CCharacter * user ) const
pvpMode |= PVP_MODE::PvpDuel; 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) // pvp session (i.e everything else)
{ {
if ( user->getPVPInterface().isValid() ) if ( user->getPVPInterface().isValid() )
@ -596,9 +641,15 @@ void CPVPManager2::setPVPModeInMirror( const CCharacter * user ) const
pvpMode |= interf.getPVPSession()->getPVPMode(); pvpMode |= interf.getPVPSession()->getPVPMode();
} }
} }
CMirrorPropValue<TYPE_PVP_MODE> propPvpMode( TheDataset, user->getEntityRowId(), DSPropertyPVP_MODE ); CMirrorPropValue<TYPE_PVP_MODE> propPvpMode( TheDataset, user->getEntityRowId(), DSPropertyPVP_MODE );
propPvpMode = pvpMode; 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); CCharacter * pTarget = dynamic_cast<CCharacter*>(target);
if( pTarget ) if( pTarget )
{ {
// priviledgePVP is Full PVP, only ally of teammates anf guildmates // Full PVP is ennemy of everybody
if (pTarget->priviledgePVP() || actor->priviledgePVP()) 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; return PVP_RELATION::Ennemy;
} }
if( IsRingShard ) if( IsRingShard )
return relation; // disable PVP on Ring shards (only if target is a CCharacter, because we must let attack NPCs) 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 // temp : until new manager is finished we have to check the char pvp session too
IPVP * pvpSession = pTarget->getPVPInterface().getPVPSession(); IPVP * pvpSession = pTarget->getPVPInterface().getPVPSession();
if( pvpSession ) if( pvpSession )
@ -713,8 +758,8 @@ PVP_RELATION::TPVPRelation CPVPManager2::getPVPRelation( CCharacter * actor, CEn
if( relationTmp == PVP_RELATION::NeutralPVP ) if( relationTmp == PVP_RELATION::NeutralPVP )
relation = PVP_RELATION::NeutralPVP; relation = PVP_RELATION::NeutralPVP;
// Check if ally (neutralpvp has priority over ally) // Check if ally (neutralpvp and active has priority over ally)
if( relationTmp == PVP_RELATION::Ally && relation != PVP_RELATION::NeutralPVP ) if (relationTmp == PVP_RELATION::Ally && relation != PVP_RELATION::NeutralPVP)
relation = PVP_RELATION::Ally; relation = PVP_RELATION::Ally;
} }
@ -730,6 +775,7 @@ bool CPVPManager2::isCurativeActionValid( CCharacter * actor, CEntityBase * targ
PVP_RELATION::TPVPRelation pvpRelation = getPVPRelation( actor, target, true ); PVP_RELATION::TPVPRelation pvpRelation = getPVPRelation( actor, target, true );
bool actionValid; bool actionValid;
nlinfo("Pvp relation = %d", pvpRelation);
switch( pvpRelation ) switch( pvpRelation )
{ {
case PVP_RELATION::Ally : case PVP_RELATION::Ally :
@ -757,11 +803,12 @@ bool CPVPManager2::isCurativeActionValid( CCharacter * actor, CEntityBase * targ
if( actionValid && !checkMode ) if( actionValid && !checkMode )
{ {
CCharacter * pTarget = dynamic_cast<CCharacter*>(target); CCharacter * pTarget = dynamic_cast<CCharacter*>(target);
if(pTarget)
actor->clearSafeInPvPSafeZone(); //if(pTarget)
// actor->clearSafeInPvPSafeZone();
// propagate faction pvp flag // propagate faction pvp flag
if( pvpRelation == PVP_RELATION::Ally ) if( pvpRelation == PVP_RELATION::Ally)
{ {
if( _PVPFactionAllyReminder ) if( _PVPFactionAllyReminder )
{ {
@ -782,10 +829,6 @@ bool CPVPManager2::isCurativeActionValid( CCharacter * actor, CEntityBase * targ
{ {
actor->refreshOutpostLeavingTimer(); actor->refreshOutpostLeavingTimer();
} }
// propagate full pvp
if( pTarget->priviledgePVP() )
actor->setPriviledgePVP(true);
} }
} }
return actionValid; return actionValid;
@ -832,7 +875,13 @@ bool CPVPManager2::isOffensiveActionValid( CCharacter * actor, CEntityBase * tar
{ {
CCharacter * pTarget = dynamic_cast<CCharacter*>(target); CCharacter * pTarget = dynamic_cast<CCharacter*>(target);
if(pTarget) if(pTarget)
actor->clearSafeInPvPSafeZone(); {
if (actor->getDuelOpponent() == pTarget) // No _PVPFactionEnemyReminder when in duel
CPVPManager2::getInstance()->setPVPFactionAllyReminder(false);
else
actor->clearSafeInPvPSafeZone();
}
if( _PVPFactionEnemyReminder ) if( _PVPFactionEnemyReminder )
{ {
actor->setPVPRecentActionFlag(); actor->setPVPRecentActionFlag();
@ -886,10 +935,20 @@ bool CPVPManager2::canApplyAreaEffect(CCharacter* actor, CEntityBase * areaTarge
if( actionValid ) if( actionValid )
{ {
/* if ((pTarget->getGuildId() != 0) && (actor->getGuildId() != 0) && (actor->getGuildId() != pTarget->getGuildId()))
return false;
*/
if( areaTarget->getId().getType() == RYZOMID::player ) if( areaTarget->getId().getType() == RYZOMID::player )
{ {
CCharacter * pTarget = dynamic_cast<CCharacter*>(areaTarget); 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(); actor->clearSafeInPvPSafeZone();
// set faction flag // set faction flag
if( offensive && _PVPFactionEnemyReminder ) 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) 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); TMAPExtraFactionChannel::iterator it = _UserChannel.find(channelName);
if( it == _UserChannel.end() ) if( it == _UserChannel.end() )
@ -1244,6 +1308,14 @@ void CPVPManager2::askForDuel( const NLMISC::CEntityId & userId )
return; 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 // remove previous invitation, and check that user is not invited
bool problem = false; bool problem = false;

@ -76,10 +76,12 @@ public:
void onIOSMirrorUp(); void onIOSMirrorUp();
/// callback called at each tick /// callback called at each tick
void tickUpdate(); void tickUpdate();
/// return dynamic channel TChanID attribued to a faction /// return dynamic channel TChanID attributed to a faction
TChanID getFactionDynChannel( const std::string& channelName ); 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); 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 /// return dynamic channel TChanID attribued to a faction
const std::string &getPassUserChannel( TChanID channelId); 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 /// 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 // brodcast message to channel
void broadcastMessage(TChanID channel, const ucstring& speakerName ,const ucstring& txt); void broadcastMessage(TChanID channel, const ucstring& speakerName ,const ucstring& txt);
// send list of users to player // 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 // add faction channel to character if needed
void addFactionChannelToCharacter(TChanID channel, CCharacter * user, bool writeRight = true, bool userChannel = false); void addFactionChannelToCharacter(TChanID channel, CCharacter * user, bool writeRight = true, bool userChannel = false);
// remove faction channel for character // remove faction channel for character

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

@ -155,6 +155,12 @@ void CTradeBase::copy( IItemTrade * itt )
else _ItemPtr = 0; 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 //uint32 CTradeBase::getFactionPointPrice() const
//{ //{

@ -202,7 +202,8 @@ public:
void setAvailable( bool a ); void setAvailable( bool a );
// return game cycle left for item in store // 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 // get quantity
uint32 getQuantity() const { return _Quantity; } uint32 getQuantity() const { return _Quantity; }

@ -57,6 +57,7 @@ void CTeam::init( CCharacter* leader, uint16 teamId )
_ValidityFlags.Fake = false; _ValidityFlags.Fake = false;
_NbMembers = 1; _NbMembers = 1;
_TeamId = teamId; _TeamId = teamId;
_LeagueId = leader->getLeagueId();
_LeaderId = leader->getId(); _LeaderId = leader->getId();
_TeamMembers.push_back(_LeaderId); _TeamMembers.push_back(_LeaderId);
// init the team chat group // init the team chat group
@ -120,6 +121,12 @@ void CTeam::release()
PROGRESSIONPVE::CCharacterProgressionPVE::getInstance()->disbandTeam(_TeamId, _TeamMembers); PROGRESSIONPVE::CCharacterProgressionPVE::getInstance()->disbandTeam(_TeamId, _TeamMembers);
PROGRESSIONPVP::CCharacterProgressionPVP::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; _TeamId = CTEAM::InvalidTeamId;
_TeamMembers.clear(); _TeamMembers.clear();
_NbMembers = 0; _NbMembers = 0;
@ -167,7 +174,8 @@ void CTeam::addCharacter(CCharacter *newCharacter)
else else
{ {
// newCharacter->_PropertyDatabase.setProp( "GROUP:SUCCESSOR_INDEX", 1 ); // 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 // update all member's DB
@ -283,6 +291,9 @@ void CTeam::addCharacter(CCharacter *newCharacter)
// set the character team // set the character team
newCharacter->setTeamId(_TeamId); newCharacter->setTeamId(_TeamId);
// set the character alliance
newCharacter->setLeagueId(_LeagueId);
// Add character to chat group // Add character to chat group
TGroupId idGroupe = CHAT_GROUPS_IDS::getTeamChatGroupId(_TeamId); TGroupId idGroupe = CHAT_GROUPS_IDS::getTeamChatGroupId(_TeamId);
CMessage msgout("ADD_TO_GROUP"); CMessage msgout("ADD_TO_GROUP");
@ -383,6 +394,7 @@ void CTeam::removeCharacter( CCharacter * player )
///\todo give him a player team Id ///\todo give him a player team Id
player->setTeamId( CTEAM::InvalidTeamId ); player->setTeamId( CTEAM::InvalidTeamId );
player->setLeagueId(DYN_CHAT_INVALID_CHAN);
player->updateTargetingChars(); player->updateTargetingChars();
// tell progression system this player has been removed from his team // tell progression system this player has been removed from his team
@ -410,13 +422,19 @@ void CTeam::removeCharacter( CCharacter * player )
clearPlayerTeamDB( *_TeamMembers.begin() ); clearPlayerTeamDB( *_TeamMembers.begin() );
CCharacter * lastPlayer = PlayerManager.getOnlineChar( *_TeamMembers.begin() ); CCharacter * lastPlayer = PlayerManager.getOnlineChar( *_TeamMembers.begin() );
if ( lastPlayer ) if ( lastPlayer )
{
lastPlayer->setTeamId( CTEAM::InvalidTeamId ); lastPlayer->setTeamId( CTEAM::InvalidTeamId );
lastPlayer->setLeagueId(DYN_CHAT_INVALID_CHAN);
}
else else
{ {
nlwarning("<CTeam removeCharacter> charId %s not found in the team", (*_TeamMembers.begin()).toString().c_str() ); nlwarning("<CTeam removeCharacter> charId %s not found in the team", (*_TeamMembers.begin()).toString().c_str() );
return; return;
} }
// remove league
setLeague("");
// remove the team chat group // remove the team chat group
TGroupId idGroupe = CHAT_GROUPS_IDS::getTeamChatGroupId(_TeamId); TGroupId idGroupe = CHAT_GROUPS_IDS::getTeamChatGroupId(_TeamId);
CMessage msgRemoveGroup("REMOVE_GROUP"); CMessage msgRemoveGroup("REMOVE_GROUP");
@ -437,80 +455,26 @@ void CTeam::removeCharacter( CCharacter * player )
// if that was the leader, get another one // if that was the leader, get another one
else if ( _LeaderId == charId ) else if ( _LeaderId == charId )
{ {
_LeaderId = _SuccessorId; setLeader(_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() );
} }
// if that was the successor, inform the new one else if ( _SuccessorId == charId )
/* else if ( formerPos == 1 && _NbMembers > 2)
{ {
list<CEntityId>::iterator itTmp = _TeamMembers.begin(); // The current successor dropped from team; set it to the next in line after leader
++itTmp; setSuccessor(1);
const CEntityId & successorId = *(itTmp);
CCharacter *successor = PlayerManager.getOnlineChar( successorId );
if (successor)
{
successor->_PropertyDatabase.setProp( "GROUP:SUCCESSOR_INDEX", -1 );
}
else
nlwarning("<CTeam removeCharacter> invalid new successor %s", successorId.toString().c_str() );
} }
*/ else
else if ( _SuccessorId == charId )
{ {
for (list<CEntityId>::const_iterator it = _TeamMembers.begin(); it != _TeamMembers.end(); ++it) // 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)
{ {
if ( (*it) != _LeaderId ) if (_SuccessorId == (*it))
{
_SuccessorId = (*it );
CCharacter *successor = PlayerManager.getOnlineChar( _SuccessorId );
if (successor)
{
// successor->_PropertyDatabase.setProp( "GROUP:SUCCESSOR_INDEX", -1 );
CBankAccessor_PLR::getGROUP().setSUCCESSOR_INDEX(successor->_PropertyDatabase, 0xf);
}
break; 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) for (std::list<NLMISC::CEntityId>::iterator it = _TeamMembers.begin() ; it != _TeamMembers.end() ; ++it)
@ -607,114 +571,171 @@ void CTeam::removeCharacter( CCharacter * player )
}// CTeam removeCharacter }// CTeam removeCharacter
void CTeam::setSuccessor( uint8 memberIdx ) void CTeam::setLeague(const string &leagueName)
{ {
/* TChanID chanId = _LeagueId;
list<CEntityId>::const_iterator it = _TeamMembers.begin(); if (_LeagueId != DYN_CHAT_INVALID_CHAN)
uint8 i = 0;
for (; it != _TeamMembers.end(); ++it)
{ {
if ( i == memberIdx ) // Remove players from previous channel
break; _LeagueId = DYN_CHAT_INVALID_CHAN;
++i; 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);
return; if (_LeagueId == DYN_CHAT_INVALID_CHAN)
{
nlinfo("Error channel creation !!!");
return;
}
// set historic size of the newly created channel
DynChatEGS.setHistoricSize(_LeagueId, 100);
} }
_SuccessorId = (*it);
SM_STATIC_PARAMS_1( params,STRING_MANAGER::player ); updateLeague();
params[0].EId = (*it ); }
sendDynamicMessageToMembers("TEAM_NEW_SUCCESSOR",params);
for (std::list<CEntityId>::const_iterator it = _TeamMembers.begin() ; it != _TeamMembers.end() ; ++it) void CTeam::updateLeague()
{
for (list<CEntityId>::iterator it = _TeamMembers.begin() ; it != _TeamMembers.end() ; ++it)
{ {
uint8 hp, sap, stamina; CCharacter * ch = PlayerManager.getOnlineChar((*it));
uint32 nameId; if (ch != NULL && ch->getLeagueId() != _LeagueId)
CCharacter* character = PlayerManager.getOnlineChar( (*it) );
if (character != NULL)
{ {
// update the current character team slot ch->setLeagueId(_LeagueId);
///\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();
sprintf(buffer, "GROUP:%d:HP",position );
character->_PropertyDatabase.setProp( buffer, hp );
sprintf(buffer, "GROUP:%d:SAP",position );
character->_PropertyDatabase.setProp( buffer, sap );
sprintf(buffer, "GROUP:%d:STA",position ); uint8 CTeam::getSuccessorIndex()
character->_PropertyDatabase.setProp( buffer, stamina ); {
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:NAME",position ); void CTeam::setLeader(CEntityId id, bool bMessage)
character->_PropertyDatabase.setProp( buffer, nameId ); {
_LeaderId = id;
sprintf(buffer, "GROUP:%d:UID",position ); // Move new leader to top of list
character->_PropertyDatabase.setProp( buffer, newCharacter->getEntityRowId().getCompressedIndex() ); _TeamMembers.remove(_LeaderId);
_TeamMembers.insert(_TeamMembers.begin(), _LeaderId);
sprintf(buffer, "GROUP:%d:PRESENT",position ); // inform the new leader
character->_PropertyDatabase.setProp( buffer, (uint8)1 ); SM_STATIC_PARAMS_1(params1, STRING_MANAGER::player);
params1[0].setEId( id );
PHRASE_UTILITIES::sendDynamicSystemMessage(TheDataset.getDataSetRow(_LeaderId), "TEAM_YOU_NEW_LEADER", params1);
// update the new character team slot corresponding to character // inform the group
if ( character->getPhysScores()._PhysicalScores[ SCORES::hit_points ].Max != 0) SM_STATIC_PARAMS_2(params, STRING_MANAGER::player, STRING_MANAGER::player);
hp = (uint8) ( ( float(TeamMembersStatusMaxValue) * ( character->getPhysScores()._PhysicalScores[ SCORES::hit_points ].Current ) ) / ( character->getPhysScores()._PhysicalScores[ SCORES::hit_points ].Max ) ); params[0].setEId( id );
else params[1].setEId( _LeaderId );
hp = 0;
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;
if ( character->getPhysScores()._PhysicalScores[ SCORES::stamina ].Max != 0) set<CEntityId> exclude;
stamina = (uint8) ( ( float(TeamMembersStatusMaxValue) * ( character->getPhysScores()._PhysicalScores[ SCORES::stamina ].Current ) ) / ( character->getPhysScores()._PhysicalScores[ SCORES::stamina ].Max ) ); exclude.insert( _LeaderId );
else exclude.insert( id );
stamina = 0; sendDynamicMessageToMembers("TEAM_NEW_LEADER", params, exclude);
CMirrorPropValueRO<uint32> nameIndexValue2( TheDataset, character->getId(), "NameIndex" ); // New leader was successor, choose a new successor
nameId = nameIndexValue2(); if (id == _SuccessorId)
{
_SuccessorId = CEntityId::Unknown;
// Set the new successor to next in line
setSuccessor(1);
}
sprintf(buffer, "GROUP:%d:HP",i ); // update leader DB
newCharacter->_PropertyDatabase.setProp( buffer, hp ); CCharacter *leader = PlayerManager.getOnlineChar( _LeaderId );
if (leader)
sprintf(buffer, "GROUP:%d:SAP",i ); {
newCharacter->_PropertyDatabase.setProp( buffer, sap ); // switch dyn chat speaker
CMissionManager::getInstance()->switchDynChatSpeaker(leader, _LeaderId);
sprintf(buffer, "GROUP:%d:STA",i ); CBankAccessor_PLR::getGROUP().setLEADER_INDEX(leader->_PropertyDatabase, 0xf);
newCharacter->_PropertyDatabase.setProp( buffer, stamina ); }
else
nlwarning("<CTeam setLeader> invalid new leader %s", _LeaderId.toString().c_str() );
}
sprintf(buffer, "GROUP:%d:NAME",i ); void CTeam::setLeader(uint8 memberIdx, bool bMessage)
newCharacter->_PropertyDatabase.setProp( buffer, nameId ); {
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 ); void CTeam::setSuccessor( uint8 memberIdx, bool bMessage)
newCharacter->_PropertyDatabase.setProp( buffer, character->getEntityRowId().getCompressedIndex() ); {
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 ); _SuccessorId = (*it);
newCharacter->_PropertyDatabase.setProp( buffer, (uint8)1 ); 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
{
CBankAccessor_PLR::getGROUP().setSUCCESSOR_INDEX(ch->_PropertyDatabase, memberIdx);
}
} }
else
nlwarning("<CTeam::addCharacter> Unknown character %s", (*it).toString().c_str() );
++i; ++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; 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/misc_const.h"
#include "game_share/string_manager_sender.h" #include "game_share/string_manager_sender.h"
#include "game_share/scores.h" #include "game_share/scores.h"
#include "game_share/dyn_chat.h"
#include "mission_manager/mission_event.h" #include "mission_manager/mission_event.h"
#include "mission_manager/ai_alias_translator.h" #include "mission_manager/ai_alias_translator.h"
#include "team_manager/reward_sharing.h" #include "team_manager/reward_sharing.h"
@ -73,17 +74,54 @@ public:
void removeCharacter( CCharacter * newChar ); void removeCharacter( CCharacter * newChar );
/** /**
* set the successor of the team leader * return the index of team leader successor
* \param memberIdx is the index of the member in hte team *
*/
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 setSuccessor( uint8 memberIdx ); 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 the team
* \param bMessage whether to show the message
*/
void setSuccessor( uint8 memberIdx, bool bMessage = true );
/** /**
* get the leader of the team * get the leader of the team
* \return team leader Id * \return team leader Id
*/ */
inline const NLMISC::CEntityId & getLeader() const { return _LeaderId; } 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 ///\return number of team members
inline uint8 getTeamSize() const { return _NbMembers; } inline uint8 getTeamSize() const { return _NbMembers; }
@ -108,6 +146,12 @@ public:
///\return the team id ///\return the team id
inline uint16 getTeamId() const { return _TeamId; } 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 /// send a message to the team
void sendDynamicMessageToMembers(const std::string &msgName, const TVectorParamCheck &params, const std::set<NLMISC::CEntityId> &excluded) const; 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 inline void sendDynamicMessageToMembers(const std::string &msgName, const TVectorParamCheck &params) const
@ -171,7 +215,8 @@ public:
CMissionTeam* getMissionByAlias( TAIAlias missionAlias ); CMissionTeam* getMissionByAlias( TAIAlias missionAlias );
/* void updateMembersDb();
/*
bool processMissionStepEvent(std::list< const CMissionEvent* > & eventList, uint missionIndex, uint32 stepIndex ); bool processMissionStepEvent(std::list< const CMissionEvent* > & eventList, uint missionIndex, uint32 stepIndex );
bool processMissionEvent( 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 ///\id of the team
uint16 _TeamId; 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 /// Team Members. The index of an entity in the container is its position
std::list<NLMISC::CEntityId> _TeamMembers; std::list<NLMISC::CEntityId> _TeamMembers;
@ -212,6 +260,7 @@ private:
/// id of the team leader /// id of the team leader
NLMISC::CEntityId _LeaderId; NLMISC::CEntityId _LeaderId;
/// successor id /// successor id
NLMISC::CEntityId _SuccessorId; NLMISC::CEntityId _SuccessorId;

@ -71,6 +71,195 @@ void CTeamManager::addAllTeamsToChatGroup()
} }
} // 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 : // joinProposal :
//--------------------------------------------------- //---------------------------------------------------
@ -90,7 +279,7 @@ void CTeamManager::joinProposal( CCharacter * leader, const CEntityId &targetId)
CCharacter *invitedPlayer = PlayerManager.getOnlineChar( targetId ); CCharacter *invitedPlayer = PlayerManager.getOnlineChar( targetId );
if ( invitedPlayer == NULL ) if ( invitedPlayer == NULL )
{ {
CCharacter::sendDynamicSystemMessage( leader->getId(),"INVALID_TEAM_TARGET" ); CCharacter::sendDynamicSystemMessage( leader->getId(),"INVALID_LEAGUE_TARGET" );
return; return;
} }
@ -117,7 +306,7 @@ void CTeamManager::joinProposal( CCharacter * leader, const CEntityId &targetId)
} }
else if ( code == CantInviteEnemy ) else if ( code == CantInviteEnemy )
{ {
CCharacter::sendDynamicSystemMessage( leader->getId(),"TEAM_CANT_INVITE_ENEMIE" ); CCharacter::sendDynamicSystemMessage( leader->getId(),"TEAM_CANT_INVITE_ENEMY" );
return; return;
} }
else if ( code == CantInvite ) else if ( code == CantInvite )
@ -423,7 +612,7 @@ void CTeamManager::removeCharacter( const CEntityId &charId )
{ {
const list<CEntityId> &members = team->getTeamMembers(); const list<CEntityId> &members = team->getTeamMembers();
CEntityId eId(*(++members.begin())); CEntityId eId(team->getSuccessor());
params[0].setEIdAIAlias( eId, CAIAliasTranslator::getInstance()->getAIAlias(eId) ); params[0].setEIdAIAlias( eId, CAIAliasTranslator::getInstance()->getAIAlias(eId) );
PHRASE_UTILITIES::sendDynamicSystemMessage(TheDataset.getDataSetRow(charId), "TEAM_YOU_LEAVE_LEADER", params); 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()); 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 }// 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 : // processMissionTeamEvent :
//--------------------------------------------------- //---------------------------------------------------
@ -519,6 +750,7 @@ CTeamManager::TInviteRetCode CTeamManager::isInvitableBy(CCharacter * invited, C
{ {
return AlreadyInvited; return AlreadyInvited;
} }
// get the target team, which must be fake // get the target team, which must be fake
CTeam * team = getRealTeam( invited->getTeamId() ); CTeam * team = getRealTeam( invited->getTeamId() );
if( team ) if( team )
@ -528,7 +760,8 @@ CTeamManager::TInviteRetCode CTeamManager::isInvitableBy(CCharacter * invited, C
// check that the invitor is alone or a group leader // check that the invitor is alone or a group leader
team = getRealTeam( invitor->getTeamId() ); team = getRealTeam( invitor->getTeamId() );
if ( team && team->getLeader()!= invitor->getId() )
if (team && team->getLeader()!= invitor->getId())
{ {
return CantInvite; return CantInvite;
} }
@ -538,9 +771,9 @@ CTeamManager::TInviteRetCode CTeamManager::isInvitableBy(CCharacter * invited, C
return CantInvite; return CantInvite;
// cannot invite enemy in faction PvP zones // 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() ) if( invited->getPvPRecentActionFlag() || invitor->getPvPRecentActionFlag() )
return CantInviteEnemy; return CantInviteEnemy;*/
return Ok; return Ok;
} }

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

@ -248,9 +248,9 @@ public :
* \param target is the id of the target char * \param target is the id of the target char
* \param phraseId is the phrase id (uint32) * \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) if (entityId.getType() == RYZOMID::player)
{ {
// init event faction ID in mirror // init event faction ID in mirror
CMirrorPropValue<TYPE_EVENT_FACTION_ID> propEventFactionId( TheDataset, entityIndex, DSPropertyEVENT_FACTION_ID ); //CMirrorPropValue<TYPE_EVENT_FACTION_ID> propEventFactionId( TheDataset, entityIndex, DSPropertyEVENT_FACTION_ID );
propEventFactionId = 0; //propEventFactionId = 0;
} }
entityIndex = DataSet->getNextAddedEntity(); entityIndex = DataSet->getNextAddedEntity();
@ -620,7 +620,7 @@ void CInputOutputService::addCharacterName( const TDataSetRow& chId, const ucstr
if( itInfos == _NameToInfos.end() ) if( itInfos == _NameToInfos.end() )
{ {
// New name does not exist // 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) // 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 else
ci->UntranslatedEventFactionId = SM->storeString( eventFaction ); ci->UntranslatedEventFactionId = SM->storeString( eventFaction );
CMirrorPropValue<TYPE_EVENT_FACTION_ID> propEventFactionId( TheDataset, chId, DSPropertyEVENT_FACTION_ID ); // CMirrorPropValue<TYPE_EVENT_FACTION_ID> propEventFactionId( TheDataset, chId, DSPropertyEVENT_FACTION_ID );
propEventFactionId = SM->translateEventFaction( ci->UntranslatedEventFactionId ); // propEventFactionId = SM->translateEventFaction( ci->UntranslatedEventFactionId );
} }
else else
{ {
@ -1513,12 +1513,14 @@ void cbEmoteCrowd( CMessage& msgin, const string &serviceName, TServiceId servic
//----------------------------------------------- //-----------------------------------------------
void cbEmoteSolePlayer( CMessage& msgin, const string &serviceName, TServiceId serviceId ) void cbEmoteSolePlayer( CMessage& msgin, const string &serviceName, TServiceId serviceId )
{ {
TDataSetRow sender;
TDataSetRow target; TDataSetRow target;
uint32 phraseId; uint32 phraseId;
msgin.serial(sender);
msgin.serial(target); msgin.serial(target);
msgin.serial(phraseId); msgin.serial(phraseId);
CChatManager &cm = IOS->getChatManager(); 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); SM->setPhrase(msgin);
} }
void cbSetPhraseLang( CMessage& msgin, const string& serviceName, TServiceId serviceId )
{
SM->setPhraseLang(msgin);
}
//----------------------------------------------- //-----------------------------------------------
// Add a new channel in the dyn chat // 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 { "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", 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}, { "UPDATE_AIALIAS", cbUpdateAIAlias},

@ -231,7 +231,8 @@ public:
{ {
static const string NAME("name"); 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 // can't replace this parameter, write a del char
const static string s("\010"); const static string s("\010");
@ -270,7 +271,8 @@ public:
if (playerInfo != 0) if (playerInfo != 0)
{ {
static const string NAME("name"); 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 // can't replace this parameter, write a del char
const static string s("\010"); const static string s("\010");

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

Loading…
Cancel
Save