mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-11 16:51:29 +00:00
[GM Commands] Split GM Commands Into Separate Files (#1766)
* Split GM commands into their own files * Code cleanup
This commit is contained in:
parent
293361a1f7
commit
0550fcfd3f
2
.gitignore
vendored
2
.gitignore
vendored
@ -54,3 +54,5 @@ bin/
|
||||
/Win32
|
||||
/x64
|
||||
/client_files/**/CMakeFiles/
|
||||
|
||||
.idea
|
||||
|
||||
@ -65,3 +65,8 @@ void FileUtil::mkdir(const std::string& directory_name)
|
||||
::mkdir(directory_name.c_str(), 0755);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool file_exists(const std::string& name) {
|
||||
std::ifstream f(name.c_str());
|
||||
return f.good();
|
||||
}
|
||||
|
||||
@ -28,5 +28,6 @@ public:
|
||||
static void mkdir(const std::string& directory_name);
|
||||
};
|
||||
|
||||
bool file_exists(const std::string& name);
|
||||
|
||||
#endif //EQEMU_FILE_UTIL_H
|
||||
|
||||
@ -1633,3 +1633,41 @@ uint32 GetProcLimitTimer(int32 spell_id, int proc_type) {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool CastRestrictedSpell(int spellid)
|
||||
{
|
||||
switch (spellid) {
|
||||
case SPELL_TOUCH_OF_VINITRAS:
|
||||
case SPELL_DESPERATE_HOPE:
|
||||
case SPELL_CHARM:
|
||||
case SPELL_METAMORPHOSIS65:
|
||||
case SPELL_JT_BUFF:
|
||||
case SPELL_CAN_O_WHOOP_ASS:
|
||||
case SPELL_PHOENIX_CHARM:
|
||||
case SPELL_CAZIC_TOUCH:
|
||||
case SPELL_AVATAR_KNOCKBACK:
|
||||
case SPELL_SHAPECHANGE65:
|
||||
case SPELL_SUNSET_HOME1218:
|
||||
case SPELL_SUNSET_HOME819:
|
||||
case SPELL_SHAPECHANGE75:
|
||||
case SPELL_SHAPECHANGE80:
|
||||
case SPELL_SHAPECHANGE85:
|
||||
case SPELL_SHAPECHANGE90:
|
||||
case SPELL_SHAPECHANGE95:
|
||||
case SPELL_SHAPECHANGE100:
|
||||
case SPELL_SHAPECHANGE25:
|
||||
case SPELL_SHAPECHANGE30:
|
||||
case SPELL_SHAPECHANGE35:
|
||||
case SPELL_SHAPECHANGE40:
|
||||
case SPELL_SHAPECHANGE45:
|
||||
case SPELL_SHAPECHANGE50:
|
||||
case SPELL_NPC_AEGOLISM:
|
||||
case SPELL_SHAPECHANGE55:
|
||||
case SPELL_SHAPECHANGE60:
|
||||
case SPELL_COMMAND_OF_DRUZZIL:
|
||||
case SPELL_SHAPECHANGE70:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1531,5 +1531,6 @@ bool IsShortDurationBuff(uint16 spell_id);
|
||||
bool IsSpellUsableThisZoneType(uint16 spell_id, uint8 zone_type);
|
||||
const char *GetSpellName(uint16 spell_id);
|
||||
int GetSpellStatValue(uint32 spell_id, const char* stat_identifier, uint8 slot = 0);
|
||||
bool CastRestrictedSpell(int spellid);
|
||||
|
||||
#endif
|
||||
|
||||
183
utils/gm_commands/main.go
Normal file
183
utils/gm_commands/main.go
Normal file
@ -0,0 +1,183 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// zone/command.cpp
|
||||
commands, err := os.ReadFile("./zone/command.cpp")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
commandsString := string(commands)
|
||||
|
||||
s := strings.Split(commandsString, "void command_")
|
||||
commandFiles := []string{}
|
||||
if len(s) > 1 {
|
||||
startListing := false
|
||||
for i, chunk := range s {
|
||||
if strings.Contains(chunk, "logcommand(Client *c") {
|
||||
startListing = true
|
||||
}
|
||||
|
||||
// get function name
|
||||
functionName := ""
|
||||
nameSplit := strings.Split(chunk, "(Client")
|
||||
if len(nameSplit) > 0 {
|
||||
functionName = strings.TrimSpace(nameSplit[0])
|
||||
}
|
||||
|
||||
if startListing &&
|
||||
len(s[i-1]) > 0 &&
|
||||
!strings.Contains(s[i-1], "#ifdef") &&
|
||||
!strings.Contains(chunk, "#ifdef") &&
|
||||
!strings.Contains(chunk, "#ifdef BOTS") &&
|
||||
!strings.Contains(chunk, "#ifdef EQPROFILE") &&
|
||||
!strings.Contains(functionName, "bot") &&
|
||||
!strings.Contains(functionName, "help") &&
|
||||
!strings.Contains(functionName, "findaliases") {
|
||||
|
||||
fmt.Println(functionName)
|
||||
|
||||
// build command file name
|
||||
commandFile := fmt.Sprintf("zone/gm_commands/%v.cpp", functionName)
|
||||
|
||||
// append command file nam eto list
|
||||
commandFiles = append(commandFiles, commandFile)
|
||||
|
||||
includes := ""
|
||||
if strings.Contains(chunk, "Client") {
|
||||
includes = fmt.Sprintf("%v%v\n", includes, "#include \"../client.h\"")
|
||||
}
|
||||
if strings.Contains(chunk, "parse->") {
|
||||
includes = fmt.Sprintf("%v%v\n", includes, "#include \"../quest_parser_collection.h\"")
|
||||
}
|
||||
if strings.Contains(chunk, "worldserver.") {
|
||||
includes = fmt.Sprintf("%v%v\n", includes, "#include \"../worldserver.h\"")
|
||||
includes = fmt.Sprintf("%v%v\n", includes, "extern WorldServer worldserver;")
|
||||
}
|
||||
if strings.Contains(chunk, "RegionType") {
|
||||
includes = fmt.Sprintf("%v%v\n", includes, "#include \"../water_map.h\"")
|
||||
}
|
||||
if strings.Contains(chunk, "Corpse") {
|
||||
includes = fmt.Sprintf("%v%v\n", includes, "#include \"../corpse.h\"")
|
||||
}
|
||||
if strings.Contains(chunk, "Object") {
|
||||
includes = fmt.Sprintf("%v%v\n", includes, "#include \"../object.h\"")
|
||||
}
|
||||
if strings.Contains(chunk, "DoorManipulation") {
|
||||
includes = fmt.Sprintf("%v%v\n", includes, "#include \"door_manipulation.h\"")
|
||||
}
|
||||
if strings.Contains(chunk, "Group") {
|
||||
includes = fmt.Sprintf("%v%v\n", includes, "#include \"../groups.h\"")
|
||||
}
|
||||
if strings.Contains(chunk, "httplib") {
|
||||
includes = fmt.Sprintf("%v%v\n", includes, "#include \"../../common/http/httplib.h\"")
|
||||
}
|
||||
if strings.Contains(chunk, "guild_mgr") {
|
||||
includes = fmt.Sprintf("%v%v\n", includes, "#include \"../guild_mgr.h\"")
|
||||
}
|
||||
if strings.Contains(chunk, "expedition") {
|
||||
includes = fmt.Sprintf("%v%v\n", includes, "#include \"../expedition.h\"")
|
||||
}
|
||||
if strings.Contains(chunk, "DataBucket::") {
|
||||
includes = fmt.Sprintf("%v%v\n", includes, "#include \"../data_bucket.h\"")
|
||||
}
|
||||
if strings.Contains(chunk, "file_exists") {
|
||||
includes = fmt.Sprintf("%v%v\n", includes, "#include \"../../common/file_util.h\"")
|
||||
}
|
||||
if strings.Contains(chunk, "std::thread") {
|
||||
includes = fmt.Sprintf("%v%v\n", includes, "#include <thread>")
|
||||
}
|
||||
if strings.Contains(chunk, "Door") {
|
||||
includes = fmt.Sprintf("%v%v\n", includes, "#include \"../doors.h\"")
|
||||
}
|
||||
if strings.Contains(chunk, "NOW_INVISIBLE") {
|
||||
includes = fmt.Sprintf("%v%v\n", includes, "#include \"../string_ids.h\"")
|
||||
}
|
||||
if strings.Contains(chunk, "Expansion::") {
|
||||
includes = fmt.Sprintf("%v%v\n", includes, "#include \"../../common/content/world_content_service.h\"")
|
||||
}
|
||||
if strings.Contains(chunk, "MobMovementManager::") {
|
||||
includes = fmt.Sprintf("%v%v\n", includes, "#include \"../mob_movement_manager.h\"")
|
||||
}
|
||||
if strings.Contains(chunk, "MobStuckBehavior::") {
|
||||
includes = fmt.Sprintf("%v%v\n", includes, "#include \"../mob_movement_manager.h\"")
|
||||
}
|
||||
if strings.Contains(chunk, "ReloadAllPatches") {
|
||||
includes = fmt.Sprintf("%v%v\n", includes, "#include \"../../common/patches/patches.h\"")
|
||||
}
|
||||
if strings.Contains(chunk, "ProfanityManager") {
|
||||
includes = fmt.Sprintf("%v%v\n", includes, "#include \"../../common/profanity_manager.h\"")
|
||||
}
|
||||
if strings.Contains(chunk, "npc_scale_manager") {
|
||||
includes = fmt.Sprintf("%v%v\n", includes, "#include \"../npc_scale_manager.h\"")
|
||||
}
|
||||
if strings.Contains(chunk, "g_Math") {
|
||||
includes = fmt.Sprintf("%v%v\n", includes, "#include \"../fastmath.h\"")
|
||||
includes = fmt.Sprintf("%v%v\n", includes, "extern FastMath g_Math;")
|
||||
}
|
||||
if strings.Contains(chunk, "raid") {
|
||||
includes = fmt.Sprintf("%v%v\n", includes, "#include \"../raids.h\"")
|
||||
}
|
||||
if strings.Contains(chunk, "Raid") {
|
||||
includes = fmt.Sprintf("%v%v\n", includes, "#include \"../raids.h\"")
|
||||
}
|
||||
if strings.Contains(chunk, "GetOS") {
|
||||
includes = fmt.Sprintf("%v%v\n", includes, "#include \"../../common/serverinfo.h\"")
|
||||
}
|
||||
if strings.Contains(chunk, "LANG_") {
|
||||
includes = fmt.Sprintf("%v%v\n", includes, "#include \"../../common/languages.h\"")
|
||||
}
|
||||
if strings.Contains(chunk, "ServerOP_Shared") {
|
||||
includes = fmt.Sprintf("%v%v\n", includes, "#include \"../../common/shared_tasks.h\"")
|
||||
}
|
||||
if strings.Contains(chunk, "title_manager") {
|
||||
includes = fmt.Sprintf("%v%v\n", includes, "#include \"../titles.h\"")
|
||||
}
|
||||
if strings.Contains(chunk, "CatchSignal") {
|
||||
includes = fmt.Sprintf("%v%v\n", includes, "#include \"../../world/main.h\"")
|
||||
}
|
||||
|
||||
// build the contents of the command file
|
||||
commandString := fmt.Sprintf("%v\nvoid command_%v", includes, chunk)
|
||||
|
||||
//write file contents
|
||||
err := ioutil.WriteFile(commandFile, []byte(commandString), 0777)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
commandOnly := fmt.Sprintf("void command_%v", chunk)
|
||||
commandsString = strings.ReplaceAll(commandsString, commandOnly, "")
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// rewrite commands.cpp with functions removed
|
||||
err := ioutil.WriteFile("zone/command.cpp", []byte(commandsString), 0777)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
fmt.Println("# CmakeLists")
|
||||
|
||||
// sort a-z
|
||||
sort.Slice(commandFiles, func(i, j int) bool {
|
||||
return commandFiles[i] < commandFiles[j]
|
||||
})
|
||||
|
||||
for _, file := range commandFiles {
|
||||
file = strings.ReplaceAll(file, "zone/", "")
|
||||
fmt.Println(file)
|
||||
}
|
||||
}
|
||||
|
||||
//fmt.Print(string(commands))
|
||||
}
|
||||
@ -1,293 +1,576 @@
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
|
||||
|
||||
SET(zone_sources
|
||||
aa.cpp
|
||||
aa_ability.cpp
|
||||
aggro.cpp
|
||||
aggromanager.cpp
|
||||
api_service.cpp
|
||||
attack.cpp
|
||||
aura.cpp
|
||||
beacon.cpp
|
||||
bonuses.cpp
|
||||
bot.cpp
|
||||
bot_command.cpp
|
||||
bot_database.cpp
|
||||
botspellsai.cpp
|
||||
cheat_manager.cpp
|
||||
client.cpp
|
||||
client_mods.cpp
|
||||
client_packet.cpp
|
||||
client_process.cpp
|
||||
command.cpp
|
||||
corpse.cpp
|
||||
data_bucket.cpp
|
||||
doors.cpp
|
||||
dialogue_window.cpp
|
||||
dynamic_zone.cpp
|
||||
effects.cpp
|
||||
embparser.cpp
|
||||
embparser_api.cpp
|
||||
embperl.cpp
|
||||
embxs.cpp
|
||||
encounter.cpp
|
||||
entity.cpp
|
||||
exp.cpp
|
||||
expedition.cpp
|
||||
expedition_database.cpp
|
||||
expedition_request.cpp
|
||||
fastmath.cpp
|
||||
fearpath.cpp
|
||||
forage.cpp
|
||||
groups.cpp
|
||||
guild.cpp
|
||||
guild_mgr.cpp
|
||||
hate_list.cpp
|
||||
heal_rotation.cpp
|
||||
horse.cpp
|
||||
inventory.cpp
|
||||
loottables.cpp
|
||||
lua_bot.cpp
|
||||
lua_bit.cpp
|
||||
lua_corpse.cpp
|
||||
lua_client.cpp
|
||||
lua_door.cpp
|
||||
lua_encounter.cpp
|
||||
lua_entity.cpp
|
||||
lua_entity_list.cpp
|
||||
lua_expedition.cpp
|
||||
lua_general.cpp
|
||||
lua_group.cpp
|
||||
lua_hate_list.cpp
|
||||
lua_inventory.cpp
|
||||
lua_item.cpp
|
||||
lua_iteminst.cpp
|
||||
lua_mob.cpp
|
||||
lua_mod.cpp
|
||||
lua_npc.cpp
|
||||
lua_object.cpp
|
||||
lua_packet.cpp
|
||||
lua_parser.cpp
|
||||
lua_parser_events.cpp
|
||||
lua_raid.cpp
|
||||
lua_spawn.cpp
|
||||
lua_spell.cpp
|
||||
lua_stat_bonuses.cpp
|
||||
embperl.cpp
|
||||
embxs.cpp
|
||||
entity.cpp
|
||||
exp.cpp
|
||||
fearpath.cpp
|
||||
forage.cpp
|
||||
global_loot_manager.cpp
|
||||
gm_commands/door_manipulation.cpp
|
||||
groups.cpp
|
||||
guild.cpp
|
||||
guild_mgr.cpp
|
||||
hate_list.cpp
|
||||
horse.cpp
|
||||
inventory.cpp
|
||||
loottables.cpp
|
||||
main.cpp
|
||||
map.cpp
|
||||
merc.cpp
|
||||
mob.cpp
|
||||
mob_ai.cpp
|
||||
mob_appearance.cpp
|
||||
mob_movement_manager.cpp
|
||||
mob_info.cpp
|
||||
mod_functions.cpp
|
||||
npc.cpp
|
||||
npc_ai.cpp
|
||||
npc_scale_manager.cpp
|
||||
object.cpp
|
||||
oriented_bounding_box.cpp
|
||||
pathfinder_interface.cpp
|
||||
pathfinder_nav_mesh.cpp
|
||||
pathfinder_null.cpp
|
||||
pathing.cpp
|
||||
perl_bot.cpp
|
||||
perl_client.cpp
|
||||
perl_doors.cpp
|
||||
perl_entity.cpp
|
||||
perl_expedition.cpp
|
||||
perl_groups.cpp
|
||||
perl_hateentry.cpp
|
||||
perl_inventory.cpp
|
||||
perl_mob.cpp
|
||||
perl_npc.cpp
|
||||
perl_object.cpp
|
||||
perl_perlpacket.cpp
|
||||
perl_player_corpse.cpp
|
||||
perl_questitem.cpp
|
||||
perl_raids.cpp
|
||||
perl_spell.cpp
|
||||
perlpacket.cpp
|
||||
petitions.cpp
|
||||
pets.cpp
|
||||
position.cpp
|
||||
qglobals.cpp
|
||||
queryserv.cpp
|
||||
questmgr.cpp
|
||||
quest_parser_collection.cpp
|
||||
raids.cpp
|
||||
raycast_mesh.cpp
|
||||
shared_task_zone_messaging.cpp
|
||||
spawn2.cpp
|
||||
spawn2.h
|
||||
spawngroup.cpp
|
||||
special_attacks.cpp
|
||||
spell_effects.cpp
|
||||
spells.cpp
|
||||
task_client_state.cpp
|
||||
task_goal_list_manager.cpp
|
||||
task_manager.cpp
|
||||
task_proximity_manager.cpp
|
||||
tasks.cpp
|
||||
titles.cpp
|
||||
tradeskills.cpp
|
||||
trading.cpp
|
||||
trap.cpp
|
||||
tribute.cpp
|
||||
tune.cpp
|
||||
water_map.cpp
|
||||
water_map_v1.cpp
|
||||
water_map_v2.cpp
|
||||
waypoints.cpp
|
||||
worldserver.cpp
|
||||
xtargetautohaters.cpp
|
||||
zone.cpp
|
||||
zone_config.cpp
|
||||
zonedb.cpp
|
||||
zone_event_scheduler.cpp
|
||||
zone_reload.cpp
|
||||
zone_store.cpp
|
||||
zoning.cpp
|
||||
)
|
||||
aa.cpp
|
||||
aa_ability.cpp
|
||||
aggro.cpp
|
||||
aggromanager.cpp
|
||||
api_service.cpp
|
||||
attack.cpp
|
||||
aura.cpp
|
||||
beacon.cpp
|
||||
bonuses.cpp
|
||||
bot.cpp
|
||||
bot_command.cpp
|
||||
bot_database.cpp
|
||||
botspellsai.cpp
|
||||
cheat_manager.cpp
|
||||
client.cpp
|
||||
client_mods.cpp
|
||||
client_packet.cpp
|
||||
client_process.cpp
|
||||
command.cpp
|
||||
corpse.cpp
|
||||
data_bucket.cpp
|
||||
doors.cpp
|
||||
dialogue_window.cpp
|
||||
dynamic_zone.cpp
|
||||
effects.cpp
|
||||
embparser.cpp
|
||||
embparser_api.cpp
|
||||
embperl.cpp
|
||||
embxs.cpp
|
||||
encounter.cpp
|
||||
entity.cpp
|
||||
exp.cpp
|
||||
expedition.cpp
|
||||
expedition_database.cpp
|
||||
expedition_request.cpp
|
||||
fastmath.cpp
|
||||
fearpath.cpp
|
||||
forage.cpp
|
||||
groups.cpp
|
||||
guild.cpp
|
||||
guild_mgr.cpp
|
||||
hate_list.cpp
|
||||
heal_rotation.cpp
|
||||
horse.cpp
|
||||
inventory.cpp
|
||||
loottables.cpp
|
||||
lua_bot.cpp
|
||||
lua_bit.cpp
|
||||
lua_corpse.cpp
|
||||
lua_client.cpp
|
||||
lua_door.cpp
|
||||
lua_encounter.cpp
|
||||
lua_entity.cpp
|
||||
lua_entity_list.cpp
|
||||
lua_expedition.cpp
|
||||
lua_general.cpp
|
||||
lua_group.cpp
|
||||
lua_hate_list.cpp
|
||||
lua_inventory.cpp
|
||||
lua_item.cpp
|
||||
lua_iteminst.cpp
|
||||
lua_mob.cpp
|
||||
lua_mod.cpp
|
||||
lua_npc.cpp
|
||||
lua_object.cpp
|
||||
lua_packet.cpp
|
||||
lua_parser.cpp
|
||||
lua_parser_events.cpp
|
||||
lua_raid.cpp
|
||||
lua_spawn.cpp
|
||||
lua_spell.cpp
|
||||
lua_stat_bonuses.cpp
|
||||
embperl.cpp
|
||||
embxs.cpp
|
||||
entity.cpp
|
||||
exp.cpp
|
||||
fearpath.cpp
|
||||
forage.cpp
|
||||
global_loot_manager.cpp
|
||||
gm_commands/door_manipulation.cpp
|
||||
groups.cpp
|
||||
guild.cpp
|
||||
guild_mgr.cpp
|
||||
hate_list.cpp
|
||||
horse.cpp
|
||||
inventory.cpp
|
||||
loottables.cpp
|
||||
main.cpp
|
||||
map.cpp
|
||||
merc.cpp
|
||||
mob.cpp
|
||||
mob_ai.cpp
|
||||
mob_appearance.cpp
|
||||
mob_movement_manager.cpp
|
||||
mob_info.cpp
|
||||
mod_functions.cpp
|
||||
npc.cpp
|
||||
npc_ai.cpp
|
||||
npc_scale_manager.cpp
|
||||
object.cpp
|
||||
oriented_bounding_box.cpp
|
||||
pathfinder_interface.cpp
|
||||
pathfinder_nav_mesh.cpp
|
||||
pathfinder_null.cpp
|
||||
pathing.cpp
|
||||
perl_bot.cpp
|
||||
perl_client.cpp
|
||||
perl_doors.cpp
|
||||
perl_entity.cpp
|
||||
perl_expedition.cpp
|
||||
perl_groups.cpp
|
||||
perl_hateentry.cpp
|
||||
perl_inventory.cpp
|
||||
perl_mob.cpp
|
||||
perl_npc.cpp
|
||||
perl_object.cpp
|
||||
perl_perlpacket.cpp
|
||||
perl_player_corpse.cpp
|
||||
perl_questitem.cpp
|
||||
perl_raids.cpp
|
||||
perl_spell.cpp
|
||||
perlpacket.cpp
|
||||
petitions.cpp
|
||||
pets.cpp
|
||||
position.cpp
|
||||
qglobals.cpp
|
||||
queryserv.cpp
|
||||
questmgr.cpp
|
||||
quest_parser_collection.cpp
|
||||
raids.cpp
|
||||
raycast_mesh.cpp
|
||||
shared_task_zone_messaging.cpp
|
||||
spawn2.cpp
|
||||
spawn2.h
|
||||
spawngroup.cpp
|
||||
special_attacks.cpp
|
||||
spell_effects.cpp
|
||||
spells.cpp
|
||||
task_client_state.cpp
|
||||
task_goal_list_manager.cpp
|
||||
task_manager.cpp
|
||||
task_proximity_manager.cpp
|
||||
tasks.cpp
|
||||
titles.cpp
|
||||
tradeskills.cpp
|
||||
trading.cpp
|
||||
trap.cpp
|
||||
tribute.cpp
|
||||
tune.cpp
|
||||
water_map.cpp
|
||||
water_map_v1.cpp
|
||||
water_map_v2.cpp
|
||||
waypoints.cpp
|
||||
worldserver.cpp
|
||||
xtargetautohaters.cpp
|
||||
zone.cpp
|
||||
zone_config.cpp
|
||||
zonedb.cpp
|
||||
zone_event_scheduler.cpp
|
||||
zone_reload.cpp
|
||||
zone_store.cpp
|
||||
zoning.cpp
|
||||
)
|
||||
|
||||
SET(zone_headers
|
||||
aa.h
|
||||
aa_ability.h
|
||||
aggromanager.h
|
||||
api_service.h
|
||||
aura.h
|
||||
basic_functions.h
|
||||
beacon.h
|
||||
bot.h
|
||||
bot_command.h
|
||||
bot_database.h
|
||||
bot_structs.h
|
||||
cheat_manager.h
|
||||
client.h
|
||||
client_packet.h
|
||||
command.h
|
||||
common.h
|
||||
corpse.h
|
||||
data_bucket.h
|
||||
doors.h
|
||||
dialogue_window.h
|
||||
dynamic_zone.h
|
||||
embparser.h
|
||||
embperl.h
|
||||
embxs.h
|
||||
encounter.h
|
||||
entity.h
|
||||
errmsg.h
|
||||
event_codes.h
|
||||
expedition.h
|
||||
expedition_database.h
|
||||
expedition_request.h
|
||||
fastmath.h
|
||||
forage.h
|
||||
global_loot_manager.h
|
||||
gm_commands/door_manipulation.h
|
||||
groups.h
|
||||
guild_mgr.h
|
||||
hate_list.h
|
||||
heal_rotation.h
|
||||
horse.h
|
||||
lua_bot.h
|
||||
lua_bit.h
|
||||
lua_client.h
|
||||
lua_corpse.h
|
||||
lua_door.h
|
||||
lua_encounter.h
|
||||
lua_entity.h
|
||||
lua_entity_list.h
|
||||
lua_expedition.h
|
||||
lua_general.h
|
||||
lua_group.h
|
||||
lua_hate_list.h
|
||||
lua_inventory.h
|
||||
lua_item.h
|
||||
lua_iteminst.h
|
||||
lua_mob.h
|
||||
lua_mod.h
|
||||
lua_npc.h
|
||||
lua_object.h
|
||||
lua_packet.h
|
||||
lua_parser.h
|
||||
lua_parser_events.h
|
||||
lua_ptr.h
|
||||
lua_raid.h
|
||||
lua_spawn.h
|
||||
lua_spell.h
|
||||
lua_stat_bonuses.h
|
||||
map.h
|
||||
masterentity.h
|
||||
maxskill.h
|
||||
message.h
|
||||
merc.h
|
||||
mob.h
|
||||
mob_movement_manager.h
|
||||
npc.h
|
||||
npc_ai.h
|
||||
npc_scale_manager.h
|
||||
object.h
|
||||
oriented_bounding_box.h
|
||||
pathfinder_interface.h
|
||||
pathfinder_nav_mesh.h
|
||||
pathfinder_null.h
|
||||
perlpacket.h
|
||||
petitions.h
|
||||
pets.h
|
||||
position.h
|
||||
qglobals.h
|
||||
quest_interface.h
|
||||
queryserv.h
|
||||
quest_interface.h
|
||||
questmgr.h
|
||||
quest_parser_collection.h
|
||||
raids.h
|
||||
raycast_mesh.h
|
||||
skills.h
|
||||
shared_task_zone_messaging.h
|
||||
spawn2.cpp
|
||||
spawn2.h
|
||||
spawngroup.h
|
||||
string_ids.h
|
||||
task_client_state.h
|
||||
task_goal_list_manager.h
|
||||
task_manager.h
|
||||
task_proximity_manager.h
|
||||
tasks.h
|
||||
titles.h
|
||||
trap.h
|
||||
water_map.h
|
||||
water_map_v1.h
|
||||
water_map_v2.h
|
||||
worldserver.h
|
||||
xtargetautohaters.h
|
||||
zone.h
|
||||
zone_event_scheduler.h
|
||||
zone_config.h
|
||||
zonedb.h
|
||||
zonedump.h
|
||||
zone_reload.h
|
||||
zone_store.h
|
||||
aa.h
|
||||
aa_ability.h
|
||||
aggromanager.h
|
||||
api_service.h
|
||||
aura.h
|
||||
basic_functions.h
|
||||
beacon.h
|
||||
bot.h
|
||||
bot_command.h
|
||||
bot_database.h
|
||||
bot_structs.h
|
||||
cheat_manager.h
|
||||
client.h
|
||||
client_packet.h
|
||||
command.h
|
||||
common.h
|
||||
corpse.h
|
||||
data_bucket.h
|
||||
doors.h
|
||||
dialogue_window.h
|
||||
dynamic_zone.h
|
||||
embparser.h
|
||||
embperl.h
|
||||
embxs.h
|
||||
encounter.h
|
||||
entity.h
|
||||
errmsg.h
|
||||
event_codes.h
|
||||
expedition.h
|
||||
expedition_database.h
|
||||
expedition_request.h
|
||||
fastmath.h
|
||||
forage.h
|
||||
global_loot_manager.h
|
||||
gm_commands/door_manipulation.h
|
||||
groups.h
|
||||
guild_mgr.h
|
||||
hate_list.h
|
||||
heal_rotation.h
|
||||
horse.h
|
||||
lua_bot.h
|
||||
lua_bit.h
|
||||
lua_client.h
|
||||
lua_corpse.h
|
||||
lua_door.h
|
||||
lua_encounter.h
|
||||
lua_entity.h
|
||||
lua_entity_list.h
|
||||
lua_expedition.h
|
||||
lua_general.h
|
||||
lua_group.h
|
||||
lua_hate_list.h
|
||||
lua_inventory.h
|
||||
lua_item.h
|
||||
lua_iteminst.h
|
||||
lua_mob.h
|
||||
lua_mod.h
|
||||
lua_npc.h
|
||||
lua_object.h
|
||||
lua_packet.h
|
||||
lua_parser.h
|
||||
lua_parser_events.h
|
||||
lua_ptr.h
|
||||
lua_raid.h
|
||||
lua_spawn.h
|
||||
lua_spell.h
|
||||
lua_stat_bonuses.h
|
||||
map.h
|
||||
masterentity.h
|
||||
maxskill.h
|
||||
message.h
|
||||
merc.h
|
||||
mob.h
|
||||
mob_movement_manager.h
|
||||
npc.h
|
||||
npc_ai.h
|
||||
npc_scale_manager.h
|
||||
object.h
|
||||
oriented_bounding_box.h
|
||||
pathfinder_interface.h
|
||||
pathfinder_nav_mesh.h
|
||||
pathfinder_null.h
|
||||
perlpacket.h
|
||||
petitions.h
|
||||
pets.h
|
||||
position.h
|
||||
qglobals.h
|
||||
quest_interface.h
|
||||
queryserv.h
|
||||
quest_interface.h
|
||||
questmgr.h
|
||||
quest_parser_collection.h
|
||||
raids.h
|
||||
raycast_mesh.h
|
||||
skills.h
|
||||
shared_task_zone_messaging.h
|
||||
spawn2.cpp
|
||||
spawn2.h
|
||||
spawngroup.h
|
||||
string_ids.h
|
||||
task_client_state.h
|
||||
task_goal_list_manager.h
|
||||
task_manager.h
|
||||
task_proximity_manager.h
|
||||
tasks.h
|
||||
titles.h
|
||||
trap.h
|
||||
water_map.h
|
||||
water_map_v1.h
|
||||
water_map_v2.h
|
||||
worldserver.h
|
||||
xtargetautohaters.h
|
||||
zone.h
|
||||
zone_event_scheduler.h
|
||||
zone_config.h
|
||||
zonedb.h
|
||||
zonedump.h
|
||||
zone_reload.h
|
||||
zone_store.h
|
||||
)
|
||||
|
||||
SET(gm_commands
|
||||
gm_commands/acceptrules.cpp
|
||||
gm_commands/advnpcspawn.cpp
|
||||
gm_commands/aggro.cpp
|
||||
gm_commands/aggrozone.cpp
|
||||
gm_commands/ai.cpp
|
||||
gm_commands/appearance.cpp
|
||||
gm_commands/attack.cpp
|
||||
gm_commands/augmentitem.cpp
|
||||
gm_commands/ban.cpp
|
||||
gm_commands/beard.cpp
|
||||
gm_commands/beardcolor.cpp
|
||||
gm_commands/bestz.cpp
|
||||
gm_commands/bind.cpp
|
||||
gm_commands/camerashake.cpp
|
||||
gm_commands/castspell.cpp
|
||||
gm_commands/chat.cpp
|
||||
gm_commands/checklos.cpp
|
||||
gm_commands/copycharacter.cpp
|
||||
gm_commands/corpse.cpp
|
||||
gm_commands/corpsefix.cpp
|
||||
gm_commands/cvs.cpp
|
||||
gm_commands/damage.cpp
|
||||
gm_commands/databuckets.cpp
|
||||
gm_commands/date.cpp
|
||||
gm_commands/dbspawn2.cpp
|
||||
gm_commands/delacct.cpp
|
||||
gm_commands/deletegraveyard.cpp
|
||||
gm_commands/delpetition.cpp
|
||||
gm_commands/depop.cpp
|
||||
gm_commands/depopzone.cpp
|
||||
gm_commands/details.cpp
|
||||
gm_commands/devtools.cpp
|
||||
gm_commands/disablerecipe.cpp
|
||||
gm_commands/disarmtrap.cpp
|
||||
gm_commands/distance.cpp
|
||||
gm_commands/doanim.cpp
|
||||
gm_commands/door.cpp
|
||||
gm_commands/dye.cpp
|
||||
gm_commands/dz.cpp
|
||||
gm_commands/dzkickplayers.cpp
|
||||
gm_commands/editmassrespawn.cpp
|
||||
gm_commands/emote.cpp
|
||||
gm_commands/emotesearch.cpp
|
||||
gm_commands/emoteview.cpp
|
||||
gm_commands/enablerecipe.cpp
|
||||
gm_commands/endurance.cpp
|
||||
gm_commands/equipitem.cpp
|
||||
gm_commands/face.cpp
|
||||
gm_commands/faction.cpp
|
||||
gm_commands/findclass.cpp
|
||||
gm_commands/findfaction.cpp
|
||||
gm_commands/findnpctype.cpp
|
||||
gm_commands/findrace.cpp
|
||||
gm_commands/findskill.cpp
|
||||
gm_commands/findspell.cpp
|
||||
gm_commands/findtask.cpp
|
||||
gm_commands/findzone.cpp
|
||||
gm_commands/fixmob.cpp
|
||||
gm_commands/flag.cpp
|
||||
gm_commands/flagedit.cpp
|
||||
gm_commands/flags.cpp
|
||||
gm_commands/flymode.cpp
|
||||
gm_commands/fov.cpp
|
||||
gm_commands/freeze.cpp
|
||||
gm_commands/gassign.cpp
|
||||
gm_commands/gearup.cpp
|
||||
gm_commands/gender.cpp
|
||||
gm_commands/getplayerburiedcorpsecount.cpp
|
||||
gm_commands/getvariable.cpp
|
||||
gm_commands/ginfo.cpp
|
||||
gm_commands/giveitem.cpp
|
||||
gm_commands/givemoney.cpp
|
||||
gm_commands/globalview.cpp
|
||||
gm_commands/gm.cpp
|
||||
gm_commands/gmspeed.cpp
|
||||
gm_commands/gmzone.cpp
|
||||
gm_commands/goto.cpp
|
||||
gm_commands/grid.cpp
|
||||
gm_commands/guild.cpp
|
||||
gm_commands/guildapprove.cpp
|
||||
gm_commands/guildcreate.cpp
|
||||
gm_commands/guildlist.cpp
|
||||
gm_commands/hair.cpp
|
||||
gm_commands/haircolor.cpp
|
||||
gm_commands/haste.cpp
|
||||
gm_commands/hatelist.cpp
|
||||
gm_commands/heal.cpp
|
||||
gm_commands/helm.cpp
|
||||
gm_commands/heritage.cpp
|
||||
gm_commands/heromodel.cpp
|
||||
gm_commands/hideme.cpp
|
||||
gm_commands/hp.cpp
|
||||
gm_commands/incstat.cpp
|
||||
gm_commands/instance.cpp
|
||||
gm_commands/interrogateinv.cpp
|
||||
gm_commands/interrupt.cpp
|
||||
gm_commands/invsnapshot.cpp
|
||||
gm_commands/invul.cpp
|
||||
gm_commands/ipban.cpp
|
||||
gm_commands/iplookup.cpp
|
||||
gm_commands/iteminfo.cpp
|
||||
gm_commands/itemsearch.cpp
|
||||
gm_commands/kick.cpp
|
||||
gm_commands/kill.cpp
|
||||
gm_commands/killallnpcs.cpp
|
||||
gm_commands/lastname.cpp
|
||||
gm_commands/list.cpp
|
||||
gm_commands/listpetition.cpp
|
||||
gm_commands/loc.cpp
|
||||
gm_commands/lock.cpp
|
||||
gm_commands/logcommand.cpp
|
||||
gm_commands/logs.cpp
|
||||
gm_commands/makepet.cpp
|
||||
gm_commands/mana.cpp
|
||||
gm_commands/max_all_skills.cpp
|
||||
gm_commands/memspell.cpp
|
||||
gm_commands/merchantcloseshop.cpp
|
||||
gm_commands/merchantopenshop.cpp
|
||||
gm_commands/modifynpcstat.cpp
|
||||
gm_commands/motd.cpp
|
||||
gm_commands/movechar.cpp
|
||||
gm_commands/movement.cpp
|
||||
gm_commands/myskills.cpp
|
||||
gm_commands/mysql.cpp
|
||||
gm_commands/mystats.cpp
|
||||
gm_commands/name.cpp
|
||||
gm_commands/netstats.cpp
|
||||
gm_commands/network.cpp
|
||||
gm_commands/npccast.cpp
|
||||
gm_commands/npcedit.cpp
|
||||
gm_commands/npceditmass.cpp
|
||||
gm_commands/npcemote.cpp
|
||||
gm_commands/npcloot.cpp
|
||||
gm_commands/npcsay.cpp
|
||||
gm_commands/npcshout.cpp
|
||||
gm_commands/npcspawn.cpp
|
||||
gm_commands/npcspecialattk.cpp
|
||||
gm_commands/npcstats.cpp
|
||||
gm_commands/npctype_cache.cpp
|
||||
gm_commands/npctypespawn.cpp
|
||||
gm_commands/nudge.cpp
|
||||
gm_commands/nukebuffs.cpp
|
||||
gm_commands/nukeitem.cpp
|
||||
gm_commands/object.cpp
|
||||
gm_commands/oocmute.cpp
|
||||
gm_commands/opcode.cpp
|
||||
gm_commands/path.cpp
|
||||
gm_commands/peekinv.cpp
|
||||
gm_commands/peqzone.cpp
|
||||
gm_commands/permaclass.cpp
|
||||
gm_commands/permagender.cpp
|
||||
gm_commands/permarace.cpp
|
||||
gm_commands/petitioninfo.cpp
|
||||
gm_commands/petname.cpp
|
||||
gm_commands/pf.cpp
|
||||
gm_commands/picklock.cpp
|
||||
gm_commands/profanity.cpp
|
||||
gm_commands/proximity.cpp
|
||||
gm_commands/push.cpp
|
||||
gm_commands/pvp.cpp
|
||||
gm_commands/qglobal.cpp
|
||||
gm_commands/questerrors.cpp
|
||||
gm_commands/race.cpp
|
||||
gm_commands/raidloot.cpp
|
||||
gm_commands/randomfeatures.cpp
|
||||
gm_commands/refreshgroup.cpp
|
||||
gm_commands/reloadaa.cpp
|
||||
gm_commands/reloadallrules.cpp
|
||||
gm_commands/reloademote.cpp
|
||||
gm_commands/reloadlevelmods.cpp
|
||||
gm_commands/reloadmerchants.cpp
|
||||
gm_commands/reloadperlexportsettings.cpp
|
||||
gm_commands/reloadqst.cpp
|
||||
gm_commands/reloadstatic.cpp
|
||||
gm_commands/reloadtitles.cpp
|
||||
gm_commands/reloadtraps.cpp
|
||||
gm_commands/reloadworld.cpp
|
||||
gm_commands/reloadworldrules.cpp
|
||||
gm_commands/reloadzps.cpp
|
||||
gm_commands/repop.cpp
|
||||
gm_commands/resetaa.cpp
|
||||
gm_commands/resetaa_timer.cpp
|
||||
gm_commands/resetdisc_timer.cpp
|
||||
gm_commands/revoke.cpp
|
||||
gm_commands/roambox.cpp
|
||||
gm_commands/rules.cpp
|
||||
gm_commands/save.cpp
|
||||
gm_commands/scale.cpp
|
||||
gm_commands/scribespell.cpp
|
||||
gm_commands/scribespells.cpp
|
||||
gm_commands/sendzonespawns.cpp
|
||||
gm_commands/sensetrap.cpp
|
||||
gm_commands/serverinfo.cpp
|
||||
gm_commands/serverrules.cpp
|
||||
gm_commands/set_adventure_points.cpp
|
||||
gm_commands/setaapts.cpp
|
||||
gm_commands/setaaxp.cpp
|
||||
gm_commands/setanim.cpp
|
||||
gm_commands/setcrystals.cpp
|
||||
gm_commands/setfaction.cpp
|
||||
gm_commands/setgraveyard.cpp
|
||||
gm_commands/setlanguage.cpp
|
||||
gm_commands/setlsinfo.cpp
|
||||
gm_commands/setpass.cpp
|
||||
gm_commands/setpvppoints.cpp
|
||||
gm_commands/setskill.cpp
|
||||
gm_commands/setskillall.cpp
|
||||
gm_commands/setstartzone.cpp
|
||||
gm_commands/setstat.cpp
|
||||
gm_commands/setxp.cpp
|
||||
gm_commands/showbonusstats.cpp
|
||||
gm_commands/showbuffs.cpp
|
||||
gm_commands/shownpcgloballoot.cpp
|
||||
gm_commands/shownumhits.cpp
|
||||
gm_commands/showskills.cpp
|
||||
gm_commands/showspellslist.cpp
|
||||
gm_commands/showstats.cpp
|
||||
gm_commands/showzonegloballoot.cpp
|
||||
gm_commands/showzonepoints.cpp
|
||||
gm_commands/shutdown.cpp
|
||||
gm_commands/size.cpp
|
||||
gm_commands/spawn.cpp
|
||||
gm_commands/spawnfix.cpp
|
||||
gm_commands/spawnstatus.cpp
|
||||
gm_commands/spellinfo.cpp
|
||||
gm_commands/stun.cpp
|
||||
gm_commands/summon.cpp
|
||||
gm_commands/summonburiedplayercorpse.cpp
|
||||
gm_commands/summonitem.cpp
|
||||
gm_commands/suspend.cpp
|
||||
gm_commands/task.cpp
|
||||
gm_commands/tattoo.cpp
|
||||
gm_commands/tempname.cpp
|
||||
gm_commands/texture.cpp
|
||||
gm_commands/time.cpp
|
||||
gm_commands/timers.cpp
|
||||
gm_commands/timezone.cpp
|
||||
gm_commands/title.cpp
|
||||
gm_commands/titlesuffix.cpp
|
||||
gm_commands/traindisc.cpp
|
||||
gm_commands/trapinfo.cpp
|
||||
gm_commands/tune.cpp
|
||||
gm_commands/ucs.cpp
|
||||
gm_commands/undye.cpp
|
||||
gm_commands/undyeme.cpp
|
||||
gm_commands/unfreeze.cpp
|
||||
gm_commands/unlock.cpp
|
||||
gm_commands/unscribespell.cpp
|
||||
gm_commands/unscribespells.cpp
|
||||
gm_commands/untraindisc.cpp
|
||||
gm_commands/untraindiscs.cpp
|
||||
gm_commands/uptime.cpp
|
||||
gm_commands/version.cpp
|
||||
gm_commands/viewnpctype.cpp
|
||||
gm_commands/viewpetition.cpp
|
||||
gm_commands/viewzoneloot.cpp
|
||||
gm_commands/wc.cpp
|
||||
gm_commands/weather.cpp
|
||||
gm_commands/who.cpp
|
||||
gm_commands/worldshutdown.cpp
|
||||
gm_commands/worldwide.cpp
|
||||
gm_commands/wp.cpp
|
||||
gm_commands/wpadd.cpp
|
||||
gm_commands/wpinfo.cpp
|
||||
gm_commands/xtargets.cpp
|
||||
gm_commands/zclip.cpp
|
||||
gm_commands/zcolor.cpp
|
||||
gm_commands/zheader.cpp
|
||||
gm_commands/zonebootup.cpp
|
||||
gm_commands/zonelock.cpp
|
||||
gm_commands/zoneshutdown.cpp
|
||||
gm_commands/zonespawn.cpp
|
||||
gm_commands/zonestatus.cpp
|
||||
gm_commands/zopp.cpp
|
||||
gm_commands/zsafecoords.cpp
|
||||
gm_commands/zsave.cpp
|
||||
gm_commands/zsky.cpp
|
||||
gm_commands/zstats.cpp
|
||||
gm_commands/zunderworld.cpp
|
||||
gm_commands/zuwcoords.cpp
|
||||
)
|
||||
|
||||
ADD_EXECUTABLE(zone ${zone_sources} ${zone_headers})
|
||||
ADD_EXECUTABLE(zone ${zone_sources} ${zone_headers} ${gm_commands})
|
||||
|
||||
INSTALL(TARGETS zone RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
|
||||
|
||||
|
||||
15194
zone/command.cpp
15194
zone/command.cpp
File diff suppressed because it is too large
Load Diff
@ -1,22 +1,3 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.org)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
#ifndef COMMAND_H
|
||||
#define COMMAND_H
|
||||
|
||||
@ -25,18 +6,18 @@ class Seperator;
|
||||
|
||||
#include "../common/types.h"
|
||||
|
||||
#define COMMAND_CHAR '#'
|
||||
#define COMMAND_CHAR '#'
|
||||
|
||||
typedef void (*CmdFuncPtr)(Client *,const Seperator *);
|
||||
typedef void (*CmdFuncPtr)(Client *, const Seperator *);
|
||||
|
||||
typedef struct {
|
||||
int access;
|
||||
const char *desc; // description of command
|
||||
CmdFuncPtr function; // null means perl function
|
||||
} CommandRecord;
|
||||
int access;
|
||||
const char *desc; // description of command
|
||||
CmdFuncPtr function; // null means perl function
|
||||
} CommandRecord;
|
||||
|
||||
extern int (*command_dispatch)(Client *,char const*);
|
||||
extern int commandcount; // number of commands loaded
|
||||
extern int (*command_dispatch)(Client *, char const *);
|
||||
extern int commandcount; // number of commands loaded
|
||||
|
||||
// the command system:
|
||||
int command_init(void);
|
||||
@ -59,7 +40,7 @@ void command_augmentitem(Client *c, const Seperator *sep);
|
||||
void command_ban(Client *c, const Seperator *sep);
|
||||
void command_beard(Client *c, const Seperator *sep);
|
||||
void command_beardcolor(Client *c, const Seperator *sep);
|
||||
void command_bind(Client* c, const Seperator *sep);
|
||||
void command_bind(Client *c, const Seperator *sep);
|
||||
void command_camerashake(Client *c, const Seperator *sep);
|
||||
void command_castspell(Client *c, const Seperator *sep);
|
||||
void command_chat(Client *c, const Seperator *sep);
|
||||
@ -87,10 +68,10 @@ void command_doanim(Client *c, const Seperator *sep);
|
||||
void command_dye(Client *c, const Seperator *sep);
|
||||
void command_dz(Client *c, const Seperator *sep);
|
||||
void command_dzkickplayers(Client *c, const Seperator *sep);
|
||||
void command_editmassrespawn(Client* c, const Seperator* sep);
|
||||
void command_editmassrespawn(Client *c, const Seperator *sep);
|
||||
void command_emote(Client *c, const Seperator *sep);
|
||||
void command_emotesearch(Client* c, const Seperator *sep);
|
||||
void command_emoteview(Client* c, const Seperator *sep);
|
||||
void command_emotesearch(Client *c, const Seperator *sep);
|
||||
void command_emoteview(Client *c, const Seperator *sep);
|
||||
void command_emptyinventory(Client *c, const Seperator *sep);
|
||||
void command_enablerecipe(Client *c, const Seperator *sep);
|
||||
void command_endurance(Client *c, const Seperator *sep);
|
||||
@ -121,14 +102,14 @@ void command_getvariable(Client *c, const Seperator *sep);
|
||||
void command_ginfo(Client *c, const Seperator *sep);
|
||||
void command_giveitem(Client *c, const Seperator *sep);
|
||||
void command_givemoney(Client *c, const Seperator *sep);
|
||||
void command_globalview(Client* c, const Seperator *sep);
|
||||
void command_globalview(Client *c, const Seperator *sep);
|
||||
void command_gm(Client *c, const Seperator *sep);
|
||||
void command_gmspeed(Client *c, const Seperator *sep);
|
||||
void command_gmzone(Client *c, const Seperator *sep);
|
||||
void command_goto(Client *c, const Seperator *sep);
|
||||
void command_grid(Client *c, const Seperator *sep);
|
||||
void command_guild(Client *c, const Seperator *sep);
|
||||
bool helper_guild_edit(Client *c, uint32 dbid, uint32 eqid, uint8 rank, const char* what, const char* value);
|
||||
bool helper_guild_edit(Client *c, uint32 dbid, uint32 eqid, uint8 rank, const char *what, const char *value);
|
||||
void command_guildapprove(Client *c, const Seperator *sep);
|
||||
void command_guildcreate(Client *c, const Seperator *sep);
|
||||
void command_guildlist(Client *c, const Seperator *sep);
|
||||
@ -193,12 +174,14 @@ void command_npcspecialattk(Client *c, const Seperator *sep);
|
||||
void command_npcstats(Client *c, const Seperator *sep);
|
||||
void command_npctype_cache(Client *c, const Seperator *sep);
|
||||
void command_npctypespawn(Client *c, const Seperator *sep);
|
||||
void command_nudge(Client* c, const Seperator* sep);
|
||||
void command_nudge(Client *c, const Seperator *sep);
|
||||
void command_nukebuffs(Client *c, const Seperator *sep);
|
||||
void command_nukeitem(Client *c, const Seperator *sep);
|
||||
void command_object(Client* c, const Seperator *sep);
|
||||
void command_object(Client *c, const Seperator *sep);
|
||||
void command_oocmute(Client *c, const Seperator *sep);
|
||||
void command_opcode(Client *c, const Seperator *sep);
|
||||
void command_bestz(Client *c, const Seperator *message);
|
||||
void command_pf(Client *c, const Seperator *message);
|
||||
|
||||
#ifdef PACKET_PROFILER
|
||||
void command_packetprofile(Client *c, const Seperator *sep);
|
||||
@ -225,24 +208,24 @@ void command_pvp(Client *c, const Seperator *sep);
|
||||
void command_qglobal(Client *c, const Seperator *sep);
|
||||
void command_questerrors(Client *c, const Seperator *sep);
|
||||
void command_race(Client *c, const Seperator *sep);
|
||||
void command_raidloot(Client* c, const Seperator *sep);
|
||||
void command_raidloot(Client *c, const Seperator *sep);
|
||||
void command_randomfeatures(Client *c, const Seperator *sep);
|
||||
void command_refreshgroup(Client *c, const Seperator *sep);
|
||||
void command_reloadaa(Client *c, const Seperator *sep);
|
||||
void command_reloadallrules(Client *c, const Seperator *sep);
|
||||
void command_reloademote(Client* c, const Seperator *sep);
|
||||
void command_reloademote(Client *c, const Seperator *sep);
|
||||
void command_reloadlevelmods(Client *c, const Seperator *sep);
|
||||
void command_reloadmerchants(Client *c, const Seperator *sep);
|
||||
void command_reloadperlexportsettings(Client *c, const Seperator *sep);
|
||||
void command_reloadqst(Client *c, const Seperator *sep);
|
||||
void command_reloadstatic(Client *c, const Seperator *sep);
|
||||
void command_reloadtitles(Client *c, const Seperator *sep);
|
||||
void command_reloadtraps(Client* c, const Seperator *sep);
|
||||
void command_reloadtraps(Client *c, const Seperator *sep);
|
||||
void command_reloadworld(Client *c, const Seperator *sep);
|
||||
void command_reloadworldrules(Client *c, const Seperator *sep);
|
||||
void command_reloadzps(Client *c, const Seperator *sep);
|
||||
void command_repop(Client *c, const Seperator *sep);
|
||||
void command_resetaa(Client* c,const Seperator *sep);
|
||||
void command_resetaa(Client *c, const Seperator *sep);
|
||||
void command_resetaa_timer(Client *c, const Seperator *sep);
|
||||
void command_resetdisc_timer(Client *c, const Seperator *sep);
|
||||
void command_revoke(Client *c, const Seperator *sep);
|
||||
@ -305,7 +288,7 @@ void command_timezone(Client *c, const Seperator *sep);
|
||||
void command_title(Client *c, const Seperator *sep);
|
||||
void command_titlesuffix(Client *c, const Seperator *sep);
|
||||
void command_traindisc(Client *c, const Seperator *sep);
|
||||
void command_trapinfo(Client* c, const Seperator *sep);
|
||||
void command_trapinfo(Client *c, const Seperator *sep);
|
||||
void command_tune(Client *c, const Seperator *sep);
|
||||
void command_ucs(Client *c, const Seperator *sep);
|
||||
void command_undye(Client *c, const Seperator *sep);
|
||||
|
||||
11
zone/gm_commands/acceptrules.cpp
Executable file
11
zone/gm_commands/acceptrules.cpp
Executable file
@ -0,0 +1,11 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_acceptrules(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (!database.GetAgreementFlag(c->AccountID())) {
|
||||
database.SetAgreementFlag(c->AccountID());
|
||||
c->SendAppearancePacket(AT_Anim, ANIM_STAND);
|
||||
c->Message(Chat::White, "It is recorded you have agreed to the rules.");
|
||||
}
|
||||
}
|
||||
|
||||
534
zone/gm_commands/advnpcspawn.cpp
Executable file
534
zone/gm_commands/advnpcspawn.cpp
Executable file
@ -0,0 +1,534 @@
|
||||
#include "../client.h"
|
||||
#include "../groups.h"
|
||||
|
||||
void command_advnpcspawn(Client *c, const Seperator *sep)
|
||||
{
|
||||
int arguments = sep->argnum;
|
||||
if (!arguments) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"Usage: #advnpcspawn addentry [Spawngroup ID] [NPC ID] [Spawn Chance] - Adds a new Spawngroup Entry"
|
||||
);
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"Usage: #advnpcspawn addspawn [Spawngroup ID] - Adds a new Spawngroup Entry from an existing Spawngroup"
|
||||
);
|
||||
c->Message(Chat::White, "Usage: #advnpcspawn clearbox [Spawngroup ID] - Clears the roambox of a Spawngroup");
|
||||
c->Message(Chat::White, "Usage: #advnpcspawn deletespawn - Deletes a Spawngroup");
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"Usage: #advnpcspawn editbox [Spawngroup ID] [Distance] [Minimum X] [Maximum X] [Minimum Y] [Maximum Y] [Delay] - Edit the roambox of a Spawngroup"
|
||||
);
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"Usage: #advnpcspawn editrespawn [Respawn Timer] [Variance] - Edit the Respawn Timer of a Spawngroup"
|
||||
);
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"Usage: #advnpcspawn makegroup [Spawn Group Name] [Spawn Limit] [Distance] [Minimum X] [Maximum X] [Minimum Y] [Maximum Y] [Delay] - Makes a new Spawngroup"
|
||||
);
|
||||
c->Message(Chat::White, "Usage: #advnpcspawn makenpc - Makes a new NPC");
|
||||
c->Message(Chat::White, "Usage: #advnpcspawn movespawn - Moves a Spawngroup to your current location");
|
||||
c->Message(Chat::White, "Usage: #advnpcspawn setversion [Version] - Sets a Spawngroup's Version");
|
||||
return;
|
||||
}
|
||||
|
||||
std::string spawn_command = str_tolower(sep->arg[1]);
|
||||
bool is_add_entry = spawn_command.find("addentry") != std::string::npos;
|
||||
bool is_add_spawn = spawn_command.find("addspawn") != std::string::npos;
|
||||
bool is_clear_box = spawn_command.find("clearbox") != std::string::npos;
|
||||
bool is_delete_spawn = spawn_command.find("deletespawn") != std::string::npos;
|
||||
bool is_edit_box = spawn_command.find("editgroup") != std::string::npos;
|
||||
bool is_edit_respawn = spawn_command.find("editrespawn") != std::string::npos;
|
||||
bool is_make_group = spawn_command.find("makegroup") != std::string::npos;
|
||||
bool is_make_npc = spawn_command.find("makenpc") != std::string::npos;
|
||||
bool is_move_spawn = spawn_command.find("movespawn") != std::string::npos;
|
||||
bool is_set_version = spawn_command.find("setversion") != std::string::npos;
|
||||
if (
|
||||
!is_add_entry &&
|
||||
!is_add_spawn &&
|
||||
!is_clear_box &&
|
||||
!is_delete_spawn &&
|
||||
!is_edit_box &&
|
||||
!is_edit_respawn &&
|
||||
!is_make_group &&
|
||||
!is_make_npc &&
|
||||
!is_move_spawn &&
|
||||
!is_set_version
|
||||
) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"Usage: #advnpcspawn addentry [Spawngroup ID] [NPC ID] [Spawn Chance] - Adds a new Spawngroup Entry"
|
||||
);
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"Usage: #advnpcspawn addspawn [Spawngroup ID] - Adds a new Spawngroup Entry from an existing Spawngroup"
|
||||
);
|
||||
c->Message(Chat::White, "Usage: #advnpcspawn clearbox [Spawngroup ID] - Clears the roambox of a Spawngroup");
|
||||
c->Message(Chat::White, "Usage: #advnpcspawn deletespawn - Deletes a Spawngroup");
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"Usage: #advnpcspawn editbox [Spawngroup ID] [Distance] [Minimum X] [Maximum X] [Minimum Y] [Maximum Y] [Delay] - Edit the roambox of a Spawngroup"
|
||||
);
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"Usage: #advnpcspawn editrespawn [Respawn Timer] [Variance] - Edit the Respawn Timer of a Spawngroup"
|
||||
);
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"Usage: #advnpcspawn makegroup [Spawn Group Name] [Spawn Limit] [Distance] [Minimum X] [Maximum X] [Minimum Y] [Maximum Y] [Delay] - Makes a new Spawngroup"
|
||||
);
|
||||
c->Message(Chat::White, "Usage: #advnpcspawn makenpc - Makes a new NPC");
|
||||
c->Message(Chat::White, "Usage: #advnpcspawn movespawn - Moves a Spawngroup to your current location");
|
||||
c->Message(Chat::White, "Usage: #advnpcspawn setversion [Version] - Sets a Spawngroup's Version");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (is_add_entry) {
|
||||
if (arguments < 4) {
|
||||
c->Message(Chat::White, "Usage: #advnpcspawn addentry [Spawngroup ID] [NPC ID] [Spawn Chance]");
|
||||
return;
|
||||
}
|
||||
|
||||
auto spawngroup_id = std::stoi(sep->arg[2]);
|
||||
auto npc_id = std::stoi(sep->arg[2]);
|
||||
auto spawn_chance = std::stoi(sep->arg[2]);
|
||||
|
||||
std::string query = fmt::format(
|
||||
SQL(
|
||||
INSERT INTO spawnentry(spawngroupID, npcID, chance)
|
||||
VALUES({}, {}, {})
|
||||
),
|
||||
spawngroup_id,
|
||||
npc_id,
|
||||
spawn_chance
|
||||
);
|
||||
auto results = content_db.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
c->Message(Chat::White, "Failed to add entry to Spawngroup.");
|
||||
return;
|
||||
}
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"{} ({}) added to Spawngroup {}, its spawn chance is {}%%.",
|
||||
database.GetCleanNPCNameByID(npc_id),
|
||||
npc_id,
|
||||
spawngroup_id,
|
||||
spawn_chance
|
||||
).c_str()
|
||||
);
|
||||
return;
|
||||
}
|
||||
else if (is_add_spawn) {
|
||||
content_db.NPCSpawnDB(
|
||||
NPCSpawnTypes::AddSpawnFromSpawngroup,
|
||||
zone->GetShortName(),
|
||||
zone->GetInstanceVersion(),
|
||||
c,
|
||||
0,
|
||||
std::stoi(sep->arg[2])
|
||||
);
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Spawn Added | Added spawn from Spawngroup ID {}.",
|
||||
std::stoi(sep->arg[2])
|
||||
).c_str()
|
||||
);
|
||||
return;
|
||||
}
|
||||
else if (is_clear_box) {
|
||||
if (arguments != 2 || !sep->IsNumber(2)) {
|
||||
c->Message(Chat::White, "Usage: #advnpcspawn clearbox [Spawngroup ID]");
|
||||
return;
|
||||
}
|
||||
|
||||
std::string query = fmt::format(
|
||||
"UPDATE spawngroup SET dist = 0, min_x = 0, max_x = 0, min_y = 0, max_y = 0, delay = 0 WHERE id = {}",
|
||||
std::stoi(sep->arg[2])
|
||||
);
|
||||
auto results = content_db.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
c->Message(Chat::White, "Failed to clear Spawngroup box.");
|
||||
return;
|
||||
}
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Spawngroup {} Roambox Cleared | Delay: 0 Distance: 0.00",
|
||||
std::stoi(sep->arg[2])
|
||||
).c_str()
|
||||
);
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Spawngroup {} Roambox Cleared | Minimum X: 0.00 Maximum X: 0.00",
|
||||
std::stoi(sep->arg[2])
|
||||
).c_str()
|
||||
);
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Spawngroup {} Roambox Cleared | Minimum Y: 0.00 Maximum Y: 0.00",
|
||||
std::stoi(sep->arg[2])
|
||||
).c_str()
|
||||
);
|
||||
return;
|
||||
}
|
||||
else if (is_delete_spawn) {
|
||||
if (!c->GetTarget() || !c->GetTarget()->IsNPC()) {
|
||||
c->Message(Chat::White, "You must target an NPC to use this command.");
|
||||
return;
|
||||
}
|
||||
|
||||
NPC *target = c->GetTarget()->CastToNPC();
|
||||
Spawn2 *spawn2 = target->respawn2;
|
||||
if (!spawn2) {
|
||||
c->Message(Chat::White, "Failed to delete spawn because NPC has no Spawn2.");
|
||||
return;
|
||||
}
|
||||
|
||||
auto spawn2_id = spawn2->GetID();
|
||||
std::string query = fmt::format(
|
||||
"DELETE FROM spawn2 WHERE id = {}",
|
||||
spawn2_id
|
||||
);
|
||||
auto results = content_db.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
c->Message(Chat::White, "Failed to delete spawn.");
|
||||
return;
|
||||
}
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Spawn2 {} Deleted | Name: {} ({})",
|
||||
spawn2_id,
|
||||
target->GetCleanName(),
|
||||
target->GetID()
|
||||
).c_str()
|
||||
);
|
||||
target->Depop(false);
|
||||
return;
|
||||
}
|
||||
else if (is_edit_box) {
|
||||
if (
|
||||
arguments != 8 ||
|
||||
!sep->IsNumber(3) ||
|
||||
!sep->IsNumber(4) ||
|
||||
!sep->IsNumber(5) ||
|
||||
!sep->IsNumber(6) ||
|
||||
!sep->IsNumber(7) ||
|
||||
!sep->IsNumber(8)
|
||||
) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"Usage: #advnpcspawn editbox [Spawngroup ID] [Distance] [Minimum X] [Maximum X] [Minimum Y] [Maximum Y] [Delay]"
|
||||
);
|
||||
return;
|
||||
}
|
||||
auto spawngroup_id = std::stoi(sep->arg[2]);
|
||||
auto distance = std::stof(sep->arg[3]);
|
||||
auto minimum_x = std::stof(sep->arg[4]);
|
||||
auto maximum_x = std::stof(sep->arg[5]);
|
||||
auto minimum_y = std::stof(sep->arg[6]);
|
||||
auto maximum_y = std::stof(sep->arg[7]);
|
||||
auto delay = std::stoi(sep->arg[8]);
|
||||
|
||||
std::string query = fmt::format(
|
||||
"UPDATE spawngroup SET dist = {:.2f}, min_x = {:.2f}, max_x = {:.2f}, max_y = {:.2f}, min_y = {:.2f}, delay = {} WHERE id = {}",
|
||||
distance,
|
||||
minimum_x,
|
||||
maximum_x,
|
||||
minimum_y,
|
||||
maximum_y,
|
||||
delay,
|
||||
spawngroup_id
|
||||
);
|
||||
auto results = content_db.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
c->Message(Chat::White, "Failed to edit Spawngroup box.");
|
||||
return;
|
||||
}
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Spawngroup {} Roambox Edited | Delay: {} Distance: {:.2f}",
|
||||
spawngroup_id,
|
||||
delay,
|
||||
distance
|
||||
).c_str()
|
||||
);
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Spawngroup {} Roambox Edited | Minimum X: {:.2f} Maximum X: {:.2f}",
|
||||
spawngroup_id,
|
||||
minimum_x,
|
||||
maximum_x
|
||||
).c_str()
|
||||
);
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Spawngroup {} Roambox Edited | Minimum Y: {:.2f} Maximum Y: {:.2f}",
|
||||
spawngroup_id,
|
||||
minimum_y,
|
||||
maximum_y
|
||||
).c_str()
|
||||
);
|
||||
return;
|
||||
}
|
||||
else if (is_edit_respawn) {
|
||||
if (arguments < 2 || !sep->IsNumber(2)) {
|
||||
c->Message(Chat::White, "Usage: #advnpcspawn editrespawn [Respawn Timer] [Variance]");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!c->GetTarget() || !c->GetTarget()->IsNPC()) {
|
||||
c->Message(Chat::White, "You must target an NPC to use this command.");
|
||||
return;
|
||||
}
|
||||
|
||||
NPC *target = c->GetTarget()->CastToNPC();
|
||||
Spawn2 *spawn2 = target->respawn2;
|
||||
if (!spawn2) {
|
||||
c->Message(Chat::White, "Failed to edit respawn because NPC has no Spawn2.");
|
||||
return;
|
||||
}
|
||||
|
||||
auto spawn2_id = spawn2->GetID();
|
||||
uint32 respawn_timer = std::stoi(sep->arg[2]);
|
||||
uint32 variance = (
|
||||
sep->IsNumber(3) ?
|
||||
std::stoi(sep->arg[3]) :
|
||||
spawn2->GetVariance()
|
||||
);
|
||||
std::string query = fmt::format(
|
||||
"UPDATE spawn2 SET respawntime = {}, variance = {} WHERE id = {}",
|
||||
respawn_timer,
|
||||
variance,
|
||||
spawn2_id
|
||||
);
|
||||
auto results = content_db.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
c->Message(Chat::White, "Failed to edit respawn.");
|
||||
return;
|
||||
}
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Spawn2 {} Respawn Modified | Name: {} ({}) Respawn Timer: {} Variance: {}",
|
||||
spawn2_id,
|
||||
target->GetCleanName(),
|
||||
target->GetID(),
|
||||
respawn_timer,
|
||||
variance
|
||||
).c_str()
|
||||
);
|
||||
spawn2->SetRespawnTimer(respawn_timer);
|
||||
spawn2->SetVariance(variance);
|
||||
return;
|
||||
}
|
||||
else if (is_make_group) {
|
||||
if (
|
||||
arguments != 9 ||
|
||||
!sep->IsNumber(3) ||
|
||||
!sep->IsNumber(4) ||
|
||||
!sep->IsNumber(5) ||
|
||||
!sep->IsNumber(6) ||
|
||||
!sep->IsNumber(7) ||
|
||||
!sep->IsNumber(8) ||
|
||||
!sep->IsNumber(9)
|
||||
) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"Usage: #advncspawn makegroup [Spawn Group Name] [Spawn Limit] [Distance] [Minimum X] [Maximum X] [Minimum Y] [Maximum Y] [Delay]"
|
||||
);
|
||||
return;
|
||||
}
|
||||
std::string spawngroup_name = sep->arg[2];
|
||||
auto spawn_limit = std::stoi(sep->arg[3]);
|
||||
auto distance = std::stof(sep->arg[4]);
|
||||
auto minimum_x = std::stof(sep->arg[5]);
|
||||
auto maximum_x = std::stof(sep->arg[6]);
|
||||
auto minimum_y = std::stof(sep->arg[7]);
|
||||
auto maximum_y = std::stof(sep->arg[8]);
|
||||
auto delay = std::stoi(sep->arg[9]);
|
||||
|
||||
std::string query = fmt::format(
|
||||
"INSERT INTO spawngroup"
|
||||
"(name, spawn_limit, dist, min_x, max_x, min_y, max_y, delay)"
|
||||
"VALUES ('{}', {}, {:.2f}, {:.2f}, {:.2f}, {:.2f}, {:.2f}, {})",
|
||||
spawngroup_name,
|
||||
spawn_limit,
|
||||
distance,
|
||||
minimum_x,
|
||||
maximum_x,
|
||||
minimum_y,
|
||||
maximum_y,
|
||||
delay
|
||||
);
|
||||
auto results = content_db.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
c->Message(Chat::White, "Failed to make Spawngroup.");
|
||||
return;
|
||||
}
|
||||
|
||||
auto spawngroup_id = results.LastInsertedID();
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Spawngroup {} Created | Name: {} Spawn Limit: {}",
|
||||
spawngroup_id,
|
||||
spawngroup_name,
|
||||
spawn_limit
|
||||
).c_str()
|
||||
);
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Spawngroup {} Created | Delay: {} Distance: {:.2f}",
|
||||
spawngroup_id,
|
||||
delay,
|
||||
distance
|
||||
).c_str()
|
||||
);
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Spawngroup {} Created | Minimum X: {:.2f} Maximum X: {:.2f}",
|
||||
spawngroup_id,
|
||||
minimum_x,
|
||||
maximum_x
|
||||
).c_str()
|
||||
);
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Spawngroup {} Created | Minimum Y: {:.2f} Maximum Y: {:.2f}",
|
||||
spawngroup_id,
|
||||
minimum_y,
|
||||
maximum_y
|
||||
).c_str()
|
||||
);
|
||||
return;
|
||||
}
|
||||
else if (is_make_npc) {
|
||||
if (!c->GetTarget() || !c->GetTarget()->IsNPC()) {
|
||||
c->Message(Chat::White, "You must target an NPC to use this command.");
|
||||
return;
|
||||
}
|
||||
|
||||
NPC *target = c->GetTarget()->CastToNPC();
|
||||
content_db.NPCSpawnDB(
|
||||
NPCSpawnTypes::CreateNewNPC,
|
||||
zone->GetShortName(),
|
||||
zone->GetInstanceVersion(),
|
||||
c,
|
||||
target
|
||||
);
|
||||
return;
|
||||
}
|
||||
else if (is_move_spawn) {
|
||||
if (!c->GetTarget() || !c->GetTarget()->IsNPC()) {
|
||||
c->Message(Chat::White, "You must target an NPC to use this command.");
|
||||
return;
|
||||
}
|
||||
|
||||
NPC *target = c->GetTarget()->CastToNPC();
|
||||
Spawn2 *spawn2 = target->respawn2;
|
||||
if (!spawn2) {
|
||||
c->Message(Chat::White, "Failed to move spawn because NPC has no Spawn2.");
|
||||
return;
|
||||
}
|
||||
|
||||
auto client_position = c->GetPosition();
|
||||
auto spawn2_id = spawn2->GetID();
|
||||
std::string query = fmt::format(
|
||||
"UPDATE spawn2 SET x = {:.2f}, y = {:.2f}, z = {:.2f}, heading = {:.2f} WHERE id = {}",
|
||||
client_position.x,
|
||||
client_position.y,
|
||||
client_position.z,
|
||||
client_position.w,
|
||||
spawn2_id
|
||||
);
|
||||
auto results = content_db.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
c->Message(Chat::White, "Failed to move spawn.");
|
||||
return;
|
||||
}
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Spawn2 {} Moved | Name: {} ({})",
|
||||
spawn2_id,
|
||||
target->GetCleanName(),
|
||||
target->GetID()
|
||||
).c_str()
|
||||
);
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Spawn2 {} Moved | XYZ: {}, {}, {} Heading: {}",
|
||||
spawn2_id,
|
||||
client_position.x,
|
||||
client_position.y,
|
||||
client_position.z,
|
||||
client_position.w
|
||||
).c_str()
|
||||
);
|
||||
target->GMMove(
|
||||
client_position.x,
|
||||
client_position.y,
|
||||
client_position.z,
|
||||
client_position.w
|
||||
);
|
||||
return;
|
||||
}
|
||||
else if (is_set_version) {
|
||||
if (arguments != 2 || !sep->IsNumber(2)) {
|
||||
c->Message(Chat::White, "Usage: #advnpcspawn setversion [Version]");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!c->GetTarget() || !c->GetTarget()->IsNPC()) {
|
||||
c->Message(Chat::White, "You must target an NPC to use this command.");
|
||||
return;
|
||||
}
|
||||
|
||||
NPC *target = c->GetTarget()->CastToNPC();
|
||||
auto version = std::stoi(sep->arg[2]);
|
||||
std::string query = fmt::format(
|
||||
"UPDATE spawn2 SET version = {} WHERE spawngroupID = {}",
|
||||
version,
|
||||
target->GetSpawnGroupId()
|
||||
);
|
||||
auto results = content_db.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
c->Message(Chat::White, "Failed to set version.");
|
||||
return;
|
||||
}
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Spawngroup {} Version Modified | Name: {} ({}) Version: {}",
|
||||
target->GetSpawnGroupId(),
|
||||
target->GetCleanName(),
|
||||
target->GetID(),
|
||||
version
|
||||
).c_str()
|
||||
);
|
||||
target->Depop(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
21
zone/gm_commands/aggro.cpp
Executable file
21
zone/gm_commands/aggro.cpp
Executable file
@ -0,0 +1,21 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_aggro(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (c->GetTarget() == nullptr || !c->GetTarget()->IsNPC()) {
|
||||
c->Message(Chat::White, "Error: you must have an NPC target.");
|
||||
return;
|
||||
}
|
||||
float d = atof(sep->arg[1]);
|
||||
if (d == 0.0f) {
|
||||
c->Message(Chat::Red, "Error: distance argument required.");
|
||||
return;
|
||||
}
|
||||
bool verbose = false;
|
||||
if (sep->arg[2][0] == '-' && sep->arg[2][1] == 'v' && sep->arg[2][2] == '\0') {
|
||||
verbose = true;
|
||||
}
|
||||
|
||||
entity_list.DescribeAggro(c, c->GetTarget()->CastToNPC(), d, verbose);
|
||||
}
|
||||
|
||||
19
zone/gm_commands/aggrozone.cpp
Executable file
19
zone/gm_commands/aggrozone.cpp
Executable file
@ -0,0 +1,19 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_aggrozone(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (!c) {
|
||||
return;
|
||||
}
|
||||
|
||||
Mob *m = c->CastToMob();
|
||||
|
||||
if (!m) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 hate = atoi(sep->arg[1]); //should default to 0 if we don't enter anything
|
||||
entity_list.AggroZone(m, hate);
|
||||
c->Message(Chat::White, "Train to you! Last chance to go invulnerable...");
|
||||
}
|
||||
|
||||
139
zone/gm_commands/ai.cpp
Executable file
139
zone/gm_commands/ai.cpp
Executable file
@ -0,0 +1,139 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_ai(Client *c, const Seperator *sep)
|
||||
{
|
||||
Mob *target = c->GetTarget();
|
||||
|
||||
if (strcasecmp(sep->arg[1], "factionid") == 0) {
|
||||
if (target && sep->IsNumber(2)) {
|
||||
if (target->IsNPC()) {
|
||||
target->CastToNPC()->SetNPCFactionID(atoi(sep->arg[2]));
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "%s is not an NPC.", target->GetName());
|
||||
}
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Usage: (targeted) #ai factionid [factionid]");
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sep->arg[1], "spellslist") == 0) {
|
||||
if (target && sep->IsNumber(2) && atoi(sep->arg[2]) >= 0) {
|
||||
if (target->IsNPC()) {
|
||||
target->CastToNPC()->AI_AddNPCSpells(atoi(sep->arg[2]));
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "%s is not an NPC.", target->GetName());
|
||||
}
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Usage: (targeted) #ai spellslist [npc_spells_id]");
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sep->arg[1], "con") == 0) {
|
||||
if (target && sep->arg[2][0] != 0) {
|
||||
Mob *tar2 = entity_list.GetMob(sep->arg[2]);
|
||||
if (tar2) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"%s considering %s: %i",
|
||||
target->GetName(),
|
||||
tar2->GetName(),
|
||||
tar2->GetReverseFactionCon(target));
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Error: %s not found.", sep->arg[2]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Usage: (targeted) #ai con [mob name]");
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sep->arg[1], "guard") == 0) {
|
||||
if (target && target->IsNPC()) {
|
||||
target->CastToNPC()->SaveGuardSpot(target->GetPosition());
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"Usage: (targeted) #ai guard - sets npc to guard the current location (use #summon to move)"
|
||||
);
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sep->arg[1], "roambox") == 0) {
|
||||
if (target && target->IsAIControlled() && target->IsNPC()) {
|
||||
if ((sep->argnum == 6 || sep->argnum == 7 || sep->argnum == 8) && sep->IsNumber(2) && sep->IsNumber(3) &&
|
||||
sep->IsNumber(4) && sep->IsNumber(5) && sep->IsNumber(6)) {
|
||||
uint32 tmp = 2500;
|
||||
uint32 tmp2 = 2500;
|
||||
if (sep->IsNumber(7)) {
|
||||
tmp = atoi(sep->arg[7]);
|
||||
}
|
||||
if (sep->IsNumber(8)) {
|
||||
tmp2 = atoi(sep->arg[8]);
|
||||
}
|
||||
target->CastToNPC()->AI_SetRoambox(
|
||||
atof(sep->arg[2]),
|
||||
atof(sep->arg[3]),
|
||||
atof(sep->arg[4]),
|
||||
atof(sep->arg[5]),
|
||||
atof(sep->arg[6]),
|
||||
tmp,
|
||||
tmp2
|
||||
);
|
||||
}
|
||||
else if ((sep->argnum == 3 || sep->argnum == 4) && sep->IsNumber(2) && sep->IsNumber(3)) {
|
||||
uint32 tmp = 2500;
|
||||
uint32 tmp2 = 2500;
|
||||
if (sep->IsNumber(4)) {
|
||||
tmp = atoi(sep->arg[4]);
|
||||
}
|
||||
if (sep->IsNumber(5)) {
|
||||
tmp2 = atoi(sep->arg[5]);
|
||||
}
|
||||
target->CastToNPC()->AI_SetRoambox(atof(sep->arg[2]), atof(sep->arg[3]), tmp, tmp2);
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Usage: #ai roambox dist max_x min_x max_y min_y [delay] [mindelay]");
|
||||
c->Message(Chat::White, "Usage: #ai roambox dist roamdist [delay] [mindelay]");
|
||||
}
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "You need a AI NPC targeted");
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sep->arg[1], "stop") == 0 && c->Admin() >= commandToggleAI) {
|
||||
if (target) {
|
||||
if (target->IsAIControlled()) {
|
||||
target->AI_Stop();
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Error: Target is not AI controlled");
|
||||
}
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Usage: Target a Mob with AI enabled and use this to turn off their AI.");
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sep->arg[1], "start") == 0 && c->Admin() >= commandToggleAI) {
|
||||
if (target) {
|
||||
if (!target->IsAIControlled()) {
|
||||
target->AI_Start();
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Error: Target is already AI controlled");
|
||||
}
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Usage: Target a Mob with AI disabled and use this to turn on their AI.");
|
||||
}
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "#AI Sub-commands");
|
||||
c->Message(Chat::White, " factionid");
|
||||
c->Message(Chat::White, " spellslist");
|
||||
c->Message(Chat::White, " con");
|
||||
c->Message(Chat::White, " guard");
|
||||
}
|
||||
}
|
||||
|
||||
26
zone/gm_commands/appearance.cpp
Executable file
26
zone/gm_commands/appearance.cpp
Executable file
@ -0,0 +1,26 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_appearance(Client *c, const Seperator *sep)
|
||||
{
|
||||
Mob *t = c->CastToMob();
|
||||
|
||||
// sends any appearance packet
|
||||
// Dev debug command, for appearance types
|
||||
if (sep->arg[2][0] == 0) {
|
||||
c->Message(Chat::White, "Usage: #appearance type value");
|
||||
}
|
||||
else {
|
||||
if ((c->GetTarget())) {
|
||||
t = c->GetTarget();
|
||||
}
|
||||
t->SendAppearancePacket(atoi(sep->arg[1]), atoi(sep->arg[2]));
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"Sending appearance packet: target=%s, type=%s, value=%s",
|
||||
t->GetName(),
|
||||
sep->arg[1],
|
||||
sep->arg[2]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
18
zone/gm_commands/attack.cpp
Executable file
18
zone/gm_commands/attack.cpp
Executable file
@ -0,0 +1,18 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_attack(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (c->GetTarget() && c->GetTarget()->IsNPC() && sep->arg[1] != 0) {
|
||||
Mob *sictar = entity_list.GetMob(sep->argplus[1]);
|
||||
if (sictar) {
|
||||
c->GetTarget()->CastToNPC()->AddToHateList(sictar, 1, 0);
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Error: %s not found", sep->arg[1]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Usage: (needs NPC targeted) #attack targetname");
|
||||
}
|
||||
}
|
||||
|
||||
18
zone/gm_commands/augmentitem.cpp
Executable file
18
zone/gm_commands/augmentitem.cpp
Executable file
@ -0,0 +1,18 @@
|
||||
#include "../client.h"
|
||||
#include "../object.h"
|
||||
|
||||
void command_augmentitem(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (!c) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto in_augment = new AugmentItem_Struct[sizeof(AugmentItem_Struct)];
|
||||
in_augment->container_slot = 1000; // <watch>
|
||||
in_augment->augment_slot = -1;
|
||||
if (c->GetTradeskillObject() != nullptr) {
|
||||
Object::HandleAugmentation(c, in_augment, c->GetTradeskillObject());
|
||||
}
|
||||
safe_delete_array(in_augment);
|
||||
}
|
||||
|
||||
72
zone/gm_commands/ban.cpp
Executable file
72
zone/gm_commands/ban.cpp
Executable file
@ -0,0 +1,72 @@
|
||||
#include "../client.h"
|
||||
#include "../worldserver.h"
|
||||
|
||||
extern WorldServer worldserver;
|
||||
|
||||
void command_ban(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (sep->arg[1][0] == 0 || sep->arg[2][0] == 0) {
|
||||
c->Message(Chat::White, "Usage: #ban <charname> <message>");
|
||||
return;
|
||||
}
|
||||
|
||||
auto account_id = database.GetAccountIDByChar(sep->arg[1]);
|
||||
|
||||
std::string message;
|
||||
int i = 2;
|
||||
while (1) {
|
||||
if (sep->arg[i][0] == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (message.length() > 0) {
|
||||
message.push_back(' ');
|
||||
}
|
||||
|
||||
message += sep->arg[i];
|
||||
++i;
|
||||
}
|
||||
|
||||
if (message.length() == 0) {
|
||||
c->Message(Chat::White, "Usage: #ban <charname> <message>");
|
||||
return;
|
||||
}
|
||||
|
||||
if (account_id == 0) {
|
||||
c->Message(Chat::Red, "Character does not exist.");
|
||||
return;
|
||||
}
|
||||
|
||||
std::string query = StringFormat(
|
||||
"UPDATE account SET status = -2, ban_reason = '%s' "
|
||||
"WHERE id = %i", EscapeString(message).c_str(), account_id
|
||||
);
|
||||
auto results = database.QueryDatabase(query);
|
||||
|
||||
c->Message(
|
||||
Chat::Red,
|
||||
"Account number %i with the character %s has been banned with message: \"%s\"",
|
||||
account_id,
|
||||
sep->arg[1],
|
||||
message.c_str());
|
||||
|
||||
ServerPacket flagUpdatePack(ServerOP_FlagUpdate, 6);
|
||||
*((uint32 *) &flagUpdatePack.pBuffer[0]) = account_id;
|
||||
*((int16 *) &flagUpdatePack.pBuffer[4]) = -2;
|
||||
worldserver.SendPacket(&flagUpdatePack);
|
||||
|
||||
Client *client = nullptr;
|
||||
client = entity_list.GetClientByName(sep->arg[1]);
|
||||
if (client) {
|
||||
client->WorldKick();
|
||||
return;
|
||||
}
|
||||
|
||||
ServerPacket kickPlayerPack(ServerOP_KickPlayer, sizeof(ServerKickPlayer_Struct));
|
||||
ServerKickPlayer_Struct *skp = (ServerKickPlayer_Struct *) kickPlayerPack.pBuffer;
|
||||
strcpy(skp->adminname, c->GetName());
|
||||
strcpy(skp->name, sep->arg[1]);
|
||||
skp->adminrank = c->Admin();
|
||||
worldserver.SendPacket(&kickPlayerPack);
|
||||
}
|
||||
|
||||
37
zone/gm_commands/beard.cpp
Executable file
37
zone/gm_commands/beard.cpp
Executable file
@ -0,0 +1,37 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_beard(Client *c, const Seperator *sep)
|
||||
{
|
||||
Mob *target = c->GetTarget();
|
||||
if (!sep->IsNumber(1)) {
|
||||
c->Message(Chat::White, "Usage: #beard [number of beard style]");
|
||||
}
|
||||
else if (!target) {
|
||||
c->Message(Chat::White, "Error: this command requires a target");
|
||||
}
|
||||
else {
|
||||
uint16 Race = target->GetRace();
|
||||
uint8 Gender = target->GetGender();
|
||||
uint8 Texture = 0xFF;
|
||||
uint8 HelmTexture = 0xFF;
|
||||
uint8 HairColor = target->GetHairColor();
|
||||
uint8 BeardColor = target->GetBeardColor();
|
||||
uint8 EyeColor1 = target->GetEyeColor1();
|
||||
uint8 EyeColor2 = target->GetEyeColor2();
|
||||
uint8 HairStyle = target->GetHairStyle();
|
||||
uint8 LuclinFace = target->GetLuclinFace();
|
||||
uint8 Beard = atoi(sep->arg[1]);
|
||||
uint32 DrakkinHeritage = target->GetDrakkinHeritage();
|
||||
uint32 DrakkinTattoo = target->GetDrakkinTattoo();
|
||||
uint32 DrakkinDetails = target->GetDrakkinDetails();
|
||||
|
||||
target->SendIllusionPacket(
|
||||
Race, Gender, Texture, HelmTexture, HairColor, BeardColor,
|
||||
EyeColor1, EyeColor2, HairStyle, LuclinFace, Beard, 0xFF,
|
||||
DrakkinHeritage, DrakkinTattoo, DrakkinDetails
|
||||
);
|
||||
|
||||
c->Message(Chat::White, "Beard = %i", atoi(sep->arg[1]));
|
||||
}
|
||||
}
|
||||
|
||||
37
zone/gm_commands/beardcolor.cpp
Executable file
37
zone/gm_commands/beardcolor.cpp
Executable file
@ -0,0 +1,37 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_beardcolor(Client *c, const Seperator *sep)
|
||||
{
|
||||
Mob *target = c->GetTarget();
|
||||
if (!sep->IsNumber(1)) {
|
||||
c->Message(Chat::White, "Usage: #beardcolor [number of beard color]");
|
||||
}
|
||||
else if (!target) {
|
||||
c->Message(Chat::White, "Error: this command requires a target");
|
||||
}
|
||||
else {
|
||||
uint16 Race = target->GetRace();
|
||||
uint8 Gender = target->GetGender();
|
||||
uint8 Texture = 0xFF;
|
||||
uint8 HelmTexture = 0xFF;
|
||||
uint8 HairColor = target->GetHairColor();
|
||||
uint8 BeardColor = atoi(sep->arg[1]);
|
||||
uint8 EyeColor1 = target->GetEyeColor1();
|
||||
uint8 EyeColor2 = target->GetEyeColor2();
|
||||
uint8 HairStyle = target->GetHairStyle();
|
||||
uint8 LuclinFace = target->GetLuclinFace();
|
||||
uint8 Beard = target->GetBeard();
|
||||
uint32 DrakkinHeritage = target->GetDrakkinHeritage();
|
||||
uint32 DrakkinTattoo = target->GetDrakkinTattoo();
|
||||
uint32 DrakkinDetails = target->GetDrakkinDetails();
|
||||
|
||||
target->SendIllusionPacket(
|
||||
Race, Gender, Texture, HelmTexture, HairColor, BeardColor,
|
||||
EyeColor1, EyeColor2, HairStyle, LuclinFace, Beard, 0xFF,
|
||||
DrakkinHeritage, DrakkinTattoo, DrakkinDetails
|
||||
);
|
||||
|
||||
c->Message(Chat::White, "Beard Color = %i", atoi(sep->arg[1]));
|
||||
}
|
||||
}
|
||||
|
||||
89
zone/gm_commands/bestz.cpp
Executable file
89
zone/gm_commands/bestz.cpp
Executable file
@ -0,0 +1,89 @@
|
||||
#include "../client.h"
|
||||
#include "../water_map.h"
|
||||
|
||||
void command_bestz(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (zone->zonemap == nullptr) {
|
||||
c->Message(Chat::White, "Map not loaded for this zone");
|
||||
}
|
||||
else {
|
||||
glm::vec3 me;
|
||||
me.x = c->GetX();
|
||||
me.y = c->GetY();
|
||||
me.z = c->GetZ() + (c->GetSize() == 0.0 ? 6 : c->GetSize()) * HEAD_POSITION;
|
||||
glm::vec3 hit;
|
||||
glm::vec3 bme(me);
|
||||
bme.z -= 500;
|
||||
|
||||
float best_z = zone->zonemap->FindBestZ(me, &hit);
|
||||
|
||||
if (best_z != BEST_Z_INVALID) {
|
||||
c->Message(Chat::White, "Z is %.3f at (%.3f, %.3f).", best_z, me.x, me.y);
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Found no Z.");
|
||||
}
|
||||
}
|
||||
|
||||
if (zone->watermap == nullptr) {
|
||||
c->Message(Chat::White, "Water Region Map not loaded for this zone");
|
||||
}
|
||||
else {
|
||||
WaterRegionType RegionType;
|
||||
float z;
|
||||
|
||||
if (c->GetTarget()) {
|
||||
z = c->GetTarget()->GetZ();
|
||||
auto position = glm::vec3(c->GetTarget()->GetX(), c->GetTarget()->GetY(), z);
|
||||
RegionType = zone->watermap->ReturnRegionType(position);
|
||||
c->Message(Chat::White, "InWater returns %d", zone->watermap->InWater(position));
|
||||
c->Message(Chat::White, "InLava returns %d", zone->watermap->InLava(position));
|
||||
|
||||
}
|
||||
else {
|
||||
z = c->GetZ();
|
||||
auto position = glm::vec3(c->GetX(), c->GetY(), z);
|
||||
RegionType = zone->watermap->ReturnRegionType(position);
|
||||
c->Message(Chat::White, "InWater returns %d", zone->watermap->InWater(position));
|
||||
c->Message(Chat::White, "InLava returns %d", zone->watermap->InLava(position));
|
||||
|
||||
}
|
||||
|
||||
switch (RegionType) {
|
||||
case RegionTypeNormal: {
|
||||
c->Message(Chat::White, "There is nothing special about the region you are in!");
|
||||
break;
|
||||
}
|
||||
case RegionTypeWater: {
|
||||
c->Message(Chat::White, "You/your target are in Water.");
|
||||
break;
|
||||
}
|
||||
case RegionTypeLava: {
|
||||
c->Message(Chat::White, "You/your target are in Lava.");
|
||||
break;
|
||||
}
|
||||
case RegionTypeVWater: {
|
||||
c->Message(Chat::White, "You/your target are in VWater (Icy Water?).");
|
||||
break;
|
||||
}
|
||||
case RegionTypePVP: {
|
||||
c->Message(Chat::White, "You/your target are in a pvp enabled area.");
|
||||
break;
|
||||
}
|
||||
case RegionTypeSlime: {
|
||||
c->Message(Chat::White, "You/your target are in slime.");
|
||||
break;
|
||||
}
|
||||
case RegionTypeIce: {
|
||||
c->Message(Chat::White, "You/your target are in ice.");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
c->Message(Chat::White, "You/your target are in an unknown region type.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
17
zone/gm_commands/bind.cpp
Executable file
17
zone/gm_commands/bind.cpp
Executable file
@ -0,0 +1,17 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_bind(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (c->GetTarget() != 0) {
|
||||
if (c->GetTarget()->IsClient()) {
|
||||
c->GetTarget()->CastToClient()->SetBindPoint();
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Error: target not a Player");
|
||||
}
|
||||
}
|
||||
else {
|
||||
c->SetBindPoint();
|
||||
}
|
||||
}
|
||||
|
||||
24
zone/gm_commands/camerashake.cpp
Executable file
24
zone/gm_commands/camerashake.cpp
Executable file
@ -0,0 +1,24 @@
|
||||
#include "../client.h"
|
||||
#include "../worldserver.h"
|
||||
|
||||
extern WorldServer worldserver;
|
||||
|
||||
void command_camerashake(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (c) {
|
||||
if (sep->arg[1][0] && sep->arg[2][0]) {
|
||||
auto pack = new ServerPacket(ServerOP_CameraShake, sizeof(ServerCameraShake_Struct));
|
||||
ServerCameraShake_Struct *scss = (ServerCameraShake_Struct *) pack->pBuffer;
|
||||
scss->duration = atoi(sep->arg[1]);
|
||||
scss->intensity = atoi(sep->arg[2]);
|
||||
worldserver.SendPacket(pack);
|
||||
c->Message(Chat::Red, "Successfully sent the packet to world! Shake it, world, shake it!");
|
||||
safe_delete(pack);
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::Red, "Usage -- #camerashake [duration], [intensity [1-10])");
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
77
zone/gm_commands/castspell.cpp
Executable file
77
zone/gm_commands/castspell.cpp
Executable file
@ -0,0 +1,77 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_castspell(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (SPDAT_RECORDS <= 0) {
|
||||
c->Message(Chat::White, "Spells not loaded.");
|
||||
return;
|
||||
}
|
||||
|
||||
Mob *target = c;
|
||||
if (c->GetTarget()) {
|
||||
target = c->GetTarget();
|
||||
}
|
||||
|
||||
if (!sep->IsNumber(1)) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"Usage: #castspell [Spell ID] [Instant (0 = False, 1 = True, Default is 1 if Unused)]"
|
||||
);
|
||||
}
|
||||
else {
|
||||
uint16 spell_id = std::stoul(sep->arg[1]);
|
||||
|
||||
if (CastRestrictedSpell(spell_id) && c->Admin() < commandCastSpecials) {
|
||||
c->Message(Chat::Red, "Unable to cast spell.");
|
||||
}
|
||||
else if (spell_id >= SPDAT_RECORDS) {
|
||||
c->Message(Chat::White, "Invalid Spell ID.");
|
||||
}
|
||||
else {
|
||||
bool instant_cast = (c->Admin() >= commandInstacast ? true : false);
|
||||
if (instant_cast && sep->IsNumber(2)) {
|
||||
instant_cast = std::stoi(sep->arg[2]) ? true : false;
|
||||
c->Message(Chat::White, fmt::format("{}", std::stoi(sep->arg[2])).c_str());
|
||||
}
|
||||
|
||||
if (c->Admin() >= commandInstacast && instant_cast) {
|
||||
c->SpellFinished(
|
||||
spell_id,
|
||||
target,
|
||||
EQ::spells::CastingSlot::Item,
|
||||
0,
|
||||
-1,
|
||||
spells[spell_id].resist_difficulty
|
||||
);
|
||||
}
|
||||
else {
|
||||
c->CastSpell(spell_id, target->GetID(), EQ::spells::CastingSlot::Item, spells[spell_id].cast_time);
|
||||
}
|
||||
|
||||
if (c != target) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Cast {} ({}) on {}{}.",
|
||||
GetSpellName(spell_id),
|
||||
spell_id,
|
||||
target->GetCleanName(),
|
||||
instant_cast ? " instantly" : ""
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Cast {} ({}) on yourself{}.",
|
||||
GetSpellName(spell_id),
|
||||
spell_id,
|
||||
instant_cast ? " instantly" : ""
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
15
zone/gm_commands/chat.cpp
Executable file
15
zone/gm_commands/chat.cpp
Executable file
@ -0,0 +1,15 @@
|
||||
#include "../client.h"
|
||||
#include "../worldserver.h"
|
||||
|
||||
extern WorldServer worldserver;
|
||||
|
||||
void command_chat(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (sep->arg[2][0] == 0) {
|
||||
c->Message(Chat::White, "Usage: #chat [channum] [message]");
|
||||
}
|
||||
else if (!worldserver.SendChannelMessage(0, 0, (uint8) atoi(sep->arg[1]), 0, 0, 100, sep->argplus[2])) {
|
||||
c->Message(Chat::White, "Error: World server disconnected");
|
||||
}
|
||||
}
|
||||
|
||||
20
zone/gm_commands/checklos.cpp
Executable file
20
zone/gm_commands/checklos.cpp
Executable file
@ -0,0 +1,20 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_checklos(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (!c->GetTarget()) {
|
||||
c->Message(Chat::White, "You must have a target to use this command.");
|
||||
}
|
||||
|
||||
bool has_los = c->CheckLosFN(c->GetTarget());
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"You {}have line of sight to {} ({}).",
|
||||
has_los ? "" : "do not ",
|
||||
c->GetTarget()->GetCleanName(),
|
||||
c->GetTarget()->GetID()
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
|
||||
34
zone/gm_commands/copycharacter.cpp
Executable file
34
zone/gm_commands/copycharacter.cpp
Executable file
@ -0,0 +1,34 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_copycharacter(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (sep->argnum < 3) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"Usage: [source_character_name] [destination_character_name] [destination_account_name]"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string source_character_name = sep->arg[1];
|
||||
std::string destination_character_name = sep->arg[2];
|
||||
std::string destination_account_name = sep->arg[3];
|
||||
|
||||
bool result = database.CopyCharacter(
|
||||
source_character_name,
|
||||
destination_character_name,
|
||||
destination_account_name
|
||||
);
|
||||
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Character Copy [{}] to [{}] via account [{}] [{}]",
|
||||
source_character_name,
|
||||
destination_character_name,
|
||||
destination_account_name,
|
||||
result ? "Success" : "Failed"
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
|
||||
168
zone/gm_commands/corpse.cpp
Executable file
168
zone/gm_commands/corpse.cpp
Executable file
@ -0,0 +1,168 @@
|
||||
#include "../client.h"
|
||||
#include "../corpse.h"
|
||||
|
||||
void command_corpse(Client *c, const Seperator *sep)
|
||||
{
|
||||
Mob *target = c->GetTarget();
|
||||
|
||||
if (strcasecmp(sep->arg[1], "DeletePlayerCorpses") == 0 && c->Admin() >= commandEditPlayerCorpses) {
|
||||
int32 tmp = entity_list.DeletePlayerCorpses();
|
||||
if (tmp >= 0) {
|
||||
c->Message(Chat::White, "%i corpses deleted.", tmp);
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "DeletePlayerCorpses Error #%i", tmp);
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sep->arg[1], "delete") == 0) {
|
||||
if (target == 0 || !target->IsCorpse()) {
|
||||
c->Message(Chat::White, "Error: Target the corpse you wish to delete");
|
||||
}
|
||||
else if (target->IsNPCCorpse()) {
|
||||
|
||||
c->Message(Chat::White, "Depoping %s.", target->GetName());
|
||||
target->CastToCorpse()->Delete();
|
||||
}
|
||||
else if (c->Admin() >= commandEditPlayerCorpses) {
|
||||
c->Message(Chat::White, "Deleting %s.", target->GetName());
|
||||
target->CastToCorpse()->Delete();
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Insufficient status to delete player corpse.");
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sep->arg[1], "ListNPC") == 0) {
|
||||
entity_list.ListNPCCorpses(c);
|
||||
}
|
||||
else if (strcasecmp(sep->arg[1], "ListPlayer") == 0) {
|
||||
entity_list.ListPlayerCorpses(c);
|
||||
}
|
||||
else if (strcasecmp(sep->arg[1], "DeleteNPCCorpses") == 0) {
|
||||
int32 tmp = entity_list.DeleteNPCCorpses();
|
||||
if (tmp >= 0) {
|
||||
c->Message(Chat::White, "%d corpses deleted.", tmp);
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "DeletePlayerCorpses Error #%d", tmp);
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sep->arg[1], "charid") == 0 && c->Admin() >= commandEditPlayerCorpses) {
|
||||
if (target == 0 || !target->IsPlayerCorpse()) {
|
||||
c->Message(Chat::White, "Error: Target must be a player corpse.");
|
||||
}
|
||||
else if (!sep->IsNumber(2)) {
|
||||
c->Message(Chat::White, "Error: charid must be a number.");
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"Setting CharID=%u on PlayerCorpse '%s'",
|
||||
target->CastToCorpse()->SetCharID(atoi(sep->arg[2])),
|
||||
target->GetName());
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sep->arg[1], "ResetLooter") == 0) {
|
||||
if (target == 0 || !target->IsCorpse()) {
|
||||
c->Message(Chat::White, "Error: Target the corpse you wish to reset");
|
||||
}
|
||||
else {
|
||||
target->CastToCorpse()->ResetLooter();
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sep->arg[1], "RemoveCash") == 0) {
|
||||
if (target == 0 || !target->IsCorpse()) {
|
||||
c->Message(Chat::White, "Error: Target the corpse you wish to remove the cash from");
|
||||
}
|
||||
else if (!target->IsPlayerCorpse() || c->Admin() >= commandEditPlayerCorpses) {
|
||||
c->Message(Chat::White, "Removing Cash from %s.", target->GetName());
|
||||
target->CastToCorpse()->RemoveCash();
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Insufficient status to modify player corpse.");
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sep->arg[1], "InspectLoot") == 0) {
|
||||
if (target == 0 || !target->IsCorpse()) {
|
||||
c->Message(Chat::White, "Error: Target must be a corpse.");
|
||||
}
|
||||
else {
|
||||
target->CastToCorpse()->QueryLoot(c);
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sep->arg[1], "lock") == 0) {
|
||||
if (target == 0 || !target->IsCorpse()) {
|
||||
c->Message(Chat::White, "Error: Target must be a corpse.");
|
||||
}
|
||||
else {
|
||||
target->CastToCorpse()->Lock();
|
||||
c->Message(Chat::White, "Locking %s...", target->GetName());
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sep->arg[1], "unlock") == 0) {
|
||||
if (target == 0 || !target->IsCorpse()) {
|
||||
c->Message(Chat::White, "Error: Target must be a corpse.");
|
||||
}
|
||||
else {
|
||||
target->CastToCorpse()->UnLock();
|
||||
c->Message(Chat::White, "Unlocking %s...", target->GetName());
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sep->arg[1], "depop") == 0) {
|
||||
if (target == 0 || !target->IsPlayerCorpse()) {
|
||||
c->Message(Chat::White, "Error: Target must be a player corpse.");
|
||||
}
|
||||
else if (c->Admin() >= commandEditPlayerCorpses && target->IsPlayerCorpse()) {
|
||||
c->Message(Chat::White, "Depoping %s.", target->GetName());
|
||||
target->CastToCorpse()->DepopPlayerCorpse();
|
||||
if (!sep->arg[2][0] || atoi(sep->arg[2]) != 0) {
|
||||
target->CastToCorpse()->Bury();
|
||||
}
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Insufficient status to depop player corpse.");
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sep->arg[1], "depopall") == 0) {
|
||||
if (target == 0 || !target->IsClient()) {
|
||||
c->Message(Chat::White, "Error: Target must be a player.");
|
||||
}
|
||||
else if (c->Admin() >= commandEditPlayerCorpses && target->IsClient()) {
|
||||
c->Message(Chat::White, "Depoping %s\'s corpses.", target->GetName());
|
||||
target->CastToClient()->DepopAllCorpses();
|
||||
if (!sep->arg[2][0] || atoi(sep->arg[2]) != 0) {
|
||||
target->CastToClient()->BuryPlayerCorpses();
|
||||
}
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Insufficient status to depop player corpse.");
|
||||
}
|
||||
|
||||
}
|
||||
else if (strcasecmp(sep->arg[1], "moveallgraveyard") == 0) {
|
||||
int count = entity_list.MovePlayerCorpsesToGraveyard(true);
|
||||
c->Message(Chat::White, "Moved [%d] player corpse(s) to zone graveyard", count);
|
||||
}
|
||||
else if (sep->arg[1][0] == 0 || strcasecmp(sep->arg[1], "help") == 0) {
|
||||
c->Message(Chat::White, "#Corpse Sub-Commands:");
|
||||
c->Message(Chat::White, " DeleteNPCCorpses");
|
||||
c->Message(Chat::White, " Delete - Delete targetted corpse");
|
||||
c->Message(Chat::White, " ListNPC");
|
||||
c->Message(Chat::White, " ListPlayer");
|
||||
c->Message(Chat::White, " Lock - GM locks the corpse - cannot be looted by non-GM");
|
||||
c->Message(Chat::White, " MoveAllGraveyard - move all player corpses to zone's graveyard or non-instance");
|
||||
c->Message(Chat::White, " UnLock");
|
||||
c->Message(Chat::White, " RemoveCash");
|
||||
c->Message(Chat::White, " InspectLoot");
|
||||
c->Message(Chat::White, " [to remove items from corpses, loot them]");
|
||||
c->Message(Chat::White, "Lead-GM status required to delete/modify player corpses");
|
||||
c->Message(Chat::White, " DeletePlayerCorpses");
|
||||
c->Message(Chat::White, " CharID [charid] - change player corpse's owner");
|
||||
c->Message(Chat::White, " Depop [bury] - Depops single target corpse.");
|
||||
c->Message(Chat::White, " Depopall [bury] - Depops all target player's corpses.");
|
||||
c->Message(Chat::White, "Set bury to 0 to skip burying the corpses.");
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Error, #corpse sub-command not found");
|
||||
}
|
||||
}
|
||||
|
||||
8
zone/gm_commands/corpsefix.cpp
Executable file
8
zone/gm_commands/corpsefix.cpp
Executable file
@ -0,0 +1,8 @@
|
||||
#include "../client.h"
|
||||
#include "../corpse.h"
|
||||
|
||||
void command_corpsefix(Client *c, const Seperator *sep)
|
||||
{
|
||||
entity_list.CorpseFix(c);
|
||||
}
|
||||
|
||||
17
zone/gm_commands/cvs.cpp
Executable file
17
zone/gm_commands/cvs.cpp
Executable file
@ -0,0 +1,17 @@
|
||||
#include "../client.h"
|
||||
#include "../worldserver.h"
|
||||
|
||||
extern WorldServer worldserver;
|
||||
|
||||
void command_cvs(Client *c, const Seperator *sep)
|
||||
{
|
||||
auto pack = new ServerPacket(
|
||||
ServerOP_ClientVersionSummary,
|
||||
sizeof(ServerRequestClientVersionSummary_Struct)
|
||||
);
|
||||
auto srcvss = (ServerRequestClientVersionSummary_Struct *) pack->pBuffer;
|
||||
strn0cpy(srcvss->Name, c->GetName(), sizeof(srcvss->Name));
|
||||
worldserver.SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
}
|
||||
|
||||
21
zone/gm_commands/damage.cpp
Executable file
21
zone/gm_commands/damage.cpp
Executable file
@ -0,0 +1,21 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_damage(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (c->GetTarget() == 0) {
|
||||
c->Message(Chat::White, "Error: #Damage: No Target.");
|
||||
}
|
||||
else if (!sep->IsNumber(1)) {
|
||||
c->Message(Chat::White, "Usage: #damage x");
|
||||
}
|
||||
else {
|
||||
int32 nkdmg = atoi(sep->arg[1]);
|
||||
if (nkdmg > 2100000000) {
|
||||
c->Message(Chat::White, "Enter a value less then 2,100,000,000.");
|
||||
}
|
||||
else {
|
||||
c->GetTarget()->Damage(c, nkdmg, SPELL_UNKNOWN, EQ::skills::SkillHandtoHand, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
92
zone/gm_commands/databuckets.cpp
Executable file
92
zone/gm_commands/databuckets.cpp
Executable file
@ -0,0 +1,92 @@
|
||||
#include "../client.h"
|
||||
#include "../data_bucket.h"
|
||||
|
||||
void command_databuckets(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (sep->arg[1][0] == 0) {
|
||||
c->Message(Chat::Yellow, "Usage: #databuckets view (partial key)|(limit) OR #databuckets delete (key)");
|
||||
return;
|
||||
}
|
||||
if (strcasecmp(sep->arg[1], "view") == 0) {
|
||||
|
||||
std::string key_filter;
|
||||
uint8 limit = 50;
|
||||
for (int i = 2; i < 4; i++) {
|
||||
if (sep->arg[i][0] == '\0') {
|
||||
break;
|
||||
}
|
||||
if (strcasecmp(sep->arg[i], "limit") == 0) {
|
||||
limit = (uint8) atoi(sep->arg[i + 1]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (sep->arg[2]) {
|
||||
key_filter = str_tolower(sep->arg[2]);
|
||||
}
|
||||
std::string query = "SELECT `id`, `key`, `value`, `expires` FROM data_buckets";
|
||||
if (!key_filter.empty()) { query += StringFormat(" WHERE `key` LIKE '%%%s%%'", key_filter.c_str()); }
|
||||
query += StringFormat(" LIMIT %u", limit);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return;
|
||||
}
|
||||
if (results.RowCount() == 0) {
|
||||
c->Message(Chat::Yellow, "No data_buckets found");
|
||||
return;
|
||||
}
|
||||
int _ctr = 0;
|
||||
// put in window for easier readability in case want command line for something else
|
||||
std::string window_title = "Data Buckets";
|
||||
std::string window_text =
|
||||
"<table>"
|
||||
"<tr>"
|
||||
"<td>ID</td>"
|
||||
"<td>Expires</td>"
|
||||
"<td>Key</td>"
|
||||
"<td>Value</td>"
|
||||
"</tr>";
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
auto id = static_cast<uint32>(atoi(row[0]));
|
||||
std::string key = row[1];
|
||||
std::string value = row[2];
|
||||
std::string expires = row[3];
|
||||
window_text.append(
|
||||
StringFormat(
|
||||
"<tr>"
|
||||
"<td>%u</td>"
|
||||
"<td>%s</td>"
|
||||
"<td>%s</td>"
|
||||
"<td>%s</td>"
|
||||
"</tr>",
|
||||
id,
|
||||
expires.c_str(),
|
||||
key.c_str(),
|
||||
value.c_str()
|
||||
));
|
||||
_ctr++;
|
||||
std::string del_saylink = StringFormat("#databuckets delete %s", key.c_str());
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"%s : %s",
|
||||
EQ::SayLinkEngine::GenerateQuestSaylink(del_saylink, false, "Delete").c_str(),
|
||||
key.c_str(),
|
||||
" Value: ",
|
||||
value.c_str());
|
||||
}
|
||||
window_text.append("</table>");
|
||||
c->SendPopupToClient(window_title.c_str(), window_text.c_str());
|
||||
std::string response = _ctr > 0 ? StringFormat("Found %i matching data buckets", _ctr).c_str()
|
||||
: "No Databuckets found.";
|
||||
c->Message(Chat::Yellow, response.c_str());
|
||||
}
|
||||
else if (strcasecmp(sep->arg[1], "delete") == 0) {
|
||||
if (DataBucket::DeleteData(sep->argplus[2])) {
|
||||
c->Message(Chat::Yellow, "data bucket %s deleted.", sep->argplus[2]);
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::Red, "An error occurred deleting data bucket %s", sep->argplus[2]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
29
zone/gm_commands/date.cpp
Executable file
29
zone/gm_commands/date.cpp
Executable file
@ -0,0 +1,29 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_date(Client *c, const Seperator *sep)
|
||||
{
|
||||
//yyyy mm dd hh mm local
|
||||
if (sep->arg[3][0] == 0 || !sep->IsNumber(1) || !sep->IsNumber(2) || !sep->IsNumber(3)) {
|
||||
c->Message(Chat::Red, "Usage: #date yyyy mm dd [HH MM]");
|
||||
}
|
||||
else {
|
||||
int h = 0, m = 0;
|
||||
TimeOfDay_Struct eqTime;
|
||||
zone->zone_time.GetCurrentEQTimeOfDay(time(0), &eqTime);
|
||||
if (!sep->IsNumber(4)) {
|
||||
h = eqTime.hour;
|
||||
}
|
||||
else {
|
||||
h = atoi(sep->arg[4]);
|
||||
}
|
||||
if (!sep->IsNumber(5)) {
|
||||
m = eqTime.minute;
|
||||
}
|
||||
else {
|
||||
m = atoi(sep->arg[5]);
|
||||
}
|
||||
c->Message(Chat::Red, "Setting world time to %s-%s-%s %i:%i...", sep->arg[1], sep->arg[2], sep->arg[3], h, m);
|
||||
zone->SetDate(atoi(sep->arg[1]), atoi(sep->arg[2]), atoi(sep->arg[3]), h, m);
|
||||
}
|
||||
}
|
||||
|
||||
31
zone/gm_commands/dbspawn2.cpp
Executable file
31
zone/gm_commands/dbspawn2.cpp
Executable file
@ -0,0 +1,31 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_dbspawn2(Client *c, const Seperator *sep)
|
||||
{
|
||||
|
||||
if (sep->IsNumber(1) && sep->IsNumber(2) && sep->IsNumber(3)) {
|
||||
LogInfo("Spawning database spawn");
|
||||
uint16 cond = 0;
|
||||
int16 cond_min = 0;
|
||||
if (sep->IsNumber(4)) {
|
||||
cond = atoi(sep->arg[4]);
|
||||
if (sep->IsNumber(5)) {
|
||||
cond_min = atoi(sep->arg[5]);
|
||||
}
|
||||
}
|
||||
database.CreateSpawn2(
|
||||
c,
|
||||
atoi(sep->arg[1]),
|
||||
zone->GetShortName(),
|
||||
c->GetPosition(),
|
||||
atoi(sep->arg[2]),
|
||||
atoi(sep->arg[3]),
|
||||
cond,
|
||||
cond_min
|
||||
);
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Usage: #dbspawn2 spawngroup respawn variance [condition_id] [condition_min]");
|
||||
}
|
||||
}
|
||||
|
||||
21
zone/gm_commands/delacct.cpp
Executable file
21
zone/gm_commands/delacct.cpp
Executable file
@ -0,0 +1,21 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_delacct(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (sep->arg[1][0] == 0) {
|
||||
c->Message(Chat::White, "Format: #delacct accountname");
|
||||
}
|
||||
else {
|
||||
std::string user;
|
||||
std::string loginserver;
|
||||
ParseAccountString(sep->arg[1], user, loginserver);
|
||||
|
||||
if (database.DeleteAccount(user.c_str(), loginserver.c_str())) {
|
||||
c->Message(Chat::White, "The account was deleted.");
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Unable to delete account.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
35
zone/gm_commands/deletegraveyard.cpp
Executable file
35
zone/gm_commands/deletegraveyard.cpp
Executable file
@ -0,0 +1,35 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_deletegraveyard(Client *c, const Seperator *sep)
|
||||
{
|
||||
uint32 zoneid = 0;
|
||||
uint32 graveyard_id = 0;
|
||||
|
||||
if (!sep->arg[1][0]) {
|
||||
c->Message(Chat::White, "Usage: #deletegraveyard [zonename]");
|
||||
return;
|
||||
}
|
||||
|
||||
zoneid = ZoneID(sep->arg[1]);
|
||||
graveyard_id = content_db.GetZoneGraveyardID(zoneid, 0);
|
||||
|
||||
if (zoneid > 0 && graveyard_id > 0) {
|
||||
if (content_db.DeleteGraveyard(zoneid, graveyard_id)) {
|
||||
c->Message(Chat::White, "Successfuly deleted graveyard %u for zone %s.", graveyard_id, sep->arg[1]);
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Unable to delete graveyard %u for zone %s.", graveyard_id, sep->arg[1]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (zoneid <= 0) {
|
||||
c->Message(Chat::White, "Unable to retrieve a ZoneID for the zone: %s", sep->arg[1]);
|
||||
}
|
||||
else if (graveyard_id <= 0) {
|
||||
c->Message(Chat::White, "Unable to retrieve a valid GraveyardID for the zone: %s", sep->arg[1]);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
20
zone/gm_commands/delpetition.cpp
Executable file
20
zone/gm_commands/delpetition.cpp
Executable file
@ -0,0 +1,20 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_delpetition(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (sep->arg[1][0] == 0 || strcasecmp(sep->arg[1], "*") == 0) {
|
||||
c->Message(Chat::White, "Usage: #delpetition (petition number) Type #listpetition for a list");
|
||||
return;
|
||||
}
|
||||
|
||||
c->Message(Chat::Red, "Attempting to delete petition number: %i", atoi(sep->argplus[1]));
|
||||
std::string query = StringFormat("DELETE FROM petitions WHERE petid = %i", atoi(sep->argplus[1]));
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return;
|
||||
}
|
||||
|
||||
LogInfo("Delete petition request from [{}], petition number:", c->GetName(), atoi(sep->argplus[1]));
|
||||
|
||||
}
|
||||
|
||||
14
zone/gm_commands/depop.cpp
Executable file
14
zone/gm_commands/depop.cpp
Executable file
@ -0,0 +1,14 @@
|
||||
#include "../client.h"
|
||||
#include "../corpse.h"
|
||||
|
||||
void command_depop(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (c->GetTarget() == 0 || !(c->GetTarget()->IsNPC() || c->GetTarget()->IsNPCCorpse())) {
|
||||
c->Message(Chat::White, "You must have a NPC target for this command. (maybe you meant #depopzone?)");
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Depoping '%s'.", c->GetTarget()->GetName());
|
||||
c->GetTarget()->Depop();
|
||||
}
|
||||
}
|
||||
|
||||
8
zone/gm_commands/depopzone.cpp
Executable file
8
zone/gm_commands/depopzone.cpp
Executable file
@ -0,0 +1,8 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_depopzone(Client *c, const Seperator *sep)
|
||||
{
|
||||
zone->Depop();
|
||||
c->Message(Chat::White, "Zone depoped.");
|
||||
}
|
||||
|
||||
37
zone/gm_commands/details.cpp
Executable file
37
zone/gm_commands/details.cpp
Executable file
@ -0,0 +1,37 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_details(Client *c, const Seperator *sep)
|
||||
{
|
||||
Mob *target = c->GetTarget();
|
||||
if (!sep->IsNumber(1)) {
|
||||
c->Message(Chat::White, "Usage: #details [number of drakkin detail]");
|
||||
}
|
||||
else if (!target) {
|
||||
c->Message(Chat::White, "Error: this command requires a target");
|
||||
}
|
||||
else {
|
||||
uint16 Race = target->GetRace();
|
||||
uint8 Gender = target->GetGender();
|
||||
uint8 Texture = 0xFF;
|
||||
uint8 HelmTexture = 0xFF;
|
||||
uint8 HairColor = target->GetHairColor();
|
||||
uint8 BeardColor = target->GetBeardColor();
|
||||
uint8 EyeColor1 = target->GetEyeColor1();
|
||||
uint8 EyeColor2 = target->GetEyeColor2();
|
||||
uint8 HairStyle = target->GetHairStyle();
|
||||
uint8 LuclinFace = target->GetLuclinFace();
|
||||
uint8 Beard = target->GetBeard();
|
||||
uint32 DrakkinHeritage = target->GetDrakkinHeritage();
|
||||
uint32 DrakkinTattoo = target->GetDrakkinTattoo();
|
||||
uint32 DrakkinDetails = atoi(sep->arg[1]);
|
||||
|
||||
target->SendIllusionPacket(
|
||||
Race, Gender, Texture, HelmTexture, HairColor, BeardColor,
|
||||
EyeColor1, EyeColor2, HairStyle, LuclinFace, Beard, 0xFF,
|
||||
DrakkinHeritage, DrakkinTattoo, DrakkinDetails
|
||||
);
|
||||
|
||||
c->Message(Chat::White, "Details = %i", atoi(sep->arg[1]));
|
||||
}
|
||||
}
|
||||
|
||||
22
zone/gm_commands/devtools.cpp
Executable file
22
zone/gm_commands/devtools.cpp
Executable file
@ -0,0 +1,22 @@
|
||||
#include "../client.h"
|
||||
#include "../data_bucket.h"
|
||||
|
||||
void command_devtools(Client *c, const Seperator *sep)
|
||||
{
|
||||
std::string dev_tools_key = StringFormat("%i-dev-tools-disabled", c->AccountID());
|
||||
|
||||
/**
|
||||
* Handle window toggle
|
||||
*/
|
||||
if (strcasecmp(sep->arg[1], "disable") == 0) {
|
||||
DataBucket::SetData(dev_tools_key, "true");
|
||||
c->SetDevToolsEnabled(false);
|
||||
}
|
||||
if (strcasecmp(sep->arg[1], "enable") == 0) {
|
||||
DataBucket::DeleteData(dev_tools_key);
|
||||
c->SetDevToolsEnabled(true);
|
||||
}
|
||||
|
||||
c->ShowDevToolsMenu();
|
||||
}
|
||||
|
||||
29
zone/gm_commands/disablerecipe.cpp
Executable file
29
zone/gm_commands/disablerecipe.cpp
Executable file
@ -0,0 +1,29 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_disablerecipe(Client *c, const Seperator *sep)
|
||||
{
|
||||
uint32 recipe_id = 0;
|
||||
bool success = false;
|
||||
if (c) {
|
||||
if (sep->argnum == 1) {
|
||||
recipe_id = atoi(sep->arg[1]);
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Invalid number of arguments.\nUsage: #disablerecipe recipe_id");
|
||||
return;
|
||||
}
|
||||
if (recipe_id > 0) {
|
||||
success = content_db.DisableRecipe(recipe_id);
|
||||
if (success) {
|
||||
c->Message(Chat::White, "Recipe disabled.");
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Recipe not disabled.");
|
||||
}
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Invalid recipe id.\nUsage: #disablerecipe recipe_id");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
25
zone/gm_commands/disarmtrap.cpp
Executable file
25
zone/gm_commands/disarmtrap.cpp
Executable file
@ -0,0 +1,25 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_disarmtrap(Client *c, const Seperator *sep)
|
||||
{
|
||||
Mob *target = c->GetTarget();
|
||||
|
||||
if (!target) {
|
||||
c->Message(Chat::Red, "You must have a target.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (target->IsNPC()) {
|
||||
if (c->HasSkill(EQ::skills::SkillDisarmTraps)) {
|
||||
if (DistanceSquaredNoZ(c->GetPosition(), target->GetPosition()) > RuleI(Adventure, LDoNTrapDistanceUse)) {
|
||||
c->Message(Chat::Red, "%s is too far away.", target->GetCleanName());
|
||||
return;
|
||||
}
|
||||
c->HandleLDoNDisarm(target->CastToNPC(), c->GetSkill(EQ::skills::SkillDisarmTraps), LDoNTypeMechanical);
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::Red, "You do not have the disarm trap skill.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
23
zone/gm_commands/distance.cpp
Executable file
23
zone/gm_commands/distance.cpp
Executable file
@ -0,0 +1,23 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_distance(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (c->GetTarget()) {
|
||||
Mob *target = c->GetTarget();
|
||||
if (c != target) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"{} ({}) is {:.2f} units from you.",
|
||||
target->GetCleanName(),
|
||||
target->GetID(),
|
||||
Distance(
|
||||
c->GetPosition(),
|
||||
target->GetPosition()
|
||||
)
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
20
zone/gm_commands/doanim.cpp
Executable file
20
zone/gm_commands/doanim.cpp
Executable file
@ -0,0 +1,20 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_doanim(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (!sep->IsNumber(1)) {
|
||||
c->Message(Chat::White, "Usage: #DoAnim [number]");
|
||||
}
|
||||
else if (c->Admin() >= commandDoAnimOthers) {
|
||||
if (c->GetTarget() == 0) {
|
||||
c->Message(Chat::White, "Error: You need a target.");
|
||||
}
|
||||
else {
|
||||
c->GetTarget()->DoAnim(atoi(sep->arg[1]), atoi(sep->arg[2]));
|
||||
}
|
||||
}
|
||||
else {
|
||||
c->DoAnim(atoi(sep->arg[1]), atoi(sep->arg[2]));
|
||||
}
|
||||
}
|
||||
|
||||
9
zone/gm_commands/door.cpp
Executable file
9
zone/gm_commands/door.cpp
Executable file
@ -0,0 +1,9 @@
|
||||
#include "../client.h"
|
||||
#include "door_manipulation.h"
|
||||
#include "../doors.h"
|
||||
|
||||
void command_door(Client *c, const Seperator *sep)
|
||||
{
|
||||
DoorManipulation::CommandHandler(c, sep);
|
||||
}
|
||||
|
||||
@ -37,7 +37,10 @@ void DoorManipulation::CommandHandler(Client *c, const Seperator *sep)
|
||||
// option
|
||||
if (arg1.empty()) {
|
||||
DoorManipulation::CommandHeader(c);
|
||||
c->Message(Chat::White, "#door create <modelname> | Creates a door from a model. (Example IT78 creates a campfire)");
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"#door create <modelname> | Creates a door from a model. (Example IT78 creates a campfire)"
|
||||
);
|
||||
c->Message(Chat::White, "#door setinvertstate [0|1] | Sets selected door invert state");
|
||||
c->Message(Chat::White, "#door setincline <incline> | Sets selected door incline");
|
||||
c->Message(Chat::White, "#door opentype <opentype> | Sets selected door opentype");
|
||||
@ -129,7 +132,7 @@ void DoorManipulation::CommandHandler(Client *c, const Seperator *sep)
|
||||
std::vector<std::string> move_h_options_negative;
|
||||
std::vector<std::string> set_size_options_positive;
|
||||
std::vector<std::string> set_size_options_negative;
|
||||
for (const auto &move_option : move_options) {
|
||||
for (const auto &move_option : move_options) {
|
||||
if (move_option == move_x_action) {
|
||||
move_x_options_positive.emplace_back(
|
||||
EQ::SayLinkEngine::GenerateQuestSaylink(
|
||||
@ -297,10 +300,10 @@ void DoorManipulation::CommandHandler(Client *c, const Seperator *sep)
|
||||
|
||||
// we're passing a move action here
|
||||
if (!arg3.empty() && StringIsNumber(arg3)) {
|
||||
float x_move = 0.0f;
|
||||
float y_move = 0.0f;
|
||||
float z_move = 0.0f;
|
||||
float h_move = 0.0f;
|
||||
float x_move = 0.0f;
|
||||
float y_move = 0.0f;
|
||||
float z_move = 0.0f;
|
||||
float h_move = 0.0f;
|
||||
float set_size = 0.0f;
|
||||
|
||||
if (arg2 == move_x_action) {
|
||||
|
||||
87
zone/gm_commands/dye.cpp
Executable file
87
zone/gm_commands/dye.cpp
Executable file
@ -0,0 +1,87 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_dye(Client *c, const Seperator *sep)
|
||||
{
|
||||
int arguments = sep->argnum;
|
||||
|
||||
if (arguments == 0) {
|
||||
c->Message(Chat::White, "Command Syntax: #dye help | #dye [slot] [red] [green] [blue] [use_tint]");
|
||||
return;
|
||||
}
|
||||
|
||||
uint8 slot = 0;
|
||||
uint8 red = 255;
|
||||
uint8 green = 255;
|
||||
uint8 blue = 255;
|
||||
uint8 use_tint = 255;
|
||||
|
||||
std::vector<std::string> dye_slots = {
|
||||
"Helmet",
|
||||
"Chest",
|
||||
"Arms",
|
||||
"Wrist",
|
||||
"Hands",
|
||||
"Legs",
|
||||
"Feet"
|
||||
};
|
||||
|
||||
if (arguments == 1 && !strcasecmp(sep->arg[1], "help")) {
|
||||
int slot_id = 0;
|
||||
std::vector<std::string> slot_messages;
|
||||
c->Message(Chat::White, "Command Syntax: #dye help | #dye [slot] [red] [green] [blue] [use_tint]");
|
||||
c->Message(Chat::White, "Red, Green, and Blue go from 0 to 255.");
|
||||
|
||||
for (const auto &slot : dye_slots) {
|
||||
slot_messages.push_back(fmt::format("({}) {}", slot_id, slot));
|
||||
slot_id++;
|
||||
}
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"{} {}",
|
||||
"Slots are as follows:",
|
||||
implode(", ", slot_messages)
|
||||
).c_str()
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (arguments >= 1 && sep->IsNumber(1)) {
|
||||
slot = atoi(sep->arg[1]);
|
||||
}
|
||||
|
||||
if (arguments >= 2 && sep->IsNumber(2)) {
|
||||
red = atoi(sep->arg[2]);
|
||||
}
|
||||
|
||||
if (arguments >= 3 && sep->IsNumber(3)) {
|
||||
green = atoi(sep->arg[3]);
|
||||
}
|
||||
|
||||
if (arguments >= 4 && sep->IsNumber(4)) {
|
||||
blue = atoi(sep->arg[4]);
|
||||
}
|
||||
|
||||
if (arguments >= 5 && sep->IsNumber(5)) {
|
||||
use_tint = atoi(sep->arg[5]);
|
||||
}
|
||||
|
||||
if (RuleB(Command, DyeCommandRequiresDyes)) {
|
||||
uint32 dye_item_id = 32557;
|
||||
if (c->CountItem(dye_item_id) >= 1) {
|
||||
c->RemoveItem(dye_item_id);
|
||||
}
|
||||
else {
|
||||
EQ::SayLinkEngine linker;
|
||||
linker.SetLinkType(EQ::saylink::SayLinkItemData);
|
||||
const EQ::ItemData *dye_item = database.GetItem(dye_item_id);
|
||||
linker.SetItemData(dye_item);
|
||||
c->Message(Chat::White, fmt::format("This command requires a {} to use.", linker.GenerateLink()).c_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
c->DyeArmorBySlot(slot, red, green, blue, use_tint);
|
||||
}
|
||||
|
||||
244
zone/gm_commands/dz.cpp
Executable file
244
zone/gm_commands/dz.cpp
Executable file
@ -0,0 +1,244 @@
|
||||
#include "../client.h"
|
||||
#include "../expedition.h"
|
||||
|
||||
void command_dz(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (!c || !zone) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcasecmp(sep->arg[1], "cache") == 0) {
|
||||
if (strcasecmp(sep->arg[2], "reload") == 0) {
|
||||
DynamicZone::CacheAllFromDatabase();
|
||||
Expedition::CacheAllFromDatabase();
|
||||
c->Message(
|
||||
Chat::White, fmt::format(
|
||||
"Reloaded [{}] dynamic zone(s) and [{}] expedition(s) from database",
|
||||
zone->dynamic_zone_cache.size(), zone->expedition_cache.size()
|
||||
).c_str());
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sep->arg[1], "expedition") == 0) {
|
||||
if (strcasecmp(sep->arg[2], "list") == 0) {
|
||||
std::vector<Expedition *> expeditions;
|
||||
for (const auto &expedition : zone->expedition_cache) {
|
||||
expeditions.emplace_back(expedition.second.get());
|
||||
}
|
||||
|
||||
std::sort(
|
||||
expeditions.begin(), expeditions.end(),
|
||||
[](const Expedition *lhs, const Expedition *rhs) {
|
||||
return lhs->GetID() < rhs->GetID();
|
||||
}
|
||||
);
|
||||
|
||||
c->Message(Chat::White, fmt::format("Total Active Expeditions: [{}]", expeditions.size()).c_str());
|
||||
for (const auto &expedition : expeditions) {
|
||||
auto dz = expedition->GetDynamicZone();
|
||||
if (!dz) {
|
||||
LogExpeditions("Expedition [{}] has an invalid dz [{}] in cache",
|
||||
expedition->GetID(),
|
||||
expedition->GetDynamicZoneID());
|
||||
continue;
|
||||
}
|
||||
|
||||
auto leader_saylink = EQ::SayLinkEngine::GenerateQuestSaylink(
|
||||
fmt::format(
|
||||
"#goto {}", expedition->GetLeaderName()), false, expedition->GetLeaderName());
|
||||
auto zone_saylink = EQ::SayLinkEngine::GenerateQuestSaylink(
|
||||
fmt::format(
|
||||
"#zoneinstance {}", dz->GetInstanceID()), false, "zone"
|
||||
);
|
||||
|
||||
auto seconds = dz->GetSecondsRemaining();
|
||||
|
||||
c->Message(
|
||||
Chat::White, fmt::format(
|
||||
"expedition id: [{}] dz id: [{}] name: [{}] leader: [{}] {}: [{}]:[{}]:[{}]:[{}] members: [{}] remaining: [{:02}:{:02}:{:02}]",
|
||||
expedition->GetID(),
|
||||
expedition->GetDynamicZoneID(),
|
||||
expedition->GetName(),
|
||||
leader_saylink,
|
||||
zone_saylink,
|
||||
ZoneName(dz->GetZoneID()),
|
||||
dz->GetZoneID(),
|
||||
dz->GetInstanceID(),
|
||||
dz->GetZoneVersion(),
|
||||
dz->GetMemberCount(),
|
||||
seconds / 3600, // hours
|
||||
(seconds / 60) % 60, // minutes
|
||||
seconds % 60 // seconds
|
||||
).c_str());
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sep->arg[2], "reload") == 0) {
|
||||
Expedition::CacheAllFromDatabase();
|
||||
c->Message(
|
||||
Chat::White, fmt::format(
|
||||
"Reloaded [{}] expeditions to cache from database.", zone->expedition_cache.size()
|
||||
).c_str());
|
||||
}
|
||||
else if (strcasecmp(sep->arg[2], "destroy") == 0 && sep->IsNumber(3)) {
|
||||
auto expedition_id = std::strtoul(sep->arg[3], nullptr, 10);
|
||||
auto expedition = Expedition::FindCachedExpeditionByID(expedition_id);
|
||||
if (expedition) {
|
||||
c->Message(
|
||||
Chat::White, fmt::format(
|
||||
"Destroying expedition [{}] ({})",
|
||||
expedition_id, expedition->GetName()).c_str());
|
||||
expedition->GetDynamicZone()->RemoveAllMembers();
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::Red, fmt::format("Failed to destroy expedition [{}]", sep->arg[3]).c_str());
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sep->arg[2], "unlock") == 0 && sep->IsNumber(3)) {
|
||||
auto expedition_id = std::strtoul(sep->arg[3], nullptr, 10);
|
||||
auto expedition = Expedition::FindCachedExpeditionByID(expedition_id);
|
||||
if (expedition) {
|
||||
c->Message(Chat::White, fmt::format("Unlocking expedition [{}]", expedition_id).c_str());
|
||||
expedition->SetLocked(false, ExpeditionLockMessage::None, true);
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::Red, fmt::format("Failed to find expedition [{}]", sep->arg[3]).c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sep->arg[1], "list") == 0) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format("Total Dynamic Zones (cache): [{}]", zone->dynamic_zone_cache.size()).c_str());
|
||||
|
||||
std::vector<DynamicZone *> dynamic_zones;
|
||||
for (const auto &dz : zone->dynamic_zone_cache) {
|
||||
dynamic_zones.emplace_back(dz.second.get());
|
||||
}
|
||||
|
||||
std::sort(
|
||||
dynamic_zones.begin(), dynamic_zones.end(),
|
||||
[](const DynamicZone *lhs, const DynamicZone *rhs) {
|
||||
return lhs->GetID() < rhs->GetID();
|
||||
}
|
||||
);
|
||||
|
||||
for (const auto &dz : dynamic_zones) {
|
||||
auto seconds = dz->GetSecondsRemaining();
|
||||
auto zone_saylink = EQ::SayLinkEngine::GenerateQuestSaylink(
|
||||
fmt::format("#zoneinstance {}", dz->GetInstanceID()), false, "zone"
|
||||
);
|
||||
|
||||
std::string aligned_type = fmt::format(
|
||||
"[{}]",
|
||||
DynamicZone::GetDynamicZoneTypeName(static_cast<DynamicZoneType>(dz->GetType())));
|
||||
c->Message(
|
||||
Chat::White, fmt::format(
|
||||
"id: [{}] type: {:>10} {}: [{}]:[{}]:[{}] members: [{}] remaining: [{:02}:{:02}:{:02}]",
|
||||
dz->GetID(),
|
||||
aligned_type,
|
||||
zone_saylink,
|
||||
dz->GetZoneID(),
|
||||
dz->GetInstanceID(),
|
||||
dz->GetZoneVersion(),
|
||||
dz->GetMemberCount(),
|
||||
seconds / 3600, // hours
|
||||
(seconds / 60) % 60, // minutes
|
||||
seconds % 60 // seconds
|
||||
).c_str());
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sep->arg[1], "listdb") == 0) {
|
||||
auto dz_list = DynamicZonesRepository::AllDzInstancePlayerCounts(database);
|
||||
c->Message(Chat::White, fmt::format("Total Dynamic Zones (database): [{}]", dz_list.size()).c_str());
|
||||
|
||||
auto now = std::chrono::system_clock::now();
|
||||
|
||||
for (const auto &dz : dz_list) {
|
||||
auto expire_time = std::chrono::system_clock::from_time_t(dz.start_time + dz.duration);
|
||||
auto remaining = std::chrono::duration_cast<std::chrono::seconds>(expire_time - now);
|
||||
auto seconds = std::max(0, static_cast<int>(remaining.count()));
|
||||
bool is_expired = now > expire_time;
|
||||
|
||||
if (!is_expired || strcasecmp(sep->arg[2], "all") == 0) {
|
||||
auto zone_saylink = is_expired ? "zone" : EQ::SayLinkEngine::GenerateQuestSaylink(
|
||||
fmt::format("#zoneinstance {}", dz.instance), false, "zone"
|
||||
);
|
||||
|
||||
c->Message(
|
||||
Chat::White, fmt::format(
|
||||
"id: [{}] type: [{}] {}: [{}]:[{}]:[{}] members: [{}] remaining: [{:02}:{:02}:{:02}]",
|
||||
dz.id,
|
||||
DynamicZone::GetDynamicZoneTypeName(static_cast<DynamicZoneType>(dz.type)),
|
||||
zone_saylink,
|
||||
dz.zone,
|
||||
dz.instance,
|
||||
dz.version,
|
||||
dz.member_count,
|
||||
seconds / 3600, // hours
|
||||
(seconds / 60) % 60, // minutes
|
||||
seconds % 60 // seconds
|
||||
).c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sep->arg[1], "lockouts") == 0) {
|
||||
if (strcasecmp(sep->arg[2], "remove") == 0 && sep->arg[3][0] != '\0') {
|
||||
if (sep->arg[5][0] == '\0') {
|
||||
c->Message(
|
||||
Chat::White, fmt::format(
|
||||
"Removing [{}] lockouts on [{}].", sep->arg[4][0] ? sep->arg[4] : "all", sep->arg[3]
|
||||
).c_str());
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::White, fmt::format(
|
||||
"Removing [{}]:[{}] lockout on [{}].", sep->arg[4], sep->arg[5], sep->arg[3]
|
||||
).c_str());
|
||||
}
|
||||
Expedition::RemoveLockoutsByCharacterName(sep->arg[3], sep->arg[4], sep->arg[5]);
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sep->arg[1], "makeleader") == 0 && sep->IsNumber(2) && sep->arg[3][0] != '\0') {
|
||||
auto expedition_id = std::strtoul(sep->arg[2], nullptr, 10);
|
||||
auto expedition = Expedition::FindCachedExpeditionByID(expedition_id);
|
||||
if (expedition) {
|
||||
auto char_name = FormatName(sep->arg[3]);
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format("Setting expedition [{}] leader to [{}]", expedition_id, char_name).c_str());
|
||||
expedition->SendWorldMakeLeaderRequest(c->CharacterID(), char_name);
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::Red, fmt::format("Failed to find expedition [{}]", expedition_id).c_str());
|
||||
}
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "#dz usage:");
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"#dz cache reload - reload the current zone cache from db (also reloads expedition cache dependency)"
|
||||
);
|
||||
c->Message(Chat::White, "#dz expedition list - list expeditions in current zone cache");
|
||||
c->Message(Chat::White, "#dz expedition reload - reload expedition zone cache from database");
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"#dz expedition destroy <expedition_id> - destroy expedition globally (must be in cache)"
|
||||
);
|
||||
c->Message(Chat::White, "#dz expedition unlock <expedition_id> - unlock expedition");
|
||||
c->Message(Chat::White, "#dz list - list all dynamic zone instances from current zone cache");
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"#dz listdb [all] - list dynamic zone instances from database -- 'all' includes expired"
|
||||
);
|
||||
c->Message(Chat::White, "#dz lockouts remove <char_name> - delete all of character's expedition lockouts");
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"#dz lockouts remove <char_name> \"<expedition_name>\" - delete lockouts by expedition"
|
||||
);
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"#dz lockouts remove <char_name> \"<expedition_name>\" \"<event_name>\" - delete lockout by expedition event"
|
||||
);
|
||||
c->Message(Chat::White, "#dz makeleader <expedition_id> <character_name> - set new expedition leader");
|
||||
}
|
||||
}
|
||||
|
||||
13
zone/gm_commands/dzkickplayers.cpp
Executable file
13
zone/gm_commands/dzkickplayers.cpp
Executable file
@ -0,0 +1,13 @@
|
||||
#include "../client.h"
|
||||
#include "../expedition.h"
|
||||
|
||||
void command_dzkickplayers(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (c) {
|
||||
auto expedition = c->GetExpedition();
|
||||
if (expedition) {
|
||||
expedition->DzKickPlayers(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
140
zone/gm_commands/editmassrespawn.cpp
Executable file
140
zone/gm_commands/editmassrespawn.cpp
Executable file
@ -0,0 +1,140 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_editmassrespawn(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (strcasecmp(sep->arg[1], "usage") == 0) {
|
||||
c->Message(Chat::White, "#editmassrespawn [exact_match: =]npc_type_name new_respawn_seconds (apply)");
|
||||
return;
|
||||
}
|
||||
|
||||
std::string search_npc_type;
|
||||
if (sep->arg[1]) {
|
||||
search_npc_type = sep->arg[1];
|
||||
}
|
||||
|
||||
int change_respawn_seconds = 0;
|
||||
if (sep->arg[2] && sep->IsNumber(2)) {
|
||||
change_respawn_seconds = atoi(sep->arg[2]);
|
||||
}
|
||||
|
||||
bool change_apply = false;
|
||||
if (sep->arg[3] && strcasecmp(sep->arg[3], "apply") == 0) {
|
||||
change_apply = true;
|
||||
}
|
||||
|
||||
std::string search_encapsulator = "%";
|
||||
if (search_npc_type[0] == '=') {
|
||||
|
||||
search_npc_type = search_npc_type.substr(1);
|
||||
search_encapsulator = "";
|
||||
}
|
||||
|
||||
std::string query = fmt::format(
|
||||
SQL(
|
||||
SELECT npc_types.id, spawn2.spawngroupID, spawn2.id, npc_types.name, spawn2.respawntime
|
||||
FROM spawn2
|
||||
INNER JOIN spawnentry ON spawn2.spawngroupID = spawnentry.spawngroupID
|
||||
INNER JOIN npc_types ON spawnentry.npcID = npc_types.id
|
||||
WHERE spawn2.zone LIKE '{}'
|
||||
AND spawn2.version = '{}'
|
||||
AND npc_types.name LIKE '{}{}{}'
|
||||
ORDER BY npc_types.id, spawn2.spawngroupID, spawn2.id
|
||||
),
|
||||
zone->GetShortName(),
|
||||
zone->GetInstanceVersion(),
|
||||
search_encapsulator,
|
||||
search_npc_type,
|
||||
search_encapsulator
|
||||
);
|
||||
|
||||
std::string status = "(Searching)";
|
||||
if (change_apply) {
|
||||
status = "(Applying)";
|
||||
}
|
||||
|
||||
int results_count = 0;
|
||||
|
||||
auto results = content_db.QueryDatabase(query);
|
||||
if (results.Success() && results.RowCount()) {
|
||||
|
||||
results_count = results.RowCount();
|
||||
|
||||
for (auto row : results) {
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"NPC (npcid:{}) (sgid:{}) (s2id:{}) [{}] Respawn: Current [{}] New [{}] {}",
|
||||
row[0],
|
||||
row[1],
|
||||
row[2],
|
||||
row[3],
|
||||
row[4],
|
||||
change_respawn_seconds,
|
||||
status
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
|
||||
c->Message(Chat::Yellow, "Found (%i) NPC's that match this search...", results_count);
|
||||
|
||||
if (change_respawn_seconds > 0) {
|
||||
|
||||
if (change_apply) {
|
||||
|
||||
results = content_db.QueryDatabase(
|
||||
fmt::format(
|
||||
SQL(
|
||||
UPDATE spawn2
|
||||
SET respawntime = '{}'
|
||||
WHERE id IN(
|
||||
SELECT spawn2.id
|
||||
FROM spawn2
|
||||
INNER JOIN spawnentry ON spawn2.spawngroupID = spawnentry.spawngroupID
|
||||
INNER JOIN npc_types ON spawnentry.npcID = npc_types.id
|
||||
WHERE spawn2.zone LIKE '{}'
|
||||
AND spawn2.version = '{}'
|
||||
AND npc_types.name LIKE '{}{}{}'
|
||||
)
|
||||
),
|
||||
change_respawn_seconds,
|
||||
zone->GetShortName(),
|
||||
zone->GetInstanceVersion(),
|
||||
search_encapsulator,
|
||||
search_npc_type,
|
||||
search_encapsulator
|
||||
)
|
||||
);
|
||||
|
||||
if (results.Success()) {
|
||||
|
||||
c->Message(Chat::Yellow, "Changes applied to (%i) NPC 'Spawn2' entries", results_count);
|
||||
zone->Repop();
|
||||
}
|
||||
else {
|
||||
|
||||
c->Message(Chat::Yellow, "Found (0) NPC's that match this search...");
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
std::string saylink = fmt::format(
|
||||
"#editmassrespawn {}{} {} apply",
|
||||
(search_encapsulator.empty() ? "=" : ""),
|
||||
search_npc_type,
|
||||
change_respawn_seconds
|
||||
);
|
||||
|
||||
c->Message(
|
||||
Chat::Yellow, "To apply these changes, click <%s> or type [%s]",
|
||||
EQ::SayLinkEngine::GenerateQuestSaylink(saylink, false, "Apply").c_str(),
|
||||
saylink.c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
c->Message(Chat::Yellow, "Found (0) NPC's that match this search...");
|
||||
}
|
||||
}
|
||||
|
||||
45
zone/gm_commands/emote.cpp
Executable file
45
zone/gm_commands/emote.cpp
Executable file
@ -0,0 +1,45 @@
|
||||
#include "../client.h"
|
||||
#include "../worldserver.h"
|
||||
|
||||
extern WorldServer worldserver;
|
||||
|
||||
void command_emote(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (sep->arg[3][0] == 0) {
|
||||
c->Message(Chat::White, "Usage: #emote [name | world | zone] type# message");
|
||||
}
|
||||
else {
|
||||
if (strcasecmp(sep->arg[1], "zone") == 0) {
|
||||
char *newmessage = 0;
|
||||
if (strstr(sep->arg[3], "^") == 0) {
|
||||
entity_list.Message(0, atoi(sep->arg[2]), sep->argplus[3]);
|
||||
}
|
||||
else {
|
||||
for (newmessage = strtok((char *) sep->arg[3], "^");
|
||||
newmessage != nullptr;
|
||||
newmessage = strtok(nullptr, "^"))
|
||||
entity_list.Message(0, atoi(sep->arg[2]), newmessage);
|
||||
}
|
||||
}
|
||||
else if (!worldserver.Connected()) {
|
||||
c->Message(Chat::White, "Error: World server disconnected");
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[1], "world")) {
|
||||
worldserver.SendEmoteMessage(
|
||||
0,
|
||||
0,
|
||||
atoi(sep->arg[2]),
|
||||
sep->argplus[3]
|
||||
);
|
||||
}
|
||||
else {
|
||||
worldserver.SendEmoteMessage(
|
||||
sep->arg[1],
|
||||
0,
|
||||
atoi(sep->arg[2]),
|
||||
sep->argplus[3]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
78
zone/gm_commands/emotesearch.cpp
Executable file
78
zone/gm_commands/emotesearch.cpp
Executable file
@ -0,0 +1,78 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_emotesearch(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (sep->arg[1][0] == 0) {
|
||||
c->Message(Chat::White, "Usage: #emotesearch [search string or emoteid]");
|
||||
}
|
||||
else {
|
||||
const char *search_criteria = sep->argplus[1];
|
||||
int count = 0;
|
||||
|
||||
if (Seperator::IsNumber(search_criteria)) {
|
||||
uint16 emoteid = atoi(search_criteria);
|
||||
LinkedListIterator<NPC_Emote_Struct *> iterator(zone->NPCEmoteList);
|
||||
iterator.Reset();
|
||||
while (iterator.MoreElements()) {
|
||||
NPC_Emote_Struct *nes = iterator.GetData();
|
||||
if (emoteid == nes->emoteid) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"EmoteID: %i Event: %i Type: %i Text: %s",
|
||||
nes->emoteid,
|
||||
nes->event_,
|
||||
nes->type,
|
||||
nes->text
|
||||
);
|
||||
count++;
|
||||
}
|
||||
iterator.Advance();
|
||||
}
|
||||
if (count == 0) {
|
||||
c->Message(Chat::White, "No emotes found.");
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "%i emote(s) found", count);
|
||||
}
|
||||
}
|
||||
else {
|
||||
char sText[64];
|
||||
char sCriteria[515];
|
||||
strn0cpy(sCriteria, search_criteria, sizeof(sCriteria));
|
||||
strupr(sCriteria);
|
||||
char *pdest;
|
||||
|
||||
LinkedListIterator<NPC_Emote_Struct *> iterator(zone->NPCEmoteList);
|
||||
iterator.Reset();
|
||||
while (iterator.MoreElements()) {
|
||||
NPC_Emote_Struct *nes = iterator.GetData();
|
||||
strn0cpy(sText, nes->text, sizeof(sText));
|
||||
strupr(sText);
|
||||
pdest = strstr(sText, sCriteria);
|
||||
if (pdest != nullptr) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"EmoteID: %i Event: %i Type: %i Text: %s",
|
||||
nes->emoteid,
|
||||
nes->event_,
|
||||
nes->type,
|
||||
nes->text
|
||||
);
|
||||
count++;
|
||||
}
|
||||
if (count == 50) {
|
||||
break;
|
||||
}
|
||||
|
||||
iterator.Advance();
|
||||
}
|
||||
if (count == 50) {
|
||||
c->Message(Chat::White, "50 emotes shown...too many results.");
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "%i emote(s) found", count);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
39
zone/gm_commands/emoteview.cpp
Executable file
39
zone/gm_commands/emoteview.cpp
Executable file
@ -0,0 +1,39 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_emoteview(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (!c->GetTarget() || !c->GetTarget()->IsNPC()) {
|
||||
c->Message(Chat::White, "You must target a NPC to view their emotes.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (c->GetTarget() && c->GetTarget()->IsNPC()) {
|
||||
int count = 0;
|
||||
int emoteid = c->GetTarget()->CastToNPC()->GetEmoteID();
|
||||
|
||||
LinkedListIterator<NPC_Emote_Struct *> iterator(zone->NPCEmoteList);
|
||||
iterator.Reset();
|
||||
while (iterator.MoreElements()) {
|
||||
NPC_Emote_Struct *nes = iterator.GetData();
|
||||
if (emoteid == nes->emoteid) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"EmoteID: %i Event: %i Type: %i Text: %s",
|
||||
nes->emoteid,
|
||||
nes->event_,
|
||||
nes->type,
|
||||
nes->text
|
||||
);
|
||||
count++;
|
||||
}
|
||||
iterator.Advance();
|
||||
}
|
||||
if (count == 0) {
|
||||
c->Message(Chat::White, "No emotes found.");
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "%i emote(s) found", count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
29
zone/gm_commands/enablerecipe.cpp
Executable file
29
zone/gm_commands/enablerecipe.cpp
Executable file
@ -0,0 +1,29 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_enablerecipe(Client *c, const Seperator *sep)
|
||||
{
|
||||
uint32 recipe_id = 0;
|
||||
bool success = false;
|
||||
if (c) {
|
||||
if (sep->argnum == 1) {
|
||||
recipe_id = atoi(sep->arg[1]);
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Invalid number of arguments.\nUsage: #enablerecipe recipe_id");
|
||||
return;
|
||||
}
|
||||
if (recipe_id > 0) {
|
||||
success = content_db.EnableRecipe(recipe_id);
|
||||
if (success) {
|
||||
c->Message(Chat::White, "Recipe enabled.");
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Recipe not enabled.");
|
||||
}
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Invalid recipe id.\nUsage: #enablerecipe recipe_id");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
27
zone/gm_commands/endurance.cpp
Executable file
27
zone/gm_commands/endurance.cpp
Executable file
@ -0,0 +1,27 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_endurance(Client *c, const Seperator *sep)
|
||||
{
|
||||
auto target = c->GetTarget() ? c->GetTarget() : c;
|
||||
if (target->IsClient()) {
|
||||
target->CastToClient()->SetEndurance(target->CastToClient()->GetMaxEndurance());
|
||||
}
|
||||
else {
|
||||
target->SetEndurance(target->GetMaxEndurance());
|
||||
}
|
||||
|
||||
if (c != target) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Set {} ({}) to full Endurance.",
|
||||
target->GetCleanName(),
|
||||
target->GetID()
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Restored your Endurance to full.");
|
||||
}
|
||||
}
|
||||
|
||||
82
zone/gm_commands/equipitem.cpp
Executable file
82
zone/gm_commands/equipitem.cpp
Executable file
@ -0,0 +1,82 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_equipitem(Client *c, const Seperator *sep)
|
||||
{
|
||||
uint32 slot_id = atoi(sep->arg[1]);
|
||||
if (sep->IsNumber(1) && (slot_id >= EQ::invslot::EQUIPMENT_BEGIN && slot_id <= EQ::invslot::EQUIPMENT_END)) {
|
||||
const EQ::ItemInstance *from_inst = c->GetInv().GetItem(EQ::invslot::slotCursor);
|
||||
const EQ::ItemInstance *to_inst = c->GetInv().GetItem(slot_id); // added (desync issue when forcing stack to stack)
|
||||
bool partialmove = false;
|
||||
int16 movecount;
|
||||
|
||||
if (from_inst && from_inst->IsClassCommon()) {
|
||||
auto outapp = new EQApplicationPacket(OP_MoveItem, sizeof(MoveItem_Struct));
|
||||
MoveItem_Struct *mi = (MoveItem_Struct *) outapp->pBuffer;
|
||||
mi->from_slot = EQ::invslot::slotCursor;
|
||||
mi->to_slot = slot_id;
|
||||
// mi->number_in_stack = from_inst->GetCharges(); // replaced with con check for stacking
|
||||
|
||||
// crude stackable check to only 'move' the difference count on client instead of entire stack when applicable
|
||||
if (to_inst && to_inst->IsStackable() &&
|
||||
(to_inst->GetItem()->ID == from_inst->GetItem()->ID) &&
|
||||
(to_inst->GetCharges() < to_inst->GetItem()->StackSize) &&
|
||||
(from_inst->GetCharges() > to_inst->GetItem()->StackSize - to_inst->GetCharges())) {
|
||||
movecount = to_inst->GetItem()->StackSize - to_inst->GetCharges();
|
||||
mi->number_in_stack = (uint32) movecount;
|
||||
partialmove = true;
|
||||
}
|
||||
else {
|
||||
mi->number_in_stack = from_inst->GetCharges();
|
||||
}
|
||||
|
||||
// Save move changes
|
||||
// Added conditional check to packet send..would have sent change even on a swap failure..whoops!
|
||||
|
||||
if (partialmove) { // remove this con check if someone can figure out removing charges from cursor stack issue below
|
||||
// mi->number_in_stack is always from_inst->GetCharges() when partialmove is false
|
||||
c->Message(Chat::Red, "Error: Partial stack added to existing stack exceeds allowable stacksize");
|
||||
safe_delete(outapp);
|
||||
return;
|
||||
}
|
||||
else if (c->SwapItem(mi)) {
|
||||
c->FastQueuePacket(&outapp);
|
||||
|
||||
// if the below code is still needed..just send an an item trade packet to each slot..it should overwrite the client instance
|
||||
|
||||
// below code has proper logic, but client does not like to have cursor charges changed
|
||||
// (we could delete the cursor item and resend, but issues would arise if there are queued items)
|
||||
//if (partialmove) {
|
||||
// EQApplicationPacket* outapp2 = new EQApplicationPacket(OP_DeleteItem, sizeof(DeleteItem_Struct));
|
||||
// DeleteItem_Struct* di = (DeleteItem_Struct*)outapp2->pBuffer;
|
||||
// di->from_slot = SLOT_CURSOR;
|
||||
// di->to_slot = 0xFFFFFFFF;
|
||||
// di->number_in_stack = 0xFFFFFFFF;
|
||||
|
||||
// c->Message(Chat::White, "Deleting %i charges from stack", movecount); // debug line..delete
|
||||
|
||||
// for (int16 deletecount=0; deletecount < movecount; deletecount++)
|
||||
// have to use 'movecount' because mi->number_in_stack is 'ENCODED' at this point (i.e., 99 charges returns 22...)
|
||||
// c->QueuePacket(outapp2);
|
||||
|
||||
// safe_delete(outapp2);
|
||||
//}
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::Red, "Error: Unable to equip current item");
|
||||
}
|
||||
safe_delete(outapp);
|
||||
|
||||
// also send out a wear change packet?
|
||||
}
|
||||
else if (from_inst == nullptr) {
|
||||
c->Message(Chat::Red, "Error: There is no item on your cursor");
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::Red, "Error: Item on your cursor cannot be equipped");
|
||||
}
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Usage: #equipitem slotid[0-21] - equips the item on your cursor to the position");
|
||||
}
|
||||
}
|
||||
|
||||
37
zone/gm_commands/face.cpp
Executable file
37
zone/gm_commands/face.cpp
Executable file
@ -0,0 +1,37 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_face(Client *c, const Seperator *sep)
|
||||
{
|
||||
Mob *target = c->GetTarget();
|
||||
if (!sep->IsNumber(1)) {
|
||||
c->Message(Chat::White, "Usage: #face [number of face]");
|
||||
}
|
||||
else if (!target) {
|
||||
c->Message(Chat::White, "Error: this command requires a target");
|
||||
}
|
||||
else {
|
||||
uint16 Race = target->GetRace();
|
||||
uint8 Gender = target->GetGender();
|
||||
uint8 Texture = 0xFF;
|
||||
uint8 HelmTexture = 0xFF;
|
||||
uint8 HairColor = target->GetHairColor();
|
||||
uint8 BeardColor = target->GetBeardColor();
|
||||
uint8 EyeColor1 = target->GetEyeColor1();
|
||||
uint8 EyeColor2 = target->GetEyeColor2();
|
||||
uint8 HairStyle = target->GetHairStyle();
|
||||
uint8 LuclinFace = atoi(sep->arg[1]);
|
||||
uint8 Beard = target->GetBeard();
|
||||
uint32 DrakkinHeritage = target->GetDrakkinHeritage();
|
||||
uint32 DrakkinTattoo = target->GetDrakkinTattoo();
|
||||
uint32 DrakkinDetails = target->GetDrakkinDetails();
|
||||
|
||||
target->SendIllusionPacket(
|
||||
Race, Gender, Texture, HelmTexture, HairColor, BeardColor,
|
||||
EyeColor1, EyeColor2, HairStyle, LuclinFace, Beard, 0xFF,
|
||||
DrakkinHeritage, DrakkinTattoo, DrakkinDetails
|
||||
);
|
||||
|
||||
c->Message(Chat::White, "Face = %i", atoi(sep->arg[1]));
|
||||
}
|
||||
}
|
||||
|
||||
174
zone/gm_commands/faction.cpp
Executable file
174
zone/gm_commands/faction.cpp
Executable file
@ -0,0 +1,174 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_faction(Client *c, const Seperator *sep)
|
||||
{
|
||||
int arguments = sep->argnum;
|
||||
if (!arguments) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"Usage: #faction review [Search Criteria | All] - Review Targeted Player's Faction Hits"
|
||||
);
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"Usage: #faction reset [Faction ID] - Reset Targeted Player's Faction to Base Faction Value"
|
||||
);
|
||||
c->Message(Chat::White, "Usage: #faction view - Displays Target NPC's Primary Faction");
|
||||
return;
|
||||
}
|
||||
|
||||
std::string faction_filter;
|
||||
if (sep->arg[2]) {
|
||||
faction_filter = str_tolower(sep->arg[2]);
|
||||
}
|
||||
|
||||
if (!strcasecmp(sep->arg[1], "review")) {
|
||||
if (!(c->GetTarget() && c->GetTarget()->IsClient())) {
|
||||
c->Message(Chat::Red, "Player Target Required for faction review");
|
||||
return;
|
||||
}
|
||||
|
||||
Client *target = c->GetTarget()->CastToClient();
|
||||
uint32 character_id = target->CharacterID();
|
||||
std::string query;
|
||||
if (!strcasecmp(faction_filter.c_str(), "all")) {
|
||||
query = fmt::format(
|
||||
"SELECT id, `name`, current_value FROM faction_list INNER JOIN faction_values ON faction_list.id = faction_values.faction_id WHERE char_id = {}",
|
||||
character_id
|
||||
);
|
||||
}
|
||||
else {
|
||||
query = fmt::format(
|
||||
"SELECT id, `name`, current_value FROM faction_list INNER JOIN faction_values ON faction_list.id = faction_values.faction_id WHERE `name` like '%{}%' and char_id = {}",
|
||||
faction_filter.c_str(),
|
||||
character_id
|
||||
);
|
||||
}
|
||||
|
||||
auto results = content_db.QueryDatabase(query);
|
||||
if (!results.Success() || !results.RowCount()) {
|
||||
c->Message(Chat::Yellow, "No faction hits found. All are at base level.");
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 found_count = 0;
|
||||
for (auto row : results) {
|
||||
uint32 faction_number = (found_count + 1);
|
||||
auto faction_id = std::stoul(row[0]);
|
||||
std::string faction_name = row[1];
|
||||
std::string faction_value = row[2];
|
||||
std::string reset_link = EQ::SayLinkEngine::GenerateQuestSaylink(
|
||||
fmt::format("#faction reset {}", faction_id),
|
||||
false,
|
||||
"Reset"
|
||||
);
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Faction {} | Name: {} ({}) Value: {} [{}]",
|
||||
faction_number,
|
||||
faction_name,
|
||||
faction_id,
|
||||
faction_value,
|
||||
reset_link
|
||||
).c_str()
|
||||
);
|
||||
found_count++;
|
||||
}
|
||||
|
||||
auto faction_message = (
|
||||
found_count > 0 ?
|
||||
(
|
||||
found_count == 1 ?
|
||||
"A Faction was" :
|
||||
fmt::format("{} Factions were", found_count)
|
||||
) :
|
||||
"No Factions were"
|
||||
);
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"{} found.",
|
||||
faction_message
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[1], "reset")) {
|
||||
if (strlen(faction_filter.c_str()) > 0) {
|
||||
if (c->GetTarget() && c->GetTarget()->IsClient()) {
|
||||
Client *target = c->GetTarget()->CastToClient();
|
||||
if (
|
||||
(
|
||||
!c->GetFeigned() &&
|
||||
c->GetAggroCount() == 0
|
||||
) ||
|
||||
(
|
||||
!target->GetFeigned() &&
|
||||
target->GetAggroCount() == 0
|
||||
)
|
||||
) {
|
||||
uint32 character_id = target->CharacterID();
|
||||
uint32 faction_id = std::stoul(faction_filter.c_str());
|
||||
if (target->ReloadCharacterFaction(target, faction_id, character_id)) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Faction Reset | {} ({}) was reset for {}.",
|
||||
content_db.GetFactionName(faction_id),
|
||||
faction_id,
|
||||
target->GetCleanName()
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Faction Reset Failed | {} ({}) was unable to be reset for {}.",
|
||||
content_db.GetFactionName(faction_id),
|
||||
faction_id,
|
||||
target->GetCleanName()
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"You cannot reset factions while you or your target is in combat or feigned."
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "You must target a PC for this command.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"Usage: #faction reset [Faction ID] - Reset Targeted Player's Faction to Base Faction Value"
|
||||
);
|
||||
}
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[1], "view")) {
|
||||
if (c->GetTarget() && c->GetTarget()->IsNPC()) {
|
||||
Mob *target = c->GetTarget();
|
||||
uint32 npc_id = target->GetNPCTypeID();
|
||||
uint32 npc_faction_id = target->CastToNPC()->GetPrimaryFaction();
|
||||
std::string npc_name = target->GetCleanName();
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"{} ({}) has a Primary Faction of {} ({}).",
|
||||
npc_name,
|
||||
npc_id,
|
||||
content_db.GetFactionName(npc_faction_id),
|
||||
npc_faction_id
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
84
zone/gm_commands/findclass.cpp
Executable file
84
zone/gm_commands/findclass.cpp
Executable file
@ -0,0 +1,84 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_findclass(Client *c, const Seperator *sep)
|
||||
{
|
||||
int arguments = sep->argnum;
|
||||
|
||||
if (arguments == 0) {
|
||||
c->Message(Chat::White, "Command Syntax: #findclass [search criteria]");
|
||||
return;
|
||||
}
|
||||
|
||||
if (sep->IsNumber(1)) {
|
||||
int class_id = std::stoi(sep->arg[1]);
|
||||
if (class_id >= WARRIOR && class_id <= MERCERNARY_MASTER) {
|
||||
std::string class_name = GetClassIDName(class_id);
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Class {}: {}",
|
||||
class_id,
|
||||
class_name
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Class ID {} was not found.",
|
||||
class_id
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::string search_criteria = str_tolower(sep->argplus[1]);
|
||||
int found_count = 0;
|
||||
for (int class_id = WARRIOR; class_id <= MERCERNARY_MASTER; class_id++) {
|
||||
std::string class_name = GetClassIDName(class_id);
|
||||
std::string class_name_lower = str_tolower(class_name);
|
||||
if (search_criteria.length() > 0 && class_name_lower.find(search_criteria) == std::string::npos) {
|
||||
continue;
|
||||
}
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Class {}: {}",
|
||||
class_id,
|
||||
class_name
|
||||
).c_str()
|
||||
);
|
||||
found_count++;
|
||||
|
||||
if (found_count == 20) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found_count == 20) {
|
||||
c->Message(Chat::White, "20 Classes found... max reached.");
|
||||
}
|
||||
else {
|
||||
auto class_message = (
|
||||
found_count > 0 ?
|
||||
(
|
||||
found_count == 1 ?
|
||||
"A Class was" :
|
||||
fmt::format("{} Classes were", found_count)
|
||||
) :
|
||||
"No Classes were"
|
||||
);
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"{} found.",
|
||||
class_message
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
89
zone/gm_commands/findfaction.cpp
Executable file
89
zone/gm_commands/findfaction.cpp
Executable file
@ -0,0 +1,89 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_findfaction(Client *c, const Seperator *sep)
|
||||
{
|
||||
int arguments = sep->argnum;
|
||||
|
||||
if (arguments == 0) {
|
||||
c->Message(Chat::White, "Command Syntax: #findfaction [search criteria]");
|
||||
return;
|
||||
}
|
||||
|
||||
if (sep->IsNumber(1)) {
|
||||
int faction_id = std::stoi(sep->arg[1]);
|
||||
auto faction_name = content_db.GetFactionName(faction_id);
|
||||
if (!faction_name.empty()) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Faction {}: {}",
|
||||
faction_id,
|
||||
faction_name
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Faction ID {} was not found.",
|
||||
faction_id
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::string search_criteria = str_tolower(sep->argplus[1]);
|
||||
int found_count = 0;
|
||||
int max_faction_id = content_db.GetMaxFaction();
|
||||
for (int faction_id = 0; faction_id < max_faction_id; faction_id++) {
|
||||
std::string faction_name = content_db.GetFactionName(faction_id);
|
||||
std::string faction_name_lower = str_tolower(faction_name);
|
||||
if (faction_name.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (faction_name.find(search_criteria) == std::string::npos) {
|
||||
continue;
|
||||
}
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Faction {}: {}",
|
||||
faction_id,
|
||||
faction_name
|
||||
).c_str()
|
||||
);
|
||||
found_count++;
|
||||
|
||||
if (found_count == 20) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found_count == 20) {
|
||||
c->Message(Chat::White, "20 Factions found... max reached.");
|
||||
}
|
||||
else {
|
||||
auto faction_message = (
|
||||
found_count > 0 ?
|
||||
(
|
||||
found_count == 1 ?
|
||||
"A Faction was" :
|
||||
fmt::format("{} Factions were", found_count)
|
||||
) :
|
||||
"No Factions were"
|
||||
);
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"{} found.",
|
||||
faction_message
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
77
zone/gm_commands/findnpctype.cpp
Executable file
77
zone/gm_commands/findnpctype.cpp
Executable file
@ -0,0 +1,77 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_findnpctype(Client *c, const Seperator *sep)
|
||||
{
|
||||
int arguments = sep->argnum;
|
||||
if (!arguments) {
|
||||
c->Message(Chat::White, "Usage: #findnpctype [Search Criteria]");
|
||||
return;
|
||||
}
|
||||
|
||||
std::string query;
|
||||
std::string search_criteria = sep->arg[1];
|
||||
if (sep->IsNumber(1)) {
|
||||
query = fmt::format(
|
||||
"SELECT id, name FROM npc_types WHERE id = {}",
|
||||
search_criteria
|
||||
);
|
||||
}
|
||||
else {
|
||||
query = fmt::format(
|
||||
"SELECT id, name FROM npc_types WHERE name LIKE '%%{}%%'",
|
||||
search_criteria
|
||||
);
|
||||
}
|
||||
|
||||
auto results = content_db.QueryDatabase(query);
|
||||
if (!results.Success() || !results.RowCount()) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"No matches found for '{}'.",
|
||||
search_criteria
|
||||
).c_str()
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
int found_count = 0;
|
||||
|
||||
for (auto row : results) {
|
||||
int found_number = (found_count + 1);
|
||||
if (found_count == 20) {
|
||||
break;
|
||||
}
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"NPC {} | {} ({})",
|
||||
found_number,
|
||||
row[1],
|
||||
row[0]
|
||||
).c_str()
|
||||
);
|
||||
found_count++;
|
||||
}
|
||||
|
||||
if (found_count == 20) {
|
||||
c->Message(Chat::White, "20 NPCs were found, max reached.");
|
||||
}
|
||||
else {
|
||||
auto npc_message = (
|
||||
found_count == 1 ?
|
||||
"An NPC was" :
|
||||
fmt::format("{} NPCs were", found_count)
|
||||
);
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"{} found.",
|
||||
npc_message
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
84
zone/gm_commands/findrace.cpp
Executable file
84
zone/gm_commands/findrace.cpp
Executable file
@ -0,0 +1,84 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_findrace(Client *c, const Seperator *sep)
|
||||
{
|
||||
int arguments = sep->argnum;
|
||||
|
||||
if (arguments == 0) {
|
||||
c->Message(Chat::White, "Command Syntax: #findrace [search criteria]");
|
||||
return;
|
||||
}
|
||||
|
||||
if (sep->IsNumber(1)) {
|
||||
int race_id = std::stoi(sep->arg[1]);
|
||||
std::string race_name = GetRaceIDName(race_id);
|
||||
if (race_id >= RACE_HUMAN_1 && race_id <= RACE_PEGASUS_732) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Race {}: {}",
|
||||
race_id,
|
||||
race_name
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Race ID {} was not found.",
|
||||
race_id
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::string search_criteria = str_tolower(sep->argplus[1]);
|
||||
int found_count = 0;
|
||||
for (int race_id = RACE_HUMAN_1; race_id <= RACE_PEGASUS_732; race_id++) {
|
||||
std::string race_name = GetRaceIDName(race_id);
|
||||
std::string race_name_lower = str_tolower(race_name);
|
||||
if (search_criteria.length() > 0 && race_name_lower.find(search_criteria) == std::string::npos) {
|
||||
continue;
|
||||
}
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Race {}: {}",
|
||||
race_id,
|
||||
race_name
|
||||
).c_str()
|
||||
);
|
||||
found_count++;
|
||||
|
||||
if (found_count == 20) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found_count == 20) {
|
||||
c->Message(Chat::White, "20 Races found... max reached.");
|
||||
}
|
||||
else {
|
||||
auto race_message = (
|
||||
found_count > 0 ?
|
||||
(
|
||||
found_count == 1 ?
|
||||
"A Race was" :
|
||||
fmt::format("{} Races were", found_count)
|
||||
) :
|
||||
"No Races were"
|
||||
);
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"{} found.",
|
||||
race_message
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
90
zone/gm_commands/findskill.cpp
Executable file
90
zone/gm_commands/findskill.cpp
Executable file
@ -0,0 +1,90 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_findskill(Client *c, const Seperator *sep)
|
||||
{
|
||||
int arguments = sep->argnum;
|
||||
|
||||
if (arguments == 0) {
|
||||
c->Message(Chat::White, "Command Syntax: #findskill [search criteria]");
|
||||
return;
|
||||
}
|
||||
|
||||
std::map<EQ::skills::SkillType, std::string> skills = EQ::skills::GetSkillTypeMap();
|
||||
if (sep->IsNumber(1)) {
|
||||
int skill_id = std::stoi(sep->arg[1]);
|
||||
if (skill_id >= EQ::skills::Skill1HBlunt && skill_id < EQ::skills::SkillCount) {
|
||||
for (auto skill : skills) {
|
||||
if (skill_id == skill.first) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Skill {}: {}",
|
||||
skill.first,
|
||||
skill.second
|
||||
).c_str()
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Skill ID {} was not found.",
|
||||
skill_id
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::string search_criteria = str_tolower(sep->argplus[1]);
|
||||
if (!search_criteria.empty()) {
|
||||
int found_count = 0;
|
||||
for (auto skill : skills) {
|
||||
std::string skill_name_lower = str_tolower(skill.second);
|
||||
if (skill_name_lower.find(search_criteria) == std::string::npos) {
|
||||
continue;
|
||||
}
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Skill {}: {}",
|
||||
skill.first,
|
||||
skill.second
|
||||
).c_str()
|
||||
);
|
||||
found_count++;
|
||||
|
||||
if (found_count == 20) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found_count == 20) {
|
||||
c->Message(Chat::White, "20 Skills were found, max reached.");
|
||||
}
|
||||
else {
|
||||
auto skill_message = (
|
||||
found_count > 0 ?
|
||||
(
|
||||
found_count == 1 ?
|
||||
"A Skill was" :
|
||||
fmt::format("{} Skills were", found_count)
|
||||
) :
|
||||
"No Skills were"
|
||||
);
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"{} found.",
|
||||
skill_message
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
129
zone/gm_commands/findspell.cpp
Executable file
129
zone/gm_commands/findspell.cpp
Executable file
@ -0,0 +1,129 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_findspell(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (SPDAT_RECORDS <= 0) {
|
||||
c->Message(Chat::White, "Spells not loaded");
|
||||
return;
|
||||
}
|
||||
|
||||
int arguments = sep->argnum;
|
||||
|
||||
if (arguments == 0) {
|
||||
c->Message(Chat::White, "Command Syntax: #findspell [search criteria]");
|
||||
return;
|
||||
}
|
||||
|
||||
if (sep->IsNumber(1)) {
|
||||
int spell_id = std::stoi(sep->arg[1]);
|
||||
if (!IsValidSpell(spell_id)) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Spell ID {} was not found.",
|
||||
spell_id
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Spell {}: {}",
|
||||
spell_id,
|
||||
spells[spell_id].name
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::string search_criteria = str_tolower(sep->argplus[1]);
|
||||
int found_count = 0;
|
||||
for (int spell_id = 0; spell_id < SPDAT_RECORDS; spell_id++) {
|
||||
auto current_spell = spells[spell_id];
|
||||
if (current_spell.name[0] != 0) {
|
||||
std::string spell_name = current_spell.name;
|
||||
std::string spell_name_lower = str_tolower(spell_name);
|
||||
if (search_criteria.length() > 0 && spell_name_lower.find(search_criteria) == std::string::npos) {
|
||||
continue;
|
||||
}
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Spell {}: {}",
|
||||
spell_id,
|
||||
spell_name
|
||||
).c_str()
|
||||
);
|
||||
found_count++;
|
||||
|
||||
if (found_count == 20) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (found_count == 20) {
|
||||
c->Message(Chat::White, "20 Spells found... max reached.");
|
||||
}
|
||||
else {
|
||||
auto spell_message = (
|
||||
found_count > 0 ?
|
||||
(
|
||||
found_count == 1 ?
|
||||
"A Spell was" :
|
||||
fmt::format("{} Spells were", found_count)
|
||||
) :
|
||||
"No Spells were"
|
||||
);
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"{} found.",
|
||||
spell_message
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline bool CastRestrictedSpell(int spellid)
|
||||
{
|
||||
switch (spellid) {
|
||||
case SPELL_TOUCH_OF_VINITRAS:
|
||||
case SPELL_DESPERATE_HOPE:
|
||||
case SPELL_CHARM:
|
||||
case SPELL_METAMORPHOSIS65:
|
||||
case SPELL_JT_BUFF:
|
||||
case SPELL_CAN_O_WHOOP_ASS:
|
||||
case SPELL_PHOENIX_CHARM:
|
||||
case SPELL_CAZIC_TOUCH:
|
||||
case SPELL_AVATAR_KNOCKBACK:
|
||||
case SPELL_SHAPECHANGE65:
|
||||
case SPELL_SUNSET_HOME1218:
|
||||
case SPELL_SUNSET_HOME819:
|
||||
case SPELL_SHAPECHANGE75:
|
||||
case SPELL_SHAPECHANGE80:
|
||||
case SPELL_SHAPECHANGE85:
|
||||
case SPELL_SHAPECHANGE90:
|
||||
case SPELL_SHAPECHANGE95:
|
||||
case SPELL_SHAPECHANGE100:
|
||||
case SPELL_SHAPECHANGE25:
|
||||
case SPELL_SHAPECHANGE30:
|
||||
case SPELL_SHAPECHANGE35:
|
||||
case SPELL_SHAPECHANGE40:
|
||||
case SPELL_SHAPECHANGE45:
|
||||
case SPELL_SHAPECHANGE50:
|
||||
case SPELL_NPC_AEGOLISM:
|
||||
case SPELL_SHAPECHANGE55:
|
||||
case SPELL_SHAPECHANGE60:
|
||||
case SPELL_COMMAND_OF_DRUZZIL:
|
||||
case SPELL_SHAPECHANGE70:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
89
zone/gm_commands/findtask.cpp
Executable file
89
zone/gm_commands/findtask.cpp
Executable file
@ -0,0 +1,89 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_findtask(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (RuleB(TaskSystem, EnableTaskSystem)) {
|
||||
int arguments = sep->argnum;
|
||||
|
||||
if (arguments == 0) {
|
||||
c->Message(Chat::White, "Command Syntax: #findtask [search criteria]");
|
||||
return;
|
||||
}
|
||||
|
||||
if (sep->IsNumber(1)) {
|
||||
auto task_id = std::stoul(sep->arg[1]);
|
||||
auto task_name = task_manager->GetTaskName(task_id);
|
||||
auto task_message = (
|
||||
!task_name.empty() ?
|
||||
fmt::format(
|
||||
"Task {}: {}",
|
||||
task_id,
|
||||
task_name
|
||||
).c_str() :
|
||||
fmt::format(
|
||||
"Task ID {} was not found.",
|
||||
task_id
|
||||
).c_str()
|
||||
);
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
task_message
|
||||
);
|
||||
}
|
||||
else {
|
||||
std::string search_criteria = str_tolower(sep->argplus[1]);
|
||||
if (!search_criteria.empty()) {
|
||||
int found_count = 0;
|
||||
for (uint32 task_id = 1; task_id <= MAXTASKS; task_id++) {
|
||||
auto task_name = task_manager->GetTaskName(task_id);
|
||||
std::string task_name_lower = str_tolower(task_name);
|
||||
if (task_name_lower.find(search_criteria) == std::string::npos) {
|
||||
continue;
|
||||
}
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Task {}: {}",
|
||||
task_id,
|
||||
task_name
|
||||
).c_str()
|
||||
);
|
||||
found_count++;
|
||||
|
||||
if (found_count == 20) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found_count == 20) {
|
||||
c->Message(Chat::White, "20 Tasks were found, max reached.");
|
||||
}
|
||||
else {
|
||||
auto task_message = (
|
||||
found_count > 0 ?
|
||||
(
|
||||
found_count == 1 ?
|
||||
"A Task was" :
|
||||
fmt::format("{} Tasks were", found_count)
|
||||
) :
|
||||
"No Tasks were"
|
||||
);
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"{} found.",
|
||||
task_message
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "This command cannot be used while the Task system is disabled.");
|
||||
}
|
||||
}
|
||||
|
||||
95
zone/gm_commands/findzone.cpp
Executable file
95
zone/gm_commands/findzone.cpp
Executable file
@ -0,0 +1,95 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_findzone(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (sep->arg[1][0] == 0) {
|
||||
c->Message(Chat::White, "Usage: #findzone [search criteria]");
|
||||
c->Message(Chat::White, "Usage: #findzone expansion [expansion number]");
|
||||
return;
|
||||
}
|
||||
|
||||
std::string query;
|
||||
int id = atoi((const char *) sep->arg[1]);
|
||||
|
||||
std::string arg1 = sep->arg[1];
|
||||
|
||||
if (arg1 == "expansion") {
|
||||
query = fmt::format(
|
||||
"SELECT zoneidnumber, short_name, long_name, version FROM zone WHERE expansion = {}",
|
||||
sep->arg[2]
|
||||
);
|
||||
}
|
||||
else {
|
||||
|
||||
/**
|
||||
* If id evaluates to 0, then search as if user entered a string
|
||||
*/
|
||||
if (id == 0) {
|
||||
query = fmt::format(
|
||||
"SELECT zoneidnumber, short_name, long_name, version FROM zone WHERE long_name LIKE '%{}%' OR `short_name` LIKE '%{}%'",
|
||||
EscapeString(sep->arg[1]),
|
||||
EscapeString(sep->arg[1])
|
||||
);
|
||||
}
|
||||
else {
|
||||
query = fmt::format(
|
||||
"SELECT zoneidnumber, short_name, long_name, version FROM zone WHERE zoneidnumber = {}",
|
||||
id
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
auto results = content_db.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
c->Message(Chat::White, "Error querying database.");
|
||||
c->Message(Chat::White, query.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
const int maxrows = 100;
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
std::string zone_id = row[0];
|
||||
std::string short_name = row[1];
|
||||
std::string long_name = row[2];
|
||||
int version = atoi(row[3]);
|
||||
|
||||
if (++count > maxrows) {
|
||||
c->Message(Chat::White, "%i zones shown. Too many results.", maxrows);
|
||||
break;
|
||||
}
|
||||
|
||||
std::string command_zone = EQ::SayLinkEngine::GenerateQuestSaylink("#zone " + short_name, false, "zone");
|
||||
std::string command_gmzone = EQ::SayLinkEngine::GenerateQuestSaylink(
|
||||
fmt::format("#gmzone {} {}", short_name, version),
|
||||
false,
|
||||
"gmzone"
|
||||
);
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"[{}] [{}] [{}] ID ({}) Version ({}) [{}]",
|
||||
(version == 0 ? command_zone : "zone"),
|
||||
command_gmzone,
|
||||
short_name,
|
||||
zone_id,
|
||||
version,
|
||||
long_name
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
|
||||
if (count <= maxrows) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"Query complete. %i rows shown. %s",
|
||||
count,
|
||||
(arg1 == "expansion" ? "(expansion search)" : ""));
|
||||
}
|
||||
else if (count == 0) {
|
||||
c->Message(Chat::White, "No matches found for %s.", sep->arg[1]);
|
||||
}
|
||||
}
|
||||
|
||||
250
zone/gm_commands/fixmob.cpp
Executable file
250
zone/gm_commands/fixmob.cpp
Executable file
@ -0,0 +1,250 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_fixmob(Client *c, const Seperator *sep)
|
||||
{
|
||||
Mob *target = c->GetTarget();
|
||||
const char *Usage = "Usage: #fixmob [race|gender|texture|helm|face|hair|haircolor|beard|beardcolor|heritage|tattoo|detail] [next|prev]";
|
||||
|
||||
if (!sep->arg[1]) {
|
||||
c->Message(Chat::White, Usage);
|
||||
}
|
||||
else if (!target) {
|
||||
c->Message(Chat::White, "Error: this command requires a target");
|
||||
}
|
||||
else {
|
||||
|
||||
uint32 Adjustment = 1; // Previous or Next
|
||||
char codeMove = 0;
|
||||
|
||||
if (sep->arg[2]) {
|
||||
char *command2 = sep->arg[2];
|
||||
codeMove = (command2[0] | 0x20); // First character, lower-cased
|
||||
if (codeMove == 'n') {
|
||||
Adjustment = 1;
|
||||
}
|
||||
else if (codeMove == 'p') {
|
||||
Adjustment = -1;
|
||||
}
|
||||
}
|
||||
|
||||
uint16 Race = target->GetRace();
|
||||
uint8 Gender = target->GetGender();
|
||||
uint8 Texture = 0xFF;
|
||||
uint8 HelmTexture = 0xFF;
|
||||
uint8 HairColor = target->GetHairColor();
|
||||
uint8 BeardColor = target->GetBeardColor();
|
||||
uint8 EyeColor1 = target->GetEyeColor1();
|
||||
uint8 EyeColor2 = target->GetEyeColor2();
|
||||
uint8 HairStyle = target->GetHairStyle();
|
||||
uint8 LuclinFace = target->GetLuclinFace();
|
||||
uint8 Beard = target->GetBeard();
|
||||
uint32 DrakkinHeritage = target->GetDrakkinHeritage();
|
||||
uint32 DrakkinTattoo = target->GetDrakkinTattoo();
|
||||
uint32 DrakkinDetails = target->GetDrakkinDetails();
|
||||
|
||||
const char *ChangeType = nullptr; // If it's still nullptr after processing, they didn't send a valid command
|
||||
uint32 ChangeSetting;
|
||||
char *command = sep->arg[1];
|
||||
|
||||
if (strcasecmp(command, "race") == 0) {
|
||||
if (Race == 1 && codeMove == 'p') {
|
||||
Race = RuleI(NPC, MaxRaceID);
|
||||
}
|
||||
else if (Race >= RuleI(NPC, MaxRaceID) && codeMove != 'p') {
|
||||
Race = 1;
|
||||
}
|
||||
else {
|
||||
Race += Adjustment;
|
||||
}
|
||||
ChangeType = "Race";
|
||||
ChangeSetting = Race;
|
||||
}
|
||||
else if (strcasecmp(command, "gender") == 0) {
|
||||
if (Gender == 0 && codeMove == 'p') {
|
||||
Gender = 2;
|
||||
}
|
||||
else if (Gender >= 2 && codeMove != 'p') {
|
||||
Gender = 0;
|
||||
}
|
||||
else {
|
||||
Gender += Adjustment;
|
||||
}
|
||||
ChangeType = "Gender";
|
||||
ChangeSetting = Gender;
|
||||
}
|
||||
else if (strcasecmp(command, "texture") == 0) {
|
||||
Texture = target->GetTexture();
|
||||
|
||||
if (Texture == 0 && codeMove == 'p') {
|
||||
Texture = 25;
|
||||
}
|
||||
else if (Texture >= 25 && codeMove != 'p') {
|
||||
Texture = 0;
|
||||
}
|
||||
else {
|
||||
Texture += Adjustment;
|
||||
}
|
||||
ChangeType = "Texture";
|
||||
ChangeSetting = Texture;
|
||||
}
|
||||
else if (strcasecmp(command, "helm") == 0) {
|
||||
HelmTexture = target->GetHelmTexture();
|
||||
if (HelmTexture == 0 && codeMove == 'p') {
|
||||
HelmTexture = 25;
|
||||
}
|
||||
else if (HelmTexture >= 25 && codeMove != 'p') {
|
||||
HelmTexture = 0;
|
||||
}
|
||||
else {
|
||||
HelmTexture += Adjustment;
|
||||
}
|
||||
ChangeType = "HelmTexture";
|
||||
ChangeSetting = HelmTexture;
|
||||
}
|
||||
else if (strcasecmp(command, "face") == 0) {
|
||||
if (LuclinFace == 0 && codeMove == 'p') {
|
||||
LuclinFace = 87;
|
||||
}
|
||||
else if (LuclinFace >= 87 && codeMove != 'p') {
|
||||
LuclinFace = 0;
|
||||
}
|
||||
else {
|
||||
LuclinFace += Adjustment;
|
||||
}
|
||||
ChangeType = "LuclinFace";
|
||||
ChangeSetting = LuclinFace;
|
||||
}
|
||||
else if (strcasecmp(command, "hair") == 0) {
|
||||
if (HairStyle == 0 && codeMove == 'p') {
|
||||
HairStyle = 8;
|
||||
}
|
||||
else if (HairStyle >= 8 && codeMove != 'p') {
|
||||
HairStyle = 0;
|
||||
}
|
||||
else {
|
||||
HairStyle += Adjustment;
|
||||
}
|
||||
ChangeType = "HairStyle";
|
||||
ChangeSetting = HairStyle;
|
||||
}
|
||||
else if (strcasecmp(command, "haircolor") == 0) {
|
||||
if (HairColor == 0 && codeMove == 'p') {
|
||||
HairColor = 24;
|
||||
}
|
||||
else if (HairColor >= 24 && codeMove != 'p') {
|
||||
HairColor = 0;
|
||||
}
|
||||
else {
|
||||
HairColor += Adjustment;
|
||||
}
|
||||
ChangeType = "HairColor";
|
||||
ChangeSetting = HairColor;
|
||||
}
|
||||
else if (strcasecmp(command, "beard") == 0) {
|
||||
if (Beard == 0 && codeMove == 'p') {
|
||||
Beard = 11;
|
||||
}
|
||||
else if (Beard >= 11 && codeMove != 'p') {
|
||||
Beard = 0;
|
||||
}
|
||||
else {
|
||||
Beard += Adjustment;
|
||||
}
|
||||
ChangeType = "Beard";
|
||||
ChangeSetting = Beard;
|
||||
}
|
||||
else if (strcasecmp(command, "beardcolor") == 0) {
|
||||
if (BeardColor == 0 && codeMove == 'p') {
|
||||
BeardColor = 24;
|
||||
}
|
||||
else if (BeardColor >= 24 && codeMove != 'p') {
|
||||
BeardColor = 0;
|
||||
}
|
||||
else {
|
||||
BeardColor += Adjustment;
|
||||
}
|
||||
ChangeType = "BeardColor";
|
||||
ChangeSetting = BeardColor;
|
||||
}
|
||||
else if (strcasecmp(command, "heritage") == 0) {
|
||||
if (DrakkinHeritage == 0 && codeMove == 'p') {
|
||||
DrakkinHeritage = 6;
|
||||
}
|
||||
else if (DrakkinHeritage >= 6 && codeMove != 'p') {
|
||||
DrakkinHeritage = 0;
|
||||
}
|
||||
else {
|
||||
DrakkinHeritage += Adjustment;
|
||||
}
|
||||
ChangeType = "DrakkinHeritage";
|
||||
ChangeSetting = DrakkinHeritage;
|
||||
}
|
||||
else if (strcasecmp(command, "tattoo") == 0) {
|
||||
if (DrakkinTattoo == 0 && codeMove == 'p') {
|
||||
DrakkinTattoo = 8;
|
||||
}
|
||||
else if (DrakkinTattoo >= 8 && codeMove != 'p') {
|
||||
DrakkinTattoo = 0;
|
||||
}
|
||||
else {
|
||||
DrakkinTattoo += Adjustment;
|
||||
}
|
||||
ChangeType = "DrakkinTattoo";
|
||||
ChangeSetting = DrakkinTattoo;
|
||||
}
|
||||
else if (strcasecmp(command, "detail") == 0) {
|
||||
if (DrakkinDetails == 0 && codeMove == 'p') {
|
||||
DrakkinDetails = 7;
|
||||
}
|
||||
else if (DrakkinDetails >= 7 && codeMove != 'p') {
|
||||
DrakkinDetails = 0;
|
||||
}
|
||||
else {
|
||||
DrakkinDetails += Adjustment;
|
||||
}
|
||||
ChangeType = "DrakkinDetails";
|
||||
ChangeSetting = DrakkinDetails;
|
||||
}
|
||||
|
||||
// Hack to fix some races that base features from face
|
||||
switch (Race) {
|
||||
case 2: // Barbarian
|
||||
if (LuclinFace > 10) {
|
||||
LuclinFace -= ((DrakkinTattoo - 1) * 10);
|
||||
}
|
||||
LuclinFace += (DrakkinTattoo * 10);
|
||||
break;
|
||||
case 3: // Erudite
|
||||
if (LuclinFace > 10) {
|
||||
LuclinFace -= ((HairStyle - 1) * 10);
|
||||
}
|
||||
LuclinFace += (HairStyle * 10);
|
||||
break;
|
||||
case 5: // HighElf
|
||||
case 6: // DarkElf
|
||||
case 7: // HalfElf
|
||||
if (LuclinFace > 10) {
|
||||
LuclinFace -= ((Beard - 1) * 10);
|
||||
}
|
||||
LuclinFace += (Beard * 10);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (ChangeType == nullptr) {
|
||||
c->Message(Chat::White, Usage);
|
||||
}
|
||||
else {
|
||||
target->SendIllusionPacket(
|
||||
Race, Gender, Texture, HelmTexture, HairColor, BeardColor,
|
||||
EyeColor1, EyeColor2, HairStyle, LuclinFace, Beard, 0xFF,
|
||||
DrakkinHeritage, DrakkinTattoo, DrakkinDetails
|
||||
);
|
||||
|
||||
c->Message(Chat::White, "%s=%i", ChangeType, ChangeSetting);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
53
zone/gm_commands/flag.cpp
Executable file
53
zone/gm_commands/flag.cpp
Executable file
@ -0,0 +1,53 @@
|
||||
#include "../client.h"
|
||||
#include "../worldserver.h"
|
||||
|
||||
extern WorldServer worldserver;
|
||||
|
||||
void command_flag(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (sep->arg[2][0] == 0) {
|
||||
if (!c->GetTarget() || (c->GetTarget() && c->GetTarget() == c)) {
|
||||
c->UpdateAdmin();
|
||||
c->Message(Chat::White, "Refreshed your admin flag from DB.");
|
||||
}
|
||||
else if (c->GetTarget() && c->GetTarget() != c && c->GetTarget()->IsClient()) {
|
||||
c->GetTarget()->CastToClient()->UpdateAdmin();
|
||||
c->Message(Chat::White, "%s's admin flag has been refreshed.", c->GetTarget()->GetName());
|
||||
c->GetTarget()->Message(Chat::White, "%s refreshed your admin flag.", c->GetName());
|
||||
}
|
||||
}
|
||||
else if (!sep->IsNumber(1) || atoi(sep->arg[1]) < -2 || atoi(sep->arg[1]) > 255 || strlen(sep->arg[2]) == 0) {
|
||||
c->Message(Chat::White, "Usage: #flag [status] [acctname]");
|
||||
}
|
||||
|
||||
else if (c->Admin() < commandChangeFlags) {
|
||||
//this check makes banning players by less than this level
|
||||
//impossible, but i'll leave it in anyways
|
||||
c->Message(Chat::White, "You may only refresh your own flag, doing so now.");
|
||||
c->UpdateAdmin();
|
||||
}
|
||||
else {
|
||||
if (atoi(sep->arg[1]) > c->Admin()) {
|
||||
c->Message(Chat::White, "You cannot set people's status to higher than your own");
|
||||
}
|
||||
else if (atoi(sep->arg[1]) < 0 && c->Admin() < commandBanPlayers) {
|
||||
c->Message(Chat::White, "You have too low of status to suspend/ban");
|
||||
}
|
||||
else if (!database.SetAccountStatus(sep->argplus[2], atoi(sep->arg[1]))) {
|
||||
c->Message(Chat::White, "Unable to set GM Flag.");
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Set GM Flag on account.");
|
||||
|
||||
std::string user;
|
||||
std::string loginserver;
|
||||
ParseAccountString(sep->argplus[2], user, loginserver);
|
||||
|
||||
ServerPacket pack(ServerOP_FlagUpdate, 6);
|
||||
*((uint32 *) pack.pBuffer) = database.GetAccountIDByName(user.c_str(), loginserver.c_str());
|
||||
*((int16 *) &pack.pBuffer[4]) = atoi(sep->arg[1]);
|
||||
worldserver.SendPacket(&pack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
157
zone/gm_commands/flagedit.cpp
Executable file
157
zone/gm_commands/flagedit.cpp
Executable file
@ -0,0 +1,157 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_flagedit(Client *c, const Seperator *sep)
|
||||
{
|
||||
//super-command for editing zone flags
|
||||
if (sep->arg[1][0] == '\0' || !strcasecmp(sep->arg[1], "help")) {
|
||||
c->Message(Chat::White, "Syntax: #flagedit [lockzone|unlockzone|listzones|give|take].");
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"...lockzone [zone id/short] [flag name] - Set the specified flag name on the zone, locking the zone"
|
||||
);
|
||||
c->Message(Chat::White, "...unlockzone [zone id/short] - Removes the flag requirement from the specified zone");
|
||||
c->Message(Chat::White, "...listzones - List all zones which require a flag, and their flag's name");
|
||||
c->Message(Chat::White, "...give [zone id/short] - Give your target the zone flag for the specified zone.");
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"...take [zone id/short] - Take the zone flag for the specified zone away from your target"
|
||||
);
|
||||
c->Message(Chat::White, "...Note: use #flags to view flags on a person");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcasecmp(sep->arg[1], "lockzone")) {
|
||||
uint32 zoneid = 0;
|
||||
if (sep->arg[2][0] != '\0') {
|
||||
zoneid = atoi(sep->arg[2]);
|
||||
if (zoneid < 1) {
|
||||
zoneid = ZoneID(sep->arg[2]);
|
||||
}
|
||||
}
|
||||
if (zoneid < 1) {
|
||||
c->Message(Chat::Red, "zone required. see help.");
|
||||
return;
|
||||
}
|
||||
|
||||
char flag_name[128];
|
||||
if (sep->argplus[3][0] == '\0') {
|
||||
c->Message(Chat::Red, "flag name required. see help.");
|
||||
return;
|
||||
}
|
||||
database.DoEscapeString(flag_name, sep->argplus[3], 64);
|
||||
flag_name[127] = '\0';
|
||||
|
||||
std::string query = StringFormat(
|
||||
"UPDATE zone SET flag_needed = '%s' "
|
||||
"WHERE zoneidnumber = %d AND version = %d",
|
||||
flag_name, zoneid, zone->GetInstanceVersion());
|
||||
auto results = content_db.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
c->Message(Chat::Red, "Error updating zone: %s", results.ErrorMessage().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
c->Message(Chat::Yellow, "Success! Zone %s now requires a flag, named %s", ZoneName(zoneid), flag_name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcasecmp(sep->arg[1], "unlockzone")) {
|
||||
uint32 zoneid = 0;
|
||||
if (sep->arg[2][0] != '\0') {
|
||||
zoneid = atoi(sep->arg[2]);
|
||||
if (zoneid < 1) {
|
||||
zoneid = ZoneID(sep->arg[2]);
|
||||
}
|
||||
}
|
||||
|
||||
if (zoneid < 1) {
|
||||
c->Message(Chat::Red, "zone required. see help.");
|
||||
return;
|
||||
}
|
||||
|
||||
std::string query = StringFormat(
|
||||
"UPDATE zone SET flag_needed = '' "
|
||||
"WHERE zoneidnumber = %d AND version = %d",
|
||||
zoneid, zone->GetInstanceVersion());
|
||||
auto results = content_db.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
c->Message(Chat::Yellow, "Error updating zone: %s", results.ErrorMessage().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
c->Message(Chat::Yellow, "Success! Zone %s no longer requires a flag.", ZoneName(zoneid));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcasecmp(sep->arg[1], "listzones")) {
|
||||
std::string query = "SELECT zoneidnumber, short_name, long_name, version, flag_needed "
|
||||
"FROM zone WHERE flag_needed != ''";
|
||||
auto results = content_db.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return;
|
||||
}
|
||||
|
||||
c->Message(Chat::White, "Zones which require flags:");
|
||||
for (auto row = results.begin(); row != results.end(); ++row)
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"Zone %s (%s,%s) version %s requires key %s",
|
||||
row[2],
|
||||
row[0],
|
||||
row[1],
|
||||
row[3],
|
||||
row[4]
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcasecmp(sep->arg[1], "give")) {
|
||||
uint32 zoneid = 0;
|
||||
if (sep->arg[2][0] != '\0') {
|
||||
zoneid = atoi(sep->arg[2]);
|
||||
if (zoneid < 1) {
|
||||
zoneid = ZoneID(sep->arg[2]);
|
||||
}
|
||||
}
|
||||
if (zoneid < 1) {
|
||||
c->Message(Chat::Red, "zone required. see help.");
|
||||
return;
|
||||
}
|
||||
|
||||
Mob *t = c->GetTarget();
|
||||
if (t == nullptr || !t->IsClient()) {
|
||||
c->Message(Chat::Red, "client target required");
|
||||
return;
|
||||
}
|
||||
|
||||
t->CastToClient()->SetZoneFlag(zoneid);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcasecmp(sep->arg[1], "give")) {
|
||||
uint32 zoneid = 0;
|
||||
if (sep->arg[2][0] != '\0') {
|
||||
zoneid = atoi(sep->arg[2]);
|
||||
if (zoneid < 1) {
|
||||
zoneid = ZoneID(sep->arg[2]);
|
||||
}
|
||||
}
|
||||
if (zoneid < 1) {
|
||||
c->Message(Chat::Red, "zone required. see help.");
|
||||
return;
|
||||
}
|
||||
|
||||
Mob *t = c->GetTarget();
|
||||
if (t == nullptr || !t->IsClient()) {
|
||||
c->Message(Chat::Red, "client target required");
|
||||
return;
|
||||
}
|
||||
|
||||
t->CastToClient()->ClearZoneFlag(zoneid);
|
||||
return;
|
||||
}
|
||||
|
||||
c->Message(Chat::Yellow, "Invalid action specified. use '#flagedit help' for help");
|
||||
}
|
||||
|
||||
16
zone/gm_commands/flags.cpp
Executable file
16
zone/gm_commands/flags.cpp
Executable file
@ -0,0 +1,16 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_flags(Client *c, const Seperator *sep)
|
||||
{
|
||||
Client *t = c;
|
||||
|
||||
if (c->Admin() >= minStatusToSeeOthersZoneFlags) {
|
||||
Mob *tgt = c->GetTarget();
|
||||
if (tgt != nullptr && tgt->IsClient()) {
|
||||
t = tgt->CastToClient();
|
||||
}
|
||||
}
|
||||
|
||||
t->SendZoneFlagInfo(c);
|
||||
}
|
||||
|
||||
40
zone/gm_commands/flymode.cpp
Executable file
40
zone/gm_commands/flymode.cpp
Executable file
@ -0,0 +1,40 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_flymode(Client *c, const Seperator *sep)
|
||||
{
|
||||
Mob *t = c;
|
||||
|
||||
if (strlen(sep->arg[1]) == 1 && sep->IsNumber(1) && atoi(sep->arg[1]) >= 0 && atoi(sep->arg[1]) <= 5) {
|
||||
if (c->GetTarget()) {
|
||||
t = c->GetTarget();
|
||||
}
|
||||
|
||||
int fm = atoi(sep->arg[1]);
|
||||
|
||||
t->SetFlyMode(static_cast<GravityBehavior>(fm));
|
||||
t->SendAppearancePacket(AT_Levitate, fm);
|
||||
if (sep->arg[1][0] == '0') {
|
||||
c->Message(Chat::White, "Setting %s to Grounded", t->GetName());
|
||||
}
|
||||
else if (sep->arg[1][0] == '1') {
|
||||
c->Message(Chat::White, "Setting %s to Flying", t->GetName());
|
||||
}
|
||||
else if (sep->arg[1][0] == '2') {
|
||||
c->Message(Chat::White, "Setting %s to Levitating", t->GetName());
|
||||
}
|
||||
else if (sep->arg[1][0] == '3') {
|
||||
c->Message(Chat::White, "Setting %s to In Water", t->GetName());
|
||||
}
|
||||
else if (sep->arg[1][0] == '4') {
|
||||
c->Message(Chat::White, "Setting %s to Floating(Boat)", t->GetName());
|
||||
}
|
||||
else if (sep->arg[1][0] == '5') {
|
||||
c->Message(Chat::White, "Setting %s to Levitating While Running", t->GetName());
|
||||
}
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "#flymode [0/1/2/3/4/5]");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
42
zone/gm_commands/fov.cpp
Executable file
42
zone/gm_commands/fov.cpp
Executable file
@ -0,0 +1,42 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_fov(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (c->GetTarget()) {
|
||||
auto target = c->GetTarget();
|
||||
std::string behind_message = (
|
||||
c->BehindMob(
|
||||
target,
|
||||
c->GetX(),
|
||||
c->GetY()
|
||||
) ?
|
||||
"behind" :
|
||||
"not behind"
|
||||
);
|
||||
std::string gender_message = (
|
||||
target->GetGender() == MALE ?
|
||||
"he" :
|
||||
(
|
||||
target->GetGender() == FEMALE ?
|
||||
"she" :
|
||||
"it"
|
||||
)
|
||||
);
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"You are {} {} ({}), {} has a heading of {}.",
|
||||
behind_message,
|
||||
target->GetCleanName(),
|
||||
target->GetID(),
|
||||
gender_message,
|
||||
target->GetHeading()
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "You must have a target to use this command.");
|
||||
}
|
||||
}
|
||||
|
||||
12
zone/gm_commands/freeze.cpp
Executable file
12
zone/gm_commands/freeze.cpp
Executable file
@ -0,0 +1,12 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_freeze(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (c->GetTarget() != 0) {
|
||||
c->GetTarget()->SendAppearancePacket(AT_Anim, ANIM_FREEZE);
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "ERROR: Freeze requires a target.");
|
||||
}
|
||||
}
|
||||
|
||||
14
zone/gm_commands/gassign.cpp
Executable file
14
zone/gm_commands/gassign.cpp
Executable file
@ -0,0 +1,14 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_gassign(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (sep->IsNumber(1) && c->GetTarget() && c->GetTarget()->IsNPC() &&
|
||||
c->GetTarget()->CastToNPC()->GetSpawnPointID() > 0) {
|
||||
int spawn2id = c->GetTarget()->CastToNPC()->GetSpawnPointID();
|
||||
database.AssignGrid(c, atoi(sep->arg[1]), spawn2id);
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Usage: #gassign [num] - must have an npc target!");
|
||||
}
|
||||
}
|
||||
|
||||
181
zone/gm_commands/gearup.cpp
Executable file
181
zone/gm_commands/gearup.cpp
Executable file
@ -0,0 +1,181 @@
|
||||
#include "../client.h"
|
||||
#include "../../common/http/httplib.h"
|
||||
#include "../../common/content/world_content_service.h"
|
||||
|
||||
void command_gearup(Client *c, const Seperator *sep)
|
||||
{
|
||||
std::string tool_table_name = "tool_gearup_armor_sets";
|
||||
if (!database.DoesTableExist(tool_table_name)) {
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Table [{}] does not exist. Downloading from Github and installing...",
|
||||
tool_table_name
|
||||
).c_str()
|
||||
);
|
||||
|
||||
// http get request
|
||||
httplib::Client cli("https://raw.githubusercontent.com");
|
||||
cli.set_connection_timeout(0, 15000000); // 15 sec
|
||||
cli.set_read_timeout(15, 0); // 15 seconds
|
||||
cli.set_write_timeout(15, 0); // 15 seconds
|
||||
|
||||
int sourced_queries = 0;
|
||||
std::string url = "/EQEmu/Server/master/utils/sql/git/optional/2020_07_20_tool_gearup_armor_sets.sql";
|
||||
|
||||
if (auto res = cli.Get(url.c_str())) {
|
||||
if (res->status == 200) {
|
||||
for (auto &s: SplitString(res->body, ';')) {
|
||||
if (!trim(s).empty()) {
|
||||
auto results = database.QueryDatabase(s);
|
||||
if (!results.ErrorMessage().empty()) {
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Error sourcing SQL [{}]", results.ErrorMessage()
|
||||
).c_str()
|
||||
);
|
||||
return;
|
||||
}
|
||||
sourced_queries++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Error retrieving URL [{}]",
|
||||
url
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Table [{}] installed. Sourced [{}] queries",
|
||||
tool_table_name, sourced_queries
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
|
||||
std::string expansion_arg = sep->arg[1];
|
||||
std::string expansion_filter;
|
||||
if (expansion_arg.length() > 0) {
|
||||
expansion_filter = fmt::format("and `expansion` = {}", expansion_arg);
|
||||
}
|
||||
|
||||
auto results = database.QueryDatabase(
|
||||
fmt::format(
|
||||
SQL (
|
||||
select
|
||||
item_id,
|
||||
slot
|
||||
from
|
||||
{}
|
||||
where
|
||||
`class` = {}
|
||||
and `level` = {}
|
||||
{}
|
||||
order by score desc, expansion desc
|
||||
),
|
||||
tool_table_name,
|
||||
c->GetClass(),
|
||||
c->GetLevel(),
|
||||
expansion_filter
|
||||
)
|
||||
);
|
||||
|
||||
int items_equipped = 0;
|
||||
int items_already_have = 0;
|
||||
std::set<int> equipped;
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
int item_id = atoi(row[0]);
|
||||
int slot_id = atoi(row[1]);
|
||||
|
||||
if (equipped.find(slot_id) != equipped.end()) {
|
||||
if (slot_id == EQ::invslot::slotEar1) {
|
||||
slot_id = EQ::invslot::slotEar2;
|
||||
}
|
||||
if (slot_id == EQ::invslot::slotFinger1) {
|
||||
slot_id = EQ::invslot::slotFinger2;
|
||||
}
|
||||
if (slot_id == EQ::invslot::slotWrist1) {
|
||||
slot_id = EQ::invslot::slotWrist2;
|
||||
}
|
||||
}
|
||||
|
||||
if (equipped.find(slot_id) == equipped.end()) {
|
||||
const EQ::ItemData *item = database.GetItem(item_id);
|
||||
bool has_item = (c->GetInv().HasItem(item_id, 1, invWhereWorn) != INVALID_INDEX);
|
||||
bool can_wear_item = !c->CheckLoreConflict(item) && !has_item;
|
||||
if (!can_wear_item) {
|
||||
items_already_have++;
|
||||
}
|
||||
|
||||
if (c->CastToMob()->CanClassEquipItem(item_id) && can_wear_item) {
|
||||
equipped.insert(slot_id);
|
||||
c->SummonItem(
|
||||
item_id,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
slot_id
|
||||
);
|
||||
items_equipped++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Equipped items [{}] already had [{}] items equipped",
|
||||
items_equipped,
|
||||
items_already_have
|
||||
).c_str()
|
||||
);
|
||||
|
||||
if (expansion_arg.empty()) {
|
||||
results = database.QueryDatabase(
|
||||
fmt::format(
|
||||
SQL (
|
||||
select
|
||||
expansion
|
||||
from
|
||||
{}
|
||||
where
|
||||
class = {}
|
||||
and level = {}
|
||||
group by
|
||||
expansion;
|
||||
),
|
||||
tool_table_name,
|
||||
c->GetClass(),
|
||||
c->GetLevel()
|
||||
)
|
||||
);
|
||||
|
||||
c->Message(Chat::White, "Choose armor from a specific era");
|
||||
std::string message;
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
int expansion = atoi(row[0]);
|
||||
message += "[" + EQ::SayLinkEngine::GenerateQuestSaylink(
|
||||
fmt::format("#gearup {}", expansion),
|
||||
false,
|
||||
Expansion::ExpansionName[expansion]
|
||||
) + "] ";
|
||||
|
||||
if (message.length() > 2000) {
|
||||
c->Message(Chat::White, message.c_str());
|
||||
message = "";
|
||||
}
|
||||
}
|
||||
if (message.length() > 0) {
|
||||
c->Message(Chat::White, message.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
17
zone/gm_commands/gender.cpp
Executable file
17
zone/gm_commands/gender.cpp
Executable file
@ -0,0 +1,17 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_gender(Client *c, const Seperator *sep)
|
||||
{
|
||||
Mob *t = c->CastToMob();
|
||||
|
||||
if (sep->IsNumber(1) && atoi(sep->arg[1]) >= 0 && atoi(sep->arg[1]) <= 500) {
|
||||
if ((c->GetTarget()) && c->Admin() >= commandGenderOthers) {
|
||||
t = c->GetTarget();
|
||||
}
|
||||
t->SendIllusionPacket(t->GetRace(), atoi(sep->arg[1]));
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Usage: #gender [0/1/2]");
|
||||
}
|
||||
}
|
||||
|
||||
27
zone/gm_commands/getplayerburiedcorpsecount.cpp
Executable file
27
zone/gm_commands/getplayerburiedcorpsecount.cpp
Executable file
@ -0,0 +1,27 @@
|
||||
#include "../client.h"
|
||||
#include "../corpse.h"
|
||||
|
||||
void command_getplayerburiedcorpsecount(Client *c, const Seperator *sep)
|
||||
{
|
||||
Client *t = c;
|
||||
|
||||
if (c->GetTarget() && c->GetTarget()->IsClient() && c->GetGM()) {
|
||||
t = c->GetTarget()->CastToClient();
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "You must first select a target!");
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 CorpseCount = database.GetCharacterBuriedCorpseCount(t->CharacterID());
|
||||
|
||||
if (CorpseCount > 0) {
|
||||
c->Message(Chat::White, "Your target has a total of %u buried corpses.", CorpseCount);
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Your target doesn't have any buried corpses.");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
13
zone/gm_commands/getvariable.cpp
Executable file
13
zone/gm_commands/getvariable.cpp
Executable file
@ -0,0 +1,13 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_getvariable(Client *c, const Seperator *sep)
|
||||
{
|
||||
std::string tmp;
|
||||
if (database.GetVariable(sep->argplus[1], tmp)) {
|
||||
c->Message(Chat::White, "%s = %s", sep->argplus[1], tmp.c_str());
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "GetVariable(%s) returned false", sep->argplus[1]);
|
||||
}
|
||||
}
|
||||
|
||||
52
zone/gm_commands/ginfo.cpp
Executable file
52
zone/gm_commands/ginfo.cpp
Executable file
@ -0,0 +1,52 @@
|
||||
#include "../client.h"
|
||||
#include "../groups.h"
|
||||
|
||||
void command_ginfo(Client *c, const Seperator *sep)
|
||||
{
|
||||
Client *t;
|
||||
|
||||
if (c->GetTarget() && c->GetTarget()->IsClient()) {
|
||||
t = c->GetTarget()->CastToClient();
|
||||
}
|
||||
else {
|
||||
t = c;
|
||||
}
|
||||
|
||||
Group *g = t->GetGroup();
|
||||
if (!g) {
|
||||
c->Message(Chat::White, "This client is not in a group");
|
||||
return;
|
||||
}
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"Player: %s is in Group #%lu: with %i members",
|
||||
t->GetName(),
|
||||
(unsigned long) g->GetID(),
|
||||
g->GroupCount());
|
||||
|
||||
uint32 r;
|
||||
for (r = 0; r < MAX_GROUP_MEMBERS; r++) {
|
||||
if (g->members[r] == nullptr) {
|
||||
if (g->membername[r][0] == '\0') {
|
||||
continue;
|
||||
}
|
||||
c->Message(
|
||||
Chat::White, "...Zoned Member: %s, Roles: %s %s %s", g->membername[r],
|
||||
(g->MemberRoles[r] & RoleAssist) ? "Assist" : "",
|
||||
(g->MemberRoles[r] & RoleTank) ? "Tank" : "",
|
||||
(g->MemberRoles[r] & RolePuller) ? "Puller" : ""
|
||||
);
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::White, "...In-Zone Member: %s (0x%x) Roles: %s %s %s", g->membername[r], g->members[r],
|
||||
(g->MemberRoles[r] & RoleAssist) ? "Assist" : "",
|
||||
(g->MemberRoles[r] & RoleTank) ? "Tank" : "",
|
||||
(g->MemberRoles[r] & RolePuller) ? "Puller" : ""
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
111
zone/gm_commands/giveitem.cpp
Executable file
111
zone/gm_commands/giveitem.cpp
Executable file
@ -0,0 +1,111 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_giveitem(Client *c, const Seperator *sep)
|
||||
{
|
||||
uint32 item_id = 0;
|
||||
int16 charges = -1;
|
||||
uint32 augment_one = 0;
|
||||
uint32 augment_two = 0;
|
||||
uint32 augment_three = 0;
|
||||
uint32 augment_four = 0;
|
||||
uint32 augment_five = 0;
|
||||
uint32 augment_six = 0;
|
||||
int arguments = sep->argnum;
|
||||
std::string cmd_msg = sep->msg;
|
||||
size_t link_open = cmd_msg.find('\x12');
|
||||
size_t link_close = cmd_msg.find_last_of('\x12');
|
||||
if (c->GetTarget()) {
|
||||
if (!c->GetTarget()->IsClient()) {
|
||||
c->Message(Chat::Red, "You can only give items to players with this command.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (link_open != link_close && (cmd_msg.length() - link_open) > EQ::constants::SAY_LINK_BODY_SIZE) {
|
||||
EQ::SayLinkBody_Struct link_body;
|
||||
EQ::saylink::DegenerateLinkBody(
|
||||
link_body,
|
||||
cmd_msg.substr(link_open + 1, EQ::constants::SAY_LINK_BODY_SIZE));
|
||||
item_id = link_body.item_id;
|
||||
augment_one = link_body.augment_1;
|
||||
augment_two = link_body.augment_2;
|
||||
augment_three = link_body.augment_3;
|
||||
augment_four = link_body.augment_4;
|
||||
augment_five = link_body.augment_5;
|
||||
augment_six = link_body.augment_6;
|
||||
}
|
||||
else if (sep->IsNumber(1)) {
|
||||
item_id = atoi(sep->arg[1]);
|
||||
}
|
||||
else if (!sep->IsNumber(1)) {
|
||||
c->Message(
|
||||
Chat::Red,
|
||||
"Usage: #giveitem [item id | link] [charges] [augment_one_id] [augment_two_id] [augment_three_id] [augment_four_id] [augment_five_id] [augment_six_id] (Charges are optional.)"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
Client *client_target = c->GetTarget()->CastToClient();
|
||||
uint8 item_status = 0;
|
||||
uint8 current_status = c->Admin();
|
||||
const EQ::ItemData *item = database.GetItem(item_id);
|
||||
if (item) {
|
||||
item_status = item->MinStatus;
|
||||
}
|
||||
|
||||
if (item_status > current_status) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Insufficient status to summon this item, current status is {}, required status is {}.",
|
||||
current_status,
|
||||
item_status
|
||||
).c_str()
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (arguments >= 2 && sep->IsNumber(2)) {
|
||||
charges = atoi(sep->arg[2]);
|
||||
}
|
||||
|
||||
if (arguments >= 3 && sep->IsNumber(3)) {
|
||||
augment_one = atoi(sep->arg[3]);
|
||||
}
|
||||
|
||||
if (arguments >= 4 && sep->IsNumber(4)) {
|
||||
augment_two = atoi(sep->arg[4]);
|
||||
}
|
||||
|
||||
if (arguments >= 5 && sep->IsNumber(5)) {
|
||||
augment_three = atoi(sep->arg[5]);
|
||||
}
|
||||
|
||||
if (arguments >= 6 && sep->IsNumber(6)) {
|
||||
augment_four = atoi(sep->arg[6]);
|
||||
}
|
||||
|
||||
if (arguments >= 7 && sep->IsNumber(7)) {
|
||||
augment_five = atoi(sep->arg[7]);
|
||||
}
|
||||
|
||||
if (arguments == 8 && sep->IsNumber(8)) {
|
||||
augment_six = atoi(sep->arg[8]);
|
||||
}
|
||||
|
||||
client_target->SummonItem(
|
||||
item_id,
|
||||
charges,
|
||||
augment_one,
|
||||
augment_two,
|
||||
augment_three,
|
||||
augment_four,
|
||||
augment_five,
|
||||
augment_six
|
||||
);
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::Red, "You must target a client to give the item to.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
33
zone/gm_commands/givemoney.cpp
Executable file
33
zone/gm_commands/givemoney.cpp
Executable file
@ -0,0 +1,33 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_givemoney(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (!sep->IsNumber(1)) { //as long as the first one is a number, we'll just let atoi convert the rest to 0 or a number
|
||||
c->Message(Chat::Red, "Usage: #Usage: #givemoney [pp] [gp] [sp] [cp]");
|
||||
}
|
||||
else if (c->GetTarget() == nullptr) {
|
||||
c->Message(Chat::Red, "You must target a player to give money to.");
|
||||
}
|
||||
else if (!c->GetTarget()->IsClient()) {
|
||||
c->Message(Chat::Red, "You can only give money to players with this command.");
|
||||
}
|
||||
else {
|
||||
//TODO: update this to the client, otherwise the client doesn't show any weight change until you zone, move an item, etc
|
||||
c->GetTarget()->CastToClient()->AddMoneyToPP(
|
||||
atoi(sep->arg[4]),
|
||||
atoi(sep->arg[3]),
|
||||
atoi(sep->arg[2]),
|
||||
atoi(sep->arg[1]),
|
||||
true
|
||||
);
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"Added %i Platinum, %i Gold, %i Silver, and %i Copper to %s's inventory.",
|
||||
atoi(sep->arg[1]),
|
||||
atoi(sep->arg[2]),
|
||||
atoi(sep->arg[3]),
|
||||
atoi(sep->arg[4]),
|
||||
c->GetTarget()->GetName());
|
||||
}
|
||||
}
|
||||
|
||||
80
zone/gm_commands/globalview.cpp
Executable file
80
zone/gm_commands/globalview.cpp
Executable file
@ -0,0 +1,80 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_globalview(Client *c, const Seperator *sep)
|
||||
{
|
||||
NPC *npcmob = nullptr;
|
||||
|
||||
if (c->GetTarget() && c->GetTarget()->IsNPC()) {
|
||||
npcmob = c->GetTarget()->CastToNPC();
|
||||
QGlobalCache *npc_c = nullptr;
|
||||
QGlobalCache *char_c = nullptr;
|
||||
QGlobalCache *zone_c = nullptr;
|
||||
|
||||
if (npcmob) {
|
||||
npc_c = npcmob->GetQGlobals();
|
||||
}
|
||||
|
||||
char_c = c->GetQGlobals();
|
||||
zone_c = zone->GetQGlobals();
|
||||
|
||||
std::list<QGlobal> globalMap;
|
||||
uint32 ntype = 0;
|
||||
|
||||
if (npcmob) {
|
||||
ntype = npcmob->GetNPCTypeID();
|
||||
}
|
||||
|
||||
if (npc_c) {
|
||||
QGlobalCache::Combine(globalMap, npc_c->GetBucket(), ntype, c->CharacterID(), zone->GetZoneID());
|
||||
}
|
||||
|
||||
if (char_c) {
|
||||
QGlobalCache::Combine(globalMap, char_c->GetBucket(), ntype, c->CharacterID(), zone->GetZoneID());
|
||||
}
|
||||
|
||||
if (zone_c) {
|
||||
QGlobalCache::Combine(globalMap, zone_c->GetBucket(), ntype, c->CharacterID(), zone->GetZoneID());
|
||||
}
|
||||
|
||||
auto iter = globalMap.begin();
|
||||
uint32 gcount = 0;
|
||||
|
||||
c->Message(Chat::White, "Name, Value");
|
||||
while (iter != globalMap.end()) {
|
||||
c->Message(Chat::White, "%s %s", (*iter).name.c_str(), (*iter).value.c_str());
|
||||
++iter;
|
||||
++gcount;
|
||||
}
|
||||
c->Message(Chat::White, "%u globals loaded.", gcount);
|
||||
}
|
||||
else {
|
||||
QGlobalCache *char_c = nullptr;
|
||||
QGlobalCache *zone_c = nullptr;
|
||||
|
||||
char_c = c->GetQGlobals();
|
||||
zone_c = zone->GetQGlobals();
|
||||
|
||||
std::list<QGlobal> globalMap;
|
||||
uint32 ntype = 0;
|
||||
|
||||
if (char_c) {
|
||||
QGlobalCache::Combine(globalMap, char_c->GetBucket(), ntype, c->CharacterID(), zone->GetZoneID());
|
||||
}
|
||||
|
||||
if (zone_c) {
|
||||
QGlobalCache::Combine(globalMap, zone_c->GetBucket(), ntype, c->CharacterID(), zone->GetZoneID());
|
||||
}
|
||||
|
||||
auto iter = globalMap.begin();
|
||||
uint32 gcount = 0;
|
||||
|
||||
c->Message(Chat::White, "Name, Value");
|
||||
while (iter != globalMap.end()) {
|
||||
c->Message(Chat::White, "%s %s", (*iter).name.c_str(), (*iter).value.c_str());
|
||||
++iter;
|
||||
++gcount;
|
||||
}
|
||||
c->Message(Chat::White, "%u globals loaded.", gcount);
|
||||
}
|
||||
}
|
||||
|
||||
27
zone/gm_commands/gm.cpp
Executable file
27
zone/gm_commands/gm.cpp
Executable file
@ -0,0 +1,27 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_gm(Client *c, const Seperator *sep)
|
||||
{
|
||||
bool state = atobool(sep->arg[1]);
|
||||
Client *t = c;
|
||||
|
||||
if (c->GetTarget() && c->GetTarget()->IsClient()) {
|
||||
t = c->GetTarget()->CastToClient();
|
||||
}
|
||||
|
||||
if (sep->arg[1][0] != 0) {
|
||||
t->SetGM(state);
|
||||
c->Message(Chat::White, "%s is %s a GM.", t->GetName(), state ? "now" : "no longer");
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Usage: #gm [on/off]");
|
||||
}
|
||||
}
|
||||
|
||||
// there's no need for this, as /summon already takes care of it
|
||||
// this command is here for reference but it is not added to the
|
||||
// list above
|
||||
|
||||
//To whoever wrote the above: And what about /kill, /zone, /zoneserver, etc?
|
||||
//There is a reason for the # commands: so that admins can specifically enable certain
|
||||
//commands for their users. Some might want users to #summon but not to /kill. Cant do that if they are a GM
|
||||
20
zone/gm_commands/gmspeed.cpp
Executable file
20
zone/gm_commands/gmspeed.cpp
Executable file
@ -0,0 +1,20 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_gmspeed(Client *c, const Seperator *sep)
|
||||
{
|
||||
bool state = atobool(sep->arg[1]);
|
||||
Client *t = c;
|
||||
|
||||
if (c->GetTarget() && c->GetTarget()->IsClient()) {
|
||||
t = c->GetTarget()->CastToClient();
|
||||
}
|
||||
|
||||
if (sep->arg[1][0] != 0) {
|
||||
database.SetGMSpeed(t->AccountID(), state ? 1 : 0);
|
||||
c->Message(Chat::White, "Turning GMSpeed %s for %s (zone to take effect)", state ? "On" : "Off", t->GetName());
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Usage: #gmspeed [on/off]");
|
||||
}
|
||||
}
|
||||
|
||||
88
zone/gm_commands/gmzone.cpp
Executable file
88
zone/gm_commands/gmzone.cpp
Executable file
@ -0,0 +1,88 @@
|
||||
#include "../client.h"
|
||||
#include "../data_bucket.h"
|
||||
|
||||
void command_gmzone(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (!sep->arg[1]) {
|
||||
c->Message(Chat::White, "Usage");
|
||||
c->Message(Chat::White, "-------");
|
||||
c->Message(Chat::White, "#gmzone [zone_short_name] [zone_version=0]");
|
||||
return;
|
||||
}
|
||||
|
||||
std::string zone_short_name_string = sep->arg[1];
|
||||
const char *zone_short_name = sep->arg[1];
|
||||
auto zone_version = static_cast<uint32>(sep->arg[2] ? atoi(sep->arg[2]) : 0);
|
||||
std::string identifier = "gmzone";
|
||||
uint32 zone_id = ZoneID(zone_short_name);
|
||||
uint32 duration = 100000000;
|
||||
uint16 instance_id = 0;
|
||||
|
||||
if (zone_id == 0) {
|
||||
c->Message(Chat::Red, "Invalid zone specified");
|
||||
return;
|
||||
}
|
||||
|
||||
if (sep->arg[3] && sep->arg[3][0]) {
|
||||
identifier = sep->arg[3];
|
||||
}
|
||||
|
||||
std::string bucket_key = StringFormat(
|
||||
"%s-%s-%u-instance",
|
||||
zone_short_name,
|
||||
identifier.c_str(),
|
||||
zone_version
|
||||
);
|
||||
std::string existing_zone_instance = DataBucket::GetData(bucket_key);
|
||||
|
||||
if (existing_zone_instance.length() > 0) {
|
||||
instance_id = std::stoi(existing_zone_instance);
|
||||
|
||||
c->Message(Chat::Yellow, "Found already created instance (%s) (%u)", zone_short_name, instance_id);
|
||||
}
|
||||
|
||||
if (instance_id == 0) {
|
||||
if (!database.GetUnusedInstanceID(instance_id)) {
|
||||
c->Message(Chat::Red, "Server was unable to find a free instance id.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!database.CreateInstance(instance_id, zone_id, zone_version, duration)) {
|
||||
c->Message(Chat::Red, "Server was unable to create a new instance.");
|
||||
return;
|
||||
}
|
||||
|
||||
c->Message(
|
||||
Chat::Yellow,
|
||||
"New private GM instance %s was created with id %lu.",
|
||||
zone_short_name,
|
||||
(unsigned long) instance_id
|
||||
);
|
||||
DataBucket::SetData(bucket_key, std::to_string(instance_id));
|
||||
}
|
||||
|
||||
if (instance_id > 0) {
|
||||
float target_x = -1, target_y = -1, target_z = -1, target_heading = -1;
|
||||
int16 min_status = AccountStatus::Player;
|
||||
uint8 min_level = 0;
|
||||
|
||||
if (!content_db.GetSafePoints(
|
||||
zone_short_name,
|
||||
zone_version,
|
||||
&target_x,
|
||||
&target_y,
|
||||
&target_z,
|
||||
&target_heading,
|
||||
&min_status,
|
||||
&min_level
|
||||
)) {
|
||||
c->Message(Chat::Red, "Failed to find safe coordinates for specified zone");
|
||||
}
|
||||
|
||||
c->Message(Chat::Yellow, "Zoning to private GM instance (%s) (%u)", zone_short_name, instance_id);
|
||||
|
||||
c->AssignToInstance(instance_id);
|
||||
c->MovePC(zone_id, instance_id, target_x, target_y, target_z, target_heading, 1);
|
||||
}
|
||||
}
|
||||
|
||||
63
zone/gm_commands/goto.cpp
Executable file
63
zone/gm_commands/goto.cpp
Executable file
@ -0,0 +1,63 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_goto(Client *c, const Seperator *sep)
|
||||
{
|
||||
std::string arg1 = sep->arg[1];
|
||||
|
||||
bool goto_via_target_no_args = sep->arg[1][0] == '\0' && c->GetTarget();
|
||||
bool goto_via_player_name = !sep->IsNumber(1) && !arg1.empty();
|
||||
bool goto_via_x_y_z = sep->IsNumber(1) && sep->IsNumber(2) && sep->IsNumber(3);
|
||||
|
||||
if (goto_via_target_no_args) {
|
||||
c->MovePC(
|
||||
zone->GetZoneID(),
|
||||
zone->GetInstanceID(),
|
||||
c->GetTarget()->GetX(),
|
||||
c->GetTarget()->GetY(),
|
||||
c->GetTarget()->GetZ(),
|
||||
c->GetTarget()->GetHeading()
|
||||
);
|
||||
}
|
||||
else if (goto_via_player_name) {
|
||||
|
||||
/**
|
||||
* Find them in zone first
|
||||
*/
|
||||
const char *player_name = sep->arg[1];
|
||||
std::string player_name_string = sep->arg[1];
|
||||
Client *client = entity_list.GetClientByName(player_name);
|
||||
if (client) {
|
||||
c->MovePC(
|
||||
zone->GetZoneID(),
|
||||
zone->GetInstanceID(),
|
||||
client->GetX(),
|
||||
client->GetY(),
|
||||
client->GetZ(),
|
||||
client->GetHeading()
|
||||
);
|
||||
|
||||
c->Message(Chat::Yellow, "Goto player '%s' same zone", player_name_string.c_str());
|
||||
}
|
||||
else if (c->GotoPlayer(player_name_string)) {
|
||||
c->Message(Chat::Yellow, "Goto player '%s' different zone", player_name_string.c_str());
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::Yellow, "Player '%s' not found", player_name_string.c_str());
|
||||
}
|
||||
}
|
||||
else if (goto_via_x_y_z) {
|
||||
c->MovePC(
|
||||
zone->GetZoneID(),
|
||||
zone->GetInstanceID(),
|
||||
atof(sep->arg[1]),
|
||||
atof(sep->arg[2]),
|
||||
atof(sep->arg[3]),
|
||||
(sep->arg[4] ? atof(sep->arg[4]) : c->GetHeading())
|
||||
);
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Usage: #goto [x y z] [h]");
|
||||
c->Message(Chat::White, "Usage: #goto [player_name]");
|
||||
}
|
||||
}
|
||||
|
||||
143
zone/gm_commands/grid.cpp
Executable file
143
zone/gm_commands/grid.cpp
Executable file
@ -0,0 +1,143 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_grid(Client *c, const Seperator *sep)
|
||||
{
|
||||
auto command_type = sep->arg[1];
|
||||
auto zone_id = zone->GetZoneID();
|
||||
if (strcasecmp("max", command_type) == 0) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Highest grid ID in this zone is {}.",
|
||||
content_db.GetHighestGrid(zone_id)
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else if (strcasecmp("add", command_type) == 0) {
|
||||
auto grid_id = atoi(sep->arg[2]);
|
||||
auto wander_type = atoi(sep->arg[3]);
|
||||
auto pause_type = atoi(sep->arg[4]);
|
||||
if (!content_db.GridExistsInZone(zone_id, grid_id)) {
|
||||
content_db.ModifyGrid(c, false, grid_id, wander_type, pause_type, zone_id);
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Grid {} added to zone ID {} with wander type {} and pause type {}.",
|
||||
grid_id,
|
||||
zone_id,
|
||||
wander_type,
|
||||
pause_type
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Grid {} already exists in zone ID {}.",
|
||||
grid_id,
|
||||
zone_id
|
||||
).c_str()
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (strcasecmp("show", command_type) == 0) {
|
||||
Mob *target = c->GetTarget();
|
||||
if (!target || !target->IsNPC()) {
|
||||
c->Message(Chat::White, "You need to target an NPC!");
|
||||
return;
|
||||
}
|
||||
|
||||
auto grid_id = target->CastToNPC()->GetGrid();
|
||||
std::string query = fmt::format(
|
||||
"SELECT `x`, `y`, `z`, `heading`, `number` "
|
||||
"FROM `grid_entries` "
|
||||
"WHERE `zoneid` = {} AND `gridid` = {} "
|
||||
"ORDER BY `number`",
|
||||
zone_id,
|
||||
grid_id
|
||||
);
|
||||
|
||||
auto results = content_db.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
c->Message(Chat::White, "Error querying database.");
|
||||
c->Message(Chat::White, query.c_str());
|
||||
}
|
||||
|
||||
if (results.RowCount() == 0) {
|
||||
c->Message(Chat::White, "No grid found.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Depop any node npc's already spawned
|
||||
entity_list.DespawnGridNodes(grid_id);
|
||||
|
||||
// Spawn grid nodes
|
||||
std::map<std::vector<float>, int32> zoffset;
|
||||
for (auto row : results) {
|
||||
glm::vec4 node_position = glm::vec4(atof(row[0]), atof(row[1]), atof(row[2]), atof(row[3]));
|
||||
std::vector<float> node_loc{
|
||||
node_position.x,
|
||||
node_position.y,
|
||||
node_position.z
|
||||
};
|
||||
|
||||
// If we already have a node at this location, set the z offset
|
||||
// higher from the existing one so we can see it. Adjust so if
|
||||
// there is another at the same spot we adjust again.
|
||||
auto search = zoffset.find(node_loc);
|
||||
if (search != zoffset.end()) {
|
||||
search->second = search->second + 3;
|
||||
}
|
||||
else {
|
||||
zoffset[node_loc] = 0.0;
|
||||
}
|
||||
|
||||
node_position.z += zoffset[node_loc];
|
||||
NPC::SpawnGridNodeNPC(node_position, grid_id, atoi(row[4]), zoffset[node_loc]);
|
||||
}
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Spawning nodes for grid {}.",
|
||||
grid_id
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else if (strcasecmp("hide", command_type) == 0) {
|
||||
Mob *target = c->GetTarget();
|
||||
if (!target || !target->IsNPC()) {
|
||||
c->Message(Chat::White, "You need to target an NPC!");
|
||||
return;
|
||||
}
|
||||
|
||||
auto grid_id = target->CastToNPC()->GetGrid();
|
||||
entity_list.DespawnGridNodes(grid_id);
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Depawning nodes for grid {}.",
|
||||
grid_id
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else if (strcasecmp("delete", command_type) == 0) {
|
||||
auto grid_id = atoi(sep->arg[2]);
|
||||
content_db.ModifyGrid(c, true, grid_id, 0, 0, zone_id);
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Grid {} deleted from zone ID {}.",
|
||||
grid_id,
|
||||
zone_id
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Usage: #grid [add|delete] [grid_id] [wander_type] [pause_type]");
|
||||
c->Message(Chat::White, "Usage: #grid [max] - displays the highest grid ID used in this zone (for add)");
|
||||
c->Message(Chat::White, "Usage: #grid [show] - displays wp nodes as boxes");
|
||||
}
|
||||
}
|
||||
|
||||
444
zone/gm_commands/guild.cpp
Executable file
444
zone/gm_commands/guild.cpp
Executable file
@ -0,0 +1,444 @@
|
||||
#include "../client.h"
|
||||
#include "../worldserver.h"
|
||||
|
||||
extern WorldServer worldserver;
|
||||
|
||||
#include "../guild_mgr.h"
|
||||
#include "../doors.h"
|
||||
|
||||
void command_guild(Client *c, const Seperator *sep)
|
||||
{
|
||||
int admin = c->Admin();
|
||||
Mob *target = c->GetTarget();
|
||||
|
||||
if (strcasecmp(sep->arg[1], "help") == 0) {
|
||||
c->Message(Chat::White, "GM Guild commands:");
|
||||
c->Message(Chat::White, " #guild list - lists all guilds on the server");
|
||||
c->Message(Chat::White, " #guild create {guildleader charname or CharID} guildname");
|
||||
c->Message(Chat::White, " #guild delete guildID");
|
||||
c->Message(Chat::White, " #guild rename guildID newname");
|
||||
c->Message(Chat::White, " #guild set charname guildID (0=no guild)");
|
||||
c->Message(Chat::White, " #guild setrank charname rank");
|
||||
c->Message(Chat::White, " #guild setleader guildID {guildleader charname or CharID}");
|
||||
}
|
||||
else if (strcasecmp(sep->arg[1], "status") == 0 || strcasecmp(sep->arg[1], "stat") == 0) {
|
||||
Client *client = 0;
|
||||
if (sep->arg[2][0] != 0) {
|
||||
client = entity_list.GetClientByName(sep->argplus[2]);
|
||||
}
|
||||
else if (target != 0 && target->IsClient()) {
|
||||
client = target->CastToClient();
|
||||
}
|
||||
if (client == 0) {
|
||||
c->Message(Chat::White, "You must target someone or specify a character name");
|
||||
}
|
||||
else if ((client->Admin() >= minStatusToEditOtherGuilds && admin < minStatusToEditOtherGuilds) &&
|
||||
client->GuildID() != c->GuildID()) { // no peeping for GMs, make sure tell message stays the same
|
||||
c->Message(Chat::White, "You must target someone or specify a character name.");
|
||||
}
|
||||
else {
|
||||
if (client->IsInAGuild()) {
|
||||
c->Message(Chat::White, "%s is not in a guild.", client->GetName());
|
||||
}
|
||||
else if (guild_mgr.IsGuildLeader(client->GuildID(), client->CharacterID())) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"%s is the leader of <%s> rank: %s",
|
||||
client->GetName(),
|
||||
guild_mgr.GetGuildName(client->GuildID()),
|
||||
guild_mgr.GetRankName(client->GuildID(), client->GuildRank()));
|
||||
}
|
||||
else {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"%s is a member of <%s> rank: %s",
|
||||
client->GetName(),
|
||||
guild_mgr.GetGuildName(client->GuildID()),
|
||||
guild_mgr.GetRankName(client->GuildID(), client->GuildRank()));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sep->arg[1], "info") == 0) {
|
||||
if (sep->arg[2][0] == 0 && c->IsInAGuild()) {
|
||||
if (admin >= minStatusToEditOtherGuilds) {
|
||||
c->Message(Chat::White, "Usage: #guildinfo guild_id");
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "You're not in a guild");
|
||||
}
|
||||
}
|
||||
else {
|
||||
uint32 tmp = GUILD_NONE;
|
||||
if (sep->arg[2][0] == 0) {
|
||||
tmp = c->GuildID();
|
||||
}
|
||||
else if (admin >= minStatusToEditOtherGuilds) {
|
||||
tmp = atoi(sep->arg[2]);
|
||||
}
|
||||
|
||||
if (tmp != GUILD_NONE) {
|
||||
guild_mgr.DescribeGuild(c, tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sep->arg[1], "set") == 0) {
|
||||
if (!sep->IsNumber(3)) {
|
||||
c->Message(Chat::White, "Usage: #guild set charname guildgbid (0 = clear guildtag)");
|
||||
}
|
||||
else {
|
||||
uint32 guild_id = atoi(sep->arg[3]);
|
||||
|
||||
if (guild_id == 0) {
|
||||
guild_id = GUILD_NONE;
|
||||
}
|
||||
else if (!guild_mgr.GuildExists(guild_id)) {
|
||||
c->Message(Chat::Red, "Guild %d does not exist.", guild_id);
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 charid = database.GetCharacterID(sep->arg[2]);
|
||||
if (charid == 0) {
|
||||
c->Message(Chat::Red, "Unable to find character '%s'", charid);
|
||||
return;
|
||||
}
|
||||
|
||||
//we could do the checking we need for guild_mgr.CheckGMStatus, but im lazy right now
|
||||
if (admin < minStatusToEditOtherGuilds) {
|
||||
c->Message(Chat::Red, "Access denied.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (guild_id == GUILD_NONE) {
|
||||
LogGuilds("[{}]: Removing [{}] ([{}]) from guild with GM command", c->GetName(), sep->arg[2], charid);
|
||||
}
|
||||
else {
|
||||
LogGuilds("[{}]: Putting [{}] ([{}]) into guild [{}] ([{}]) with GM command",
|
||||
c->GetName(),
|
||||
sep->arg[2],
|
||||
charid,
|
||||
guild_mgr.GetGuildName(guild_id),
|
||||
guild_id);
|
||||
}
|
||||
|
||||
if (!guild_mgr.SetGuild(charid, guild_id, GUILD_MEMBER)) {
|
||||
c->Message(Chat::Red, "Error putting '%s' into guild %d", sep->arg[2], guild_id);
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "%s has been put into guild %d", sep->arg[2], guild_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*else if (strcasecmp(sep->arg[1], "setdoor") == 0 && admin >= minStatusToEditOtherGuilds) {
|
||||
|
||||
if (!sep->IsNumber(2))
|
||||
c->Message(Chat::White, "Usage: #guild setdoor guildEQid (0 = delete guilddoor)");
|
||||
else {
|
||||
// guild doors
|
||||
if((!guilds[atoi(sep->arg[2])].databaseID) && (atoi(sep->arg[2])!=0) )
|
||||
{
|
||||
|
||||
c->Message(Chat::White, "These is no guild with this guildEQid");
|
||||
}
|
||||
else {
|
||||
c->SetIsSettingGuildDoor(true);
|
||||
c->Message(Chat::White, "Click on a door you want to become a guilddoor");
|
||||
c->SetSetGuildDoorID(atoi(sep->arg[2]));
|
||||
}
|
||||
}
|
||||
}*/
|
||||
else if (strcasecmp(sep->arg[1], "setrank") == 0) {
|
||||
int rank = atoi(sep->arg[3]);
|
||||
if (!sep->IsNumber(3)) {
|
||||
c->Message(Chat::White, "Usage: #guild setrank charname rank");
|
||||
}
|
||||
else if (rank < 0 || rank > GUILD_MAX_RANK) {
|
||||
c->Message(Chat::White, "Error: invalid rank #.");
|
||||
}
|
||||
else {
|
||||
uint32 charid = database.GetCharacterID(sep->arg[2]);
|
||||
if (charid == 0) {
|
||||
c->Message(Chat::Red, "Unable to find character '%s'", charid);
|
||||
return;
|
||||
}
|
||||
|
||||
//we could do the checking we need for guild_mgr.CheckGMStatus, but im lazy right now
|
||||
if (admin < minStatusToEditOtherGuilds) {
|
||||
c->Message(Chat::Red, "Access denied.");
|
||||
return;
|
||||
}
|
||||
|
||||
LogGuilds("[{}]: Setting [{}] ([{}])'s guild rank to [{}] with GM command",
|
||||
c->GetName(),
|
||||
sep->arg[2],
|
||||
charid,
|
||||
rank);
|
||||
|
||||
if (!guild_mgr.SetGuildRank(charid, rank)) {
|
||||
c->Message(Chat::Red, "Error while setting rank %d on '%s'.", rank, sep->arg[2]);
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "%s has been set to rank %d", sep->arg[2], rank);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sep->arg[1], "create") == 0) {
|
||||
if (sep->arg[3][0] == 0) {
|
||||
c->Message(Chat::White, "Usage: #guild create {guildleader charname or CharID} guild name");
|
||||
}
|
||||
else if (!worldserver.Connected()) {
|
||||
c->Message(Chat::White, "Error: World server dirconnected");
|
||||
}
|
||||
else {
|
||||
uint32 leader = 0;
|
||||
if (sep->IsNumber(2)) {
|
||||
leader = atoi(sep->arg[2]);
|
||||
}
|
||||
else if ((leader = database.GetCharacterID(sep->arg[2])) != 0) {
|
||||
//got it from the db..
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::Red, "Unable to find char '%s'", sep->arg[2]);
|
||||
return;
|
||||
}
|
||||
if (leader == 0) {
|
||||
c->Message(Chat::White, "Guild leader not found.");
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 tmp = guild_mgr.FindGuildByLeader(leader);
|
||||
if (tmp != GUILD_NONE) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"Error: %s already is the leader of DB# %i '%s'.",
|
||||
sep->arg[2],
|
||||
tmp,
|
||||
guild_mgr.GetGuildName(tmp));
|
||||
}
|
||||
else {
|
||||
|
||||
if (admin < minStatusToEditOtherGuilds) {
|
||||
c->Message(Chat::Red, "Access denied.");
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 id = guild_mgr.CreateGuild(sep->argplus[3], leader);
|
||||
|
||||
LogGuilds("[{}]: Creating guild [{}] with leader [{}] with GM command. It was given id [{}]",
|
||||
c->GetName(),
|
||||
sep->argplus[3],
|
||||
leader,
|
||||
(unsigned long) id);
|
||||
|
||||
if (id == GUILD_NONE) {
|
||||
c->Message(Chat::White, "Guild creation failed.");
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Guild created: Leader: %i, number %i: %s", leader, id, sep->argplus[3]);
|
||||
|
||||
if (!guild_mgr.SetGuild(leader, id, GUILD_LEADER)) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"Unable to set guild leader's guild in the database. Your going to have to run #guild set"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sep->arg[1], "delete") == 0) {
|
||||
if (!sep->IsNumber(2)) {
|
||||
c->Message(Chat::White, "Usage: #guild delete guildID");
|
||||
}
|
||||
else if (!worldserver.Connected()) {
|
||||
c->Message(Chat::White, "Error: World server dirconnected");
|
||||
}
|
||||
else {
|
||||
uint32 id = atoi(sep->arg[2]);
|
||||
|
||||
if (!guild_mgr.GuildExists(id)) {
|
||||
c->Message(Chat::White, "Guild %d does not exist!", id);
|
||||
return;
|
||||
}
|
||||
|
||||
if (admin < minStatusToEditOtherGuilds) {
|
||||
//this person is not allowed to just edit any guild, check this guild's min status.
|
||||
if (c->GuildID() != id) {
|
||||
c->Message(Chat::Red, "Access denied to edit other people's guilds");
|
||||
return;
|
||||
}
|
||||
else if (!guild_mgr.CheckGMStatus(id, admin)) {
|
||||
c->Message(Chat::Red, "Access denied to edit your guild with GM commands.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
LogGuilds("[{}]: Deleting guild [{}] ([{}]) with GM command", c->GetName(),
|
||||
guild_mgr.GetGuildName(id), id);
|
||||
|
||||
if (!guild_mgr.DeleteGuild(id)) {
|
||||
c->Message(Chat::White, "Guild delete failed.");
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Guild %d deleted.", id);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sep->arg[1], "rename") == 0) {
|
||||
if ((!sep->IsNumber(2)) || sep->arg[3][0] == 0) {
|
||||
c->Message(Chat::White, "Usage: #guild rename guildID newname");
|
||||
}
|
||||
else if (!worldserver.Connected()) {
|
||||
c->Message(Chat::White, "Error: World server dirconnected");
|
||||
}
|
||||
else {
|
||||
uint32 id = atoi(sep->arg[2]);
|
||||
|
||||
if (!guild_mgr.GuildExists(id)) {
|
||||
c->Message(Chat::White, "Guild %d does not exist!", id);
|
||||
return;
|
||||
}
|
||||
|
||||
if (admin < minStatusToEditOtherGuilds) {
|
||||
//this person is not allowed to just edit any guild, check this guild's min status.
|
||||
if (c->GuildID() != id) {
|
||||
c->Message(Chat::Red, "Access denied to edit other people's guilds");
|
||||
return;
|
||||
}
|
||||
else if (!guild_mgr.CheckGMStatus(id, admin)) {
|
||||
c->Message(Chat::Red, "Access denied to edit your guild with GM commands.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
LogGuilds("[{}]: Renaming guild [{}] ([{}]) to [{}] with GM command", c->GetName(),
|
||||
guild_mgr.GetGuildName(id), id, sep->argplus[3]);
|
||||
|
||||
if (!guild_mgr.RenameGuild(id, sep->argplus[3])) {
|
||||
c->Message(Chat::White, "Guild rename failed.");
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Guild %d renamed to %s", id, sep->argplus[3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sep->arg[1], "setleader") == 0) {
|
||||
if (sep->arg[3][0] == 0 || !sep->IsNumber(2)) {
|
||||
c->Message(Chat::White, "Usage: #guild setleader guild_id {guildleader charname or CharID}");
|
||||
}
|
||||
else if (!worldserver.Connected()) {
|
||||
c->Message(Chat::White, "Error: World server dirconnected");
|
||||
}
|
||||
else {
|
||||
uint32 leader = 0;
|
||||
if (sep->IsNumber(2)) {
|
||||
leader = atoi(sep->arg[2]);
|
||||
}
|
||||
else if ((leader = database.GetCharacterID(sep->arg[2])) != 0) {
|
||||
//got it from the db..
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::Red, "Unable to find char '%s'", sep->arg[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 tmpdb = guild_mgr.FindGuildByLeader(leader);
|
||||
if (leader == 0) {
|
||||
c->Message(Chat::White, "New leader not found.");
|
||||
}
|
||||
else if (tmpdb != 0) {
|
||||
c->Message(Chat::White, "Error: %s already is the leader of guild # %i", sep->arg[2], tmpdb);
|
||||
}
|
||||
else {
|
||||
uint32 id = atoi(sep->arg[2]);
|
||||
|
||||
if (!guild_mgr.GuildExists(id)) {
|
||||
c->Message(Chat::White, "Guild %d does not exist!", id);
|
||||
return;
|
||||
}
|
||||
|
||||
if (admin < minStatusToEditOtherGuilds) {
|
||||
//this person is not allowed to just edit any guild, check this guild's min status.
|
||||
if (c->GuildID() != id) {
|
||||
c->Message(Chat::Red, "Access denied to edit other people's guilds");
|
||||
return;
|
||||
}
|
||||
else if (!guild_mgr.CheckGMStatus(id, admin)) {
|
||||
c->Message(Chat::Red, "Access denied to edit your guild with GM commands.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
LogGuilds("[{}]: Setting leader of guild [{}] ([{}]) to [{}] with GM command", c->GetName(),
|
||||
guild_mgr.GetGuildName(id), id, leader);
|
||||
|
||||
if (!guild_mgr.SetGuildLeader(id, leader)) {
|
||||
c->Message(Chat::White, "Guild leader change failed.");
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Guild leader changed: guild # %d, Leader: %s", id, sep->argplus[3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(sep->arg[1], "list") == 0) {
|
||||
if (admin < minStatusToEditOtherGuilds) {
|
||||
c->Message(Chat::Red, "Access denied.");
|
||||
return;
|
||||
}
|
||||
guild_mgr.ListGuilds(c);
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Unknown guild command, try #guild help");
|
||||
}
|
||||
}
|
||||
/*
|
||||
bool helper_guild_edit(Client *c, uint32 dbid, uint32 eqid, uint8 rank, const char* what, const char* value) {
|
||||
struct GuildRankLevel_Struct grl;
|
||||
strcpy(grl.rankname, guild_mgr.GetRankName(eqid, rank));
|
||||
grl.demote = guilds[eqid].rank[rank].demote;
|
||||
grl.heargu = guilds[eqid].rank[rank].heargu;
|
||||
grl.invite = guilds[eqid].rank[rank].invite;
|
||||
grl.motd = guilds[eqid].rank[rank].motd;
|
||||
grl.promote = guilds[eqid].rank[rank].promote;
|
||||
grl.remove = guilds[eqid].rank[rank].remove;
|
||||
grl.speakgu = guilds[eqid].rank[rank].speakgu;
|
||||
grl.warpeace = guilds[eqid].rank[rank].warpeace;
|
||||
|
||||
if (strcasecmp(what, "title") == 0) {
|
||||
if (strlen(value) > 100)
|
||||
c->Message(Chat::White, "Error: Title has a maxium length of 100 characters.");
|
||||
else
|
||||
strcpy(grl.rankname, value);
|
||||
}
|
||||
else if (rank == 0)
|
||||
c->Message(Chat::White, "Error: Rank 0's permissions can not be changed.");
|
||||
else {
|
||||
if (!(strlen(value) == 1 && (value[0] == '0' || value[0] == '1')))
|
||||
|
||||
return false;
|
||||
if (strcasecmp(what, "demote") == 0)
|
||||
grl.demote = (value[0] == '1');
|
||||
else if (strcasecmp(what, "heargu") == 0)
|
||||
grl.heargu = (value[0] == '1');
|
||||
else if (strcasecmp(what, "invite") == 0)
|
||||
grl.invite = (value[0] == '1');
|
||||
else if (strcasecmp(what, "motd") == 0)
|
||||
grl.motd = (value[0] == '1');
|
||||
else if (strcasecmp(what, "promote") == 0)
|
||||
grl.promote = (value[0] == '1');
|
||||
else if (strcasecmp(what, "remove") == 0)
|
||||
|
||||
grl.remove = (value[0] == '1');
|
||||
else if (strcasecmp(what, "speakgu") == 0)
|
||||
grl.speakgu = (value[0] == '1');
|
||||
else if (strcasecmp(what, "warpeace") == 0)
|
||||
grl.warpeace = (value[0] == '1');
|
||||
else
|
||||
c->Message(Chat::White, "Error: Permission name not recognized.");
|
||||
}
|
||||
if (!database.EditGuild(dbid, rank, &grl))
|
||||
c->Message(Chat::White, "Error: database.EditGuild() failed");
|
||||
return true;
|
||||
}*/
|
||||
|
||||
8
zone/gm_commands/guildapprove.cpp
Executable file
8
zone/gm_commands/guildapprove.cpp
Executable file
@ -0,0 +1,8 @@
|
||||
#include "../client.h"
|
||||
#include "../guild_mgr.h"
|
||||
|
||||
void command_guildapprove(Client *c, const Seperator *sep)
|
||||
{
|
||||
guild_mgr.AddMemberApproval(atoi(sep->arg[1]), c);
|
||||
}
|
||||
|
||||
13
zone/gm_commands/guildcreate.cpp
Executable file
13
zone/gm_commands/guildcreate.cpp
Executable file
@ -0,0 +1,13 @@
|
||||
#include "../client.h"
|
||||
#include "../guild_mgr.h"
|
||||
|
||||
void command_guildcreate(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (strlen(sep->argplus[1]) > 4 && strlen(sep->argplus[1]) < 16) {
|
||||
guild_mgr.AddGuildApproval(sep->argplus[1], c);
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Guild name must be more than 4 characters and less than 16.");
|
||||
}
|
||||
}
|
||||
|
||||
14
zone/gm_commands/guildlist.cpp
Executable file
14
zone/gm_commands/guildlist.cpp
Executable file
@ -0,0 +1,14 @@
|
||||
#include "../client.h"
|
||||
#include "../guild_mgr.h"
|
||||
|
||||
void command_guildlist(Client *c, const Seperator *sep)
|
||||
{
|
||||
GuildApproval *tmp = guild_mgr.FindGuildByIDApproval(atoi(sep->arg[1]));
|
||||
if (tmp) {
|
||||
tmp->ApprovedMembers(c);
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Could not find reference id.");
|
||||
}
|
||||
}
|
||||
|
||||
37
zone/gm_commands/hair.cpp
Executable file
37
zone/gm_commands/hair.cpp
Executable file
@ -0,0 +1,37 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_hair(Client *c, const Seperator *sep)
|
||||
{
|
||||
Mob *target = c->GetTarget();
|
||||
if (!sep->IsNumber(1)) {
|
||||
c->Message(Chat::White, "Usage: #hair [number of hair style]");
|
||||
}
|
||||
else if (!target) {
|
||||
c->Message(Chat::White, "Error: this command requires a target");
|
||||
}
|
||||
else {
|
||||
uint16 Race = target->GetRace();
|
||||
uint8 Gender = target->GetGender();
|
||||
uint8 Texture = 0xFF;
|
||||
uint8 HelmTexture = 0xFF;
|
||||
uint8 HairColor = target->GetHairColor();
|
||||
uint8 BeardColor = target->GetBeardColor();
|
||||
uint8 EyeColor1 = target->GetEyeColor1();
|
||||
uint8 EyeColor2 = target->GetEyeColor2();
|
||||
uint8 HairStyle = atoi(sep->arg[1]);
|
||||
uint8 LuclinFace = target->GetLuclinFace();
|
||||
uint8 Beard = target->GetBeard();
|
||||
uint32 DrakkinHeritage = target->GetDrakkinHeritage();
|
||||
uint32 DrakkinTattoo = target->GetDrakkinTattoo();
|
||||
uint32 DrakkinDetails = target->GetDrakkinDetails();
|
||||
|
||||
target->SendIllusionPacket(
|
||||
Race, Gender, Texture, HelmTexture, HairColor, BeardColor,
|
||||
EyeColor1, EyeColor2, HairStyle, LuclinFace, Beard, 0xFF,
|
||||
DrakkinHeritage, DrakkinTattoo, DrakkinDetails
|
||||
);
|
||||
|
||||
c->Message(Chat::White, "Hair = %i", atoi(sep->arg[1]));
|
||||
}
|
||||
}
|
||||
|
||||
37
zone/gm_commands/haircolor.cpp
Executable file
37
zone/gm_commands/haircolor.cpp
Executable file
@ -0,0 +1,37 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_haircolor(Client *c, const Seperator *sep)
|
||||
{
|
||||
Mob *target = c->GetTarget();
|
||||
if (!sep->IsNumber(1)) {
|
||||
c->Message(Chat::White, "Usage: #haircolor [number of hair color]");
|
||||
}
|
||||
else if (!target) {
|
||||
c->Message(Chat::White, "Error: this command requires a target");
|
||||
}
|
||||
else {
|
||||
uint16 Race = target->GetRace();
|
||||
uint8 Gender = target->GetGender();
|
||||
uint8 Texture = 0xFF;
|
||||
uint8 HelmTexture = 0xFF;
|
||||
uint8 HairColor = atoi(sep->arg[1]);
|
||||
uint8 BeardColor = target->GetBeardColor();
|
||||
uint8 EyeColor1 = target->GetEyeColor1();
|
||||
uint8 EyeColor2 = target->GetEyeColor2();
|
||||
uint8 HairStyle = target->GetHairStyle();
|
||||
uint8 LuclinFace = target->GetLuclinFace();
|
||||
uint8 Beard = target->GetBeard();
|
||||
uint32 DrakkinHeritage = target->GetDrakkinHeritage();
|
||||
uint32 DrakkinTattoo = target->GetDrakkinTattoo();
|
||||
uint32 DrakkinDetails = target->GetDrakkinDetails();
|
||||
|
||||
target->SendIllusionPacket(
|
||||
Race, Gender, Texture, HelmTexture, HairColor, BeardColor,
|
||||
EyeColor1, EyeColor2, HairStyle, LuclinFace, Beard, 0xFF,
|
||||
DrakkinHeritage, DrakkinTattoo, DrakkinDetails
|
||||
);
|
||||
|
||||
c->Message(Chat::White, "Hair Color = %i", atoi(sep->arg[1]));
|
||||
}
|
||||
}
|
||||
|
||||
20
zone/gm_commands/haste.cpp
Executable file
20
zone/gm_commands/haste.cpp
Executable file
@ -0,0 +1,20 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_haste(Client *c, const Seperator *sep)
|
||||
{
|
||||
// #haste command to set client attack speed. Takes a percentage (100 = twice normal attack speed)
|
||||
if (sep->arg[1][0] != 0) {
|
||||
uint16 Haste = atoi(sep->arg[1]);
|
||||
if (Haste > 85) {
|
||||
Haste = 85;
|
||||
}
|
||||
c->SetExtraHaste(Haste);
|
||||
// SetAttackTimer must be called to make this take effect, so player needs to change
|
||||
// the primary weapon.
|
||||
c->Message(Chat::White, "Haste set to %d%% - Need to re-equip primary weapon before it takes effect", Haste);
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Usage: #haste [percentage]");
|
||||
}
|
||||
}
|
||||
|
||||
15
zone/gm_commands/hatelist.cpp
Executable file
15
zone/gm_commands/hatelist.cpp
Executable file
@ -0,0 +1,15 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_hatelist(Client *c, const Seperator *sep)
|
||||
{
|
||||
Mob *target = c->GetTarget();
|
||||
if (target == nullptr) {
|
||||
c->Message(Chat::White, "Error: you must have a target.");
|
||||
return;
|
||||
}
|
||||
|
||||
c->Message(Chat::White, "Display hate list for %s..", target->GetName());
|
||||
target->PrintHateListToClient(c);
|
||||
}
|
||||
|
||||
|
||||
21
zone/gm_commands/heal.cpp
Executable file
21
zone/gm_commands/heal.cpp
Executable file
@ -0,0 +1,21 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_heal(Client *c, const Seperator *sep)
|
||||
{
|
||||
auto target = c->GetTarget() ? c->GetTarget() : c;
|
||||
target->Heal();
|
||||
if (c != target) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Healed {} ({}) to full.",
|
||||
target->GetCleanName(),
|
||||
target->GetID()
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::White, "Healed yourself to full.");
|
||||
}
|
||||
}
|
||||
|
||||
37
zone/gm_commands/helm.cpp
Executable file
37
zone/gm_commands/helm.cpp
Executable file
@ -0,0 +1,37 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_helm(Client *c, const Seperator *sep)
|
||||
{
|
||||
Mob *target = c->GetTarget();
|
||||
if (!sep->IsNumber(1)) {
|
||||
c->Message(Chat::White, "Usage: #helm [number of helm texture]");
|
||||
}
|
||||
else if (!target) {
|
||||
c->Message(Chat::White, "Error: this command requires a target");
|
||||
}
|
||||
else {
|
||||
uint16 Race = target->GetRace();
|
||||
uint8 Gender = target->GetGender();
|
||||
uint8 Texture = 0xFF;
|
||||
uint8 HelmTexture = atoi(sep->arg[1]);
|
||||
uint8 HairColor = target->GetHairColor();
|
||||
uint8 BeardColor = target->GetBeardColor();
|
||||
uint8 EyeColor1 = target->GetEyeColor1();
|
||||
uint8 EyeColor2 = target->GetEyeColor2();
|
||||
uint8 HairStyle = target->GetHairStyle();
|
||||
uint8 LuclinFace = target->GetLuclinFace();
|
||||
uint8 Beard = target->GetBeard();
|
||||
uint32 DrakkinHeritage = target->GetDrakkinHeritage();
|
||||
uint32 DrakkinTattoo = target->GetDrakkinTattoo();
|
||||
uint32 DrakkinDetails = target->GetDrakkinDetails();
|
||||
|
||||
target->SendIllusionPacket(
|
||||
Race, Gender, Texture, HelmTexture, HairColor, BeardColor,
|
||||
EyeColor1, EyeColor2, HairStyle, LuclinFace, Beard, 0xFF,
|
||||
DrakkinHeritage, DrakkinTattoo, DrakkinDetails
|
||||
);
|
||||
|
||||
c->Message(Chat::White, "Helm = %i", atoi(sep->arg[1]));
|
||||
}
|
||||
}
|
||||
|
||||
37
zone/gm_commands/heritage.cpp
Executable file
37
zone/gm_commands/heritage.cpp
Executable file
@ -0,0 +1,37 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_heritage(Client *c, const Seperator *sep)
|
||||
{
|
||||
Mob *target = c->GetTarget();
|
||||
if (!sep->IsNumber(1)) {
|
||||
c->Message(Chat::White, "Usage: #heritage [number of Drakkin heritage]");
|
||||
}
|
||||
else if (!target) {
|
||||
c->Message(Chat::White, "Error: this command requires a target");
|
||||
}
|
||||
else {
|
||||
uint16 Race = target->GetRace();
|
||||
uint8 Gender = target->GetGender();
|
||||
uint8 Texture = 0xFF;
|
||||
uint8 HelmTexture = 0xFF;
|
||||
uint8 HairColor = target->GetHairColor();
|
||||
uint8 BeardColor = target->GetBeardColor();
|
||||
uint8 EyeColor1 = target->GetEyeColor1();
|
||||
uint8 EyeColor2 = target->GetEyeColor2();
|
||||
uint8 HairStyle = target->GetHairStyle();
|
||||
uint8 LuclinFace = target->GetLuclinFace();
|
||||
uint8 Beard = target->GetBeard();
|
||||
uint32 DrakkinHeritage = atoi(sep->arg[1]);
|
||||
uint32 DrakkinTattoo = target->GetDrakkinTattoo();
|
||||
uint32 DrakkinDetails = target->GetDrakkinDetails();
|
||||
|
||||
target->SendIllusionPacket(
|
||||
Race, Gender, Texture, HelmTexture, HairColor, BeardColor,
|
||||
EyeColor1, EyeColor2, HairStyle, LuclinFace, Beard, 0xFF,
|
||||
DrakkinHeritage, DrakkinTattoo, DrakkinDetails
|
||||
);
|
||||
|
||||
c->Message(Chat::White, "Heritage = %i", atoi(sep->arg[1]));
|
||||
}
|
||||
}
|
||||
|
||||
35
zone/gm_commands/heromodel.cpp
Executable file
35
zone/gm_commands/heromodel.cpp
Executable file
@ -0,0 +1,35 @@
|
||||
#include "../client.h"
|
||||
|
||||
void command_heromodel(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (sep->argnum < 1) {
|
||||
c->Message(Chat::White, "Usage: #heromodel [hero forge model] [ [slot] ] (example: #heromodel 63)");
|
||||
}
|
||||
else if (c->GetTarget() == nullptr) {
|
||||
c->Message(Chat::Red, "You must have a target to do a wear change for Hero's Forge Models.");
|
||||
}
|
||||
else {
|
||||
uint32 hero_forge_model = atoi(sep->arg[1]);
|
||||
|
||||
if (sep->argnum > 1) {
|
||||
uint8 wearslot = (uint8) atoi(sep->arg[2]);
|
||||
c->GetTarget()->SendTextureWC(wearslot, 0, hero_forge_model, 0, 0, 0);
|
||||
}
|
||||
else {
|
||||
if (hero_forge_model > 0) {
|
||||
// Conversion to simplify the command arguments
|
||||
// Hero's Forge model is actually model * 1000 + texture * 100 + wearslot
|
||||
// Hero's Forge Model slot 7 is actually for Robes, but it still needs to use wearslot 1 in the packet
|
||||
hero_forge_model *= 100;
|
||||
|
||||
for (uint8 wearslot = 0; wearslot < 7; wearslot++) {
|
||||
c->GetTarget()->SendTextureWC(wearslot, 0, (hero_forge_model + wearslot), 0, 0, 0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
c->Message(Chat::Red, "Hero's Forge Model must be greater than 0.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user