From b1b9a503256dfcf5a6ac6488032af070b0f21c3a Mon Sep 17 00:00:00 2001 From: Arkhan <49446701+DamianQualshy@users.noreply.github.com> Date: Fri, 28 Jun 2024 00:28:34 +0200 Subject: [PATCH] G2O 0.2.1 Init commit --- README.md | 6 + gamemode/client/chat.nut | 532 +++++++++++++++++++++ gamemode/client/gui.nut | 55 +++ gamemode/client/login.nut | 77 +++ gamemode/client/main.nut | 137 ++++++ gamemode/client/playerlist.nut | 415 ++++++++++++++++ gamemode/client/visual.nut | 246 ++++++++++ gamemode/import.xml | 29 ++ gamemode/server/acp.nut | 459 ++++++++++++++++++ gamemode/server/chat.nut | 135 ++++++ gamemode/server/login.nut | 124 +++++ gamemode/server/main.nut | 77 +++ gamemode/shared/anims.nut | 318 ++++++++++++ gamemode/shared/class.nut | 460 ++++++++++++++++++ gamemode/shared/packets.nut | 15 + gamemode/shared/text.nut | 119 +++++ lib/file.nut | 140 ++++++ lib/gui-framework/abstract/alignment.nut | 16 + lib/gui-framework/abstract/base.nut | 255 ++++++++++ lib/gui-framework/abstract/margin.nut | 45 ++ lib/gui-framework/abstract/offset.nut | 36 ++ lib/gui-framework/abstract/orientation.nut | 16 + lib/gui-framework/animation.nut | 210 ++++++++ lib/gui-framework/elements/bar.nut | 257 ++++++++++ lib/gui-framework/elements/button.nut | 122 +++++ lib/gui-framework/elements/checkbox.nut | 104 ++++ lib/gui-framework/elements/collection.nut | 99 ++++ lib/gui-framework/elements/draw.nut | 391 +++++++++++++++ lib/gui-framework/elements/gridlist.nut | 495 +++++++++++++++++++ lib/gui-framework/elements/input.nut | 263 ++++++++++ lib/gui-framework/elements/multidraw.nut | 235 +++++++++ lib/gui-framework/elements/radiobutton.nut | 62 +++ lib/gui-framework/elements/range.nut | 324 +++++++++++++ lib/gui-framework/elements/scrollbar.nut | 324 +++++++++++++ lib/gui-framework/elements/slider.nut | 121 +++++ lib/gui-framework/elements/tabpanel.nut | 406 ++++++++++++++++ lib/gui-framework/elements/texture.nut | 225 +++++++++ lib/gui-framework/elements/tooltip.nut | 129 +++++ lib/gui-framework/elements/window.nut | 160 +++++++ lib/gui-framework/examples/bar.nut | 31 ++ lib/gui-framework/examples/button.nut | 46 ++ lib/gui-framework/examples/checkbox.nut | 10 + lib/gui-framework/examples/draw.nut | 46 ++ lib/gui-framework/examples/gridlist.nut | 204 ++++++++ lib/gui-framework/examples/input.nut | 68 +++ lib/gui-framework/examples/multidraw.nut | 20 + lib/gui-framework/examples/radiobutton.nut | 26 + lib/gui-framework/examples/range.nut | 27 ++ lib/gui-framework/examples/scrollbar.nut | 9 + lib/gui-framework/examples/slider.nut | 13 + lib/gui-framework/examples/tabpanel.nut | 82 ++++ lib/gui-framework/examples/texture.nut | 53 ++ lib/gui-framework/examples/tooltip.nut | 62 +++ lib/gui-framework/examples/window.nut | 55 +++ lib/gui-framework/gui.xml | 33 ++ lib/gui-framework/main.nut | 44 ++ lib/gui-framework/multiple_inheritance.nut | 22 + lib/gui-framework/utility.nut | 109 +++++ lib/gui-framework/vector.nut | 11 + 59 files changed, 8610 insertions(+) create mode 100644 gamemode/client/chat.nut create mode 100644 gamemode/client/gui.nut create mode 100644 gamemode/client/login.nut create mode 100644 gamemode/client/main.nut create mode 100644 gamemode/client/playerlist.nut create mode 100644 gamemode/client/visual.nut create mode 100644 gamemode/import.xml create mode 100644 gamemode/server/acp.nut create mode 100644 gamemode/server/chat.nut create mode 100644 gamemode/server/login.nut create mode 100644 gamemode/server/main.nut create mode 100644 gamemode/shared/anims.nut create mode 100644 gamemode/shared/class.nut create mode 100644 gamemode/shared/packets.nut create mode 100644 gamemode/shared/text.nut create mode 100644 lib/file.nut create mode 100644 lib/gui-framework/abstract/alignment.nut create mode 100644 lib/gui-framework/abstract/base.nut create mode 100644 lib/gui-framework/abstract/margin.nut create mode 100644 lib/gui-framework/abstract/offset.nut create mode 100644 lib/gui-framework/abstract/orientation.nut create mode 100644 lib/gui-framework/animation.nut create mode 100644 lib/gui-framework/elements/bar.nut create mode 100644 lib/gui-framework/elements/button.nut create mode 100644 lib/gui-framework/elements/checkbox.nut create mode 100644 lib/gui-framework/elements/collection.nut create mode 100644 lib/gui-framework/elements/draw.nut create mode 100644 lib/gui-framework/elements/gridlist.nut create mode 100644 lib/gui-framework/elements/input.nut create mode 100644 lib/gui-framework/elements/multidraw.nut create mode 100644 lib/gui-framework/elements/radiobutton.nut create mode 100644 lib/gui-framework/elements/range.nut create mode 100644 lib/gui-framework/elements/scrollbar.nut create mode 100644 lib/gui-framework/elements/slider.nut create mode 100644 lib/gui-framework/elements/tabpanel.nut create mode 100644 lib/gui-framework/elements/texture.nut create mode 100644 lib/gui-framework/elements/tooltip.nut create mode 100644 lib/gui-framework/elements/window.nut create mode 100644 lib/gui-framework/examples/bar.nut create mode 100644 lib/gui-framework/examples/button.nut create mode 100644 lib/gui-framework/examples/checkbox.nut create mode 100644 lib/gui-framework/examples/draw.nut create mode 100644 lib/gui-framework/examples/gridlist.nut create mode 100644 lib/gui-framework/examples/input.nut create mode 100644 lib/gui-framework/examples/multidraw.nut create mode 100644 lib/gui-framework/examples/radiobutton.nut create mode 100644 lib/gui-framework/examples/range.nut create mode 100644 lib/gui-framework/examples/scrollbar.nut create mode 100644 lib/gui-framework/examples/slider.nut create mode 100644 lib/gui-framework/examples/tabpanel.nut create mode 100644 lib/gui-framework/examples/texture.nut create mode 100644 lib/gui-framework/examples/tooltip.nut create mode 100644 lib/gui-framework/examples/window.nut create mode 100644 lib/gui-framework/gui.xml create mode 100644 lib/gui-framework/main.nut create mode 100644 lib/gui-framework/multiple_inheritance.nut create mode 100644 lib/gui-framework/utility.nut create mode 100644 lib/gui-framework/vector.nut diff --git a/README.md b/README.md index ff450ff..34e5187 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,8 @@ # Gothic-Homecoming The Gothic Homecoming gamemode is based on how the 2011's Gothic Multiplayer worked, where you simply join a server and choose a class. + +# Features +- Class choice on join +- Animation window +- Player Visual change +- Global chat for everyone \ No newline at end of file diff --git a/gamemode/client/chat.nut b/gamemode/client/chat.nut new file mode 100644 index 0000000..065506c --- /dev/null +++ b/gamemode/client/chat.nut @@ -0,0 +1,532 @@ +///////////////////////////////////////// +/// Defines +///////////////////////////////////////// + +const CHAT_LINE_SIZE = 15; + +const CHAT_HISTORY_SIZE = 50; +const CHAT_PLAYER_HISTORY_SIZE = 5; + +const CHAT_VISIBLE = true; +const CHAT_ANIMATION_INTERVAL = 400; + +///////////////////////////////////////// +/// Line types +///////////////////////////////////////// + +class ChatLine +{ + constructor(r, g, b, text) + { + _line = Draw(0, 0, text); + _line.setColor(r, g, b); + } + + function show() + { + _line.visible = true; + } + + function hide() + { + _line.visible = false; + } + + function update(x, y) + { + _line.setPositionPx(x, y); + } + + function setAlpha(alpha) + { + _line.setAlpha(alpha) + } + + function offset() + { + return _line.heightPx; + } + + _line = null; + _animationBeginTime = -1; +} + +//--------------------------------------- + +class ChatPlayerLine extends ChatLine +{ + constructor(pid, r, g, b, text) + { + base.constructor(r, g, b, text); + + local color = getPlayerColor(pid); + _nickname = Draw(0, 0, getPlayerName(pid) + ": "); + _nickname.setColor(color.r, color.g, color.b); + } + + function show() + { + base.show(); + _nickname.visible = true; + } + + function hide() + { + base.hide(); + _nickname.visible = false; + } + + function update(x, y) + { + base.update(_nickname.widthPx + x, y); + _nickname.setPositionPx(x, y); + } + + function setAlpha(alpha) + { + base.setAlpha(alpha) + _nickname.setAlpha(alpha) + } + + function offset() + { + return _nickname.heightPx; + } + + _nickname = null; +} + +///////////////////////////////////////// +/// Chat +///////////////////////////////////////// + +Chat <- { + x = 5, + y = 5, + visible = CHAT_VISIBLE, + + _lines = queue(), + _maxLines = CHAT_LINE_SIZE, + + _historySize = CHAT_HISTORY_SIZE, + _location = 0, + + _playerHistory = queue(), + _playerHistorySize = CHAT_PLAYER_HISTORY_SIZE, + _playerHistoryLocation = 0, + + _animationInterval = CHAT_ANIMATION_INTERVAL.tofloat(), + _animationBeginTime = -1 +} + +//--------------------------------------- + +function Chat::toggle() +{ + visible ? hide() : show(); +} + +//--------------------------------------- + +function Chat::show() +{ + visible = true; + + for (local i = firstVisibleLine(); i <= lastVisibleLine(); ++i) + _lines[i].show(); +} + +//--------------------------------------- + +function Chat::hide() +{ + visible = false; + + for (local i = firstVisibleLine(); i <= lastVisibleLine(); ++i) + _lines[i].hide(); +} + +//--------------------------------------- + +function Chat::printPlayer(pid, r, g, b, msg) +{ + _printLine(ChatPlayerLine(pid, r, g, b, msg)); + + if (_playerHistorySize > 0) + { + _playerHistory.push(msg); + + if (_playerHistory.len() > _playerHistorySize) + _playerHistory.pop(); + } +} + +//--------------------------------------- + +function Chat::print(r, g, b, msg) +{ + _printLine(ChatLine(r, g, b, msg)); +} + +//--------------------------------------- + +function Chat::_printLine(line) +{ + _lines.push(line); + if (visible) _lines[lastVisibleLine()].show(); + + if (_animationInterval > 0) + { + _lines[lastVisibleLine()].setAlpha(0); + _lines[lastVisibleLine()]._animationBeginTime = getTickCount(); + } + + if (_lines.len() > _maxLines) + { + _lines[firstVisibleLine() - 1].hide(); + + if (_lines.len() > _historySize) + _lines.pop(); + + if (_animationInterval > 0) + _animationBeginTime = getTickCount(); + else + _calcPosition(); + } + else + _calcPosition(); +} + +//--------------------------------------- + +function Chat::_calcPosition() +{ + local offset = 0; + + for (local i = firstVisibleLine(); i <= lastVisibleLine(); ++i) + { + local line = _lines[i]; + + if (visible) line.show(); + line.update(x, y + offset); + + offset += line.offset(); + } + + chatInputSetPosition(x, any(y + offset)); +} + +//--------------------------------------- + +function Chat::setHistorySize(size) +{ + if (size >= _maxLines && _historySize > size) + { + local end = _lines.len() - size; + + for (local i = 0; i < end; ++i) + _lines.pop(); + } + + _historySize = size; +} + +//--------------------------------------- + +function Chat::setMaxLines(maxLines) +{ + if (maxLines <= 0 || maxLines > 30) + return; + + for (local i = firstVisibleLine(); i <= lastVisibleLine(); ++i) + _lines[i].hide(); + + _maxLines = maxLines; + _calcPosition(); + + if (_historySize < maxLines) + setHistorySize(maxLines); +} + +//--------------------------------------- + +function Chat::location() +{ + return _location; +} + +//--------------------------------------- + +function Chat::topLocation() +{ + local idx = _lines.len() - _maxLines; + + if (idx < 0) + idx = 0; + + return -idx; +} + +//--------------------------------------- + +function Chat::firstVisibleLine() +{ + local idx = _lines.len() - _maxLines + _location; + + if (idx < 0) + idx = 0; + + return idx; +} + +//--------------------------------------- + +function Chat::lastVisibleLine() +{ + local idx = _lines.len() - 1 + _location; + + if (idx < 0) + idx = 0; + + return idx; +} + +//--------------------------------------- + +function Chat::move(newLocation) +{ + if (_lines.len() < _maxLines) + return; + + if ((_lines.len() - _maxLines + newLocation < 0) || (newLocation > 0)) + return; + + if (_location == newLocation) + return; + + for (local i = firstVisibleLine(); i <= lastVisibleLine(); ++i) + _lines[i].hide(); + + _location = newLocation; + _calcPosition(); +} + +//--------------------------------------- + +function Chat::setPlayerHistorySize(size) +{ + if (_playerHistorySize > size) + loadPlayerMessage(0); + + _playerHistorySize = size; +} + +//--------------------------------------- + +function Chat::playerHistoryLocation() +{ + return _playerHistoryLocation; +} + +//--------------------------------------- + +function Chat::loadPlayerMessage(newLocation) +{ + if (!_playerHistory.len()) + return; + + if ((_playerHistory.len() + newLocation < 0) || (newLocation > 0)) + return; + + if (_playerHistoryLocation == newLocation) + return; + + _playerHistoryLocation = newLocation; + + if (newLocation != 0) + chatInputSetText(_playerHistory[_playerHistory.len() + newLocation]); + else + chatInputSetText(""); +} + +///////////////////////////////////////// +/// Events +///////////////////////////////////////// + +local function renderHandler() +{ + local now = getTickCount(); + + if (Chat._animationInterval <= 0) + return; + + local deltaTime = (now - Chat._animationBeginTime) / Chat._animationInterval; + local firstVisibleLine = Chat.firstVisibleLine(); + + for (local i = 0; i < Chat._lines.len() - firstVisibleLine; ++i) + { + local line = Chat._lines[i + firstVisibleLine]; + + if (Chat._animationBeginTime != -1) + { + if (deltaTime < 1.0) + line.update(Chat.x, Chat.y + line.offset() * (i + 1) - line.offset() * deltaTime); + else + { + Chat._calcPosition(); + Chat._animationBeginTime = -1; + } + } + + if (line._animationBeginTime != -1) + { + local deltaTime = (now - line._animationBeginTime) / Chat._animationInterval; + + if (deltaTime < 1.0) + line.setAlpha(255 * deltaTime); + else + { + line.setAlpha(255); + line._animationBeginTime = -1; + } + } + } +} + +enableEvent_Render(true); +addEventHandler("onRender", renderHandler); + +//--------------------------------------- + +local function keyHandler(key) +{ + if (chatInputIsOpen()) + { + switch (key) + { + case KEY_UP: + if (isKeyPressed(KEY_LCONTROL) || isKeyPressed(KEY_RCONTROL)) + Chat.loadPlayerMessage(Chat.playerHistoryLocation() - 1); + else + Chat.move(Chat.location() - 1); + break; + + case KEY_DOWN: + if (isKeyPressed(KEY_LCONTROL) || isKeyPressed(KEY_RCONTROL)) + Chat.loadPlayerMessage(Chat.playerHistoryLocation() + 1); + else + Chat.move(Chat.location() + 1); + break; + + case KEY_PRIOR: + Chat.move(Chat.topLocation()); + break; + + case KEY_NEXT: + Chat.move(0); + break; + + case KEY_RETURN: + Chat.move(0); + chatInputSend(); + Chat.loadPlayerMessage(0); + + setFreeze(false); + Camera.enableMovement(true); + break; + + case KEY_ESCAPE: + case KEY_TILDE: + chatInputClose(); + + setFreeze(false); + Camera.enableMovement(true); + break; + + default: + playGesticulation(heroId); + break; + } + } + else + { + switch (key) + { + case KEY_T: + if (!isConsoleOpen() && Chat.visible) + { + chatInputOpen(); + + setFreeze(true); + Camera.enableMovement(false); + } + break; + + case KEY_F9: + Chat.toggle(); + break; + } + } +} + +addEventHandler("onKey", keyHandler); + +//--------------------------------------- + +local function commandHandler(cmd, param) +{ + try + param = param.tointeger() + catch (msg) + return; + + switch (cmd) + { + case "chatlines": + Chat.setMaxLines(param); + break; + + case "chatlimit": + Chat.setHistorySize(param); + break; + + case "chatplayerlimit": + Chat.setPlayerHistorySize(param); + break + } +} + +addEventHandler("onCommand", commandHandler) + +//--------------------------------------- + +local function mouseWheelHandler(direction) +{ + if (!Chat.visible) + return; + + if (!chatInputIsOpen()) + return; + + if (isKeyPressed(KEY_LCONTROL) || isKeyPressed(KEY_RCONTROL)) + Chat.loadPlayerMessage(Chat.playerHistoryLocation() - direction); + else + Chat.move(Chat.location() - direction); +} + +addEventHandler("onMouseWheel", mouseWheelHandler); + +//--------------------------------------- + +local function messageHandler(pid, r, g, b, message) +{ + if (pid != -1) + Chat.printPlayer(pid, r, g, b, message); + else + Chat.print(r, g, b, message); +} + +addEventHandler("onPlayerMessage", messageHandler); + +// Loaded +print("chat.nut loaded...") diff --git a/gamemode/client/gui.nut b/gamemode/client/gui.nut new file mode 100644 index 0000000..66d14ad --- /dev/null +++ b/gamemode/client/gui.nut @@ -0,0 +1,55 @@ +local windowM = GUI.Window(2400, 2500, 3500, 3500, "LOG_BACK.TGA"); //bg +local logo = GUI.Draw(1650, 300, GUI_LOGO, windowM); //logo + logo.setFont("FONT_OLD_20_WHITE_HI.TGA"); + logo.setColor(230,180,55); +GUI.Texture(1390, 800, 1950, 2300, "LETTERS.TGA", windowM); //bg2 +GUI.Texture(50, 2300, 1210, 1100, "Map_DragonIsland.TGA", windowM); //map +local czasgra = GUI.Draw(225, 300, "Czas gry " + getTime().hour + ":" + getTime().min, windowM); //czasgra +local czasreal = GUI.Draw(225, 550, "Czas realny " + date().hour + ":" + date().min, windowM); //czasreal + czasgra.setColor(200,180,140); + czasreal.setColor(200,180,140); +local charaB = GUI.Button(420, 1050, 540, 300, "", GUI_CHARA, windowM); //login +local exit = GUI.Button(390, 1800, 535, 470, "", "Wyjście", windowM); //exit + +packet <- null; +addEventHandler("onInit", function(){packet <- Packet();enableEvent_Render(true);}); + +function openMENU(){setFreeze(true);windowM.setVisible(true);setCursorVisible(true);Camera.enableMovement(false);} +function closeMENU(){setFreeze(false);windowM.setVisible(false);/*chara.setVisible(false);options.setVisible(false);*/setCursorVisible(false);Camera.enableMovement(true);} + +addEventHandler("GUI.onClick", function(self){ + switch (self) + { + + case exit: + closeMENU(); + exitGame(); + break + } +}); + +addEventHandler("GUI.onMouseIn", function(node){ + if(node instanceof GUI.Button){ + if(windowM.visible) + node.draw.setColor(60, 60, 180); + /*else if(options.visible || chara.visible) + node.draw.setColor(60, 180, 60);*/ + } +}); + +addEventHandler("GUI.onMouseOut", function(node){ + if(node instanceof GUI.Button){ + if(windowM.visible) + node.draw.setColor(255, 255, 255); + } +}); + +addEventHandler("onKey", function(key){ + if(key == KEY_ESCAPE){ + if(windowM.visible){ + openMENU(); + }else{ + closeMENU(); + } + } +}); diff --git a/gamemode/client/login.nut b/gamemode/client/login.nut new file mode 100644 index 0000000..a5bdeeb --- /dev/null +++ b/gamemode/client/login.nut @@ -0,0 +1,77 @@ +local window = GUI.Window(2400, 2500, 3500, 3500, "LOG_BACK.TGA"); //bg +local logo = GUI.Draw(1700, 300, GUI_LOGO, window); //logo + logo.setFont("FONT_OLD_20_WHITE_HI.TGA"); + logo.setColor(230,180,55); +GUI.Texture(1390, 800, 1950, 2300, "LETTERS.TGA", window); //bg2 +GUI.Texture(50, 2300, 1210, 1100, "MAP_NEWWORLD_SEAMAP.TGA", window); //map +local czasgra = GUI.Draw(225, 300, GUI_GTIME + getTime().hour + ":" + getTime().min, window); //czasgra +local czasreal = GUI.Draw(225, 550, GUI_RTIME + date().hour + ":" + date().min, window); //czasreal + czasgra.setColor(200,180,140); + czasreal.setColor(200,180,140); +local login = GUI.Button(410, 1050, 540, 300, "", GUI_LOGIN, window); //login +local exit = GUI.Button(390, 1800, 535, 470, "", GUI_EXIT, window); //exit + +local textLog = GUI.Draw(2140,1100,GUI_TEXTLOG,window); +local textPas = GUI.Draw(2125,1900,GUI_TEXTPAS,window); +textLog.setFont("FONT_20_BOOK_HI.TGA"); +textPas.setFont("FONT_20_BOOK_HI.TGA"); +local inpLog = GUI.Input(1640,1400,1455,355,"INV_SLOT_FOCUS.TGA","FONT_DEFAULT.TGA", Input.Text, Align.Center, "...", 6, window); +local inpPas = GUI.Input(1640,2200,1455,355,"INV_SLOT_FOCUS.TGA","FONT_DEFAULT.TGA", Input.Password, Align.Center, "...", 2, window); +inpLog.maxLetters = 20; +inpPas.maxLetters = 20; + +local loginbad = GUI.Draw(2140,1100,LOGIN_FAIL); + +// ================================================================================================= // + +addEventHandler("onInit", function(){ + enableEvent_Render(true); + enableHud(HUD_HEALTH_BAR,false); + Camera.enableMovement(false); + Camera.setPosition(-14096.3,2758.05,-30978.6); + Camera.setRotation(0, 64, 0); + openLOGIN(); + + inpPas.setDisabled(false); + inpPas.setVisible(true); +}); + +function openLOGIN(){setFreeze(true);window.setVisible(true);setCursorVisible(true);} +function closeLOGIN(){setFreeze(false);window.setVisible(false);loginbad.setVisible(false);setCursorVisible(false);enableHud(HUD_HEALTH_BAR,true);Camera.enableMovement(true);} + +// ================================================================================================= // + +addEventHandler("GUI.onClick", function(self){ + switch (self) + { + case login: + packet.reset(); + packet.writeUInt8(packets.checklog); + packet.writeString(inpLog.getText()); + packet.writeString(md5(inpPas.getText())); + packet.send(RELIABLE); + break + + case exit: + closeLOGIN(); + exitGame(); + break + } +}); + +addEventHandler("GUI.onMouseIn", function(node){ +if(node instanceof GUI.Button && window.visible) + node.draw.setColor(240, 60, 60); +}); + +addEventHandler("GUI.onMouseOut", function(node){ +if(node instanceof GUI.Button && window.visible) + node.draw.setColor(255, 255, 255); +}); + +addEventHandler("onPacket", function(packet){ + local packetId = packet.readUInt8(); + if(packetId == packets.logfail) { + loginbad.setVisible(true); + } +}); diff --git a/gamemode/client/main.nut b/gamemode/client/main.nut new file mode 100644 index 0000000..a3bcca6 --- /dev/null +++ b/gamemode/client/main.nut @@ -0,0 +1,137 @@ +addEvent("onChangeClass"); + +mySerial <- ""; +myMac <- ""; +myIp <- ""; + +local ui = { + name = Draw(150, 150, "..."), + guild = Draw(150, 325, "..."), + description = Draw(150, 500, "..."), + cselect = Draw(3000, 7600, MAIN_CSELECT) +}; +ui.cselect.font = "FONT_OLD_20_WHITE_HI.tga"; + +local toggleUi = function(flag) { + ui.name.visible = flag; + ui.guild.visible = flag; + ui.description.visible = flag; + ui.cselect.visible = flag; + + setFreeze(flag); + Camera.enableMovement(!flag); +} + +local isSelectingClass = false; +local selectedClass = 0; +local updateClassInfo = function() { + local info = classes[selectedClass]; + + ui.name.text = info.name; + ui.guild.text = info.guild; + ui.description.text = info.description; + + clearInventory(); + setPlayerPosition(heroId, info.spawn[0], info.spawn[1], info.spawn[2]); + setPlayerAngle(heroId, info.spawn[3]); + + local x = info.spawn[0] + 200.0 * sin((3.14 / 180) * info.spawn[3]); + local z = info.spawn[2] + 200.0 * cos((3.14 / 180) * info.spawn[3]); + Camera.setPosition(x, info.spawn[1] + 20, z); + Camera.setRotation(0, info.spawn[3] + 180, 0); + + packet.reset(); + packet.writeUInt8(packets.select_class); + packet.writeUInt8(selectedClass); + packet.send(RELIABLE); +} + +addEventHandler("onKey", function(key){ + if(isSelectingClass) { + if(key == KEY_RETURN) { + clearInventory(); + packet.reset(); + packet.writeUInt8(packets.select_class); + packet.writeUInt8(selectedClass); + packet.writeUInt8(packets.selected_class); + packet.send(RELIABLE); + + // show chat + toggleUi(false); + isSelectingClass = false; + } + else if(key == KEY_A) { + selectedClass -= 1; + if(selectedClass < 0) + selectedClass = classes.len() - 1; + + while("serial" in classes[selectedClass]) { + if(classes[selectedClass].serial.find(mySerial) == null) { + selectedClass -= 1; + if(selectedClass < 0) + selectedClass = classes.len() - 1; + } else break; + } + + updateClassInfo(); + } + else if(key == KEY_D) { + selectedClass += 1; + if(selectedClass >= classes.len()) + selectedClass = 0; + + while("serial" in classes[selectedClass]) { + if(classes[selectedClass].serial.find(mySerial) == null) { + selectedClass += 1; + if(selectedClass >= classes.len()) + selectedClass = 0; + } else break; + } + + updateClassInfo(); + } + } +}); + +local sjoin = Sound("DIA_1013_BANDIT_AMBUSH_01_01.WAV"); +local sjoin_human = Sound("DIA_ANDRE_JOIN_08_18.WAV"); +local sjoin_orc = Sound("DIA_URSHAK_HALLO_18_00.WAV"); + +addEventHandler("onInit", function(){ + clearMultiplayerMessages(); + setKeyLayout(1); + enableEvent_Render(true); + + disableKey(KEY_N, true); + disableKey(KEY_L, true); + disableKey(KEY_C, true); + disableKey(KEY_ESCAPE, true); +}); + +addEventHandler("onPacket", function(packet){ + local packetId = packet.readUInt8(); + if(packetId == packets.player_info) { + mySerial = packet.readString(); + myIp = packet.readString(); + myMac = packet.readString(); + } + else if(packetId == packets.change_class) { + callEvent("onChangeClass", packet.readUInt8(), packet.readUInt8()); + } + else if(packetId == packets.first_join) { + closeLOGIN(); + isSelectingClass = true; + toggleUi(true); + updateClassInfo(); + sjoin.play(); + } + else if(packetId == packets.next_join) { + if(getPlayerInstance(heroId) == "PC_HERO"){ + sjoin_human.play(); + } + else if(getPlayerInstance(heroId) != "PC_HERO"){ + sjoin_orc.play(); + } + closeLOGIN(); + } +}); diff --git a/gamemode/client/playerlist.nut b/gamemode/client/playerlist.nut new file mode 100644 index 0000000..83048f7 --- /dev/null +++ b/gamemode/client/playerlist.nut @@ -0,0 +1,415 @@ +///////////////////////////////////////// +/// Defines +///////////////////////////////////////// + +local MAX_PLAYERS = 30; + +///////////////////////////////////////// +/// Player list class +///////////////////////////////////////// + +PlayerList <- { + // Private + _hostname = null, + _items = array(getMaxSlots(), null), + _headers = [], + _backgrounds = [], + _lineHeightPx = -1, + _begin = 0, + _size = 0, + + // Public + visible = false, + x = -1, + y = 100, + width = -1, + height = -1, + + // Constans + ID = -1, + NICKNAME = -1, + GUILD = -1, +} + +//--------------------------------------- + +function PlayerList::constructor() +{ + // List draw + _hostname = Draw(0, 0, getHostname()); + _hostname.font = "FONT_OLD_20_WHITE_HI.TGA"; + _hostname.setPositionPx(nax(4096 - _hostname.width / 2), y / 2); + + ID = registerColumn("ID", 200); + NICKNAME = registerColumn("Nick", 2000); + GUILD = registerColumn("Gildia", 1200); + // Add more columns after this line... + + resize(); + + // Create textures + registerTexture("MENU_INGAME.TGA", function () + { + tex.setPositionPx(PlayerList.x - 25,PlayerList.y - 15); + tex.setSizePx(PlayerList.width + 50, PlayerList.height + 30); + }); + + // Add more textures after this line... + + // Top + foreach (header in _headers) + header.draw.top(); +} + +//--------------------------------------- + +function PlayerList::registerColumn(name, width) +{ + local draw = Draw(0, 0, name); + draw.setColor(255, 255, 0); + + _headers.push({ + name = name, + width = width, + draw = draw, + }) + + return _headers.len() - 1; +} + +//--------------------------------------- + +function PlayerList::registerTexture(name, resize) +{ + local tex = Texture(0, 0, 0, 0, name); + local bg = { + resize = resize, + tex = tex, + } + + bg.resize(); + _backgrounds.push(bg); +} + +//--------------------------------------- + +function PlayerList::getItem(pid) +{ + return _items[pid]; +} + +//--------------------------------------- + +function PlayerList::toggle() +{ + visible ? hide() : show(); +} + +//--------------------------------------- + +function PlayerList::show() +{ + if (visible) return; + visible = true; + + _hostname.visible = true; + + foreach (header in _headers) + header.draw.visible = true; + + foreach (bg in _backgrounds) + bg.tex.visible = true; + + _showActive(); +} + +//--------------------------------------- + +function PlayerList::hide() +{ + if (!visible) return; + visible = false; + + _hostname.visible = false; + + foreach (header in _headers) + header.draw.visible = false; + + foreach (bg in _backgrounds) + bg.tex.visible = false; + + _hideActive(); +} + +//--------------------------------------- + +function PlayerList::scroll(value) +{ + _hideActive(); + + // Calculate new begin + local len = _size - MAX_PLAYERS + 1; + if (len < 0) len = 0; + + _begin -= value; + + if (_begin < 0) _begin = 0; + else if (_begin > len) _begin = len; + + _showActive(); +} + +//--------------------------------------- + +function PlayerList::insert(pid) +{ + if (pid >= _items.len()) return; + + local playerItem = heroId != pid ? PlayerListItem(pid, 255, 255, 255) : PlayerListItem(pid, 255, 150, 0); + + _items[pid] = playerItem; + ++_size; + + return playerItem; +} + +//--------------------------------------- + +function PlayerList::remove(pid) +{ + if (pid >= _items.len()) return; + + _items[pid] = null; + --_size; +} + +//--------------------------------------- + +function PlayerList::resize() +{ + local res = getResolution(); + _lineHeightPx = _headers.top().draw.heightPx; + + width = 0; + height = _lineHeightPx * MAX_PLAYERS; + + foreach (header in _headers) + width += (nax(header.width) + header.draw.widthPx); + + local headerX = x = (res.x - width) / 2.0; + local headerY = y; + local offset = _lineHeightPx; + local count = 0; + + width = 0; + foreach (header in _headers) + { + header.draw.setPositionPx(headerX + width, headerY); + width += (nax(header.width) + header.draw.widthPx); + } + + for (local i = _begin; i < _items.len() && count < MAX_PLAYERS - 1; ++i) + { + local item = _items[i]; + if (!item) continue; + + item.update(x, y + offset); + + offset += item.offset(); + ++count; + } + + foreach (bg in _backgrounds) + bg.resize(); +} + +//--------------------------------------- + +function PlayerList::_hideActive() +{ + local count = 0; + + for (local i = _begin; i < _items.len() && count < MAX_PLAYERS - 1; ++i) + { + local item = _items[i]; + if (!item) continue; + + item.hide(); + ++count; + } +} + +//--------------------------------------- + +function PlayerList::_showActive() +{ + local count = 0; + local offset = _lineHeightPx; + + for (local i = _begin; i < _items.len() && count < MAX_PLAYERS - 1; ++i) + { + local item = _items[i]; + if (!item) continue; + + item.update(x, y + offset); + item.show(); + + offset += item.offset(); + ++count; + } +} + +///////////////////////////////////////// +/// Player list item +///////////////////////////////////////// + +class PlayerListItem +{ + constructor(pid, r, g, b) + { + columns = []; + visible = false; + + foreach (header in PlayerList._headers) + { + local draw = Draw(0, 0, ""); + draw.setColor(r, g, b); + + columns.push(draw); + } + } + + function show() + { + if (visible) return; + visible = true; + + foreach (column in columns) + column.visible = true; + } + + function hide() + { + if (!visible) return; + visible = false; + + foreach (column in columns) + column.visible = false; + } + + function offset() + { + return columns.top().heightPx; + } + + function update(x, y) + { + local headers = PlayerList._headers; + local width = 0; + + foreach (id, column in columns) + { + column.setPositionPx(x + width, y); + width += (nax(headers[id].width) + headers[id].draw.widthPx); + } + } + + columns = null; + visible = false; +} + +///////////////////////////////////////// +/// Events +///////////////////////////////////////// + +local function playerCreate(pid) +{ + local playerItem = PlayerList.insert(pid); + + // Init item with default data + local color = getPlayerColor(pid); + + playerItem.columns[PlayerList.ID].text = pid.tostring(); + playerItem.columns[PlayerList.NICKNAME].text = getPlayerName(pid); + playerItem.columns[PlayerList.NICKNAME].setColor(color.r, color.g, color.b); + playerItem.columns[PlayerList.GUILD].text = ""; +} + +addEventHandler("onPlayerCreate", playerCreate); + +//--------------------------------------- + +local function playerDestroy(pid) +{ + PlayerList.remove(pid); +} + +addEventHandler("onPlayerDestroy", playerDestroy); + +//--------------------------------------- + +local function playerGuild(pid, class_id) +{ + local playerItem = PlayerList.getItem(pid); + if (playerItem == null) return; + + playerItem.columns[PlayerList.GUILD].text = classes[class_id].guild; +} + +addEventHandler("onChangeClass", playerGuild); + +//--------------------------------------- + +local function playerNickname(pid, name) +{ + local playerItem = PlayerList.getItem(pid); + if (playerItem == null) return; + + playerItem.columns[PlayerList.NICKNAME].text = name; +} + +addEventHandler("onPlayerChangeNickname", playerNickname); + +//--------------------------------------- + +local function playerColor(pid, r, g, b) +{ + local playerItem = PlayerList.getItem(pid); + if (playerItem == null) return; + + playerItem.columns[PlayerList.NICKNAME].setColor(r, g, b); +} + +addEventHandler("onPlayerChangeColor", playerColor); + +//--------------------------------------- + +local function keyHandler(key) +{ + if (key == KEY_F5 && !chatInputIsOpen()) + PlayerList.toggle(); +} + +addEventHandler("onKey", keyHandler); + +//--------------------------------------- + +local function mouseWheel(value) +{ + if (PlayerList.visible) + PlayerList.scroll(value); +} + +addEventHandler("onMouseWheel", mouseWheel); + +//--------------------------------------- + +local function resChange() +{ + PlayerList.resize(); +} + +addEventHandler("onChangeResolution", resChange); + +// Initialize PlayerList +PlayerList.constructor(); diff --git a/gamemode/client/visual.nut b/gamemode/client/visual.nut new file mode 100644 index 0000000..d8dbe9c --- /dev/null +++ b/gamemode/client/visual.nut @@ -0,0 +1,246 @@ +local isOpen = false; +local visual = { + body = { + model = ["HUM_BODY_BABE0", "HUM_BODY_NAKED0"], + tex = 10 + }, + head = { + model = ["HUM_HEAD_BALD","HUM_HEAD_FATBALD","HUM_HEAD_FIGHTER","HUM_HEAD_PONY","HUM_HEAD_PSIONIC","HUM_HEAD_THIEF", "HUM_HEAD_BABE", "HUM_HEAD_BABE1", "HUM_HEAD_BABE2", "HUM_HEAD_BABE3", "HUM_HEAD_BABE4", "HUM_HEAD_BABE5", "HUM_HEAD_BABE6", "HUM_HEAD_BABE7", "HUM_HEAD_BABE8", "HUM_HEAD_BABEHAIR"], + tex = 162 + } +}; +local mySetting = [ + 1, 8, 3, 18 //body model, texture, head model, texture +]; + +local GUI = { + Header = Draw(6390, 4750, VIS_HEADER), + Head_Model = { + Left = Texture(5750, 5350, 150, 150, "L.tga"), + Right = Texture(7550, 5350, 150, 150, "R.tga"), + Text = Draw(6000, 5250, VIS_HMODEL) + }, + Head_Texture = { + Left = Texture(5750, 5600, 150, 150, "L.tga"), + Right = Texture(7550, 5600, 150, 150, "R.tga"), + Text = Draw(6000, 5500, VIS_HTEX) + }, + Body_Model = { + Left = Texture(5750, 5850, 150, 150, "L.tga"), + Right = Texture(7550, 5850, 150, 150, "R.tga"), + Text = Draw(6000, 5750, VIS_BMODEL) + }, + Body_Texture = { + Left = Texture(5750, 6100, 150, 150, "L.tga"), + Right = Texture(7550, 6100, 150, 150, "R.tga"), + Text = Draw(6000, 6000, VIS_BTEX) + }, + Exit = { + Button = Texture(6000, 3250, 1500, 1500, "MENU_MASKE.tga"), + Text = Draw(6390, 6350, VIS_EXIT) + } +}; + +GUI.Header.font = "FONT_OLD_20_WHITE_HI.tga"; +GUI.Head_Model.Text.font = "FONT_OLD_20_WHITE_HI.tga"; +GUI.Head_Texture.Text.font = "FONT_OLD_20_WHITE_HI.tga"; +GUI.Body_Model.Text.font = "FONT_OLD_20_WHITE_HI.tga"; +GUI.Body_Texture.Text.font = "FONT_OLD_20_WHITE_HI.tga"; +GUI.Exit.Text.font = "FONT_OLD_20_WHITE_HI.tga"; + +addEventHandler("onKey", function(key){ +if(getPlayerInstance(heroId) == "PC_HERO"){ + if(key == KEY_F8){ + if(!isOpen){ + openVisualMenu(); + } else { + closeVisualMenu(); + + packet.reset(); + local vis = getPlayerVisual(heroId); + packet.writeUInt8(packets.visual); + packet.writeString(vis.bodyModel); + packet.writeUInt8(vis.bodyTxt); + packet.writeString(vis.headModel); + packet.writeUInt8(vis.headTxt); + packet.send(RELIABLE); + } + setCursorVisible(isOpen); + } +} +}); + +function openVisualMenu(){ + Camera.enableMovement(false); + local pos = getPlayerPosition(heroId); + local angle = getPlayerAngle(heroId); + pos.x = pos.x + (sin(angle * 3.14 / 180.0) * 160); + pos.z = pos.z + (cos(angle * 3.14 / 180.0) * 170); + Camera.setPosition(pos.x, pos.y, pos.z); + Camera.setRotation(0, angle - 180, 0); + enableKeys(false); + setFreeze(true); + //playAni(heroId, "S_THRONE_S1"); + + isOpen = true; + + GUI.Header.visible = true; + + GUI.Head_Model.Left.visible = true; + GUI.Head_Model.Right.visible = true; + GUI.Head_Model.Text.visible = true; + + GUI.Head_Texture.Left.visible = true; + GUI.Head_Texture.Right.visible = true; + GUI.Head_Texture.Text.visible = true; + + GUI.Body_Model.Left.visible = true; + GUI.Body_Model.Right.visible = true; + GUI.Body_Model.Text.visible = true; + + GUI.Body_Texture.Left.visible = true; + GUI.Body_Texture.Right.visible = true; + GUI.Body_Texture.Text.visible = true; + + GUI.Exit.Button.visible = true; + //GUI.Exit.Text.visible = true; +} +function closeVisualMenu(){ + Camera.enableMovement(true); + Camera.setTargetPlayer(heroId); + enableKeys(true); + setFreeze(false); + playAni(heroId, "S_RUN"); + + isOpen = false; + + GUI.Header.visible = false; + + GUI.Head_Model.Left.visible = false; + GUI.Head_Model.Right.visible = false; + GUI.Head_Model.Text.visible = false; + + GUI.Head_Texture.Left.visible = false; + GUI.Head_Texture.Right.visible = false; + GUI.Head_Texture.Text.visible = false; + + GUI.Body_Model.Left.visible = false; + GUI.Body_Model.Right.visible = false; + GUI.Body_Model.Text.visible = false; + + GUI.Body_Texture.Left.visible = false; + GUI.Body_Texture.Right.visible = false; + GUI.Body_Texture.Text.visible = false; + + GUI.Exit.Button.visible = false; + GUI.Exit.Text.visible = false; +} + +local isInside = function(x1, y1, x2, y2, w, h){ + if(x1 <= x2 + w && x1 >= x2 && y1 <= y2 + h && y1 >= y2) + return true; + else + return false; +} +local changeValue = function(id, val){ + local value = mySetting[id]; + value += val; + + if(id == 0) { + if(value > visual.body.model.len()) value = 0; + else if(value < 0) value = visual.body.model.len() - 1; + } + else if(id == 1) { + if(value > visual.body.tex) value = 0; + else if(value < 0) value = visual.body.tex - 1; + } + else if(id == 2) { + if(value > visual.head.model.len()) value = 0; + else if(value < 0) value = visual.head.model.len() - 1; + } + else if(id == 3) { + if(value > visual.head.tex) value = 0; + else if(value < 0) value = visual.head.tex - 1; + } + + mySetting[id] = value; + setPlayerVisual(heroId, visual.body.model[mySetting[0]], mySetting[1], visual.head.model[mySetting[2]], mySetting[3]); +} + +local checkBodyModel = function(x, y){ + local gui = GUI.Body_Model; + + local left_pos = gui.Left.getPosition(); + local left_size = gui.Left.getSize(); + if(isInside(x, y, left_pos.x, left_pos.y, left_size.width, left_size.height)){ + changeValue(0, -1); + return; + } + local right_pos = gui.Right.getPosition(); + local right_size = gui.Right.getSize(); + if(isInside(x, y, right_pos.x, right_pos.y, right_size.width, right_size.height)){ + changeValue(0, 1); + return; + } +} +local checkBodyTex = function(x, y){ + local gui = GUI.Body_Texture; + + local left_pos = gui.Left.getPosition(); + local left_size = gui.Left.getSize(); + if(isInside(x, y, left_pos.x, left_pos.y, left_size.width, left_size.height)){ + changeValue(1, -1); + return; + } + local right_pos = gui.Right.getPosition(); + local right_size = gui.Right.getSize(); + if(isInside(x, y, right_pos.x, right_pos.y, right_size.width, right_size.height)){ + changeValue(1, 1); + return; + } +} +local checkHeadModel = function(x, y){ + local gui = GUI.Head_Model; + + local left_pos = gui.Left.getPosition(); + local left_size = gui.Left.getSize(); + if(isInside(x, y, left_pos.x, left_pos.y, left_size.width, left_size.height)){ + changeValue(2, -1); + return; + } + local right_pos = gui.Right.getPosition(); + local right_size = gui.Right.getSize(); + if(isInside(x, y, right_pos.x, right_pos.y, right_size.width, right_size.height)){ + changeValue(2, 1); + return; + } +} +local checkHeadTex = function(x, y){ + local gui = GUI.Head_Texture; + + local left_pos = gui.Left.getPosition(); + local left_size = gui.Left.getSize(); + if(isInside(x, y, left_pos.x, left_pos.y, left_size.width, left_size.height)){ + changeValue(3, -1); + return; + } + local right_pos = gui.Right.getPosition(); + local right_size = gui.Right.getSize(); + if(isInside(x, y, right_pos.x, right_pos.y, right_size.width, right_size.height)){ + changeValue(3, 1); + return; + } +} + +addEventHandler("onMouseClick", function(btn){ + if(isOpen){ + if(btn == MOUSE_LMB){ + local mouse = getCursorPosition(); + + checkBodyModel(mouse.x, mouse.y); + checkBodyTex(mouse.x, mouse.y); + checkHeadModel(mouse.x, mouse.y); + checkHeadTex(mouse.x, mouse.y); + } + } +}); diff --git a/gamemode/import.xml b/gamemode/import.xml new file mode 100644 index 0000000..0749683 --- /dev/null +++ b/gamemode/import.xml @@ -0,0 +1,29 @@ + + +