Initial commit 2
This commit is contained in:
149
README.md
Normal file
149
README.md
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
Copr. Mitachi
|
||||||
|
|
||||||
|
Pros:
|
||||||
|
- This follows the Ymir logic, there used to be a system that gave basic items to Chinese players, though it was never really used.
|
||||||
|
- You can spawn with the items already equipped and specify any slot number you want for each item.
|
||||||
|
- You can also set up count, bonuses and stones(sockets, so also duration) in the starter equipment.
|
||||||
|
- Since it happens during character creation, there's no risk of doing it before CItem or QuestManager is properly initialized, indeed, we don't even use them here.
|
||||||
|
- The function is called during PlayerCreate, so you don't need a quest flag to prevent giving items twice. It only triggers on character creation.
|
||||||
|
- It supports a lightweight reload (core based), so you can hot test or run a starter boost event without shutting down the server.
|
||||||
|
|
||||||
|
Cons:
|
||||||
|
- The only annoying part is having to specify the exact slot indexes where items go, even for equipment. But hey, you only need to do it once.
|
||||||
|
|
||||||
|
|
||||||
|
USAGE:
|
||||||
|
The structure of the JSON file is straightforward. If you're not familiar with it, feel free to ask https://chat.openai.com.
|
||||||
|
Not in the mood to use it? No problem. I’ve already used it to generate a README for you, scroll down
|
||||||
|
|
||||||
|
# Starter Items System – `give_basic_weapon.json` Usage Guide
|
||||||
|
|
||||||
|
This file defines the initial equipment and items given **at character creation**, organized into three sections.
|
||||||
|
|
||||||
|
## `common`
|
||||||
|
These items are given to **all characters**, regardless of race or job.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "vnum": 27003, "pos": 0, "equip": false }
|
||||||
|
```
|
||||||
|
|
||||||
|
| Field | Description |
|
||||||
|
|-----------|------------------------------------------------------------------------------------|
|
||||||
|
| `vnum` | The item ID (vnum) to give |
|
||||||
|
| `pos` | Inventory slot index |
|
||||||
|
| `equip` | If true, the item is placed in the equipment slot |
|
||||||
|
| `count` | (Optional) Item quantity. Defaults to 1. |
|
||||||
|
| `sockets` | (Optional) List of socket values — default is 3, but this depends on ITEM_SOCKET_MAX_NUM in your source code. |
|
||||||
|
| `attrs` | (Optional) List of attribute structs |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## `shared`
|
||||||
|
These items are given to all characters but are **intended to be equipped**, such as accessories or armor.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "vnum": 15009, "pos": 2, "equip": true }
|
||||||
|
```
|
||||||
|
|
||||||
|
- Must specify a valid equipment position (e.g., 2 = wrist, 3 = shoes).
|
||||||
|
- `equip: true` places the item in the `EQUIPMENT` window.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## `jobs`
|
||||||
|
Job-specific equipment (e.g., armor, weapons), indexed by job ID:
|
||||||
|
|
||||||
|
| Job ID | Job |
|
||||||
|
|--------|----------|
|
||||||
|
| `0` | Warrior |
|
||||||
|
| `1` | Ninja |
|
||||||
|
| `2` | Sura |
|
||||||
|
| `3` | Shaman |
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"vnum": 11209,
|
||||||
|
"pos": 0,
|
||||||
|
"equip": true,
|
||||||
|
"sockets": [0, 0, 0],
|
||||||
|
"attrs": [
|
||||||
|
{ "type": 1, "value": 500 },
|
||||||
|
{ "type": 53, "value": 30 }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- All positions (`pos`) must be **manually specified**.
|
||||||
|
- Equipment positions follow the same logic as Metin2's `EQUIPMENT` window.
|
||||||
|
- `sockets` must contain 0–2 (default is 3, but this depends on your `ITEM_SOCKET_MAX_NUM`) integers, eg. `[0, 0, 0]`.
|
||||||
|
- `attrs` must contain objects with:
|
||||||
|
- `type`: bonus ID (e.g. `1` = Max HP)
|
||||||
|
- `value`: bonus value
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Reloading
|
||||||
|
|
||||||
|
To reload the JSON without restarting the server, use the GM command:
|
||||||
|
|
||||||
|
```
|
||||||
|
/reload give_basic_weapon
|
||||||
|
```
|
||||||
|
---
|
||||||
|
|
||||||
|
## Equipment Slot Index Reference
|
||||||
|
|
||||||
|
To determine the correct `pos` value for items marked as `"equip": true`, refer to the slot indices defined in `common/length.h`:
|
||||||
|
|
||||||
|
This is an example but check yours, last wear indexes may be different.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
enum EWearPositions
|
||||||
|
{
|
||||||
|
WEAR_BODY = 0,
|
||||||
|
WEAR_HEAD = 1,
|
||||||
|
WEAR_FOOTS = 2,
|
||||||
|
WEAR_WRIST = 3,
|
||||||
|
WEAR_WEAPON = 4,
|
||||||
|
WEAR_NECK = 5,
|
||||||
|
WEAR_EAR = 6,
|
||||||
|
WEAR_UNIQUE1 = 7,
|
||||||
|
WEAR_UNIQUE2 = 8,
|
||||||
|
WEAR_ARROW = 9,
|
||||||
|
WEAR_SHIELD = 10,
|
||||||
|
|
||||||
|
WEAR_ABILITY1 = 11,
|
||||||
|
WEAR_ABILITY2 = 12,
|
||||||
|
WEAR_ABILITY3 = 13,
|
||||||
|
WEAR_ABILITY4 = 14,
|
||||||
|
WEAR_ABILITY5 = 15,
|
||||||
|
WEAR_ABILITY6 = 16,
|
||||||
|
WEAR_ABILITY7 = 17,
|
||||||
|
WEAR_ABILITY8 = 18,
|
||||||
|
WEAR_COSTUME_BODY = 19,
|
||||||
|
WEAR_COSTUME_HAIR = 20,
|
||||||
|
|
||||||
|
WEAR_COSTUME_MOUNT = 21, // if ENABLE_MOUNT_COSTUME
|
||||||
|
WEAR_COSTUME_ACCE = 22, // if ENABLE_ACCE_COSTUME
|
||||||
|
WEAR_COSTUME_WEAPON = 23, // if ENABLE_WEAPON_COSTUME
|
||||||
|
WEAR_RING1 = 24,
|
||||||
|
WEAR_RING2 = 25,
|
||||||
|
WEAR_BELT = 26,
|
||||||
|
|
||||||
|
WEAR_MAX = 32,
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
Use the corresponding `WEAR_XXX` value as the `pos` index for your equipment items in the JSON.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Json Errors?
|
||||||
|
|
||||||
|
If you got some errors, use https://jsonformatter.org/, past the code and Validate.
|
||||||
|
It fill fix the file for you
|
||||||
2
Share-Locale-Server/README.txt
Normal file
2
Share-Locale-Server/README.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
In your locale server, like usr/game/share/locale/xx/, or, if you want, in the same directory of mob_drop_item.txt.
|
||||||
|
Add this file: give_basic_weapon.json
|
||||||
98
Share-Locale-Server/give_basic_weapon.json
Normal file
98
Share-Locale-Server/give_basic_weapon.json
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
{
|
||||||
|
"common": [
|
||||||
|
{ "vnum": 27003, "pos": 0, "equip": false },
|
||||||
|
{ "vnum": 27006, "pos": 1, "equip": false },
|
||||||
|
{ "vnum": 27102, "pos": 2, "equip": false, "count": 20 },
|
||||||
|
{ "vnum": 27105, "pos": 3, "equip": false, "count": 20 },
|
||||||
|
{ "vnum": 70038, "pos": 4, "equip": false }
|
||||||
|
],
|
||||||
|
"shared": [
|
||||||
|
{ "vnum": 15009, "pos": 2, "equip": true },
|
||||||
|
{ "vnum": 14009, "pos": 3, "equip": true },
|
||||||
|
{ "vnum": 16009, "pos": 5, "equip": true },
|
||||||
|
{ "vnum": 17009, "pos": 6, "equip": true },
|
||||||
|
{ "vnum": 13009, "pos": 10, "equip": true }
|
||||||
|
],
|
||||||
|
"jobs": {
|
||||||
|
"0": [
|
||||||
|
{ "vnum": 11209, "pos": 0, "equip": true,
|
||||||
|
"sockets": [0, 0, 0],
|
||||||
|
"attrs": [
|
||||||
|
{ "type": 1, "value": 500 },
|
||||||
|
{ "type": 53, "value": 30 }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{ "vnum": 12209, "pos": 1, "equip": true },
|
||||||
|
{
|
||||||
|
"vnum": 19,
|
||||||
|
"pos": 4,
|
||||||
|
"equip": true,
|
||||||
|
"sockets": [0, 0, 0],
|
||||||
|
"attrs": [
|
||||||
|
{ "type": 5, "value": 8 },
|
||||||
|
{ "type": 17, "value": 6 }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"1": [
|
||||||
|
{ "vnum": 11409, "pos": 0, "equip": true,
|
||||||
|
"sockets": [0, 0, 0],
|
||||||
|
"attrs": [
|
||||||
|
{ "type": 1, "value": 500 },
|
||||||
|
{ "type": 53, "value": 30 }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{ "vnum": 12349, "pos": 1, "equip": true },
|
||||||
|
{
|
||||||
|
"vnum": 1009,
|
||||||
|
"pos": 4,
|
||||||
|
"equip": true,
|
||||||
|
"sockets": [0, 0, 0],
|
||||||
|
"attrs": [
|
||||||
|
{ "type": 5, "value": 8 },
|
||||||
|
{ "type": 17, "value": 6 }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"2": [
|
||||||
|
{ "vnum": 11609, "pos": 0, "equip": true,
|
||||||
|
"sockets": [0, 0, 0],
|
||||||
|
"attrs": [
|
||||||
|
{ "type": 1, "value": 500 },
|
||||||
|
{ "type": 53, "value": 30 }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{ "vnum": 12489, "pos": 1, "equip": true },
|
||||||
|
{
|
||||||
|
"vnum": 19,
|
||||||
|
"pos": 4,
|
||||||
|
"equip": true,
|
||||||
|
"sockets": [0, 0, 0],
|
||||||
|
"attrs": [
|
||||||
|
{ "type": 5, "value": 8 },
|
||||||
|
{ "type": 17, "value": 6 }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"3": [
|
||||||
|
{ "vnum": 11809, "pos": 0, "equip": true,
|
||||||
|
"sockets": [0, 0, 0],
|
||||||
|
"attrs": [
|
||||||
|
{ "type": 1, "value": 500 },
|
||||||
|
{ "type": 53, "value": 30 }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{ "vnum": 12629, "pos": 1, "equip": true },
|
||||||
|
{
|
||||||
|
"vnum": 7009,
|
||||||
|
"pos": 4,
|
||||||
|
"equip": true,
|
||||||
|
"sockets": [0, 0, 0],
|
||||||
|
"attrs": [
|
||||||
|
{ "type": 5, "value": 8 },
|
||||||
|
{ "type": 17, "value": 6 }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
// Add
|
||||||
|
|
||||||
|
#define ENABLE_START_ITEMS
|
||||||
95
Srcs-Server/game/src/#new files to add/start_item.cpp
Normal file
95
Srcs-Server/game/src/#new files to add/start_item.cpp
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
#include "stdafx.h"
|
||||||
|
|
||||||
|
#include "start_item.h"
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
std::vector<BaseItem> g_vecCommonItems;
|
||||||
|
std::vector<BaseItem> g_vecSharedItems;
|
||||||
|
std::unordered_map<BYTE, std::vector<BaseItem>> g_umapJobItems;
|
||||||
|
|
||||||
|
bool LoadStarterItemsFromJSON()
|
||||||
|
{
|
||||||
|
const std::string strPath = LocaleService_GetBasePath() + "/give_basic_weapon.json";
|
||||||
|
std::ifstream ifsFile(strPath);
|
||||||
|
if (!ifsFile.is_open())
|
||||||
|
{
|
||||||
|
sys_err("StarterItems: Failed to open %s", strPath.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
nlohmann::json jRoot;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ifsFile >> jRoot;
|
||||||
|
}
|
||||||
|
catch (const std::exception& e)
|
||||||
|
{
|
||||||
|
sys_err("StarterItems: JSON parse error: %s", e.what());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// validate required fields
|
||||||
|
if (!jRoot.contains("common") || !jRoot.contains("shared") || !jRoot.contains("jobs"))
|
||||||
|
{
|
||||||
|
sys_err("StarterItems: Missing required sections in JSON");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<BaseItem> vecCommonItems;
|
||||||
|
std::vector<BaseItem> vecSharedItems;
|
||||||
|
std::unordered_map<BYTE, std::vector<BaseItem>> umapJobItems;
|
||||||
|
|
||||||
|
auto fnParseItem = [](const nlohmann::json& jItem) -> BaseItem {
|
||||||
|
BaseItem stItem;
|
||||||
|
stItem.vnum = jItem["vnum"];
|
||||||
|
stItem.pos = jItem["pos"];
|
||||||
|
stItem.is_equipment = jItem["equip"];
|
||||||
|
stItem.count = jItem.value("count", 1);
|
||||||
|
|
||||||
|
if (jItem.contains("sockets") && jItem["sockets"].is_array())
|
||||||
|
{
|
||||||
|
const auto& jSockets = jItem["sockets"];
|
||||||
|
for (size_t i = 0; i < MIN(jSockets.size(), stItem.sockets.size()); ++i)
|
||||||
|
stItem.sockets[i] = jSockets[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (jItem.contains("attrs") && jItem["attrs"].is_array())
|
||||||
|
{
|
||||||
|
const auto& jAttrs = jItem["attrs"];
|
||||||
|
for (size_t i = 0; i < MIN(jAttrs.size(), stItem.attrs.size()); ++i)
|
||||||
|
{
|
||||||
|
stItem.attrs[i].bType = jAttrs[i].value("type", 0);
|
||||||
|
stItem.attrs[i].sValue = jAttrs[i].value("value", 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return stItem;
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const auto& jItem : jRoot["common"])
|
||||||
|
vecCommonItems.emplace_back(fnParseItem(jItem));
|
||||||
|
|
||||||
|
for (const auto& jItem : jRoot["shared"])
|
||||||
|
vecSharedItems.emplace_back(fnParseItem(jItem));
|
||||||
|
|
||||||
|
for (const auto& [strKey, jItems] : jRoot["jobs"].items())
|
||||||
|
{
|
||||||
|
BYTE byJob = static_cast<BYTE>(std::stoi(strKey));
|
||||||
|
if (!jItems.is_array())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto& vecJob = umapJobItems[byJob];
|
||||||
|
for (const auto& jItem : jItems)
|
||||||
|
vecJob.emplace_back(fnParseItem(jItem));
|
||||||
|
}
|
||||||
|
|
||||||
|
// commit parsed items
|
||||||
|
g_vecCommonItems = std::move(vecCommonItems);
|
||||||
|
g_vecSharedItems = std::move(vecSharedItems);
|
||||||
|
g_umapJobItems = std::move(umapJobItems);
|
||||||
|
|
||||||
|
sys_log(0, "StarterItems: Loaded successfully from %s", strPath.c_str());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
20
Srcs-Server/game/src/#new files to add/start_item.h
Normal file
20
Srcs-Server/game/src/#new files to add/start_item.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "locale_service.h"
|
||||||
|
|
||||||
|
#include "../../common/tables.h"
|
||||||
|
#include "../../common/item_length.h"
|
||||||
|
|
||||||
|
struct BaseItem
|
||||||
|
{
|
||||||
|
DWORD vnum;
|
||||||
|
BYTE pos;
|
||||||
|
bool is_equipment;
|
||||||
|
BYTE count{1};
|
||||||
|
std::array<long, ITEM_SOCKET_MAX_NUM> sockets{};
|
||||||
|
std::array<TPlayerItemAttribute, ITEM_ATTRIBUTE_MAX_NUM> attrs{};
|
||||||
|
};
|
||||||
|
|
||||||
|
extern std::vector<BaseItem> g_vecCommonItems;
|
||||||
|
extern std::vector<BaseItem> g_vecSharedItems;
|
||||||
|
extern std::unordered_map<BYTE, std::vector<BaseItem>> g_umapJobItems;
|
||||||
|
extern bool LoadStarterItemsFromJSON();
|
||||||
7
Srcs-Server/game/src/Makefile
Normal file
7
Srcs-Server/game/src/Makefile
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
## 1.) Look for
|
||||||
|
|
||||||
|
DragonSoul.cpp
|
||||||
|
|
||||||
|
# replace with:
|
||||||
|
|
||||||
|
DragonSoul.cpp start_item.cpp
|
||||||
37
Srcs-Server/game/src/cmd_gm.cpp
Normal file
37
Srcs-Server/game/src/cmd_gm.cpp
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/// 1.) Search at the begin of the file
|
||||||
|
|
||||||
|
#include "unique_item.h"
|
||||||
|
#include "DragonSoul.h"
|
||||||
|
|
||||||
|
// and add under, this:
|
||||||
|
|
||||||
|
#ifdef ENABLE_START_ITEMS
|
||||||
|
#include "start_item.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// 2.) Search in void CHARACTER::MountVnum(DWORD vnum):
|
||||||
|
|
||||||
|
//RELOAD_ADMIN
|
||||||
|
case 'a':
|
||||||
|
ch->ChatPacket(CHAT_TYPE_INFO, "Reloading Admin infomation.");
|
||||||
|
db_clientdesc->DBPacket(HEADER_GD_RELOAD_ADMIN, 0, NULL, 0);
|
||||||
|
sys_log(0, "Reloading admin infomation.");
|
||||||
|
break;
|
||||||
|
//END_RELOAD_ADMIN
|
||||||
|
case 'c': // cube
|
||||||
|
// ·ÎÄà ÇÁ·Î¼¼½º¸¸ °»»êÇÑ´Ù.
|
||||||
|
Cube_init ();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
|
||||||
|
// and add under, this:
|
||||||
|
|
||||||
|
#ifdef ENABLE_START_ITEMS
|
||||||
|
if (strstr(arg1, "give_basic_weapon"))
|
||||||
|
{
|
||||||
|
ch->ChatPacket(CHAT_TYPE_INFO, "Reloading: give_basic_weapon");
|
||||||
|
LoadStarterItemsFromJSON();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
111
Srcs-Server/game/src/input_db.cpp
Normal file
111
Srcs-Server/game/src/input_db.cpp
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
/// 1.) Search at the begin of the file
|
||||||
|
|
||||||
|
#include "map_location.h"
|
||||||
|
|
||||||
|
#include "DragonSoul.h"
|
||||||
|
|
||||||
|
// and add under, this:
|
||||||
|
|
||||||
|
#ifdef ENABLE_START_ITEMS
|
||||||
|
#include "start_item.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// 2.) Scroll a bit down and look for
|
||||||
|
|
||||||
|
extern void gm_insert(const char * name, BYTE level);
|
||||||
|
extern BYTE gm_get_level(const char * name, const char * host, const char* account);
|
||||||
|
extern void gm_host_insert(const char * host);
|
||||||
|
|
||||||
|
// and add under, this:
|
||||||
|
|
||||||
|
#ifdef ENABLE_START_ITEMS
|
||||||
|
extern bool RaceToJob(unsigned race, unsigned* ret_job);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// 3.) Search:
|
||||||
|
|
||||||
|
void CInputDB::PlayerCreateSuccess(LPDESC d, const char * data)
|
||||||
|
{
|
||||||
|
[...]
|
||||||
|
}
|
||||||
|
|
||||||
|
// and add UPPER, this:
|
||||||
|
|
||||||
|
#ifdef ENABLE_START_ITEMS
|
||||||
|
static void PlayerCreateGiveBasicItems(const DWORD dwPlayerID, const BYTE byJob)
|
||||||
|
{
|
||||||
|
// extract real job
|
||||||
|
unsigned int real_job = 0;
|
||||||
|
RaceToJob(byJob, &real_job);
|
||||||
|
|
||||||
|
// helper lambda to give items
|
||||||
|
auto fnGiveItem = [&](const BaseItem& item)
|
||||||
|
{
|
||||||
|
if (!item.vnum)
|
||||||
|
return;
|
||||||
|
|
||||||
|
TPlayerItem t{};
|
||||||
|
t.id = ITEM_MANAGER::instance().GetNewID();
|
||||||
|
t.owner = dwPlayerID;
|
||||||
|
t.window = item.is_equipment ? EQUIPMENT : INVENTORY;
|
||||||
|
t.pos = item.pos;
|
||||||
|
t.vnum = item.vnum;
|
||||||
|
t.count = item.count;
|
||||||
|
|
||||||
|
std::copy(item.sockets.begin(), item.sockets.end(), t.alSockets);
|
||||||
|
std::copy(item.attrs.begin(), item.attrs.end(), t.aAttr);
|
||||||
|
|
||||||
|
db_clientdesc->DBPacketHeader(HEADER_GD_ITEM_SAVE, 0, sizeof(t));
|
||||||
|
db_clientdesc->Packet(&t, sizeof(t));
|
||||||
|
};
|
||||||
|
|
||||||
|
// items giving
|
||||||
|
for (const auto& item : g_vecCommonItems)
|
||||||
|
fnGiveItem(item);
|
||||||
|
|
||||||
|
for (const auto& item : g_vecSharedItems)
|
||||||
|
fnGiveItem(item);
|
||||||
|
|
||||||
|
if (auto it = g_umapJobItems.find(real_job); it != g_umapJobItems.end())
|
||||||
|
{
|
||||||
|
for (const auto& item : it->second)
|
||||||
|
fnGiveItem(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// 3.) Search always inside void CInputDB::PlayerCreateSuccess(LPDESC d, const char * data):
|
||||||
|
|
||||||
|
TPacketGCPlayerCreateSuccess pack{};
|
||||||
|
|
||||||
|
pack.header = HEADER_GC_CHARACTER_CREATE_SUCCESS;
|
||||||
|
pack.bAccountCharacterIndex = pPacketDB->bAccountCharacterIndex;
|
||||||
|
pack.player = pPacketDB->player;
|
||||||
|
|
||||||
|
d->Packet(&pack, sizeof(TPacketGCPlayerCreateSuccess));
|
||||||
|
|
||||||
|
|
||||||
|
// and add under (like before the function end), this:
|
||||||
|
|
||||||
|
#ifdef ENABLE_START_ITEMS
|
||||||
|
// Base items
|
||||||
|
PlayerCreateGiveBasicItems(pPacketDB->player.dwID, pPacketDB->player.byJob);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// like:
|
||||||
|
/*
|
||||||
|
....
|
||||||
|
pack.header = HEADER_GC_CHARACTER_CREATE_SUCCESS;
|
||||||
|
pack.bAccountCharacterIndex = pPacketDB->bAccountCharacterIndex;
|
||||||
|
pack.player = pPacketDB->player;
|
||||||
|
|
||||||
|
d->Packet(&pack, sizeof(TPacketGCPlayerCreateSuccess));
|
||||||
|
|
||||||
|
#ifdef ENABLE_START_ITEMS
|
||||||
|
// Base items
|
||||||
|
PlayerCreateGiveBasicItems(pPacketDB->player.dwID, pPacketDB->player.byJob);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
LogManager::instance().CharLog(pack.player.dwID, 0, 0, 0, "CREATE PLAYER", "", d->GetHostName());
|
||||||
|
}
|
||||||
|
*/
|
||||||
22
Srcs-Server/game/src/main.cpp
Normal file
22
Srcs-Server/game/src/main.cpp
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
/// 1.) Search at the begin of the file
|
||||||
|
|
||||||
|
#include "skill_power.h"
|
||||||
|
#include "DragonSoul.h"
|
||||||
|
|
||||||
|
// and add under, this:
|
||||||
|
|
||||||
|
#ifdef ENABLE_START_ITEMS
|
||||||
|
#include "start_item.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// 2.) Search inside int main(int argc, char **argv):
|
||||||
|
|
||||||
|
Blend_Item_init();
|
||||||
|
ani_init();
|
||||||
|
PanamaLoad();
|
||||||
|
|
||||||
|
// and add under, this:
|
||||||
|
|
||||||
|
#ifdef ENABLE_START_ITEMS
|
||||||
|
LoadStarterItemsFromJSON();
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user