近期有些熱情玩家的加入,想要讓伺服器更好,更多人玩
目前娛樂班的定位就是好玩簡單,不要讓玩家有要狂練等,難度太難的感覺
但大部分玩家還是認為坦克血量過低,所以我就直接修改,不等投票結果
到投票有最後決定,將會在下個月在調整

之前的坦克血量是依照玩家總等級來改變坦克血量
總共有7個階段,前3個階段我定位在新手階段,不做修改
後面4個階段血量分別是
96000
192000
384000
768000
現在調整成
960000
3840000
11520000
30720000

可能會遇到的問題先幫大家整理一下
因為大部分玩家沒有加入群組或是這網站,所以會不知道伺服器有更新
要大家如果遇到有疑問的玩家幫忙回答
另外每次的修改設定都會遇到因為血量太多如果伺服器沒有很快的有隊友加入
會很難過關,有時候玩家是1個近來待不了又出去,
會造成其他老手會認為這房都不會有新人,自己跟著不玩,惡性循環

開這伺服器會需要一些相關費用,所以開服是單純因為玩的人多才會開著
之前在開另一版的時候玩家會因為我收取贊助有一些紛爭
所以要在這邊解釋
開服要電費,網路要有更快的速度,不然會因為我在使用的時候造成玩家的LAG,
還有電腦的損壞,我從以前開到現在這已經是第3台電腦,其實上我不會有收入來源的

這幾天有玩家跟我討論到在遊戲也能獲得玄幣的問題
這部分就跟上面提到的贊助有相關,我如果開放了,玩家會不會盡可能的去洗玄幣,

以上請不要說你不贊助,又想要我修改他想要的功能,也不給我時間,
然後我自己要利用我休假的時候去修改大家要的功能,
請大家將心比心,不能接受的玩家,請去玩別的遊戲




其它更新內容
關閉坦克死亡會掉落物品來減少伺服器負擔
關閉大部分的訊息提示

第二次修改
修改轉身上限為25轉
修改坦克數量沒正常出現的BUG,功能如果還是不正常請通知

第三次修改
根據玩家體驗,坦克血量過高,所以最後面4階段的血量降低5倍

RPG阿土娛樂班更新記錄,坦克血量大翻倍


* Version 1.0.0
* - 初始發行
* - 服務器使用中文名
*
* Version 1.1.0
* - 整合l4d2_multislots原碼(Bot隨玩家人數增加)
* - 開始使用atoAttack資料夾整理原碼
* - 使用原本的gamedata檔案
*
* Version 1.2.0
* - 整合ledge_release原碼(懸掛時按Ctrl放手)
* - 更改HookEvent事件的命名方式以免重複
*
* Version 1.3.0
* - 整合l4d2_WeaponUnlock原碼(隱藏武器解鎖)
* - 增加是否開啟隱藏武器的增加傷害
* - 將所有的static const改成全域變數
*
* Version 1.4.0
* - 整合 showdamage 原碼(顯示攻擊傷害)
* - 之後會有其他插件會影響傷害數值,所以會參考 UnitedRPG_V4.0 的寫法
*
* Version 1.5.0
* - 參考 l4d_stats 原碼(殺敵統計),來學習SQL使用語法
*
* Version 1.6.0
* - 整合 difficulty_adjustment_system 原碼(自動改變難度)
*
* Version 1.7.0
* - 參考 base_stats 原碼(另一種殺敵統計),來學習SQL使用語法
* - 移除原本 l4d_stats 原碼語法
*
* Version 1.8.0
* - 參考 data_mysql 原碼(另一種殺敵統計),來學習SQL使用語法
* - 移除原本 base_stats 原碼語法
*
* Version 1.9.0
* - 測試SDKHook_OnTakeDamage改變傷害功能
* - 大幅度修改SQL語法,道具跟任務系統
*
* Version 2.0.0
* - RPG進擊班正式上線
* - 目前先設定可獲取金錢

預計下一版本功能
敵人的傷害系統
玩家能力系統
如果能順利能傷害平衡就可以把經驗系統加上
升級系統

RPG阿土進擊班2.0開服更新記錄


根據玩家測試回報
祭祀之光的數據如下

超級大範圍傷害,最高100等,點滿範圍2100距離,傷害每秒3萬持續30秒
這樣換算下來就有90萬傷害

而且只要技能過了30秒 又可以繼續放

目前先將最大範為改為800
如有疑問可再提出 感謝大家的測試


修改惡靈勢力2 RPG祭祀之光攻擊範圍


這裡教大家編寫SourceMod插件的基本介紹,SourceMod他是使用SourcePawn中使用的Pawn的版本,Pawn是一種“腳本”語言,用於在其他程序中嵌入功能。這意味著它不是獨立的語言,如C ++或Java,其細節將根據應用程序而有所不同。

您可以使用SPEdit,Crimson Editor,PSPad,UltraEdit,Notepad ++,TextPad,Pawn Studio,BasicPawn或任何其他您喜歡編寫插件的程式編輯器。

從頭開始

打開你最喜歡的程式編輯器,並創建一個新的空文件。
當你有一個空文件時,你可以開始用核心語言編寫代碼,但是,你將無法使用任何的SourceMod功能,因為編輯器不知道它們。

這是故意做的,所以可以在SourceMod之外使用SourcePawn。但是由於我們正在編寫一個SourceMod插件,因此首先啟用對SourceMod功能的訪問是一個好主意。

這是使用#include指令完成的。它告訴編譯器將來自另一個文件的代碼“複製貼上”到你的代碼中。

#include <sourcemod>

這個怎麼用?
首先,請注意,我們將文件名包含在<>括號中。
<>括號告訴編譯器查看默認的include目錄。

默認情況下,它會在遊戲路徑\left4dead2\addons\sourcemod\scripting\include。
你現在可以打開它並在那裡看到很多inc文件。
這些是SourceMod包含文件(要先安裝SourceMod平台),用於描述可用於SourceMod插件的各種功能,標記和其他功能。

這些文件是純文字的,如果時間允許可以閱讀它們。
但是,您會注意到,那裡沒有太多的代碼,當然不足以實現SourceMod的所有優點

它們是在用C ++編寫的SourceMod內核中實現的,並且被編譯為以bin結尾的二進製文件目錄。
那麼如果編譯器不知道後者的存在,你的SourcePawn代碼和SM核心如何鏈接在一起?

SourceMod包含文件是專門編寫的,所以他們說功能的實現在別的地方。編譯器知道這一點,並生成一個特殊的代碼,說明這個函數調用正在外面。當SourceMod加載您的插件時,它會檢查這些代碼並替換它自己的內部函數。這被稱為動態鏈接。

設置插件信息

現在我們可以訪問SourceMod功能,現在可以設置通過sm plugins list命令顯示的信息了。

我們可以查看sourcemod.inc文件,並查看應該聲明信息的格式。查看SM包含文件以查找您不知道的信息總是有幫助的。
還有一個API文檔,但它可能已過時,並且它只有SM核心文件,所以如果您的插件要使用任何第三方擴展或其他插件,則必須學習inc文件。所以,打開sourcemod.inc並向下滾動一下,直到看到:

/**
 * Plugin public information.
 */
struct Plugin
{
   public const char[] name;        /**< 插件名稱 */
   public const char[] description;    /**< 插件說明 */
   public const char[] author;        /**< 插件作者 */
   public const char[] version;        /**< 插件版本 */
   public const char[] url;            /**< 插件網址 */
};

和這個

/**
 * Declare this as a struct in your plugin to expose its information.
 * Example:
 *
 * public Plugin myinfo =
 * {
 *    name = "My Plugin",
 *    //etc
 * };
 */
public Plugin myinfo;

它告訴我們,我們需要創建一個全局公共變量myinfo,它必須是Plugin類型,它是一個包含5個字段的結構體,它們本身就是字符串。
對初學者來說聽起來很複雜,但很簡單。讓我們繼續創建一個:

public Plugin myinfo =
{
    name = "我的第一個插件",
    author = "作者",
    description = "我的第一個插件說明",
    version = "1.0",
    url = "http://www.sourcemod.net/"
};

該公共關鍵字意味著SourceMod將能夠直接訪問我們的變量。
插件:定義我們的變量的類型。

myinfo顯然是SourceMod所需的我們變量的名稱。
這是填寫插件信息的最佳方式。
之後,你的插件的完整代碼應該是這樣的:

#include <sourcemod>
 
public Plugin myinfo =
{
    name = "我的第一個插件",
    author = "作者",
    description = "我的第一個插件說明",
    version = "1.0",
    url = "http://www.sourcemod.net/"
};

獲取代碼運行

我們已經包含了SourceMod功能並且已經設定插件信息。
我們現在有一個完美格式的插件,可以通過SourceMod進行編譯和加載。

但是,有一個問題 - 它什麼功能都沒有。
您可能會試圖在myinfo聲明之後開始編寫代碼,以確保它不會編譯。
與其他腳本語言如Lua不同,SourcePawn不允許代碼在函數之外。

閱讀完之後,你可能想要定義一些函數,可能主要命名它,編譯並加載一個插件,看看你的代碼永遠不會被調用。
那麼我們如何讓SourceMod調用我們的代碼呢?

可以由另一方作為回調來實現。
當第一方開始前轉呼叫時,具有匹配回叫的所有方接收該呼叫。
SourceMod聲明了我們可以實現的大量有趣的內容。

正如你所看到的,轉發是讓我們的代碼執行的唯一方法,牢記這一點。
所以讓我們先實現OnPluginStart。
正如您可能已經猜到的那樣,我們的插件啟動時會調用它。
為此,我們必須查看OnPluginStart的聲明。
它在sourcemod.inc裡面聲明,我們已經熟悉這個文件,讓我們來找到它:

/**
 *當插件完全初始化並調用所有已知的外部引用時調用
 *已解決。 這只在插件的生命週期中調用一次,並且是
 *與OnPluginEnd()配對。
 *
 *如果在此回調期間發生任何運行時錯誤,則插件將被標記
 *失敗。
 *
 *不需要關閉此功能中的任何手柄或刪除掛鉤。
 * SourceMod保證插件自動關閉並正確釋放
 *所有資源。
 *
 * @noreturn
 */
forward void OnPluginStart();

空括號告訴我們,在這個轉發中沒有任何參數被傳遞,@noreturn文檔裡面告訴我們,我們不需要返回任何東西,很簡單。

那麼如何為它寫一個正確的回調呢?首先,我們的回調必須具有相同的名稱,所以它的OnPluginStart,其次,我們的回調應該有相同數量的參數,在這種情況下,最後,SourceMod需要能夠調用我們的回調,因此它需要公開。所以實現如下所示:

public void OnPluginStart ()
{ 
}

現在我們可以在大括號內編寫代碼,並且它會在我們的插件啟動時執行。

我們輸出“Hello world!” 到服務器控制台。為此,我們將使用PrintToServer函數。它在console.inc中聲明,

但是,我們不需要手動包含console.inc,因為它是作為sourcemod.inc的一部分自動包含的。

/**
 * 將消息發送到服務器控制台.
 *
 * @param format         格式化規則.
 * @param ...            可變數量的格式參數.
 * @noreturn
 */
native int PrintToServer(const char[] format, any ...);

正如你所看到的,這是一個本地函數。它在SM內核中實現。從它的論點來看,我們可以看到它是一個格式類函數。

但是,我們現在不需要任何格式,所以讓我們通過“Hello world!” 字符串作為唯一參數:

public void OnPluginStart ()
{ 
    PrintToServer (“Hello world!” ) ;
}

完成!你的插件的完整代碼應該是下面這樣的:

#include <sourcemod>
 
public Plugin myinfo =
{
    name = "我的第一個插件",
    author = "作者",
    description = "我的第一個插件說明",
    version = "1.0",
    url = "http://www.sourcemod.net/"
}; public void OnPluginStart() { PrintToServer("Hello world!"); }

在您的服務器上編譯並加載您的插件,並親自看到該消息顯示在服務器控制台中。

参考資料
https://wiki.alliedmods.net/Introduction_to_SourcePawn_1.7
https://wiki.alliedmods.net/Introduction_to_SourceMod_Plugins


SourceMod插件的基本介紹#1


一般只要使用冰動相關技能,都會有一個爆風效果,但這會導致把玩家震開
這常常會讓玩家飛到場外,造成不必要的紛爭

這技能都會分別設定友傷跟敵傷,所以我們要把爆風的攻能放在敵傷那裏面

爆風功能語法是PointPush


搜尋PointPush可以找到8個地方有使用,1個爆風主程式
語法大概是下面這樣

PointPush(Client, pos, 1000, IceBallRadius[Client], 0.5);

將這些放在特感的判斷理面,例如下面

                    if(GetClientTeam(i) == 3 && IsPlayerAlive(i) && !IsPlayerGhost(i))
                    {
                        GetEntPropVector(i, Prop_Send, "m_vecOrigin", entpos);
                        SubtractVectors(entpos, pos, distance);
                        if(GetVectorLength(distance) <= Radius)
                        {
                            DealDamage(Client, i, IceBallDamage[Client], 0 , "chain_lightning");
                            FreezePlayer(i, entpos, IceBallDuration[Client]);
                        }
                    }

要記得把PointPush放在攻擊範圍Radius判斷裡面

修改惡靈勢力2 RPG的寒冰爆彈相關技能會把我方倖存者炸飛的Bug


我們要先查詢看看資料庫查詢是否正常
但如果直接查詢,有可能會查詢到很多的資料,會有不必要的讀取時間
議使用SQL_FastQuery(),這是最簡單的查詢而且不會返回結果

例如,假設db是一個可正常連線而且有效的數據庫句柄(Handle):

if (!SQL_FastQuery(db, "UPDATE stats SET players = players + 1"))
{
    char error[255];
    SQL_GetError(db, error, sizeof(error));
    PrintToServer("Failed to query (error: %s)", error);
}

SQL_FastQuery加上驚嘆號就是查詢失敗
所以只要if裡面查詢失敗就會執行下面的部分

查詢失敗就使用SQL_GetError查找最後一個錯誤


惡靈勢力2判斷資料庫是否查詢的到資料(SQL_FastQuery)


惡靈勢力2原碼連到資料庫有兩種方法。

第一種是通過命名配置,命名配置是在
addons\sourcemod\configs\databases.cfg中列出的預設配置。

SourceMod指定如果正在使用SQL,預設有一個名為“default”的配置。

"default"
    {
        "host"                "localhost"
        "database"            "sourcemod"
        "user"                "root"
        "pass"                ""
        //"timeout"            "0"
        //"port"            "0"
    }

  • host 連線主機的位置,如果Mysql資料庫跟你遊戲Server同一台電腦使用localhost即可
    或是打上資料庫的那台電腦IP
  • database 要連線的資料庫名稱,這名稱要自己在Mysql創一個新資料庫
  • user 使用者名稱,預設是root
    root這使用者安裝MySQL時一定會有
  • pass 使用者密碼,預設的root帳號的密碼是空的,不需要輸入
    日後有修改密碼要記的修改
  • timeout 連線逾時的時間,有註解了不會執行
  • port 資料庫的連接埠,也有註解不用輸入,MySQL的port預設是3306
    除非安裝時有修改才要設定,並把//註解拿掉

另外也能不使用default,自己再增加一個自己取的名字

基於命名配置的連接,在原碼可以使用SQL_Connect或SQL_DefConnect實例化

SQL_Connect範例,可放在插件開始的地方OnPluginStart

#define DB_CONF_NAME "atol4d2SQL"//databases.cfg裡面命名的名稱
//建立與數據庫的連接
bool:ConnectDB()
{
    if (db != INVALID_HANDLE)
        return true;
    
    if (SQL_CheckConfig(DB_CONF_NAME))
    {
        new String:Error[256];
        db = SQL_Connect(DB_CONF_NAME, true, Error, sizeof(Error));

        if (db == INVALID_HANDLE)
        {
            LogError("無法連接到數據庫: %s", Error);
            return false;
        }
        else if (!SQL_FastQuery(db, "SET NAMES 'utf8'"))
        {
            if (SQL_GetError(db, Error, sizeof(Error)))
                LogError("無法將編碼更新為 UTF8: %s", Error);
            else
                LogError("無法將編碼更新為UTF8:未知");
        }
    }
    else
    {
        LogError("Databases.cfg 缺少 '%s' 輸入!", DB_CONF_NAME);
        return false;
    }

    return true;
}

SQL_DefConnect範例,可放在玩家進入遊戲或插件開始OnPluginStart相關判斷的地方

char error[255];
Database db = SQL_DefConnect(error, sizeof(error));
 
if (db == null)
{
    PrintToServer("Could not connect: %s", error);
} 
else 
{
    delete db;
}



另一種選擇是使用SQL_ConnectCustom並通過傳遞包含它們的keyvalue句柄來手動指定所有連接參數

// The function to call, when you want to connect to the database
stock Database_Connect() {
    // Make sure to close the database handle, in case you try to connect more than once
    if (g_hDatabase != INVALID_HANDLE) {
        CloseHandle(g_hDatabase);
        g_hDatabase = INVALID_HANDLE;
    }

    // Only connect if the handle is invalid
    if (g_hDatabase == INVALID_HANDLE) {
        // Use KeyValues for login credentials
        new Handle:hKeyValues = CreateKeyValues("");
        KvSetString(hKeyValues, "host", "YOUR DATABASE ADDRESS HERE");
        KvSetString(hKeyValues, "database", "YOUR DATABASE NAME HERE");
        KvSetString(hKeyValues, "user", "YOUR DATABASE USER HERE");
        KvSetString(hKeyValues, "pass", "YOUR DATABASE PASSWORD HERE");

        // Connect and write errors to sError
        decl String:sError[512];
        g_hDatabase = SQL_ConnectCustom(hKeyValues, sError, sizeof(sError), true);
        
        // Close the KeyValues handle to free memory
        CloseHandle(hKeyValues);

        if (g_hDatabase == INVALID_HANDLE) {
            // An error has occured if the database handle is still invalid
            LogError("[Database] Failed to connect to the database! Error: %s", sError);
        } else {
            // Successfully connected to the database
            // Now you can use g_hDatabase to query your database
            PrintToServer("[Database] Successfully connected to the database");
        }
    }
}

這種的方式我覺得比較複雜,看各位要選擇哪一種方式了
SQL_Connect或SQL_DefConnect算是比較雷同的寫法,也有人使用SQL_ConnectCustom
這三種選一種方法即可,不用三個語法都加到自己原碼裡

我這邊之後會研究SQL_DefConnect的寫法,感覺簡單一點

惡靈勢力2連接資料庫的2種方法

- Copyright © 阿土進擊班 - Blogger Templates - Powered by Blogger - Designed by Johanes Djogan -