Compare commits

..

No commits in common. "master" and "v0.6.6" have entirely different histories.

505 changed files with 4510 additions and 8369 deletions

View File

@ -1,2 +0,0 @@
/build/
Dockerfile

View File

@ -1,133 +0,0 @@
name: Build with vcpkg
on:
push:
branches:
- master
- v*
tags:
- v*
paths:
- .github/workflows/**
- cmake/**
- src/**
- CMakeLists.txt
pull_request:
paths:
- .github/workflows/**
- cmake/**
- src/**
- CMakeLists.txt
jobs:
job:
name: ${{ matrix.os }}-${{ matrix.cxx }}-${{ matrix.buildtype }}-luajit=${{ matrix.luajit }}
runs-on: ${{ matrix.os }}-${{ matrix.os-version }}
strategy:
fail-fast: false
max-parallel: 8
matrix:
name: [ubuntu-gcc, macos-clang, windows-msvc]
buildtype: [Debug, Release]
luajit: [on, off]
include:
- name: windows-msvc
os: windows
os-version: latest
cxx: cl.exe
cc: cl.exe
triplet: x64-windows
packages: >
boost-iostreams boost-asio boost-system boost-variant boost-lockfree boost-filesystem boost-uuid
glew luajit libogg libvorbis openal-soft opengl openssl physfs zlib
- name: ubuntu-gcc
os: ubuntu
os-version: 20.04
cxx: g++
cc: gcc
triplet: x64-linux
packages: >
boost-iostreams boost-asio boost-system boost-variant boost-lockfree glew
boost-filesystem boost-uuid physfs openal-soft libogg libvorbis zlib opengl
- name: macos-clang
os: macos
os-version: latest
cxx: clang++
cc: clang
triplet: x64-osx
packages: >
boost-iostreams boost-asio boost-system boost-variant boost-lockfree glew
boost-filesystem boost-uuid libogg libvorbis zlib opengl
exclude:
- name: windows-msvc
luajit: off
steps:
- uses: actions/checkout@v3
with:
submodules: true
- name: Unshallow
run: git fetch --prune --unshallow
- name: Get latest CMake
# Using 'latest' branch, the latest CMake is installed.
uses: lukka/get-cmake@latest
- name: Ubuntu - install opengl lua5.1 luajit
# vcpkg has lua 5.3+
run: sudo apt-get install libglew-dev liblua5.1-0-dev libluajit-5.1-dev
if: contains( matrix.os, 'ubuntu')
- name: MacOS - install physfs pkgconfig lua5.1 luajit xquartz
run: brew install physfs pkgconfig lua@5.1 luajit xquartz
if: contains( matrix.os, 'macos')
- name: Set Environment vars
run: |
echo "CXX=${{ matrix.cxx }}" >> $GITHUB_ENV
echo "CC=${{ matrix.cc }}" >> $GITHUB_ENV
- name: Run vcpkg
uses: lukka/run-vcpkg@v7
with:
vcpkgArguments: ${{ matrix.packages }}
vcpkgDirectory: ${{ runner.workspace }}/vcpkg/
vcpkgTriplet: ${{ matrix.triplet }}
vcpkgGitCommitId: 6f7ffeb18f99796233b958aaaf14ec7bd4fb64b2
- name: Build with CMake
uses: lukka/run-cmake@v3
with:
buildDirectory: ${{ runner.workspace }}/build
cmakeListsOrSettingsJson: CMakeListsTxtAdvanced
cmakeAppendedArgs: '-G Ninja -DCMAKE_BUILD_TYPE="${{ matrix.buildtype }}" -DLUAJIT="${{ matrix.luajit }}"'
useVcpkgToolchainFile: true
- name: dir
run: find $RUNNER_WORKSPACE
shell: bash
- name: Upload artifact binary
uses: actions/upload-artifact@v3
with:
name: otclient-${{ matrix.name }}-${{ matrix.buildtype }}-luajit=${{ matrix.luajit }}-${{ github.sha }}
path: ${{ runner.workspace }}/build/otclient
if: "! contains( matrix.os, 'windows')"
- name: Upload artifact binary (exe)
uses: actions/upload-artifact@v3
with:
name: otclient-${{ matrix.name }}-${{ matrix.buildtype }}-luajit=${{ matrix.luajit }}-${{ github.sha }}
path: ${{ runner.workspace }}/build/otclient.exe
if: contains( matrix.os, 'windows')
- name: Upload artifact binary (dlls)
uses: actions/upload-artifact@v3
with:
name: otclient-${{ matrix.name }}-${{ matrix.buildtype }}-luajit=${{ matrix.luajit }}-${{ github.sha }}
path: ${{ runner.workspace }}/build/*.dll
if: contains( matrix.os, 'windows')

231
.gitignore vendored
View File

@ -1,3 +1,45 @@
build*
CMakeCache.txt
CMakeFiles
cmake_install.cmake
Makefile
/otclient
/*.h
/*.cxx
*.o
*.gch
*.a
*.exe
*.spr
*.dat
*.kdev*
*.cbp
*~
*.kate-swap
*.autosave
CMakeLists.txt.user*
*.xml
*.otb
*.otbm
*.log
*.bak
*.swp
*.pic
.lvimrc
.clang_complete
config.otml
/modules/otclientrc.lua
/doc
!.gitignore
otclient.map
otclient.layout
LOCALTODO
tags
Thumbs.db
.directory
src/framework/graphics/dx/
modules/.project/modules.sublime-workspace
################# #################
## Visual Studio ## Visual Studio
################# #################
@ -9,8 +51,6 @@
*.suo *.suo
*.user *.user
*.sln.docstates *.sln.docstates
.idea/
.vscode/
# Build results # Build results
@ -20,7 +60,6 @@ x64/
build/ build/
[Bb]in/ [Bb]in/
[Oo]bj/ [Oo]bj/
cmake-build-*/
# MSTest test Results # MSTest test Results
[Tt]est[Rr]esult*/ [Tt]est[Rr]esult*/
@ -47,19 +86,16 @@ cmake-build-*/
*.vssscc *.vssscc
.builds .builds
*.pidb *.pidb
*.log
*.scc *.scc
*.dll
*.exe
# Visual C++ cache files # Visual C++ cache files
ipch/ ipch/
*.aps *.aps
*.ncb *.ncb
*.opensdf *.opensdf
*.opendb
*.sdf *.sdf
*.cachefile *.cachefile
*.VC.db
# Visual Studio profiler # Visual Studio profiler
*.psess *.psess
@ -72,184 +108,3 @@ ipch/
# ReSharper is a .NET coding add-in # ReSharper is a .NET coding add-in
_ReSharper*/ _ReSharper*/
*.[Rr]e[Ss]harper *.[Rr]e[Ss]harper
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
*.ncrunch*
.*crunch*.local.xml
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.Publish.xml
*.pubxml
# NuGet Packages Directory
## TODO: If you have NuGet Package Restore enabled, uncomment the next line
#packages/
# Windows Azure Build Output
csx
*.build.csdef
# Windows Store app package directory
AppPackages/
# Others
sql/
*.Cache
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.[Pp]ublish.xml
*.pfx
*.publishsettings
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
App_Data/*.mdf
App_Data/*.ldf
#############
## Windows detritus
#############
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Mac crap
.DS_Store
# Installer logs
pip-log.txt
# Unit test / coverage reports
.coverage
.tox
#Translations
*.mo
#Mr Developer
.mr.developer.cfg
# Vim files
*~
.*.swp
.*.swo
#################
## OTClient
#################
/otclient
/modules/otclientrc.lua
src/framework/graphics/dx/
*.o
*.gch
*.a
*.kdev*
*.cbp
*~
*.kate-swap
*.autosave
*.bak
*.swp
.lvimrc
.clang_complete
LOCALTODO
tags
# user-specific files
*.xml
*.otb
*.otbm
*.spr
*.dat
*.pic
config.otml
## Cmake cache
CMakeLists.txt.user
CMakeCache.txt
CMakeFiles
CMakeScripts
Testing
Makefile
cmake_install.cmake
install_manifest.txt
compile_commands.json
CTestTestfile.cmake
_deps
## Sublime
# Cache files for Sublime Text
*.tmlanguage.cache
*.tmPreferences.cache
*.stTheme.cache
# Workspace files are user-specific
*.sublime-workspace
# Project files should be checked into the repository, unless a significant
# proportion of contributors will probably not be using Sublime Text
# *.sublime-project
# SFTP configuration file
sftp-config.json
sftp-config-alt*.json
# Package control specific files
Package Control.last-run
Package Control.ca-list
Package Control.ca-bundle
Package Control.system-ca-bundle
Package Control.cache/
Package Control.ca-certs/
Package Control.merged-ca-bundle
Package Control.user-ca-bundle
oscrypto-ca-bundle.crt
bh_unicode_properties.cache
# Sublime-github package stores a github token in this file
# https://packagecontrol.io/packages/sublime-github
GitHub.sublime-settings

14
.travis.yml Normal file
View File

@ -0,0 +1,14 @@
language: cpp
compiler:
- gcc
before_script:
- sudo apt-get install libboost1.48-all-dev libphysfs-dev libssl-dev liblua5.1-dev libglew1.6-dev libvorbis-dev libopenal-dev libz-dev -y
script: |
cmake . -DCMAKE_BUILD_TYPE=Release
make
notifications:
irc:
channels:
- "irc.freenode.org#otclient"
on_success: change
skip_join: true

View File

@ -1,7 +1,8 @@
cmake_minimum_required(VERSION 3.1) cmake_minimum_required(VERSION 2.6)
project(otclient) project(otclient)
set(VERSION "1.0.0") set(VERSION "0.6.6")
set(LIB_NAME "otc_framework")
option(FRAMEWORK_SOUND "Use SOUND " ON) option(FRAMEWORK_SOUND "Use SOUND " ON)
option(FRAMEWORK_GRAPHICS "Use GRAPHICS " ON) option(FRAMEWORK_GRAPHICS "Use GRAPHICS " ON)
@ -23,40 +24,32 @@ set(executable_SOURCES
src/main.cpp src/main.cpp
) )
# add executable icon for win32 platforms
if(WIN32) if(WIN32)
if(MSVC) add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/otcicon.o
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/otcicon.o COMMAND ${CMAKE_RC_COMPILER}
COMMAND ${CMAKE_RC_COMPILER} -I${CMAKE_CURRENT_SOURCE_DIR}/src
-I${CMAKE_CURRENT_SOURCE_DIR}/src -i${CMAKE_CURRENT_SOURCE_DIR}/src/otcicon.rc
-fo${CMAKE_CURRENT_BINARY_DIR}/otcicon.o -o ${CMAKE_CURRENT_BINARY_DIR}/otcicon.o)
${CMAKE_CURRENT_SOURCE_DIR}/src/otcicon.rc
)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
else()
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/otcicon.o
COMMAND ${CMAKE_RC_COMPILER}
-I${CMAKE_CURRENT_SOURCE_DIR}/src
-i${CMAKE_CURRENT_SOURCE_DIR}/src/otcicon.rc
-o ${CMAKE_CURRENT_BINARY_DIR}/otcicon.o
)
endif()
set(executable_SOURCES ${executable_SOURCES} otcicon.o) set(executable_SOURCES ${executable_SOURCES} otcicon.o)
endif() endif()
add_definitions(-D"VERSION=\\"${VERSION}\\"") add_definitions(-D"VERSION=\\"${VERSION}\\"")
# add client executable # we want framework to be a library for faster compilation/linking
add_executable(${PROJECT_NAME} ${framework_SOURCES} ${client_SOURCES} ${executable_SOURCES}) if(USE_STATIC_LIBS)
add_library(${LIB_NAME} ${framework_SOURCES})
set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD 14) else()
set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD_REQUIRED ON) add_library(${LIB_NAME} SHARED ${framework_SOURCES})
message(STATUS "Linking to shared ${LIB_NAME}, make sure you copy the DLL/SO/dylib with the executable!")
target_link_libraries(${PROJECT_NAME} ${framework_LIBRARIES})
if(APPLE AND USE_STATIC_LIBS)
target_link_libraries(${PROJECT_NAME} "-framework Foundation" "-framework IOKit")
endif() endif()
target_link_libraries(${LIB_NAME} ${framework_LIBRARIES})
# add client executable
add_executable(${PROJECT_NAME} ${client_SOURCES} ${executable_SOURCES})
# target link libraries
target_link_libraries(${PROJECT_NAME} ${LIB_NAME})
if(USE_PCH) if(USE_PCH)
include(cotire) include(cotire)
@ -68,7 +61,7 @@ endif()
# installation # installation
set(DATA_INSTALL_DIR share/${PROJECT_NAME}) set(DATA_INSTALL_DIR share/${PROJECT_NAME})
install(TARGETS ${PROJECT_NAME} install(TARGETS ${PROJECT_NAME} ${LIB_NAME}
RUNTIME DESTINATION bin RUNTIME DESTINATION bin
LIBRARY DESTINATION lib LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib) ARCHIVE DESTINATION lib)

View File

@ -1,48 +0,0 @@
FROM ubuntu@sha256:b88f8848e9a1a4e4558ba7cfc4acc5879e1d0e7ac06401409062ad2627e6fb58 AS builder
RUN apt-get update; \
apt-get install -y \
build-essential \
cmake \
git-core \
libboost-atomic1.65-dev \
libboost-chrono1.65-dev \
libboost-date-time1.65-dev \
libboost-filesystem1.65-dev \
libboost-system1.65-dev \
libboost-thread1.65-dev \
libglew-dev \
liblua5.1-0-dev \
libncurses5-dev \
libopenal-dev \
libssl-dev \
libvorbis-dev \
zlib1g-dev; \
apt-get clean && apt-get autoclean
WORKDIR /
RUN git clone --branch release-3.0.2 --depth 1 https://github.com/icculus/physfs.git
WORKDIR /physfs/build/
RUN cmake ..
RUN make -j$(nproc)
RUN make install
COPY ./src/ /otclient/src/.
COPY CMakeLists.txt /otclient/.
WORKDIR /otclient/build/
RUN cmake -DCMAKE_CXX_LINK_FLAGS=-no-pie -DCMAKE_BUILD_TYPE=Release ..
RUN make -j$(nproc)
FROM ubuntu@sha256:b88f8848e9a1a4e4558ba7cfc4acc5879e1d0e7ac06401409062ad2627e6fb58
RUN apt-get update; \
apt-get install -y \
libglew2.0 \
libopenal1; \
apt-get clean && apt-get autoclean
COPY --from=builder /otclient/build/otclient /otclient/bin/otclient
COPY ./data/ /otclient/data/.
COPY ./mods/ /otclient/mods/.
COPY ./modules/ /otclient/modules/.
COPY ./init.lua /otclient/.
WORKDIR /otclient
CMD ["./bin/otclient"]

View File

@ -1,22 +0,0 @@
<!-- Welcome to the issues section if it's your first time! -->
### Before creating an issue, please ensure:
- [ ] This is a bug in the software that resides in this repository, and not a
support matter (use https://otland.net/forums/otclient.494/ for support)
- [ ] This issue is reproducible without changes to the code in this repository
### Steps to reproduce (include any configuration/script required to reproduce)
1.
2.
3.
### Expected behaviour
<!-- Tell us what should happen -->
### Actual behaviour
<!-- Tell us what happens instead -->
### Environment
<!-- Please tell which client version are you using (E.g 10.98 OTClient 0.6.6)
If the issue is environment specific (e.g. compiling errors), include
name and version of the operating system and compiler you are using. -->

View File

@ -1,6 +1,6 @@
OTClient is made available under the MIT License OTClient is made available under the MIT License
Copyright (c) 2010-2020 OTClient <https://github.com/edubart/otclient> Copyright (c) 2010-2012 OTClient <https://github.com/edubart/otclient>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -1,5 +1,4 @@
[![Build Status](https://github.com/edubart/otclient/actions/workflows/build-vcpkg.yml/badge.svg)](https://github.com/edubart/otclient/actions/workflows/build-vcpkg.yml) [![Join the chat at https://gitter.im/edubart/otclient](https://img.shields.io/badge/GITTER-join%20chat-green.svg)](https://gitter.im/edubart/otclient?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Open Source Helpers](https://www.codetriage.com/edubart/otclient/badges/users.svg)](https://www.codetriage.com/edubart/otclient) [![Build Status](https://secure.travis-ci.org/edubart/otclient.svg?branch=master)](http://travis-ci.org/edubart/otclient)
### What is otclient? ### What is otclient?
Otclient is an alternative Tibia client for usage with otserv. It aims to be complete and flexible, Otclient is an alternative Tibia client for usage with otserv. It aims to be complete and flexible,
@ -7,17 +6,21 @@ for that it uses LUA scripting for all game interface functionality and configur
similar to CSS for the client interface design. Otclient works with a modular system, this means similar to CSS for the client interface design. Otclient works with a modular system, this means
that each functionality is a separated module, giving the possibility to users modify and customize that each functionality is a separated module, giving the possibility to users modify and customize
anything easily. Users can also create new mods and extend game interface for their own purposes. anything easily. Users can also create new mods and extend game interface for their own purposes.
Otclient is written in C++11 and heavily scripted in lua. Otclient is written in C++2011, the upcoming C++ standard and heavily scripted in lua.
For a server to connect to, you can build your own with the [forgottenserver](https://github.com/otland/forgottenserver)
or connect to one listed on [otservlist](https://otservlist.org/).
### Where do I download? ### Where do I download?
Compiled for Windows can be found here (but can be outdated): The latest commits compiled for Windows can be found here.
* [Windows Builds](http://otland.net/threads/otclient-builds-windows.217977/) * [Windows Builds](http://otland.net/threads/otclient-builds-windows.217977/)
**NOTE:** You will need to download spr/dat files on your own and place them in `data/things/VERSION/` (i.e: `data/things/1098/Tibia.spr`) Here is the latest v0.6.5 release compiled for both i686(32 bit) and x86_64(64 bit) machines, with OpenGL renderer.
This release is compatible with protocols ranges from 7.60 up to 10.31.
* [For Windows](https://www.dropbox.com/sh/se1okacemoqzjve/XFqFoSKLCg/otclient-win-0.6.5.zip)
* [For Linux](https://www.dropbox.com/sh/se1okacemoqzjve/xKJL7j6vEo/otclient-linux-0.6.5.tar.gz)
**NOTE:** You will need to download spr/dat files on your own and place them in `data/things/VERSION/` (i.e: `data/things/1041/Tibia.spr`)
Older releases can be downloaded from [here](https://www.dropbox.com/sh/se1okacemoqzjve/-oWK4YFm03)
### Features ### Features
@ -31,40 +34,20 @@ client, instead otclient was designed to be a combination of a framework and tib
### Compiling ### Compiling
A package with all required libraries for compiling OTClient on Windows can be found here:
* [For MSVC 2013](https://www.dropbox.com/sh/se1okacemoqzjve/dI4ODbq7OT/otclient-msvc13-libs.zip)
* [For MingW32](https://www.dropbox.com/sh/se1okacemoqzjve/UAkRCiGXXR/otclient-libs_mingw32-dwarf2.zip)
In short, if you need to compile OTClient, follow these tutorials: In short, if you need to compile OTClient, follow these tutorials:
* [Compiling on Windows](https://github.com/edubart/otclient/wiki/Compiling-on-Windows) * [Compiling on Windows](https://github.com/edubart/otclient/wiki/Compiling-on-Windows)
* [Compiling on Linux](https://github.com/edubart/otclient/wiki/Compiling-on-Linux) * [Compiling on Linux](https://github.com/edubart/otclient/wiki/Compiling-on-Linux)
* [Compiling on OS X](https://github.com/edubart/otclient/wiki/Compiling-on-Mac-OS-X)
### Build and run with Docker
To build the image:
```sh
docker build -t edubart/otclient .
```
To run the built image:
```sh
# Disable access control for the X server.
xhost +
# Run the container image with the required bindings to the host devices and volumes.
docker run -it --rm \
--env DISPLAY \
--volume /tmp/.X11-unix:/tmp/.X11-unix \
--device /dev/dri \
--device /dev/snd edubart/otclient /bin/bash
# Enable access control for the X server.
xhost -
```
### Need help? ### Need help?
Try to ask questions in [otland](http://otland.net/f494/), now we have a board for the project there, Try to ask questions in [otland](http://otland.net/f494/), now we have a board for the project there,
or talk with us at the gitter chat. or talk with us at #otclient irc.freenode.net
### Bugs ### Bugs
@ -76,7 +59,7 @@ We encourage you to contribute to otclient! You can make pull requests of any im
### Contact ### Contact
Talk directly with us at the gitter chat [![Join the chat at https://gitter.im/edubart/otclient](https://img.shields.io/badge/GITTER-join%20chat-green.svg)](https://gitter.im/edubart/otclient?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge). Talk directly with us at #otclient irc.freenode.net or send an email directly to the project leader edub4rt@gmail.com
### License ### License

Binary file not shown.

Before

Width:  |  Height:  |  Size: 243 B

After

Width:  |  Height:  |  Size: 243 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 373 B

After

Width:  |  Height:  |  Size: 387 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 397 B

After

Width:  |  Height:  |  Size: 444 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 412 B

After

Width:  |  Height:  |  Size: 362 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 418 B

After

Width:  |  Height:  |  Size: 373 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 392 B

After

Width:  |  Height:  |  Size: 397 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 399 B

After

Width:  |  Height:  |  Size: 412 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 400 B

After

Width:  |  Height:  |  Size: 418 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 402 B

After

Width:  |  Height:  |  Size: 399 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 423 B

After

Width:  |  Height:  |  Size: 402 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 387 B

After

Width:  |  Height:  |  Size: 392 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 444 B

After

Width:  |  Height:  |  Size: 400 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 338 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

View File

Before

Width:  |  Height:  |  Size: 283 B

After

Width:  |  Height:  |  Size: 283 B

View File

Before

Width:  |  Height:  |  Size: 283 B

After

Width:  |  Height:  |  Size: 283 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 421 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

View File

@ -4,10 +4,6 @@ locale = {
charset = "cp1252", charset = "cp1252",
languageName = "Deutsch", languageName = "Deutsch",
formatNumbers = true,
decimalSeperator = ',',
thousandsSeperator = ' ',
translation = { translation = {
["1a) Offensive Name"] = false, ["1a) Offensive Name"] = false,
["1b) Invalid Name Format"] = false, ["1b) Invalid Name Format"] = false,
@ -30,7 +26,7 @@ locale = {
["4c) False Report to Gamemaster"] = false, ["4c) False Report to Gamemaster"] = false,
["Accept"] = "Annehmen", ["Accept"] = "Annehmen",
["Account name"] = "Benutzername", ["Account name"] = "Benutzername",
["Account Status"] = false, ["Account Status:"] = false,
["Action:"] = false, ["Action:"] = false,
["Add"] = "Hinzufügen", ["Add"] = "Hinzufügen",
["Add new VIP"] = "Neuen Freund hinzufügen", ["Add new VIP"] = "Neuen Freund hinzufügen",
@ -231,7 +227,7 @@ locale = {
["Pass Leadership to %s"] = "%s zum Anführer ernennen", ["Pass Leadership to %s"] = "%s zum Anführer ernennen",
["Password"] = "Passwort", ["Password"] = "Passwort",
["Piece Price:"] = "Stückpreis", ["Piece Price:"] = "Stückpreis",
["Please enter a character name"] = "Bitte gib einen Charakternamen an", ["Please enter a character name:"] = "Bitte gib einen Charakternamen an:",
["Please, press the key you wish to add onto your hotkeys manager"] = "Bitte die gewünschte Taste drücken", ["Please, press the key you wish to add onto your hotkeys manager"] = "Bitte die gewünschte Taste drücken",
["Please Select"] = false, ["Please Select"] = false,
["Please use this dialog to only report bugs. Do not report rule violations here!"] = false, ["Please use this dialog to only report bugs. Do not report rule violations here!"] = false,

View File

@ -3,10 +3,6 @@ locale = {
charset = "cp1252", charset = "cp1252",
languageName = "English", languageName = "English",
formatNumbers = true,
decimalSeperator = '.',
thousandsSeperator = ',',
-- translations are not needed because everything is already in english -- translations are not needed because everything is already in english
translation = {} translation = {}
} }

View File

@ -7,20 +7,16 @@ locale = {
charset = "cp1252", charset = "cp1252",
languageName = "Español", languageName = "Español",
formatNumbers = true,
decimalSeperator = ',',
thousandsSeperator = '.',
translation = { translation = {
["1a) Offensive Name"] = "1a) Nombre ofensivo", ["1a) Offensive Name"] = "1a) Nombre ofensivo",
["1b) Invalid Name Format"] = "1b) Formato inválido para el nombre", ["1b) Invalid Name Format"] = "1b) Formato invalido para nombre",
["1c) Unsuitable Name"] = "1c) Nombre no adecuado", ["1c) Unsuitable Name"] = "1c) Nombre no adecuado",
["1d) Name Inciting Rule Violation"] = "1d) Nombre que incita una violación al reglamento", ["1d) Name Inciting Rule Violation"] = "1d) Nombre que incita una violación al reglamento",
["2a) Offensive Statement"] = "2a) Comentario ofensivo", ["2a) Offensive Statement"] = "2a) Comentario ofensivo",
["2b) Spamming"] = "2b) Spamming", ["2b) Spamming"] = "2b) Spamming",
["2c) Illegal Advertising"] = "2c) Publicidad ilícita", ["2c) Illegal Advertising"] = "2c) Publicidad ilícita",
["2d) Off-Topic Public Statement"] = "2d) Publicación fuera de lugar", ["2d) Off-Topic Public Statement"] = "2d) Publicación fuera de lugar",
["2e) Non-English Public Statement"] = "2e) Publicación fuera del inglés", ["2e) Non-English Public Statement"] = "2e) Publicación fuera del ingles",
["2f) Inciting Rule Violation"] = "2f) Incitar a una violación al reglamento", ["2f) Inciting Rule Violation"] = "2f) Incitar a una violación al reglamento",
["3a) Bug Abuse"] = "3a) Abuso de error", ["3a) Bug Abuse"] = "3a) Abuso de error",
["3b) Game Weakness Abuse"] = "3b) Abuso de debilidad del juego", ["3b) Game Weakness Abuse"] = "3b) Abuso de debilidad del juego",
@ -28,12 +24,12 @@ locale = {
["3d) Hacking"] = "3d) Hackeo", ["3d) Hacking"] = "3d) Hackeo",
["3e) Multi-Clienting"] = "3e) Uso de múltiples clientes", ["3e) Multi-Clienting"] = "3e) Uso de múltiples clientes",
["3f) Account Trading or Sharing"] = "3f) Intercambio de cuenta", ["3f) Account Trading or Sharing"] = "3f) Intercambio de cuenta",
["4a) Threatening Gamemaster"] = "4a) Amenazar a un Gamemaster", ["4a) Threatening Gamemaster"] = "4a) Amenzar a un Gamemaster",
["4b) Pretending to Have Influence on Rule Enforcement"] = "4b) Pretender tener influencia en una parte del reglamento", ["4b) Pretending to Have Influence on Rule Enforcement"] = "4b) Pretender tener influencia en una parte del reglamento",
["4c) False Report to Gamemaster"] = "4c) Reporte falso a un Gamemaster", ["4c) False Report to Gamemaster"] = "4c) Reporte falso a un Gamemaster",
["Accept"] = "Aceptar", ["Accept"] = "Aceptar",
["Account name"] = "Nombre de la cuenta", ["Account name"] = "Nombre de cuenta",
["Account Status"] = "Estado de la cuenta", ["Account Status:"] = "Estado de cuenta:",
["Action:"] = "Acción:", ["Action:"] = "Acción:",
["Add"] = "Añadir", ["Add"] = "Añadir",
["Add new VIP"] = "Añadir nuevo VIP", ["Add new VIP"] = "Añadir nuevo VIP",
@ -44,14 +40,14 @@ locale = {
["Adjust volume"] = "Ajustar volumen", ["Adjust volume"] = "Ajustar volumen",
["Alas! Brave adventurer, you have met a sad fate.\nBut do not despair, for the gods will bring you back\ninto this world in exchange for a small sacrifice\n\nSimply click on Ok to resume your journeys!"] = "¡Ay! Aventurero valiente, has conocido un triste destino. \nPero no se desespere, porque los dioses te llevarán de vuelta \na este mundo a cambio de un pequeño sacrificio \n\nSimplemente haga clic en Aceptar para continuar con sus viajes!", ["Alas! Brave adventurer, you have met a sad fate.\nBut do not despair, for the gods will bring you back\ninto this world in exchange for a small sacrifice\n\nSimply click on Ok to resume your journeys!"] = "¡Ay! Aventurero valiente, has conocido un triste destino. \nPero no se desespere, porque los dioses te llevarán de vuelta \na este mundo a cambio de un pequeño sacrificio \n\nSimplemente haga clic en Aceptar para continuar con sus viajes!",
["All"] = "Todo", ["All"] = "Todo",
["All modules and scripts were reloaded."] = "Todos los módulos y scripts se volvieron a cargar.", ["All modules and scripts were reloaded."] = "Todos los módulos y scripts se vuelven a cargar.",
["Allow auto chase override"] = "Desactivar auto persecución al andar", ["Allow auto chase override"] = "Permitur auto persecución override",
["Also known as dash in tibia community, recommended\nfor playing characters with high speed"] = "Conocido por la comunidad de tibia como \"dash\".\nRecomenada para jugadores de alto nivel.", ["Also known as dash in tibia community, recommended\nfor playing characters with high speed"] = "Conocido por la comunidad de tibia como dash.\nRecomenada para jugadores de alto nivel.",
["Ambient light: %s%%"] = "Luz de ambiente: %s%%", ["Ambient light: %s%%"] = "Ambiente de luz: %s%%",
["Amount:"] = "Cantidad:", ["Amount:"] = "Cantidad:",
["Amount"] = "Cantidad", ["Amount"] = "Cantidad",
["Anonymous"] = "Anónimo", ["Anonymous"] = "Anónimo",
["Are you sure you want to logout?"] = "¿Estás seguro de que deseas salir?", ["Are you sure you want to logout?"] = "¿Estas seguro de que deseas salir?",
["Attack"] = "Atacar", ["Attack"] = "Atacar",
["Author"] = "Autor", ["Author"] = "Autor",
["Autoload"] = "Auto carga", ["Autoload"] = "Auto carga",
@ -60,26 +56,26 @@ locale = {
["Auto login selected character on next charlist load"] = "Ingresar la siguiente vez que aparece el charlist con el personaje seleccionado", ["Auto login selected character on next charlist load"] = "Ingresar la siguiente vez que aparece el charlist con el personaje seleccionado",
["Axe Fighting"] = "Combate con hacha", ["Axe Fighting"] = "Combate con hacha",
["Balance:"] = "Saldo:", ["Balance:"] = "Saldo:",
["Banishment"] = "Baneo", ["Banishment"] = "Banishment",
["Banishment + Final Warning"] = "Baneo + Último Aviso", ["Banishment + Final Warning"] = "Banishment + Final Warning",
["Battle"] = "Batalla", ["Battle"] = "Batalla",
["Browse"] = "Navegar", ["Browse"] = "Navegar",
["Bug report sent."] = "Reporte de error enviado.", ["Bug report sent."] = "Reporte de error enviado.",
["Button Assign"] = "Asignar botón", ["Button Assign"] = "Botón asignado",
["Buy"] = "Compra", ["Buy"] = "Compra",
["Buy Now"] = "Compra ahora", ["Buy Now"] = "Compra ahora",
["Buy Offers"] = "Comprar ofertas", ["Buy Offers"] = "Comprar oferta",
["Buy with backpack"] = "Comprar con mochila", ["Buy with backpack"] = "Comprar con mochila",
["Cancel"] = "Cancelar", ["Cancel"] = "Cancelar",
["Cannot login while already in game."] = "No se puede iniciar sesión, mientras ya estés en el juego.", ["Cannot login while already in game."] = "No se puede iniciar sesión, mientras que estés en el juego.",
["Cap"] = "Cap", ["Cap"] = "Cap",
["Capacity"] = "Capacidad", ["Capacity"] = "Capacidad",
["Center"] = "Centrar", ["Center"] = "Centrar",
["Channels"] = "Canales", ["Channels"] = "Canales",
["Character List"] = "Lista de caracteres", ["Character List"] = "Lista de carácter",
["Classic control"] = "Controles clásicos", ["Classic control"] = "Controles Clásicos",
["Clear current message window"] = "Limpiar ventana de mensajes actual", ["Clear current message window"] = "Limpiar mensaje actual en ventana",
["Clear Messages"] = "Limpiar mensajes", ["Clear Messages"] = "Limpiar mensaje",
["Clear object"] = "Limpiar objeto", ["Clear object"] = "Limpiar objeto",
["Client needs update."] = "El cliente necesita una actualización.", ["Client needs update."] = "El cliente necesita una actualización.",
["Close"] = "Cerrar", ["Close"] = "Cerrar",
@ -87,10 +83,10 @@ locale = {
["Club Fighting"] = "Combate con mazo", ["Club Fighting"] = "Combate con mazo",
["Combat Controls"] = "Controles de combate", ["Combat Controls"] = "Controles de combate",
["Comment:"] = "Comentario:", ["Comment:"] = "Comentario:",
["Connecting to game server..."] = "Conectando a servidor de juego...", ["Connecting to game server..."] = "Conectando a servidor game...",
["Connecting to login server..."] = "Conectando a servidor de login...", ["Connecting to login server..."] = "Conectando a servidor login...",
["Console"] = "Consola", ["Console"] = "Consola",
["Cooldowns"] = "Enfriamientos", ["Cooldowns"] = "Descansos",
["Copy message"] = "Copiar mensaje", ["Copy message"] = "Copiar mensaje",
["Copy name"] = "Copiar nombre", ["Copy name"] = "Copiar nombre",
["Copy Name"] = "Copiar nombre", ["Copy Name"] = "Copiar nombre",
@ -122,7 +118,7 @@ locale = {
["Enable vertical synchronization"] = "Habilitar sincronización vertical", ["Enable vertical synchronization"] = "Habilitar sincronización vertical",
["Enable walk booster"] = "Habilitar caminado turbo", ["Enable walk booster"] = "Habilitar caminado turbo",
["Enter Game"] = "Entrar al juego", ["Enter Game"] = "Entrar al juego",
["Enter one name per line."] = "Introducir un nombre por línea.", ["Enter one name per line."] = "Introducir un nombre por linea.",
["Enter with your account again to update your client."] = "Ingrese con su cuenta nuevamente para actualizar el cliente.", ["Enter with your account again to update your client."] = "Ingrese con su cuenta nuevamente para actualizar el cliente.",
["Error"] = "Error", ["Error"] = "Error",
["Error"] = "Error", ["Error"] = "Error",
@ -130,18 +126,18 @@ locale = {
["Exclude from private chat"] = "Ejecutar desde un canal privado", ["Exclude from private chat"] = "Ejecutar desde un canal privado",
["Exit"] = "Salir", ["Exit"] = "Salir",
["Experience"] = "Experiencia", ["Experience"] = "Experiencia",
["Filter list to match your level"] = "Filtrar lista para coincidir con el nivel", ["Filter list to match your level"] = "Lista de filtros que coincida con el nivel",
["Filter list to match your vocation"] = "Filtrar lsta para coincidir con la vocación", ["Filter list to match your vocation"] = "Lista de filtros que coincida con el vocación",
["Find:"] = "Encontrar:", ["Find:"] = "Encontrar:",
["Fishing"] = "Pesca", ["Fishing"] = "Pesca",
["Fist Fighting"] = "Combate a puños", ["Fist Fighting"] = "Combate con puños",
["Follow"] = "Seguir", ["Follow"] = "Seguir",
["Force Exit"] = "Forzar Salir", -- "Forzar Salida" is almost too big for a button ["Force Exit"] = "Forzar salida",
["For Your Information"] = "Para tu información", ["For Your Information"] = "Para tu información",
["Free Account"] = "Cuenta gratis", ["Free Account"] = "Cuenta gratis",
["Fullscreen"] = "Pantalla completa", ["Fullscreen"] = "Pantalla completa",
["Game"] = "Juego", ["Game"] = "Juego",
["Game framerate limit: %s"] = "Límite de cuadros por segundo en el juego: %s", ["Game framerate limit: %s"] = "Limite de cuadros por segundo en el juego: %s",
["Graphics"] = "Gráficos", ["Graphics"] = "Gráficos",
["Graphics card driver not detected"] = "Controlador de tarjeta gráfica de video no detectado", ["Graphics card driver not detected"] = "Controlador de tarjeta gráfica de video no detectado",
["Graphics Engine:"] = "Motor Gráfico:", ["Graphics Engine:"] = "Motor Gráfico:",
@ -155,32 +151,32 @@ locale = {
["Hide Offline"] = "Ocultar fuera de linea", ["Hide Offline"] = "Ocultar fuera de linea",
["Hide party members"] = "Ocultar miembros del party", ["Hide party members"] = "Ocultar miembros del party",
["Hide players"] = "Ocultar players", ["Hide players"] = "Ocultar players",
["Hide spells for higher exp. levels"] = "Ocultar hechizos para niveles más altos que tu experiencia.", ["Hide spells for higher exp. levels"] = "Ocultar hechizos para niveles mas altos que tu experiencia.",
["Hide spells for other vocations"] = "Ocultar hechizos que sean para otra vocación", ["Hide spells for other vocations"] = "Ocultar hechizos que sean para otra vocación",
["Hit Points"] = "Puntos de vida", ["Hit Points"] = "Puntos de vida",
["Hold left mouse button to navigate\nScroll mouse middle button to zoom\nRight mouse button to create map marks"] = "Mantenga presionado el botón derecho del ratón para navegar\nDesplace la rueda central del ratón para ampliar\nbotón derecho del ratón para crear marcas del mapa", ["Hold left mouse button to navigate\nScroll mouse middle button to zoom\nRight mouse button to create map marks"] = "Mantenga presionado el botón derecho del ratón para navegar\nDezplaze la rueda central del ratón para ampliar\nbotón derecho del mouse para crear marcas del mapa",
["Hotkeys"] = "Hotkeys", ["Hotkeys"] = "Hotkeys",
["If you shut down the program, your character might stay in the game.\nClick on 'Logout' to ensure that you character leaves the game properly.\nClick on 'Exit' if you want to exit the program without logging out your character."] = "Si se cierra el programa, su personaje puede permanecer en el juego.\nHaga clic en 'Desconectar' para asegurarse de que el personaje deja el juego correctamente.\nHaga clic en 'Forzar Salir' si desea salir del programa igualmente, pudiendo mantener el personaje en el juego.", ["If you shut down the program, your character might stay in the game.\nClick on 'Logout' to ensure that you character leaves the game properly.\nClick on 'Exit' if you want to exit the program without logging out your character."] = "Si se cierra el programa, tu personaje puede permanecer en el juego.\nHaga clic en 'Salir' para asegurarse de que personaje deja el juego correctamente.\nHaga click en 'Salir' si desea salir del programa sin tener que salir de tu personaje.",
["Ignore"] = "Ignorar", ["Ignore"] = "Ignorar",
["Ignore capacity"] = "Ignorar capacidad", ["Ignore capacity"] = "Ignorar Capacidad",
["Ignored players:"] = "Jugadores ignorados:", ["Ignored players:"] = "Jugadores ignorados:",
["Ignore equipped"] = "Ignorar lo equipado", ["Ignore equipped"] = "Ignorar lo equipado",
["Ignore List"] = "Ignorar lista", ["Ignore List"] = "Ignorar lista",
["Ignore players"] = "Ignorar jugadores", ["Ignore players"] = "Ignorar jugadores",
["Ignore Private Messages"] = "Ignorar mensajes privados", ["Ignore Private Messages"] = "Ignorar mensajes privados",
["Ignore Yelling"] = "Ignorar gritos", ["Ignore Yelling"] = "Ignorar gritos",
["Interface framerate limit: %s"] = "Interfaz de cuadros por segundo: %s", ["Interface framerate limit: %s"] = "Interface de cuadros por segundo: %s",
["Inventory"] = "Inventario", ["Inventory"] = "Inventario",
["Invite to Party"] = "Invitar a party", ["Invite to Party"] = "Ivitar al party",
["Invite to private chat"] = "Invitar a canal privado", ["Invite to private chat"] = "Invitar a canal privado",
["IP Address Banishment"] = "Dirección IP Baneada", ["IP Address Banishment"] = "Banishment - Dirección IP",
["Item Offers"] = "Ofertas de objetos", ["Item Offers"] = "Ofertas de objetos",
["It is empty."] = "Está vacío.", ["It is empty."] = "Está vac.",
["Join %s\'s Party"] = "Unirse al party de %s", ["Join %s\'s Party"] = "Unirse al party de %s ",
["Leave Party"] = "Dejar el party", ["Leave Party"] = "Dejar el party",
["Level"] = "Nivel", ["Level"] = "Nivel",
["Lifetime Premium Account"] = "Tiempo de Premium Account infinito", ["Lifetime Premium Account"] = "Tiempo de Premium Account infinito",
["Limits FPS to 60"] = "Límites FPS a 60", ["Limits FPS to 60"] = "Limites FPS a 60",
["List of items that you're able to buy"] = "Lista de objetos que puedes de comprar", ["List of items that you're able to buy"] = "Lista de objetos que puedes de comprar",
["List of items that you're able to sell"] = "Lista de objetos que puedes de vender", ["List of items that you're able to sell"] = "Lista de objetos que puedes de vender",
["Load"] = "Cargar", ["Load"] = "Cargar",
@ -188,44 +184,44 @@ locale = {
["Login"] = "Ingresar", ["Login"] = "Ingresar",
["Login Error"] = "Error de ingreso", ["Login Error"] = "Error de ingreso",
["Login Error"] = "Error de ingreso", ["Login Error"] = "Error de ingreso",
["Logout"] = "Desconectar", ["Logout"] = "Salir",
["Look"] = "Mirar", ["Look"] = "Mirar",
["Magic Level"] = "Nivel mágico", ["Magic Level"] = "Nivel mágico",
["Make sure that your client uses\nthe correct game protocol version"] = "Asegúrese de que el cliente este utilizando\nla versión del protocolo correcta", ["Make sure that your client uses\nthe correct game protocol version"] = "Asegúrese de que el cliente este utilizando\nes el versión del protocolo adecuado",
["Mana"] = "Mana", ["Mana"] = "Mana",
["Manage hotkeys:"] = "Administrador de hotkeys:", ["Manage hotkeys:"] = "Administrador de hotkeys:",
["Market"] = "Mercado", ["Market"] = "Mercado",
["Market Offers"] = "Ofertas del mercado", ["Market Offers"] = "Ofertas en mercado",
["Message of the day"] = "Mensaje del día", ["Message of the day"] = "Mensaje del día",
["Message to "] = "Mensaje a ", ["Message to "] = "Mensaje a",
["Message to %s"] = "Mensaje a %s", ["Message to %s"] = "Mensaje a %s",
["Minimap"] = "Minimapa", ["Minimap"] = "Minimapa",
["Module Manager"] = "Administrador de módulos", ["Module Manager"] = "Administrador de módulos",
["Module name"] = "Nombre del módulo", ["Module name"] = "Nombre del modulo",
["Mount"] = "Montar", --"Montura" if it doesn't refers to the verb ["Mount"] = "Montar", --Unique name?
["Move Stackable Item"] = "Mover objeto apilable", ["Move Stackable Item"] = "Mover objeto apilable",
["Move up"] = "Mover arriba", ["Move up"] = "Mover arriba",
["My Offers"] = "Mis ofertas", ["My Offers"] = "Mis ofertas",
["Name:"] = "Nombre:", ["Name:"] = "Nombre:",
["Name Report"] = "Reportar nombre", ["Name Report"] = "Name Report",
["Name Report + Banishment"] = "Reportar nombre + Baneo", ["Name Report + Banishment"] = "Name Report + Banishment",
["Name Report + Banishment + Final Warning"] = "Reportar nombre + Baneo + Último Aviso", ["Name Report + Banishment + Final Warning"] = "Name Report + Banishment + Final Warning",
["No"] = "No", ["No"] = "No",
["No graphics card detected, everything will be drawn using the CPU,\nthus the performance will be really bad.\nPlease update your graphics driver to have a better performance."] = "No se ha detectado una tarjeta gráfica y todo sera procesado por tu procesador,\npor lo tanto el rendimiento va a ser muy malo.\nPor favor, actualice su controlador de la gráfica para tener un rendimiento óptimo.", ["No graphics card detected, everything will be drawn using the CPU,\nthus the performance will be really bad.\nPlease update your graphics driver to have a better performance."] = "No se ha detectado una tarjeta gráfica y todo sera procesado por tu procesador,\npor lo tanto el rendimiento va a ser muy malo.\nPor favor, actualice su controlador de gráficos para tener un rendimiento optimo.",
["No item selected."] = "No hay elemento seleccionado.", ["No item selected."] = "No hay elemento seleccionado.",
["No Mount"] = "No montura", --probably "Sin" instead of "No" is more fitting? ["No Mount"] = "No montura",
["No Outfit"] = "No outfit", ["No Outfit"] = "No outfit",
["No statement has been selected."] = "No se ha seleccionado ningún comentario.", ["No statement has been selected."] = "No hay comentario seleccionado.",
["Notation"] = "Notación", ["Notation"] = "Notation",
["NPC Trade"] = "Intercambio con NPC", ["NPC Trade"] = "Intercambio con NPC",
["Offer History"] = "Historial de ofertas", ["Offer History"] = "Historial de oferta",
["Offers"] = "Ofertas", ["Offers"] = "Ofertas",
["Offer Type:"] = "Tipo de oferta:", ["Offer Type:"] = "Tipo de oferta:",
["Offline Training"] = "Entrenamiento offLine", ["Offline Training"] = "Entrenamiento offLine",
["Ok"] = "OK", ["Ok"] = "OK",
["on %s.\n"] = "en %s.\n", ["on %s.\n"] = "en %s.\n",
["Open"] = "Abrir", ["Open"] = "Abierto",
["Open a private message channel:"] = "Abrir canal privado:", ["Open a private message channel:"] = "Abrir mensaje en canal privado:",
["Open charlist automatically when starting client"] = "Abrir lista de jugadores automáticamente al iniciar el cliente", ["Open charlist automatically when starting client"] = "Abrir lista de jugadores automáticamente al iniciar el cliente",
["Open in new window"] = "Abrir en nueva ventana", ["Open in new window"] = "Abrir en nueva ventana",
["Open new channel"] = "Abrir nuevo canal", ["Open new channel"] = "Abrir nuevo canal",
@ -234,21 +230,21 @@ locale = {
["Pass Leadership to %s"] = "Pasar liderazgo a %s", ["Pass Leadership to %s"] = "Pasar liderazgo a %s",
["Password"] = "Contraseña", ["Password"] = "Contraseña",
["Piece Price:"] = "Precio por pieza:", ["Piece Price:"] = "Precio por pieza:",
["Please enter a character name"] = "Por favor ingresa nombre del jugador", ["Please enter a character name:"] = "Por favor ingresar nombre del jugador:",
["Please, press the key you wish to add onto your hotkeys manager"] = "Por favor, presiona la tecla que desees para que sea registrada en\nel administrador de hotkeys", ["Please, press the key you wish to add onto your hotkeys manager"] = "Por favor, presiona la tecla que desees para que sea registrada en\nel administrador de hotkeys",
["Please Select"] = "Por favor seleccione", ["Please Select"] = "Por favor seleccione",
["Please use this dialog to only report bugs. Do not report rule violations here!"] = "Por favor usa este diálogo sólo para reportar errores.\n¡No reportar violaciones del reglamento aquí!", ["Please use this dialog to only report bugs. Do not report rule violations here!"] = "Por favor usa este diálogo solo para reportar errores.\n¡No reportar violaciones del reglamento aquí!",
["Please wait"] = "Por favor espere", ["Please wait"] = "Por favor espere",
["Port"] = "Puerto", ["Port"] = "Puerto",
["Position:"] = "Posición:", ["Position:"] = "Posición:",
["Position: %i %i %i"] = "Posición: %i %i %i", ["Position: %i %i %i"] = "Posición: %i %i %i",
["Premium Account (%s) days left"] = "Quedan (%s) días de Premium Account", ["Premium Account (%s) days left"] = "Tienes (%s) días de Premium Account restantes",
["Price:"] = "Precio:", ["Price:"] = "Precio:",
["Primary"] = "Primario", ["Primary"] = "Primario",
["Protocol"] = "Protocolo", ["Protocol"] = "Protocolo",
["Quest Log"] = "Quest Log", --Unique name ["Quest Log"] = "Quest Log", --Unique name
["Randomize"] = "Aleatorio", ["Randomize"] = "Combinar",
["Randomize characters outfit"] = "Crear vestimenta del jugador aleatoriamente", ["Randomize characters outfit"] = "Combinar vestimenta del jugador",
["Reason:"] = "Razón:", ["Reason:"] = "Razón:",
["Refresh"] = "Refrescar", ["Refresh"] = "Refrescar",
["Refresh Offers"] = "Refrescar ofertas", ["Refresh Offers"] = "Refrescar ofertas",
@ -257,10 +253,10 @@ locale = {
["Reload All"] = "Cargar todo de nuevo", ["Reload All"] = "Cargar todo de nuevo",
["Remember account and password when starts client"] = "Recordar cuenta y contraseña al iniciar el cliente", ["Remember account and password when starts client"] = "Recordar cuenta y contraseña al iniciar el cliente",
["Remember password"] = "Recordar contraseña", ["Remember password"] = "Recordar contraseña",
["Remove"] = "Eliminar", ["Remove"] = "Remover",
["Remove %s"] = "Eliminar %s", ["Remove %s"] = "Remover %s",
["Report Bug"] = "Reportar error", ["Report Bug"] = "Reportar error",
["Reserved for more functionality later."] = "Reservado para una funcionalidad futura.", ["Reserved for more functionality later."] = "Reservado para una función futura.",
["Reset Market"] = "Reiniciar mercado", ["Reset Market"] = "Reiniciar mercado",
["Revoke %s\'s Invitation"] = "Anular %s\'s invitación", ["Revoke %s\'s Invitation"] = "Anular %s\'s invitación",
["Rotate"] = "Rotar", ["Rotate"] = "Rotar",
@ -272,7 +268,7 @@ locale = {
["Secondary"] = "Secundario", ["Secondary"] = "Secundario",
["Select object"] = "Seleccionar objeto", ["Select object"] = "Seleccionar objeto",
["Select Outfit"] = "Seleccionar outfit", ["Select Outfit"] = "Seleccionar outfit",
["Select your language"] = "Seleccionar tu idioma", ["Select your language"] = "Selectionar tu lenguaje",
["Sell"] = "Vender", ["Sell"] = "Vender",
["Sell Now"] = "Vender ahora", ["Sell Now"] = "Vender ahora",
["Sell Offers"] = "Ofertas de venta", ["Sell Offers"] = "Ofertas de venta",
@ -300,85 +296,82 @@ locale = {
["Show timestamps in console"] = "Mostrar marcas de tiempo en consola", ["Show timestamps in console"] = "Mostrar marcas de tiempo en consola",
["Show your depot items only"] = "Mostrar solo tus objetos en depot", ["Show your depot items only"] = "Mostrar solo tus objetos en depot",
["Skills"] = "Habilidades", ["Skills"] = "Habilidades",
["Sort by name"] = "Ordenar por nombre", ["Soul"] = "Soul",
["Sort by status"] = "Ordenar por estado", ["Soul Points"] = "Puntos de Soul", --I'm leaving these as is because its a unique name, if you want to change it it can be "Alma" or "Espíritu"
["Sort by type"] = "Ordernar por tipo",
["Soul"] = "Soul", --I'm leaving these as is because its a unique name, if you want to change it it can be "Alma" or "Espíritu"
["Soul Points"] = "Puntos de Soul",
["Special"] = "Especial", ["Special"] = "Especial",
["Speed"] = "Velocidad", ["Speed"] = "Velocidad",
["Spell Cooldowns"] = "Enfriamiento de hechizos", --Should 'spells'? be an unique name? ["Spell Cooldowns"] = "Spells Cooldowns", --Could be "Tiempo de recarga para los hechizos".
["Spell List"] = "Lista de hechizos", ["Spell List"] = "Lista de hechizos",
["Stamina"] = "Resistencia", ["Stamina"] = "Resistencia",
["Statement:"] = "Comentario:", ["Statement:"] = "Comentario:",
["Statement Report"] = "Statement Report", --Could be "reporte del comentario"/Not sure how to translate it correctly.. When is it used in the game? ["Statement Report"] = "Statement Report", --Could be "reporte del comentario"
["Statistics"] = "Estadísticas", ["Statistics"] = "Estadísticas",
["Stop Attack"] = "Detener ataque", ["Stop Attack"] = "Detener ataque",
["Stop Follow"] = "Detener persecución", ["Stop Follow"] = "Detener persecución",
["Support"] = "Soporte", ["Support"] = "Soporte",
["%s: (use object)"] = "%s: (usar objeto)", ["%s: (use object)"] = "%s: (usar objeto)",
["%s: (use object on target)"] = "%s: (usar objeto en un objetivo)", ["%s: (use object on target)"] = "%s: (usar objeto en un objetivo)",
["%s: (use object on yourself)"] = "%s: (usar objeto en ti mismo)", ["%s: (use object on yourself)"] = "%s: (usar objeto en mi mismo)",
["%s: (use object with crosshair)"] = "%s: (usar objeto con punto de mira)", ["%s: (use object with crosshair)"] = "%s: (usar objeto con punto de mira)",
["Sword Fighting"] = "Combate con espada", ["Sword Fighting"] = "Combate de espada",
["Terminal"] = "Terminal", ["Terminal"] = "Terminal",
["There is no way."] = "No hay forma de llegar.", ["There is no way."] = "No hay ninguna manera.",
["Title"] = "Título", ["Title"] = "Titulo",
["Total Price:"] = "Precio total:", ["Total Price:"] = "Total total:",
["Trade"] = "Intercambio", ["Trade"] = "Intercambio",
["Trade with ..."] = "Intercambiar con ...", ["Trade with ..."] = "Intercambiar con ...",
["Trying to reconnect in %s seconds."] = "Intentando reconectar en %s segundos.", ["Trying to reconnect in %s seconds."] = "",
["Unable to load dat file, please place a valid dat in '%s'"] = "No se puede cargar el archivo dat, por favor coloque un dat válido en '%s'", ["Unable to load dat file, please place a valid dat in '%s'"] = "No se puede cargar el archivo dat, por favor coloque un dat válido en '%s'",
["Unable to load spr file, please place a valid spr in '%s'"] = "No se puede cargar el archivo spr, por favor coloque un spr válido en '%s'", ["Unable to load spr file, please place a valid spr in '%s'"] = "No se puede cargar el archivo spr, por favor coloque un spr válido en '%s'",
["Unable to logout."] = "No se puede cerrar sesión.", ["Unable to logout."] = "No se puede cerrar sesión-",
["Unignore"] = "Dejar de ignorar", ["Unignore"] = "Dejar de ignorar",
["Unload"] = "Desactivar", -- Should be "Descargar", but not used to prevent misunderstandings with "Download". ["Unload"] = "No cargado",
["Update needed"] = "Es necesario actualizar", ["Update needed"] = "Es necesario actualizar",
["Use"] = "Usar", ["Use"] = "Uso",
["Use on target"] = "Usar en un objetivo", ["Use on target"] = "Usar en un objetivo",
["Use on yourself"] = "Usar en mi mismo", ["Use on yourself"] = "Usar en mi mismo",
["Use with ..."] = "Usar en ...", ["Use with ..."] = "Usar en ...",
["Version"] = "Versión", ["Version"] = "Versión",
["VIP List"] = "Lista VIP", ["VIP List"] = "Lista Vip",
["Voc."] = "Voc.", ["Voc."] = "Voc.",
["Vocation"] = "Vocación", ["Vocation"] = "Vocación",
["Waiting List"] = "Lista de espera", ["Waiting List"] = "Lista de espera",
["Website"] = "Sitio Web", ["Website"] = "Sitio Web",
["Weight:"] = "Peso:", ["Weight:"] = "Peso:",
["Will detect when to use diagonal step based on the\nkeys you are pressing"] = "Detectará cuando caminar en diagonal en base\n a las teclas pulsadas", ["Will detect when to use diagonal step based on the\nkeys you are pressing"] = "Detectara cuando se camina en diagonal usando las flechas",
["With crosshair"] = "Con punto de mira", ["With crosshair"] = "Con punto de mira",
["Yes"] = "Sí", ["Yes"] = "Si",
["You are bleeding"] = "Te estás desangrando", ["You are bleeding"] = "Te estas desangrando",
["You are burning"] = "Te estás quemando", ["You are burning"] = "Te estas quemando",
["You are cursed"] = "Estás maldecido", ["You are cursed"] = "Tu estas maldecido",
["You are dazzled"] = "Estás deslumbrado", ["You are dazzled"] = "Tu estas deslumbrado",
["You are dead."] = "Has muerto.", ["You are dead."] = "Tu estas muerto.",
["You are dead"] = "Has muerto", ["You are dead"] = "Tu estas muerto",
["You are drowning"] = "Te estás ahogando", ["You are drowning"] = "Te estas ahogando",
["You are drunk"] = "Estás ebrio", ["You are drunk"] = "Tu estas ebrio",
["You are electrified"] = "Estás electrocutado", ["You are electrified"] = "Tu estas electrocutado",
["You are freezing"] = "Te estás congelando", ["You are freezing"] = "Te estas congelando",
["You are hasted"] = "Tienes la velocidad incrementada", --The best translation I could thing of ("You have increased speed") ["You are hasted"] = "Tu estas rápido", --I dont know what is the best way to translate this so I'm leaving it as I found it.
["You are hungry"] = "Tienes hambre", ["You are hungry"] = "Tu estas hambriento",
["You are paralysed"] = "Estás paralizado", ["You are paralysed"] = "Tu estas paralizado",
["You are poisoned"] = "Estás envenedado", ["You are poisoned"] = "Tu estas envenedado",
["You are protected by a magic shield"] = "Estás protegido por un escudo mágico", ["You are protected by a magic shield"] = "Tu estas protegido por un escudo mágico",
["You are strengthened"] = "Estás reforzado", --"fortificado" maybe? ["You are strengthened"] = "Tu estas reforzado",
["You are within a protection zone"] = "Estás dentro de una zona de protección", ["You are within a protection zone"] = "Tu estas dentro de una zona de protección",
["You can enter new text."] = "Puedes escribir texto nuevo.", ["You can enter new text."] = "Tu puedes ingresar un texto nuevo.",
["You have %s percent"] = "Tienes el %s por ciento", ["You have %s percent"] = "Tu tienes %s por ciento",
["You have %s percent to go"] = "Tienes el %s por ciento para avanzar", ["You have %s percent to go"] = "Tu tienes %s por ciento para ir",
["You may not logout during a fight"] = "No te puedes desconectar durante una pelea", ["You may not logout during a fight"] = "No puedes salir durante una pelea",
["You may not logout or enter a protection zone"] = "No te puedes desconectar o entrar en una zona de protección", ["You may not logout or enter a protection zone"] = "No puedes salir o entrar en una zona de protección",
["You must enter a comment."] = "Debes escribir un comentario.", ["You must enter a comment."] = "Debes ingresar un comentario.",
["You must enter a valid server address and port."] = "Debes ingresar una dirección válida de servidor y el puerto.", ["You must enter a valid server address and port."] = "Debes ingresar una dirección válida de servidor y el puerto.",
["You must select a character to login!"] = "¡Debes seleccionar un personaje para ingresar!", -- I would use "conectarte" but it's Ok ["You must select a character to login!"] = "¡Debes seleccionar un personaje para ingresar!",
["Your Capacity:"] = "Tu capacidad:", ["Your Capacity:"] = "Tu capacidad:",
["You read the following, written by \n%s\n"] = "Lees lo siguiente, escrito por \n%s\n", ["You read the following, written by \n%s\n"] = "Lees lo siguiente, escrito por \n%s\n",
["You read the following, written on \n%s.\n"] = "Lees lo siguiente, escrito en \n%s\n", ["You read the following, written on \n%s.\n"] = "Lees lo siguiente, escrito en \n%s\n",
["Your Money:"] = "Tu dinero:", ["Your Money:"] = "Tu dinero:",
["Change language"] = "Cambiar idioma", ["Change language"] = "Cambiar idioma",
["Don't stretch or shrink Game Window"] = "No estirar ni encoger la ventana de juego" ["Don't stretch or shrink Game Window"] = "No estirar o encoger Ventana de Juego"
} }
} }

View File

@ -2,10 +2,6 @@ locale = {
name = "pl", name = "pl",
languageName = "Polski", languageName = "Polski",
formatNumbers = true,
decimalSeperator = '.',
thousandsSeperator = ' ',
translation = { translation = {
["1a) Offensive Name"] = "1a) Obrazliwe Imie", ["1a) Offensive Name"] = "1a) Obrazliwe Imie",
["1b) Invalid Name Format"] = "1b) Niepoprawny Format Imienia", ["1b) Invalid Name Format"] = "1b) Niepoprawny Format Imienia",
@ -28,7 +24,7 @@ locale = {
["4c) False Report to Gamemaster"] = "4c) Wyslanie Falszywego Raportu Mistrzowi Gry", ["4c) False Report to Gamemaster"] = "4c) Wyslanie Falszywego Raportu Mistrzowi Gry",
["Accept"] = "Akceptuj", ["Accept"] = "Akceptuj",
["Account name"] = "Numer konta", ["Account name"] = "Numer konta",
["Account Status"] = "Status Konta", ["Account Status:"] = "Status Konta:",
["Action:"] = "Akcja:", ["Action:"] = "Akcja:",
["Add"] = "Dodaj", ["Add"] = "Dodaj",
["Add new VIP"] = "Nowy VIP", ["Add new VIP"] = "Nowy VIP",
@ -228,7 +224,7 @@ locale = {
["Pass Leadership to %s"] = "Oddaj przywodztwo %s", ["Pass Leadership to %s"] = "Oddaj przywodztwo %s",
["Password"] = "Haslo", ["Password"] = "Haslo",
["Piece Price:"] = "Cena jednego przedmiotu", ["Piece Price:"] = "Cena jednego przedmiotu",
["Please enter a character name"] = "Podaj nazwe postaci", ["Please enter a character name:"] = "Podaj nazwe postaci:",
["Please, press the key you wish to add onto your hotkeys manager"] = "Nacisnij klawisz, ktory chcesz dodac do menedzera skrotow klawiszowych", ["Please, press the key you wish to add onto your hotkeys manager"] = "Nacisnij klawisz, ktory chcesz dodac do menedzera skrotow klawiszowych",
["Please Select"] = "Prosze wybrac", ["Please Select"] = "Prosze wybrac",
["Please use this dialog to only report bugs. Do not report rule violations here!"] = "Zglaszaj tylko bledy gry, nie lamanie zasad", ["Please use this dialog to only report bugs. Do not report rule violations here!"] = "Zglaszaj tylko bledy gry, nie lamanie zasad",
@ -295,7 +291,7 @@ locale = {
["Show your depot items only"] = "Pokaz tylko przedmioty z depozytu", ["Show your depot items only"] = "Pokaz tylko przedmioty z depozytu",
["Skills"] = "Umiejetnosci", ["Skills"] = "Umiejetnosci",
["Soul"] = "Dusze", ["Soul"] = "Dusze",
["Soul Points"] = "Punkty Duszy", ["Soul Points"] = "Punktey Duszy",
["Special"] = "Specialne", ["Special"] = "Specialne",
["Speed"] = "Predkosc", ["Speed"] = "Predkosc",
["Spell Cooldowns"] = "Czas odnowienia czaru", ["Spell Cooldowns"] = "Czas odnowienia czaru",

View File

@ -3,22 +3,14 @@ locale = {
charset = "cp1252", charset = "cp1252",
languageName = "Português", languageName = "Português",
formatNumbers = true,
decimalSeperator = ',',
thousandsSeperator = '.',
-- As traduções devem vir sempre em ordem alfabética. -- As traduções devem vir sempre em ordem alfabética.
translation = { translation = {
["%d of experience per hour"] = "%d de experiência por hora", ["%d of experience per hour"] = "%d de experiência por hora",
["%s has finished the request"] = "%s finalizou o pedido",
["%s has logged in."] = "%s entrou.",
["%s has logged out."] = "%s saiu.",
["%s of experience left"] = "%s de experiência faltando", ["%s of experience left"] = "%s de experiência faltando",
["%s: (use object on target)"] = "%s: (usar objeto no alvo)", ["%s: (use object on target)"] = "%s: (usar objeto no alvo)",
["%s: (use object on yourself)"] = "%s: (usar objeto em si)", ["%s: (use object on yourself)"] = "%s: (usar objeto em si)",
["%s: (use object with crosshair)"] = "%s: (usar objeto com mira)", ["%s: (use object with crosshair)"] = "%s: (usar objeto com mira)",
["%s: (use object)"] = "%s: (usar objeto)", ["%s: (use object)"] = "%s: (usar objeto)",
["(ERROR %d)"] = "(ERRO %d)",
["1a) Offensive Name"] = "1a) Nome ofensivo", ["1a) Offensive Name"] = "1a) Nome ofensivo",
["1b) Invalid Name Format"] = "1b) Nome com formato inválido", ["1b) Invalid Name Format"] = "1b) Nome com formato inválido",
["1c) Unsuitable Name"] = "1c) Nome não adequado", ["1c) Unsuitable Name"] = "1c) Nome não adequado",
@ -42,8 +34,6 @@ locale = {
["Account name"] = "Nome da conta", ["Account name"] = "Nome da conta",
["Account Status"] = "Estado da Conta", ["Account Status"] = "Estado da Conta",
["Action"] = "Ação", ["Action"] = "Ação",
["Activate ignorelist"] = "Ativar lista ignorada",
["Activate whitelist"] = "Ativar lista branca",
["Add new server"] = "Adicionar novo servidor", ["Add new server"] = "Adicionar novo servidor",
["Add new VIP"] = "Adicionar nova VIP", ["Add new VIP"] = "Adicionar nova VIP",
["Add to VIP list"] = "Adicionar a lista VIP", ["Add to VIP list"] = "Adicionar a lista VIP",
@ -52,18 +42,17 @@ locale = {
["Addon 2"] = "Addon 2", ["Addon 2"] = "Addon 2",
["Addon 3"] = "Addon 3", ["Addon 3"] = "Addon 3",
["Adjust volume"] = "Ajustar volume", ["Adjust volume"] = "Ajustar volume",
["Alas! Brave adventurer, you have met a sad fate.\nBut do not despair, for the gods will bring you back\ninto this world in exchange for a small sacrifice\n\nSimply click on Ok to resume your journeys!"] = false,
["All modules and scripts were reloaded."] = "Todos módulos e scripts foram recarregados.", ["All modules and scripts were reloaded."] = "Todos módulos e scripts foram recarregados.",
["All"] = "Todos", ["All"] = "Todos",
["Allow auto chase override"] = "Permitir sobrescrever o modo de perseguição", ["Allow auto chase override"] = "Permitir sobrescrever o modo de perseguição",
["Allow VIPs to message you"] = "Permitir que VIPs te mandem mensagem",
["Allowed Players"] = "Jogadores com permissão",
["Also known as dash in tibia community, recommended\nfor playing characters with high speed"] = "Também conhecido como dash na comunidade tibiana, recomendado\npara jogar com personagem que possuam velocidade alta", ["Also known as dash in tibia community, recommended\nfor playing characters with high speed"] = "Também conhecido como dash na comunidade tibiana, recomendado\npara jogar com personagem que possuam velocidade alta",
["Ambient light: %s%%"] = "Luz ambiente: %s%%", ["Ambient light: %s%%"] = "Luz ambiente: %s%%",
["Amount"] = "Quantidade", ["Amount"] = "Quantidade",
["Anonymous"] = "Anônimo", ["Anonymous"] = "Anônimo",
["Any"] = "Qualquer", ["Any"] = "Qualquer",
["Are you sure you want to logout?"] = "Você tem certeza que quer sair?",
["Attack"] = "Atacar", ["Attack"] = "Atacar",
["Auction End"] = "Fim do Leilão",
["Audio"] = "Áudio", ["Audio"] = "Áudio",
["Author"] = "Autor", ["Author"] = "Autor",
["Auto login selected character on next charlist load"] = "Entrar automaticamente com o personagem quando reabrir a lista de personagens", ["Auto login selected character on next charlist load"] = "Entrar automaticamente com o personagem quando reabrir a lista de personagens",
@ -75,7 +64,6 @@ locale = {
["Banishment + Final Warning"] = "Banimento + Aviso final", ["Banishment + Final Warning"] = "Banimento + Aviso final",
["Banishment"] = "Banimento", ["Banishment"] = "Banimento",
["Battle"] = "Batalha", ["Battle"] = "Batalha",
["Browse Field"] = "Navegar Campo",
["Browse"] = "Navegar", ["Browse"] = "Navegar",
["Bug report sent."] = "Reporte de bug enviado.", ["Bug report sent."] = "Reporte de bug enviado.",
["Button Assign"] = "Selecionar botão", ["Button Assign"] = "Selecionar botão",
@ -83,14 +71,12 @@ locale = {
["Buy Offers"] = "Ofertas de compra", ["Buy Offers"] = "Ofertas de compra",
["Buy with backpack"] = "Comprar com mochila", ["Buy with backpack"] = "Comprar com mochila",
["Buy"] = "Comprar", ["Buy"] = "Comprar",
["Buyer Name"] = "Nome do Comprador",
["Cancel"] = "Cancelar", ["Cancel"] = "Cancelar",
["Cannot login while already in game."] = "Não é possivel logar enquanto já estiver jogando.", ["Cannot login while already in game."] = "Não é possivel logar enquanto já estiver jogando.",
["Cap"] = "Cap", ["Cap"] = "Cap",
["Capacity"] = "Capacidade", ["Capacity"] = "Capacidade",
["Center"] = "Centro", ["Center"] = "Centro",
["Change language"] = "Trocar língua", ["Change language"] = "Trocar língua",
["Channel appended to %s"] = "Canais acrescentados a %s",
["Channels"] = "Canais", ["Channels"] = "Canais",
["Character List"] = "Lista de personagens", ["Character List"] = "Lista de personagens",
["Classic control"] = "Controle clássico", ["Classic control"] = "Controle clássico",
@ -98,7 +84,6 @@ locale = {
["Clear Messages"] = "Limpar mensagens", ["Clear Messages"] = "Limpar mensagens",
["Clear object"] = "Limpar objeto", ["Clear object"] = "Limpar objeto",
["Client needs update."] = "O client do jogo precisa ser atualizado", ["Client needs update."] = "O client do jogo precisa ser atualizado",
["Client Version"] = "Versão do Client",
["Close this channel"] = "Fechar esse canal", ["Close this channel"] = "Fechar esse canal",
["Close"] = "Fechar", ["Close"] = "Fechar",
["Club Fighting"] = "Combate com Porrete", ["Club Fighting"] = "Combate com Porrete",
@ -107,44 +92,35 @@ locale = {
["Connecting to game server..."] = "Conectando no servidor do jogo...", ["Connecting to game server..."] = "Conectando no servidor do jogo...",
["Connecting to login server..."] = "Conectando no servidor de autenticação...", ["Connecting to login server..."] = "Conectando no servidor de autenticação...",
["Connection Error"] = "Erro de Conexão", ["Connection Error"] = "Erro de Conexão",
["Connection failed the server address does not exist."] = "Conexão falhou, servidor não existe.",
["Connection failed."] = "Conexão falhou.",
["Connection refused the server might be offline or restarting.\nPlease try again later."] = "Conexão recusada, servidor pode estar offline ou reiniciando. Por favor, tente novamente mais tarde.",
["Connection timed out. Either your network is failing or the server is offline."] = "Conexão encerrada por tempo limite. Sua rede está falhando, ou o servidor está offline.",
["Console"] = "Console", ["Console"] = "Console",
["Cooldown"] = "Cooldown", ["Cooldown"] = "Cooldown",
["Cooldowns"] = "Cooldowns", ["Cooldowns"] = "Cooldowns",
["Copy message"] = "Copiar mensagem", ["Copy message"] = "Copiar mensagem",
["Copy name"] = "Copiar nome", ["Copy name"] = "Copiar nome",
["Copy Name"] = "Copiar Nome", ["Copy Name"] = "Copiar Nome",
["Copy"] = "Copiar",
["Create Map Mark"] = "Criar marca no mapa", ["Create Map Mark"] = "Criar marca no mapa",
["Create mark"] = "Criar marca", ["Create mark"] = "Criar marca",
["Create New Offer"] = "Criar nova oferta", ["Create New Offer"] = "Criar nova oferta",
["Create Offer"] = "Criar oferta", ["Create Offer"] = "Criar oferta",
["Current hotkey to add: %s"] = "Atalho atual para adicionar: %s", ["Current hotkey to add: %s"] = "Atalho atual para adicionar: %s",
["Critical Hit Chance"] = "Chance de acerto crítico", ["Current hotkeys:"] = "Atalhos atuais",
["Critical Hit Damage"] = "Dano de acerto crítico",
["Current hotkeys"] = "Atalhos atuais",
["Current Offers"] = "Ofertas atuais", ["Current Offers"] = "Ofertas atuais",
["Default"] = "Padrão", ["Default"] = "Padrão",
["Delete mark"] = "Deletar marca", ["Delete mark"] = "Deletar marca",
["Description"] = "Descrição", ["Description"] = "Descrição",
["Description:"] = "Descrição",
["Destructive Behaviour"] = "Comportamento destrutivo", ["Destructive Behaviour"] = "Comportamento destrutivo",
["Detail"] = "Detalhe", ["Detail"] = "Detalhe",
["Details"] = "Detalhes", ["Details"] = "Detalhes",
["Disable chat mode allow to walk using ASDW"] = "Desativar modo de chat permite andar usando ASDW",
["Disable Shared Experience"] = "Desativar experiência compartilhada", ["Disable Shared Experience"] = "Desativar experiência compartilhada",
["Dismount"] = "Desmontar", ["Dismount"] = "Desmontar",
["Display connection speed to the server (milliseconds)"] = "Exibir a velocidade de conexão com o servidor (milisegundos)", ["Display connection speed to the server (milliseconds)"] = "Exibir a velocidade de conexão com o servidor (milisegundos)",
["Display creature health bars"] = "Exibir barras de vida das criaturas", ["Display creature health bars"] = "Exibir barras de vida das criaturas",
["Display creature names"] = "Exibir nomes das criaturas", ["Display creature names"] = "Exibir nomes das criaturas",
["Display player mana bar"] = "Exibir barra de mana",
["Display text messages"] = "Exibir mensagens de texto", ["Display text messages"] = "Exibir mensagens de texto",
["Distance Fighting"] = "Combate a Distância", ["Distance Fighting"] = "Combate a Distância",
["Don\'t stretch or shrink Game Window"] = "Não esticar ou contrair a janela do game", ["Don't stretch or shrink Game Window"] = "Não esticar ou contrair a janela do game",
["Druid"] = "Druid", ["Druid"] = "Druid",
["Edit %s"] = "Editar %s",
["Edit hotkey text:"] = "Editar texto do atalho", ["Edit hotkey text:"] = "Editar texto do atalho",
["Edit List"] = "Editar lista", ["Edit List"] = "Editar lista",
["Edit Text"] = "Editar Texto", ["Edit Text"] = "Editar Texto",
@ -277,7 +253,7 @@ locale = {
["Pass Leadership to %s"] = "Passar liderança para %s", ["Pass Leadership to %s"] = "Passar liderança para %s",
["Password"] = "Senha", ["Password"] = "Senha",
["Piece Price"] = "Preço por peça", ["Piece Price"] = "Preço por peça",
["Please enter a character name"] = "Por favor, entre com o nome do personagem", ["Please enter a character name:"] = "Por favor, entre com o nome do personagem:",
["Please Select"] = "Por favor, selecione algo", ["Please Select"] = "Por favor, selecione algo",
["Please use this dialog to only report bugs. Do not report rule violations here!"] = "Por favor, use este campo apenas para reportar defeitos. Não reporte violação de regras aqui!", ["Please use this dialog to only report bugs. Do not report rule violations here!"] = "Por favor, use este campo apenas para reportar defeitos. Não reporte violação de regras aqui!",
["Please wait"] = "Por favor, espere", ["Please wait"] = "Por favor, espere",

View File

@ -5,10 +5,6 @@ locale = {
charset = "cp1252", charset = "cp1252",
languageName = "Svenska", languageName = "Svenska",
formatNumbers = true,
decimalSeperator = ',',
thousandsSeperator = ' ',
translation = { translation = {
["1a) Offensive Name"] = "1a) Offensivt Namn", ["1a) Offensive Name"] = "1a) Offensivt Namn",
["1b) Invalid Name Format"] = "1b) Ogiltigt Namnformat", ["1b) Invalid Name Format"] = "1b) Ogiltigt Namnformat",
@ -31,7 +27,7 @@ locale = {
["4c) False Report to Gamemaster"] = "4c) Falsk rapport till gamemaster", ["4c) False Report to Gamemaster"] = "4c) Falsk rapport till gamemaster",
["Accept"] = "Acceptera", ["Accept"] = "Acceptera",
["Account name"] = "Konto namn", ["Account name"] = "Konto namn",
["Account Status"] = false, ["Account Status:"] = false,
["Action:"] = "Handling:", ["Action:"] = "Handling:",
["Add"] = "Lägg till", ["Add"] = "Lägg till",
["Add new VIP"] = "Ny VIP", ["Add new VIP"] = "Ny VIP",
@ -232,7 +228,7 @@ locale = {
["Pass Leadership to %s"] = "Ge ledarskap till %s", ["Pass Leadership to %s"] = "Ge ledarskap till %s",
["Password"] = "Lösenord", ["Password"] = "Lösenord",
["Piece Price:"] = "Per Styck:", ["Piece Price:"] = "Per Styck:",
["Please enter a character name"] = "Skriv in ett karaktärsnamn", ["Please enter a character name:"] = "Skriv in ett karaktärsnamn:",
["Please, press the key you wish to add onto your hotkeys manager"] = "Tryck på knappen som du\nvill lägga till som snabbtangent", ["Please, press the key you wish to add onto your hotkeys manager"] = "Tryck på knappen som du\nvill lägga till som snabbtangent",
["Please Select"] = "Välj", ["Please Select"] = "Välj",
["Please use this dialog to only report bugs. Do not report rule violations here!"] = "Använd den här dialogrutan endast för att rapportera buggar. Rapportera inte regelbrott här!", ["Please use this dialog to only report bugs. Do not report rule violations here!"] = "Använd den här dialogrutan endast för att rapportera buggar. Rapportera inte regelbrott här!",

View File

@ -8,7 +8,6 @@ Button < UIButton
image-clip: 0 0 22 23 image-clip: 0 0 22 23
image-border: 3 image-border: 3
padding: 5 10 5 10 padding: 5 10 5 10
opacity: 1.0
$hover !disabled: $hover !disabled:
image-clip: 0 23 22 23 image-clip: 0 23 22 23
@ -46,7 +45,6 @@ NextButton < UIButton
size: 12 21 size: 12 21
image-source: /images/ui/arrow_horizontal image-source: /images/ui/arrow_horizontal
image-clip: 12 0 12 21 image-clip: 12 0 12 21
image-color: #ffffff
$hover !disabled: $hover !disabled:
image-clip: 12 21 12 21 image-clip: 12 21 12 21
@ -55,13 +53,12 @@ NextButton < UIButton
image-clip: 12 21 12 21 image-clip: 12 21 12 21
$disabled: $disabled:
image-color: #dfdfdf88 image-color: #dfdfdf55
PreviousButton < UIButton PreviousButton < UIButton
size: 12 21 size: 12 21
image-source: /images/ui/arrow_horizontal image-source: /images/ui/arrow_horizontal
image-clip: 0 0 12 21 image-clip: 0 0 12 21
image-color: #ffffff
$hover !disabled: $hover !disabled:
image-clip: 0 21 12 21 image-clip: 0 21 12 21
@ -70,7 +67,7 @@ PreviousButton < UIButton
image-clip: 0 21 12 21 image-clip: 0 21 12 21
$disabled: $disabled:
image-color: #dfdfdf88 image-color: #dfdfdf55
AddButton < UIButton AddButton < UIButton
size: 20 20 size: 20 20

View File

@ -27,7 +27,7 @@ MoveableTabBarButton < UIButton
color: #dfdfdf color: #dfdfdf
$on !checked: $on !checked:
color: #de6f6f color: #dfdfdf
TabBar < UITabBar TabBar < UITabBar
size: 80 21 size: 80 21
@ -36,11 +36,10 @@ TabBar < UITabBar
anchors.fill: parent anchors.fill: parent
TabBarPanel < Panel TabBarPanel < Panel
TabBarButton < UIButton TabBarButton < UIButton
size: 20 21 size: 22 23
image-source: /images/ui/tabbutton_square
image-source: /images/ui/tabbutton_square image-source: /images/ui/tabbutton_square
image-color: #dfdfdf image-color: #dfdfdf
image-clip: 0 0 20 21 image-clip: 0 0 22 23
image-border: 3 image-border: 3
image-border-bottom: 0 image-border-bottom: 0
icon-color: #dfdfdf icon-color: #dfdfdf
@ -56,7 +55,7 @@ TabBarButton < UIButton
margin-left: 5 margin-left: 5
$hover !checked: $hover !checked:
image-clip: 0 21 20 21 image-clip: 0 23 22 23
color: #dfdfdf color: #dfdfdf
$disabled: $disabled:
@ -64,7 +63,7 @@ TabBarButton < UIButton
icon-color: #dfdfdf icon-color: #dfdfdf
$checked: $checked:
image-clip: 0 42 20 21 image-clip: 0 46 22 23
color: #dfdfdf color: #dfdfdf
$on !checked: $on !checked:
@ -74,14 +73,6 @@ TabBarRounded < TabBar
TabBarRoundedPanel < TabBarPanel TabBarRoundedPanel < TabBarPanel
TabBarRoundedButton < TabBarButton TabBarRoundedButton < TabBarButton
image-source: /images/ui/tabbutton_rounded image-source: /images/ui/tabbutton_rounded
size: 22 23
image-clip: 0 0 22 23
$hover !checked:
image-clip: 0 23 22 23
$checked:
image-clip: 0 46 22 23
TabBarVertical < UITabBar TabBarVertical < UITabBar
width: 96 width: 96

View File

@ -1,62 +1,26 @@
Table < UITable Table < UITable
layout: verticalBox layout: verticalBox
header-column-style: TableHeaderColumn header-column-style: HeaderTableColumn
header-row-style: TableHeaderRow header-row-style: HeaderTableRow
column-style: TableColumn column-style: TableColumn
row-style: TableRow row-style: TableRow
TableData < UIScrollArea TableData < UIScrollArea
layout: verticalBox layout: verticalBox
TableRow < UITableRow TableRow < Label
layout: horizontalBox layout: horizontalBox
height: 10 height: 10
text-wrap: true text-wrap: true
focusable: true
even-background-color: alpha
odd-background-color: #00000022
$focus:
background-color: #294f6d
color: #ffffff
TableColumn < Label TableColumn < Label
width: 30 width: 30
text-wrap: true text-wrap: true
focusable: false
TableHeaderRow < Label TableHeaderRow < Label
layout: horizontalBox layout: horizontalBox
focusable: false
height: 10 height: 10
text-wrap: true text-wrap: true
TableHeaderColumn < UITableHeaderColumn TableHeaderColumn < Button
font: verdana-11px-antialised width: 30
background-color: alpha
color: #dfdfdfff
height: 23
focusable: true
text-offset: 0 0
image-source: /images/ui/button
image-color: #dfdfdf
image-clip: 0 0 22 23
image-border: 3
padding: 5 10 5 10
enabled: false
focusable: false
$hover !disabled:
image-clip: 0 23 22 23
$pressed:
image-clip: 0 46 22 23
text-offset: 1 1
$disabled:
color: #dfdfdf88
opacity: 0.8
SortableTableHeaderColumn < TableHeaderColumn
enabled: true
focusable: true

View File

@ -22,7 +22,7 @@ end
g_resources.addSearchPath(g_resources.getWorkDir() .. "mods", true) g_resources.addSearchPath(g_resources.getWorkDir() .. "mods", true)
-- setup directory for saving configurations -- setup directory for saving configurations
g_resources.setupUserWriteDir(('%s/'):format(g_app.getCompactName())) g_resources.setupUserWriteDir(g_app.getCompactName())
-- search all packages -- search all packages
g_resources.searchAndAddPackages('/', '.otpkg', true) g_resources.searchAndAddPackages('/', '.otpkg', true)
@ -52,4 +52,4 @@ local script = '/' .. g_app.getCompactName() .. 'rc.lua'
if g_resources.fileExists(script) then if g_resources.fileExists(script) then
dofile(script) dofile(script)
end end

View File

@ -1,8 +1,5 @@
local musicFilename = "/sounds/startup" local musicFilename = "/sounds/startup"
local musicChannel = nil local musicChannel = g_sounds.getChannel(1)
if g_sounds then
musicChannel = g_sounds.getChannel(SoundChannels.Music)
end
function setMusic(filename) function setMusic(filename)
musicFilename = filename musicFilename = filename
@ -30,14 +27,12 @@ end
function startup() function startup()
-- Play startup music (The Silver Tree, by Mattias Westlund) -- Play startup music (The Silver Tree, by Mattias Westlund)
if musicChannel then musicChannel:enqueue(musicFilename, 3)
musicChannel:enqueue(musicFilename, 3) connect(g_game, { onGameStart = function() musicChannel:stop(3) end })
connect(g_game, { onGameStart = function() musicChannel:stop(3) end }) connect(g_game, { onGameEnd = function()
connect(g_game, { onGameEnd = function() g_sounds.stopAll()
g_sounds.stopAll() musicChannel:enqueue(musicFilename, 3)
musicChannel:enqueue(musicFilename, 3) end })
end })
end
-- Check for startup errors -- Check for startup errors
local errtitle = nil local errtitle = nil
@ -62,9 +57,7 @@ function init()
onExit = exit }) onExit = exit })
g_window.setMinimumSize({ width = 600, height = 480 }) g_window.setMinimumSize({ width = 600, height = 480 })
if musicChannel then g_sounds.preload(musicFilename)
g_sounds.preload(musicFilename)
end
-- initialize in fullscreen mode on mobile devices -- initialize in fullscreen mode on mobile devices
if g_window.getPlatformType() == "X11-EGL" then if g_window.getPlatformType() == "X11-EGL" then

View File

@ -2,7 +2,7 @@ Module
name: client name: client
description: Initialize the client and setups its main window description: Initialize the client and setups its main window
author: edubart author: edubart
website: https://github.com/edubart/otclient website: www.otclient.info
reloadable: false reloadable: false
sandboxed: true sandboxed: true
scripts: [ client ] scripts: [ client ]
@ -19,3 +19,4 @@ Module
- client_terminal - client_terminal
- client_modulemanager - client_modulemanager
- client_serverlist - client_serverlist
- client_stats

View File

@ -10,7 +10,7 @@ function init()
clientVersionLabel = background:getChildById('clientVersionLabel') clientVersionLabel = background:getChildById('clientVersionLabel')
clientVersionLabel:setText(g_app.getName() .. ' ' .. g_app.getVersion() .. '\n' .. clientVersionLabel:setText(g_app.getName() .. ' ' .. g_app.getVersion() .. '\n' ..
'Rev ' .. g_app.getBuildRevision() .. ' ('.. g_app.getBuildCommit() .. ')\n' .. 'Rev ' .. g_app.getBuildRevision() .. ' ('.. g_app.getBuildCommit() .. ')\n' ..
'Built on ' .. g_app.getBuildDate() .. '\n' .. g_app.getBuildCompiler()) 'Built on ' .. g_app.getBuildDate())
if not g_game.isOnline() then if not g_game.isOnline() then
addEvent(function() g_effects.fadeIn(clientVersionLabel, 1500) end) addEvent(function() g_effects.fadeIn(clientVersionLabel, 1500) end)
@ -45,7 +45,3 @@ end
function setVersionText(text) function setVersionText(text)
clientVersionLabel:setText(text) clientVersionLabel:setText(text)
end end
function getBackground()
return background
end

View File

@ -2,7 +2,7 @@ Module
name: client_background name: client_background
description: Handles the background of the login screen description: Handles the background of the login screen
author: edubart author: edubart
website: https://github.com/edubart/otclient website: www.otclient.info
sandboxed: true sandboxed: true
scripts: [ background ] scripts: [ background ]
dependencies: [ client_topmenu ] dependencies: [ client_topmenu ]

View File

@ -8,7 +8,6 @@ local errorBox
local waitingWindow local waitingWindow
local updateWaitEvent local updateWaitEvent
local resendWaitEvent local resendWaitEvent
local loginEvent
-- private functions -- private functions
local function tryLogin(charInfo, tries) local function tryLogin(charInfo, tries)
@ -22,13 +21,13 @@ local function tryLogin(charInfo, tries)
if tries == 1 then if tries == 1 then
g_game.safeLogout() g_game.safeLogout()
end end
loginEvent = scheduleEvent(function() tryLogin(charInfo, tries+1) end, 100) scheduleEvent(function() tryLogin(charInfo, tries+1) end, 100)
return return
end end
CharacterList.hide() CharacterList.hide()
g_game.loginWorld(G.account, G.password, charInfo.worldName, charInfo.worldHost, charInfo.worldPort, charInfo.characterName, G.authenticatorToken, G.sessionKey) g_game.loginWorld(G.account, G.password, charInfo.worldName, charInfo.worldHost, charInfo.worldPort, charInfo.characterName)
loadBox = displayCancelBox(tr('Please wait'), tr('Connecting to game server...')) loadBox = displayCancelBox(tr('Please wait'), tr('Connecting to game server...'))
connect(loadBox, { onCancel = function() connect(loadBox, { onCancel = function()
@ -110,16 +109,6 @@ function onGameLoginError(message)
end end
end end
function onGameLoginToken(unknown)
CharacterList.destroyLoadBox()
-- TODO: make it possible to enter a new token here / prompt token
errorBox = displayErrorBox(tr("Two-Factor Authentification"), 'A new authentification token is required.\nPlease login again.')
errorBox.onOk = function()
errorBox = nil
EnterGame.show()
end
end
function onGameConnectionError(message, code) function onGameConnectionError(message, code)
CharacterList.destroyLoadBox() CharacterList.destroyLoadBox()
local text = translateNetworkError(code, g_game.getProtocolGame() and g_game.getProtocolGame():isConnecting(), message) local text = translateNetworkError(code, g_game.getProtocolGame() and g_game.getProtocolGame():isConnecting(), message)
@ -142,7 +131,6 @@ end
-- public functions -- public functions
function CharacterList.init() function CharacterList.init()
connect(g_game, { onLoginError = onGameLoginError }) connect(g_game, { onLoginError = onGameLoginError })
connect(g_game, { onLoginToken = onGameLoginToken })
connect(g_game, { onUpdateNeeded = onGameUpdateNeeded }) connect(g_game, { onUpdateNeeded = onGameUpdateNeeded })
connect(g_game, { onConnectionError = onGameConnectionError }) connect(g_game, { onConnectionError = onGameConnectionError })
connect(g_game, { onGameStart = CharacterList.destroyLoadBox }) connect(g_game, { onGameStart = CharacterList.destroyLoadBox })
@ -156,7 +144,6 @@ end
function CharacterList.terminate() function CharacterList.terminate()
disconnect(g_game, { onLoginError = onGameLoginError }) disconnect(g_game, { onLoginError = onGameLoginError })
disconnect(g_game, { onLoginToken = onGameLoginToken })
disconnect(g_game, { onUpdateNeeded = onGameUpdateNeeded }) disconnect(g_game, { onUpdateNeeded = onGameUpdateNeeded })
disconnect(g_game, { onConnectionError = onGameConnectionError }) disconnect(g_game, { onConnectionError = onGameConnectionError })
disconnect(g_game, { onGameStart = CharacterList.destroyLoadBox }) disconnect(g_game, { onGameStart = CharacterList.destroyLoadBox })
@ -181,20 +168,15 @@ function CharacterList.terminate()
end end
if updateWaitEvent then if updateWaitEvent then
removeEvent(updateWaitEvent) updateWaitEvent:cancel()
updateWaitEvent = nil updateWaitEvent = nil
end end
if resendWaitEvent then if resendWaitEvent then
removeEvent(resendWaitEvent) resendWaitEvent:cancel()
resendWaitEvent = nil resendWaitEvent = nil
end end
if loginEvent then
removeEvent(loginEvent)
loginEvent = nil
end
CharacterList = nil CharacterList = nil
end end
@ -254,21 +236,12 @@ function CharacterList.create(characters, account, otui)
end end
-- account -- account
local status = '' if account.premDays > 0 and account.premDays < 65535 then
if account.status == AccountStatus.Frozen then accountStatusLabel:setText(tr("Premium Account (%s) days left", account.premDays))
status = tr(' (Frozen)') elseif account.premDays >= 65535 then
elseif account.status == AccountStatus.Suspended then accountStatusLabel:setText(tr("Lifetime Premium Account"))
status = tr(' (Suspended)') else
end accountStatusLabel:setText(tr('Free Account'))
if account.subStatus == SubscriptionStatus.Free then
accountStatusLabel:setText(('%s%s'):format(tr('Free Account'), status))
elseif account.subStatus == SubscriptionStatus.Premium then
if account.premDays == 0 or account.premDays == 65535 then
accountStatusLabel:setText(('%s%s'):format(tr('Gratis Premium Account'), status))
else
accountStatusLabel:setText(('%s%s'):format(tr('Premium Account (%s) days left', account.premDays), status))
end
end end
if account.premDays > 0 and account.premDays <= 7 then if account.premDays > 0 and account.premDays <= 7 then
@ -325,10 +298,6 @@ function CharacterList.doLogin()
worldName = selected.worldName, worldName = selected.worldName,
characterName = selected.characterName } characterName = selected.characterName }
charactersWindow:hide() charactersWindow:hide()
if loginEvent then
removeEvent(loginEvent)
loginEvent = nil
end
tryLogin(charInfo) tryLogin(charInfo)
else else
displayErrorBox(tr('Error'), tr('You must select a character to login!')) displayErrorBox(tr('Error'), tr('You must select a character to login!'))
@ -349,12 +318,12 @@ function CharacterList.cancelWait()
end end
if updateWaitEvent then if updateWaitEvent then
removeEvent(updateWaitEvent) updateWaitEvent:cancel()
updateWaitEvent = nil updateWaitEvent = nil
end end
if resendWaitEvent then if resendWaitEvent then
removeEvent(resendWaitEvent) resendWaitEvent:cancel()
resendWaitEvent = nil resendWaitEvent = nil
end end

View File

@ -16,7 +16,7 @@ CharacterWidget < UIWidget
Label Label
id: name id: name
color: #bbbbbb color: #aaaaaa
anchors.top: parent.top anchors.top: parent.top
anchors.left: parent.left anchors.left: parent.left
font: verdana-11px-monochrome font: verdana-11px-monochrome
@ -29,7 +29,8 @@ CharacterWidget < UIWidget
Label Label
id: worldName id: worldName
color: #bbbbbb color: #ffffff
color: #aaaaaa
anchors.top: parent.top anchors.top: parent.top
anchors.right: parent.right anchors.right: parent.right
margin-right: 5 margin-right: 5
@ -44,21 +45,16 @@ CharacterWidget < UIWidget
MainWindow MainWindow
id: charactersWindow id: charactersWindow
!text: tr('Character List') !text: tr('Character List')
size: 250 248
visible: false visible: false
@onEnter: CharacterList.doLogin() @onEnter: CharacterList.doLogin()
@onEscape: CharacterList.hide(true) @onEscape: CharacterList.hide(true)
@onSetup: | @onSetup: |
g_keyboard.bindKeyPress('Up', function() self:getChildById('characters'):focusPreviousChild(KeyboardFocusReason) end, self) g_keyboard.bindKeyPress('Up', function() self:getChildById('characters'):focusPreviousChild(KeyboardFocusReason) end, self)
g_keyboard.bindKeyPress('Down', function() self:getChildById('characters'):focusNextChild(KeyboardFocusReason) end, self) g_keyboard.bindKeyPress('Down', function() self:getChildById('characters'):focusNextChild(KeyboardFocusReason) end, self)
if g_game.getFeature(GamePreviewState) then
self:setSize({width = 350, height = 400})
else
self:setSize({width = 250, height = 248})
end
TextList TextList
id: characters id: characters
background-color: #565656
anchors.top: parent.top anchors.top: parent.top
anchors.left: parent.left anchors.left: parent.left
anchors.right: characterListScrollBar.left anchors.right: characterListScrollBar.left

View File

@ -33,17 +33,10 @@ local function onMotd(protocol, motd)
end end
end end
local function onSessionKey(protocol, sessionKey)
G.sessionKey = sessionKey
end
local function onCharacterList(protocol, characters, account, otui) local function onCharacterList(protocol, characters, account, otui)
-- Try add server to the server list -- Try add server to the server list
ServerList.add(G.host, G.port, g_game.getClientVersion()) ServerList.add(G.host, G.port, g_game.getClientVersion())
-- Save 'Stay logged in' setting
g_settings.set('staylogged', enterGame:getChildById('stayLoggedBox'):isChecked())
if enterGame:getChildById('rememberPasswordBox'):isChecked() then if enterGame:getChildById('rememberPasswordBox'):isChecked() then
local account = g_crypt.encrypt(G.account) local account = g_crypt.encrypt(G.account)
local password = g_crypt.encrypt(G.password) local password = g_crypt.encrypt(G.password)
@ -66,19 +59,13 @@ local function onCharacterList(protocol, characters, account, otui)
loadBox:destroy() loadBox:destroy()
loadBox = nil loadBox = nil
for _, characterInfo in pairs(characters) do
if characterInfo.previewState and characterInfo.previewState ~= PreviewState.Default then
characterInfo.worldName = characterInfo.worldName .. ', Preview'
end
end
CharacterList.create(characters, account, otui) CharacterList.create(characters, account, otui)
CharacterList.show() CharacterList.show()
if motdEnabled then if motdEnabled then
local lastMotdNumber = g_settings.getNumber("motd") local lastMotdNumber = g_settings.getNumber("motd")
if G.motdNumber and G.motdNumber ~= lastMotdNumber then if G.motdNumber and G.motdNumber ~= lastMotdNumber then
g_settings.set("motd", G.motdNumber) g_settings.set("motd", motdNumber)
motdWindow = displayInfoBox(tr('Message of the day'), G.motdMessage) motdWindow = displayInfoBox(tr('Message of the day'), G.motdMessage)
connect(motdWindow, { onOk = function() CharacterList.show() motdWindow = nil end }) connect(motdWindow, { onOk = function() CharacterList.show() motdWindow = nil end })
CharacterList.hide() CharacterList.hide()
@ -116,10 +103,9 @@ function EnterGame.init()
local password = g_settings.get('password') local password = g_settings.get('password')
local host = g_settings.get('host') local host = g_settings.get('host')
local port = g_settings.get('port') local port = g_settings.get('port')
local stayLogged = g_settings.getBoolean('staylogged')
local autologin = g_settings.getBoolean('autologin') local autologin = g_settings.getBoolean('autologin')
local clientVersion = g_settings.getInteger('client-version') local clientVersion = g_settings.getInteger('client-version')
if clientVersion == 0 then clientVersion = 1074 end if clientVersion == 0 then clientVersion = 860 end
if port == nil or port == 0 then port = 7171 end if port == nil or port == 0 then port = 7171 end
@ -129,7 +115,6 @@ function EnterGame.init()
enterGame:getChildById('serverHostTextEdit'):setText(host) enterGame:getChildById('serverHostTextEdit'):setText(host)
enterGame:getChildById('serverPortTextEdit'):setText(port) enterGame:getChildById('serverPortTextEdit'):setText(port)
enterGame:getChildById('autoLoginBox'):setChecked(autologin) enterGame:getChildById('autoLoginBox'):setChecked(autologin)
enterGame:getChildById('stayLoggedBox'):setChecked(stayLogged)
clientBox = enterGame:getChildById('clientComboBox') clientBox = enterGame:getChildById('clientComboBox')
for _, proto in pairs(g_game.getSupportedClients()) do for _, proto in pairs(g_game.getSupportedClients()) do
@ -137,10 +122,6 @@ function EnterGame.init()
end end
clientBox:setCurrentOption(clientVersion) clientBox:setCurrentOption(clientVersion)
EnterGame.toggleAuthenticatorToken(clientVersion, true)
EnterGame.toggleStayLoggedBox(clientVersion, true)
connect(clientBox, { onOptionChange = EnterGame.onClientVersionChange })
enterGame:hide() enterGame:hide()
if g_app.isRunning() and not g_game.isOnline() then if g_app.isRunning() and not g_game.isOnline() then
@ -165,7 +146,6 @@ end
function EnterGame.terminate() function EnterGame.terminate()
g_keyboard.unbindKeyDown('Ctrl+G') g_keyboard.unbindKeyDown('Ctrl+G')
disconnect(clientBox, { onOptionChange = EnterGame.onClientVersionChange })
enterGame:destroy() enterGame:destroy()
enterGame = nil enterGame = nil
enterGameButton:destroy() enterGameButton:destroy()
@ -224,80 +204,14 @@ end
function EnterGame.clearAccountFields() function EnterGame.clearAccountFields()
enterGame:getChildById('accountNameTextEdit'):clearText() enterGame:getChildById('accountNameTextEdit'):clearText()
enterGame:getChildById('accountPasswordTextEdit'):clearText() enterGame:getChildById('accountPasswordTextEdit'):clearText()
enterGame:getChildById('authenticatorTokenTextEdit'):clearText()
enterGame:getChildById('accountNameTextEdit'):focus() enterGame:getChildById('accountNameTextEdit'):focus()
g_settings.remove('account') g_settings.remove('account')
g_settings.remove('password') g_settings.remove('password')
end end
function EnterGame.toggleAuthenticatorToken(clientVersion, init)
local enabled = (clientVersion >= 1072)
if enabled == enterGame.authenticatorEnabled then
return
end
enterGame:getChildById('authenticatorTokenLabel'):setOn(enabled)
enterGame:getChildById('authenticatorTokenTextEdit'):setOn(enabled)
local newHeight = enterGame:getHeight()
local newY = enterGame:getY()
if enabled then
newY = newY - enterGame.authenticatorHeight
newHeight = newHeight + enterGame.authenticatorHeight
else
newY = newY + enterGame.authenticatorHeight
newHeight = newHeight - enterGame.authenticatorHeight
end
if not init then
enterGame:breakAnchors()
enterGame:setY(newY)
enterGame:bindRectToParent()
end
enterGame:setHeight(newHeight)
enterGame.authenticatorEnabled = enabled
end
function EnterGame.toggleStayLoggedBox(clientVersion, init)
local enabled = (clientVersion >= 1074)
if enabled == enterGame.stayLoggedBoxEnabled then
return
end
enterGame:getChildById('stayLoggedBox'):setOn(enabled)
local newHeight = enterGame:getHeight()
local newY = enterGame:getY()
if enabled then
newY = newY - enterGame.stayLoggedBoxHeight
newHeight = newHeight + enterGame.stayLoggedBoxHeight
else
newY = newY + enterGame.stayLoggedBoxHeight
newHeight = newHeight - enterGame.stayLoggedBoxHeight
end
if not init then
enterGame:breakAnchors()
enterGame:setY(newY)
enterGame:bindRectToParent()
end
enterGame:setHeight(newHeight)
enterGame.stayLoggedBoxEnabled = enabled
end
function EnterGame.onClientVersionChange(comboBox, text, data)
local clientVersion = tonumber(text)
EnterGame.toggleAuthenticatorToken(clientVersion)
EnterGame.toggleStayLoggedBox(clientVersion)
end
function EnterGame.doLogin() function EnterGame.doLogin()
G.account = enterGame:getChildById('accountNameTextEdit'):getText() G.account = enterGame:getChildById('accountNameTextEdit'):getText()
G.password = enterGame:getChildById('accountPasswordTextEdit'):getText() G.password = enterGame:getChildById('accountPasswordTextEdit'):getText()
G.authenticatorToken = enterGame:getChildById('authenticatorTokenTextEdit'):getText()
G.stayLogged = enterGame:getChildById('stayLoggedBox'):isChecked()
G.host = enterGame:getChildById('serverHostTextEdit'):getText() G.host = enterGame:getChildById('serverHostTextEdit'):getText()
G.port = tonumber(enterGame:getChildById('serverPortTextEdit'):getText()) G.port = tonumber(enterGame:getChildById('serverPortTextEdit'):getText())
local clientVersion = tonumber(clientBox:getText()) local clientVersion = tonumber(clientBox:getText())
@ -316,7 +230,6 @@ function EnterGame.doLogin()
protocolLogin = ProtocolLogin.create() protocolLogin = ProtocolLogin.create()
protocolLogin.onLoginError = onError protocolLogin.onLoginError = onError
protocolLogin.onMotd = onMotd protocolLogin.onMotd = onMotd
protocolLogin.onSessionKey = onSessionKey
protocolLogin.onCharacterList = onCharacterList protocolLogin.onCharacterList = onCharacterList
protocolLogin.onUpdateNeeded = onUpdateNeeded protocolLogin.onUpdateNeeded = onUpdateNeeded
@ -327,12 +240,12 @@ function EnterGame.doLogin()
EnterGame.show() EnterGame.show()
end }) end })
g_game.chooseRsa(G.host)
g_game.setClientVersion(clientVersion) g_game.setClientVersion(clientVersion)
g_game.setProtocolVersion(g_game.getClientProtocolVersion(clientVersion)) g_game.setProtocolVersion(g_game.getClientProtocolVersion(clientVersion))
g_game.chooseRsa(G.host)
if modules.game_things.isLoaded() then if modules.game_things.isLoaded() then
protocolLogin:login(G.host, G.port, G.account, G.password, G.authenticatorToken, G.stayLogged) protocolLogin:login(G.host, G.port, G.account, G.password)
else else
loadBox:destroy() loadBox:destroy()
loadBox = nil loadBox = nil
@ -353,7 +266,6 @@ function EnterGame.setDefaultServer(host, port, protocol)
local clientLabel = enterGame:getChildById('clientLabel') local clientLabel = enterGame:getChildById('clientLabel')
local accountTextEdit = enterGame:getChildById('accountNameTextEdit') local accountTextEdit = enterGame:getChildById('accountNameTextEdit')
local passwordTextEdit = enterGame:getChildById('accountPasswordTextEdit') local passwordTextEdit = enterGame:getChildById('accountPasswordTextEdit')
local authenticatorTokenTextEdit = enterGame:getChildById('authenticatorTokenTextEdit')
if hostTextEdit:getText() ~= host then if hostTextEdit:getText() ~= host then
hostTextEdit:setText(host) hostTextEdit:setText(host)
@ -361,7 +273,6 @@ function EnterGame.setDefaultServer(host, port, protocol)
clientBox:setCurrentOption(protocol) clientBox:setCurrentOption(protocol)
accountTextEdit:setText('') accountTextEdit:setText('')
passwordTextEdit:setText('') passwordTextEdit:setText('')
authenticatorTokenTextEdit:setText('')
end end
end end
@ -375,16 +286,6 @@ function EnterGame.setUniqueServer(host, port, protocol, windowWidth, windowHeig
portTextEdit:setVisible(false) portTextEdit:setVisible(false)
portTextEdit:setHeight(0) portTextEdit:setHeight(0)
local authenticatorTokenTextEdit = enterGame:getChildById('authenticatorTokenTextEdit')
authenticatorTokenTextEdit:setText('')
authenticatorTokenTextEdit:setOn(false)
local authenticatorTokenLabel = enterGame:getChildById('authenticatorTokenLabel')
authenticatorTokenLabel:setOn(false)
local stayLoggedBox = enterGame:getChildById('stayLoggedBox')
stayLoggedBox:setChecked(false)
stayLoggedBox:setOn(false)
clientBox:setCurrentOption(protocol) clientBox:setCurrentOption(protocol)
clientBox:setVisible(false) clientBox:setVisible(false)
clientBox:setHeight(0) clientBox:setHeight(0)
@ -405,11 +306,11 @@ function EnterGame.setUniqueServer(host, port, protocol, windowWidth, windowHeig
serverListButton:setWidth(0) serverListButton:setWidth(0)
local rememberPasswordBox = enterGame:getChildById('rememberPasswordBox') local rememberPasswordBox = enterGame:getChildById('rememberPasswordBox')
rememberPasswordBox:setMarginTop(-8) rememberPasswordBox:setMarginTop(-5)
if not windowWidth then windowWidth = 236 end if not windowWidth then windowWidth = 236 end
enterGame:setWidth(windowWidth) enterGame:setWidth(windowWidth)
if not windowHeight then windowHeight = 210 end if not windowHeight then windowHeight = 200 end
enterGame:setHeight(windowHeight) enterGame:setHeight(windowHeight)
end end

View File

@ -2,7 +2,7 @@ Module
name: client_entergame name: client_entergame
description: Manages enter game and character list windows description: Manages enter game and character list windows
author: edubart author: edubart
website: https://github.com/edubart/otclient website: www.otclient.info
dependencies: dependencies:
- client_topmenu - client_topmenu

View File

@ -1,6 +1,6 @@
EnterGameWindow < MainWindow EnterGameWindow < MainWindow
!text: tr('Enter Game') !text: tr('Enter Game')
size: 236 298 size: 236 274
EnterGameButton < Button EnterGameButton < Button
width: 64 width: 64
@ -21,10 +21,6 @@ ServerListButton < UIButton
EnterGameWindow EnterGameWindow
id: enterGame id: enterGame
&authenticatorEnabled: false
&authenticatorHeight: 44
&stayLoggedBoxEnabled: false
&stayLoggedBoxHeight: 24
@onEnter: EnterGame.doLogin() @onEnter: EnterGame.doLogin()
MenuLabel MenuLabel
@ -54,52 +50,6 @@ EnterGameWindow
anchors.top: prev.bottom anchors.top: prev.bottom
margin-top: 2 margin-top: 2
MenuLabel
id: authenticatorTokenLabel
!text: tr('Authenticator Token')
anchors.left: prev.left
anchors.top: prev.bottom
text-auto-resize: true
margin-top: -12
visible: false
$on:
visible: true
margin-top: 8
TextEdit
id: authenticatorTokenTextEdit
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: -22
visible: false
max-length: 8
$on:
visible: true
margin-top: 2
CheckBox
id: stayLoggedBox
!text: tr('Stay logged during session')
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 6
margin-top: -16
visible: false
$on:
visible: true
margin-top: 8
HorizontalSeparator
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 8
MenuLabel MenuLabel
id: serverLabel id: serverLabel
!text: tr('Server') !text: tr('Server')
@ -182,24 +132,16 @@ EnterGameWindow
anchors.top: prev.bottom anchors.top: prev.bottom
margin-top: 2 margin-top: 2
HorizontalSeparator
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 6
EnterGameButton EnterGameButton
!text: tr('Ok') !text: tr('Ok')
anchors.right: parent.right anchors.right: parent.right
anchors.top: prev.bottom anchors.bottom: parent.bottom
margin-top: 4
@onClick: EnterGame.doLogin() @onClick: EnterGame.doLogin()
Label Label
id: serverInfoLabel id: serverInfoLabel
font: verdana-11px-rounded font: verdana-11px-rounded
anchors.top: prev.top anchors.bottom: parent.bottom
anchors.left: parent.left anchors.left: parent.left
margin-top: 5
color: green color: green
text-auto-resize: true text-auto-resize: true

View File

@ -113,18 +113,15 @@ function installLocale(locale)
if _G.allowedLocales and not _G.allowedLocales[locale.name] then return end if _G.allowedLocales and not _G.allowedLocales[locale.name] then return end
if locale.name ~= defaultLocaleName then if locale.name ~= defaultLocaleName then
local updatesNamesMissing = {} local updatesNeeded = 0
for _,k in pairs(neededTranslations) do for _i,k in pairs(neededTranslations) do
if locale.translation[k] == nil then if locale.translation[k] == nil then
updatesNamesMissing[#updatesNamesMissing + 1] = k updatesNeeded = updatesNeeded + 1
end end
end end
if #updatesNamesMissing > 0 then if updatesNeeded > 0 then
pdebug('Locale \'' .. locale.name .. '\' is missing ' .. #updatesNamesMissing .. ' translations.') pdebug('Locale \'' .. locale.name .. '\' is missing ' .. updatesNeeded .. ' translations.')
for _,name in pairs(updatesNamesMissing) do
pdebug('["' .. name ..'"] = \"\",')
end
end end
end end
@ -144,10 +141,7 @@ end
function setLocale(name) function setLocale(name)
local locale = installedLocales[name] local locale = installedLocales[name]
if locale == currentLocale then if locale == currentLocale then return end
g_settings.set('locale', name)
return
end
if not locale then if not locale then
pwarning("Locale " .. name .. ' does not exist.') pwarning("Locale " .. name .. ' does not exist.')
return false return false
@ -172,20 +166,16 @@ end
-- global function used to translate texts -- global function used to translate texts
function _G.tr(text, ...) function _G.tr(text, ...)
if currentLocale then if currentLocale then
if tonumber(text) and currentLocale.formatNumbers then if tonumber(text) then
local number = tostring(text):split('.') -- todo: use locale information to calculate this. also detect floating numbers
local out = '' local out = ''
local reverseNumber = number[1]:reverse() local number = tostring(text):reverse()
for i=1,#reverseNumber do for i=1,#number do
out = out .. reverseNumber:sub(i, i) out = out .. number:sub(i, i)
if i % 3 == 0 and i ~= #number then if i % 3 == 0 and i ~= #number then
out = out .. currentLocale.thousandsSeperator out = out .. ','
end end
end end
if number[2] then
out = number[2] .. currentLocale.decimalSeperator .. out
end
return out:reverse() return out:reverse()
elseif tostring(text) then elseif tostring(text) then
local translation = currentLocale.translation[text] local translation = currentLocale.translation[text]

View File

@ -2,7 +2,7 @@ Module
name: client_locales name: client_locales
description: Translates texts to selected language description: Translates texts to selected language
author: baxnie, edubart author: baxnie, edubart
website: https://github.com/edubart/otclient website: www.otclient.info
sandboxed: true sandboxed: true
scripts: [ locales ] scripts: [ locales ]
@onLoad: init() @onLoad: init()

View File

@ -21,47 +21,40 @@ neededTranslations = {
"4c) False Report to Gamemaster", "4c) False Report to Gamemaster",
"Accept", "Accept",
"Account name", "Account name",
"Account Status", "Account Status:",
"Action", "Action:",
"Activate ignorelist",
"Activate whitelist",
"Add", "Add",
"Add new server",
"Add new VIP", "Add new VIP",
"Addon 1", "Addon 1",
"Addon 2", "Addon 2",
"Addon 3", "Addon 3",
"Add to VIP list", "Add to VIP list",
"Adjust volume", "Adjust volume",
"Alas! Brave adventurer, you have met a sad fate.\nBut do not despair, for the gods will bring you back\ninto this world in exchange for a small sacrifice\n\nSimply click on Ok to resume your journeys!",
"All", "All",
"All modules and scripts were reloaded.", "All modules and scripts were reloaded.",
"Allow auto chase override", "Allow auto chase override",
"Allowed Players", "Also known as dash in tibia community, recommended\nfor playing characters with high speed",
"Allow VIPs to message you",
"Ambient light: %s%%", "Ambient light: %s%%",
"Amount:",
"Amount", "Amount",
"Anonymous", "Anonymous",
"Any", "Are you sure you want to logout?",
"Attack", "Attack",
"Auction End",
"Audio",
"Authenticator Token",
"Author", "Author",
"Autoload", "Autoload",
"Autoload priority", "Autoload priority",
"Auto login", "Auto login",
"Auto login selected character on next charlist load", "Auto login selected character on next charlist load",
"Axe Fighting", "Axe Fighting",
"Balance", "Balance:",
"Banishment", "Banishment",
"Banishment + Final Warning", "Banishment + Final Warning",
"Battle", "Battle",
"Browse", "Browse",
"Browse Field",
"Bug report sent.", "Bug report sent.",
"Button Assign", "Button Assign",
"Buy", "Buy",
"Buyer Name",
"Buy Now", "Buy Now",
"Buy Offers", "Buy Offers",
"Buy with backpack", "Buy with backpack",
@ -70,8 +63,6 @@ neededTranslations = {
"Cap", "Cap",
"Capacity", "Capacity",
"Center", "Center",
"Change language",
"Channel appended to %s",
"Channels", "Channels",
"Character List", "Character List",
"Classic control", "Classic control",
@ -79,23 +70,15 @@ neededTranslations = {
"Clear Messages", "Clear Messages",
"Clear object", "Clear object",
"Client needs update.", "Client needs update.",
"Client Version",
"Close", "Close",
"Close this channel", "Close this channel",
"Club Fighting", "Club Fighting",
"Combat Controls", "Combat Controls",
"Comment", "Comment:",
"Connecting to game server...", "Connecting to game server...",
"Connecting to login server...", "Connecting to login server...",
"Connection Error",
"Connection failed.",
"Connection failed, the server address does not exist.",
"Connection refused, the server might be offline or restarting.\nPlease try again later.",
"Connection timed out. Either your network is failing or the server is offline.",
"Console", "Console",
"Cooldown",
"Cooldowns", "Cooldowns",
"Copy",
"Copy message", "Copy message",
"Copy name", "Copy name",
"Copy Name", "Copy Name",
@ -103,72 +86,53 @@ neededTranslations = {
"Create mark", "Create mark",
"Create New Offer", "Create New Offer",
"Create Offer", "Create Offer",
"Critical Hit Chance", "Current hotkeys:",
"Critical Hit Damage",
"Current hotkeys",
"Current hotkey to add: %s", "Current hotkey to add: %s",
"Current Offers", "Current Offers",
"Default", "Default",
"Delete mark", "Delete mark",
"Description:",
"Description", "Description",
"Destructive Behaviour", "Destructive Behaviour",
"Detail", "Detail",
"Details", "Details",
"Disable chat mode, allow to walk using ASDW",
"Disable chat mode, allow to walk using ASDW",
"Disable Shared Experience", "Disable Shared Experience",
"Dismount", "Dismount",
"Display connection speed to the server (milliseconds)", "Display connection speed to the server (milliseconds)",
"Display creature health bars",
"Display creature names",
"Display player mana bar",
"Display text messages",
"Distance Fighting", "Distance Fighting",
"%d of experience per hour",
"Don\'t stretch/shrink Game Window", "Don\'t stretch/shrink Game Window",
"Druid", "Edit hotkey text:",
"Edit hotkey text",
"Edit List", "Edit List",
"Edit %s",
"Edit Text", "Edit Text",
"Edit VIP list entry", "Enable music",
"Enable audio",
"Enable chat mode",
"Enable dash walking",
"Enable lights",
"Enable music sound",
"Enable Shared Experience", "Enable Shared Experience",
"Enable smart walking", "Enable smart walking",
"Enable vertical synchronization", "Enable vertical synchronization",
"Enable walk booster",
"Enter Game", "Enter Game",
"Enter one name per line.", "Enter one name per line.",
"Enter with your account again to update your client.", "Enter with your account again to update your client.",
"Error", "Error",
"Error", "Error",
"(ERROR %d)",
"Excessive Unjustified Player Killing", "Excessive Unjustified Player Killing",
"Exclude from private chat", "Exclude from private chat",
"Exit", "Exit",
"Experience", "Experience",
"Filter list to match your level", "Filter list to match your level",
"Filter list to match your vocation", "Filter list to match your vocation",
"Filters", "Find:",
"Find",
"Fishing", "Fishing",
"Fist Fighting", "Fist Fighting",
"Follow", "Follow",
"Force Exit", "Force Exit",
"Formula",
"For Your Information", "For Your Information",
"Free Account", "Free Account",
"Fullscreen", "Fullscreen",
"Game", "Game",
"Game framerate limit: %s", "Game framerate limit: %s",
"Global ignore settings",
"Global whitelist settings",
"Graphics", "Graphics",
"Graphics card driver not detected", "Graphics card driver not detected",
"Group", "Graphics Engine:",
"Head", "Head",
"Healing", "Healing",
"Health Info", "Health Info",
@ -182,50 +146,43 @@ neededTranslations = {
"Hide spells for higher exp. levels", "Hide spells for higher exp. levels",
"Hide spells for other vocations", "Hide spells for other vocations",
"Hit Points", "Hit Points",
"Hold left mouse button to navigate\nScroll mouse middle button to zoom\nRight mouse button to create map marks\nPress Ctrl+Shift+M to view the entire game map", "Hold left mouse button to navigate\nScroll mouse middle button to zoom\nRight mouse button to create map marks",
"Host",
"Hotkey delay: %dms",
"Hotkey delay: %sms",
"Hotkeys", "Hotkeys",
"If you shut down the program, your character might stay in the game.\nClick on 'Logout' to ensure that you character leaves the game properly.\nClick on 'Exit' if you want to exit the program without logging out your character.", "If you shut down the program, your character might stay in the game.\nClick on 'Logout' to ensure that you character leaves the game properly.\nClick on 'Exit' if you want to exit the program without logging out your character.",
"Ignore", "Ignore",
"Ignore capacity", "Ignore capacity",
"Ignored Players", "Ignored players:",
"Ignore equipped", "Ignore equipped",
"Ignore List", "Ignore List",
"Ignore players", "Ignore players",
"Ignore Private Messages", "Ignore Private Messages",
"Ignore Yelling", "Ignore Yelling",
"Interface framerate limit: %s", "Interface framerate limit: %s",
"Invalid authentification token.",
"Inventory", "Inventory",
"Invite to Party", "Invite to Party",
"Invite to private chat", "Invite to private chat",
"IP Address Banishment", "IP Address Banishment",
"Item Name",
"Item Offers", "Item Offers",
"It is empty.", "It is empty.",
"Join %s\'s Party", "Join %s\'s Party",
"Knight",
"Leave Party", "Leave Party",
"Level", "Level",
"Life Leech Amount",
"Life Leech Chance",
"Lifetime Premium Account", "Lifetime Premium Account",
"Limits FPS to 60", "Limits FPS to 60",
"List of items that you're able to buy", "List of items that you're able to buy",
"List of items that you're able to sell", "List of items that you're able to sell",
"Load", "Load",
"Logging out...",
"Login", "Login",
"Login Error", "Login Error",
"Login Error", "Login Error",
"Logout", "Logout",
"Look", "Look",
"Magic Level", "Magic Level",
"Make sure that your client uses\nthe correct game client version", "Make sure that your client uses\nthe correct game protocol version",
"Mana", "Mana",
"Manage hotkeys:",
"Market", "Market",
"Market Error",
"Market Offers", "Market Offers",
"Message of the day", "Message of the day",
"Message to ", "Message to ",
@ -236,14 +193,11 @@ neededTranslations = {
"Mount", "Mount",
"Move Stackable Item", "Move Stackable Item",
"Move up", "Move up",
"Music volume: %d",
"My Offers", "My Offers",
"Name", "Name:",
"Name Report", "Name Report",
"Name Report + Banishment", "Name Report + Banishment",
"Name Report + Banishment + Final Warning", "Name Report + Banishment + Final Warning",
"New Server",
"Next level in %d hours and %d minutes",
"No", "No",
"No graphics card detected, everything will be drawn using the CPU,\nthus the performance will be really bad.\nPlease update your graphics driver to have a better performance.", "No graphics card detected, everything will be drawn using the CPU,\nthus the performance will be really bad.\nPlease update your graphics driver to have a better performance.",
"No item selected.", "No item selected.",
@ -251,47 +205,39 @@ neededTranslations = {
"No Outfit", "No Outfit",
"No statement has been selected.", "No statement has been selected.",
"Notation", "Notation",
"Notify-Login",
"NPC Trade", "NPC Trade",
"Offer History", "Offer History",
"Offers", "Offers",
"Offer Type", "Offer Type:",
"Offline Training", "Offline Training",
"Ok", "Ok",
"on %s.\n", "on %s.\n",
"Open", "Open",
"Open a private message channel", "Open a private message channel:",
"Open charlist automatically when starting client", "Open charlist automatically when starting client",
"Open in new window", "Open in new window",
"Open new channel", "Open new channel",
"Open purse",
"Open PvP",
"Open PvP Situations",
"Options", "Options",
"Overview", "Overview",
"Paladin",
"Pass Leadership to %s", "Pass Leadership to %s",
"Password", "Password",
"Piece Price", "Piece Price:",
"Please enter a character name", "Please enter a character name:",
"Please, press the key you wish to add onto your hotkeys manager", "Please, press the key you wish to add onto your hotkeys manager",
"Please Select", "Please Select",
"Please state the rule violation in one clear sentence and wait for a reply from a gamemaster. Please note that your message will disappear if you close the channel.",
"Please use this dialog to only report bugs. Do not report rule violations here!", "Please use this dialog to only report bugs. Do not report rule violations here!",
"Please wait", "Please wait",
"Please wait patiently for a gamemaster to reply",
"Port", "Port",
"Position", "Position:",
"Premium", "Position: %i %i %i",
"Premium Account (%s) days left", "Premium Account (%s) days left",
"Price", "Price:",
"Primary", "Primary",
"Process",
"Protocol", "Protocol",
"Quest Log", "Quest Log",
"Randomize", "Randomize",
"Randomize characters outfit", "Randomize characters outfit",
"Reason", "Reason:",
"Refresh", "Refresh",
"Refresh Offers", "Refresh Offers",
"Regeneration Time", "Regeneration Time",
@ -299,46 +245,31 @@ neededTranslations = {
"Reload All", "Reload All",
"Remember account and password when starts client", "Remember account and password when starts client",
"Remember password", "Remember password",
"Remove ",
"Remove", "Remove",
"Remove %s", "Remove %s",
"Report Bug", "Report Bug",
"Report Rule",
"Report Rule Violation",
"Reserved for more functionality later.", "Reserved for more functionality later.",
"Reset All",
"Reset Market", "Reset Market",
"Reset selection, filters & search",
"Revoke %s\'s Invitation", "Revoke %s\'s Invitation",
"Rotate", "Rotate",
"Rule Violation", "Rule Violation",
"Rule Violations",
"Save", "Save",
"Save Messages", "Save Messages",
"Search", "Search:",
"Search all items", "Search all items",
"Secondary", "Secondary",
"Select",
"Select all",
"Select object", "Select object",
"Select Outfit", "Select Outfit",
"Select your language", "Select your language",
"Sell", "Sell",
"Sell All",
"Seller Name",
"Sell Now", "Sell Now",
"Sell Offers", "Sell Offers",
"Send", "Send",
"Send automatically", "Send automatically",
"Send Message", "Send Message",
"Server", "Server",
"Server list",
"Server List",
"Server Log", "Server Log",
"Set Outfit", "Set Outfit",
"%s has finished the request",
"%s has logged in.",
"%s has logged out.",
"Shielding", "Shielding",
"Show all items", "Show all items",
"Show connection ping", "Show connection ping",
@ -355,15 +286,8 @@ neededTranslations = {
"Show status messages in console", "Show status messages in console",
"Show Text", "Show Text",
"Show timestamps in console", "Show timestamps in console",
"Show Top Menu",
"Show your depot items only", "Show your depot items only",
"Skills", "Skills",
"Skull Time",
"%s of experience left",
"Sorcerer",
"Sort by name",
"Sort by status",
"Sort by type",
"Soul", "Soul",
"Soul Points", "Soul Points",
"Special", "Special",
@ -371,10 +295,9 @@ neededTranslations = {
"Spell Cooldowns", "Spell Cooldowns",
"Spell List", "Spell List",
"Stamina", "Stamina",
"Statement", "Statement:",
"Statement Report", "Statement Report",
"Statistics", "Statistics",
"Stay logged during session",
"Stop Attack", "Stop Attack",
"Stop Follow", "Stop Follow",
"Support", "Support",
@ -385,23 +308,17 @@ neededTranslations = {
"Sword Fighting", "Sword Fighting",
"Terminal", "Terminal",
"There is no way.", "There is no way.",
"This offer is 25%% above the average market price", "Title",
"This offer is 25%% below the average market price", "Total Price:",
"Total Price",
"Trade", "Trade",
"Trade with ...", "Trade with ...",
"Trying to reconnect in %s seconds.", "Trying to reconnect in %s seconds.",
"Turn delay: %dms",
"Turn delay: %sms",
"Two-Factor Authentification",
"Type",
"Unable to load dat file, please place a valid dat in '%s'", "Unable to load dat file, please place a valid dat in '%s'",
"Unable to load spr file, please place a valid spr in '%s'", "Unable to load spr file, please place a valid spr in '%s'",
"Unable to logout.",
"Unignore", "Unignore",
"Unjustified Points",
"Unload", "Unload",
"Update needed", "Update needed",
"Update needed",
"Use", "Use",
"Use on target", "Use on target",
"Use on yourself", "Use on yourself",
@ -412,8 +329,7 @@ neededTranslations = {
"Vocation", "Vocation",
"Waiting List", "Waiting List",
"Website", "Website",
"Weight", "Weight:",
"Will boost your walk on high speed characters",
"Will detect when to use diagonal step based on the\nkeys you are pressing", "Will detect when to use diagonal step based on the\nkeys you are pressing",
"With crosshair", "With crosshair",
"Yes", "Yes",
@ -442,13 +358,8 @@ neededTranslations = {
"You must enter a comment.", "You must enter a comment.",
"You must enter a valid server address and port.", "You must enter a valid server address and port.",
"You must select a character to login!", "You must select a character to login!",
"You must select an action.", "Your Capacity:",
"You must select a reason.",
"Your Capacity",
"Your client needs updating, try redownloading it.",
"Your connection has been lost.\nEither your network or the server went down.",
"You read the following, written by \n%s\n", "You read the following, written by \n%s\n",
"You read the following, written on \n%s.\n", "You read the following, written on \n%s.\n",
"Your Money", "Your Money:",
"Your request has been closed",
} }

View File

@ -2,7 +2,7 @@ Module
name: client_modulemanager name: client_modulemanager
description: Manage other modules description: Manage other modules
author: edubart author: edubart
website: https://github.com/edubart/otclient website: www.otclient.info
sandboxed: true sandboxed: true
scripts: [ modulemanager ] scripts: [ modulemanager ]
dependencies: [ client_topmenu ] dependencies: [ client_topmenu ]

View File

@ -34,59 +34,15 @@ Panel
id: displayHealth id: displayHealth
!text: tr('Display creature health bars') !text: tr('Display creature health bars')
OptionCheckBox
id: displayMana
!text: tr('Display player mana bar')
OptionCheckBox OptionCheckBox
id: displayText id: displayText
!text: tr('Display text messages') !text: tr('Display text messages')
Label
id: turnDelayLabel
!text: tr('Turn delay: %sms', 30)
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 12
@onSetup: |
local value = modules.client_options.getOption('turnDelay')
self:setText(tr('Turn delay: %dms', value))
OptionScrollbar
id: turnDelay
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 3
minimum: 30
maximum: 250
Label
id: hotkeyDelayLabel
!text: tr('Hotkey delay: %dms', 30)
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 12
@onSetup: |
local value = modules.client_options.getOption('hotkeyDelay')
self:setText(tr('Hotkey delay: %dms', value))
OptionScrollbar
id: hotkeyDelay
anchors.left: parent.left
anchors.right: parent.right
anchors.top: prev.bottom
margin-top: 3
minimum: 30
maximum: 250
Button Button
id: changeLocale id: changeLocale
!text: tr('Change language') !text: tr('Change language')
@onClick: modules.client_locales.createWindow() @onClick: modules.client_locales.createWindow()
anchors.top: prev.bottom anchors.top: prev.bottom
anchors.left: prev.left anchors.left: prev.left
margin-top: 12 margin-top: 5
width: 120 width: 120

View File

@ -25,11 +25,8 @@ local defaultOptions = {
ambientLight = 25, ambientLight = 25,
displayNames = true, displayNames = true,
displayHealth = true, displayHealth = true,
displayMana = true,
displayText = true, displayText = true,
dontStretchShrink = false, dontStretchShrink = false
turnDelay = 50,
hotkeyDelay = 50,
} }
local optionsWindow local optionsWindow
@ -109,8 +106,8 @@ function init()
graphicsPanel = g_ui.loadUI('graphics') graphicsPanel = g_ui.loadUI('graphics')
optionsTabBar:addTab(tr('Graphics'), graphicsPanel, '/images/optionstab/graphics') optionsTabBar:addTab(tr('Graphics'), graphicsPanel, '/images/optionstab/graphics')
soundPanel = g_ui.loadUI('audio') audioPanel = g_ui.loadUI('audio')
optionsTabBar:addTab(tr('Audio'), soundPanel, '/images/optionstab/audio') optionsTabBar:addTab(tr('Audio'), audioPanel, '/images/optionstab/audio')
optionsButton = modules.client_topmenu.addLeftButton('optionsButton', tr('Options'), '/images/topbuttons/options', toggle) optionsButton = modules.client_topmenu.addLeftButton('optionsButton', tr('Options'), '/images/topbuttons/options', toggle)
audioButton = modules.client_topmenu.addLeftButton('audioButton', tr('Audio'), '/images/topbuttons/audio', function() toggleOption('enableAudio') end) audioButton = modules.client_topmenu.addLeftButton('audioButton', tr('Audio'), '/images/topbuttons/audio', function() toggleOption('enableAudio') end)
@ -158,17 +155,15 @@ function hide()
end end
function toggleDisplays() function toggleDisplays()
if options['displayNames'] and options['displayHealth'] and options['displayMana'] then if options['displayNames'] and options['displayHealth'] then
setOption('displayNames', false) setOption('displayNames', false)
elseif options['displayHealth'] then elseif options['displayHealth'] then
setOption('displayHealth', false) setOption('displayHealth', false)
setOption('displayMana', false)
else else
if not options['displayNames'] and not options['displayHealth'] then if not options['displayNames'] and not options['displayHealth'] then
setOption('displayNames', true) setOption('displayNames', true)
else else
setOption('displayHealth', true) setOption('displayHealth', true)
setOption('displayMana', true)
end end
end end
end end
@ -190,23 +185,17 @@ function setOption(key, value, force)
elseif key == 'fullscreen' then elseif key == 'fullscreen' then
g_window.setFullscreen(value) g_window.setFullscreen(value)
elseif key == 'enableAudio' then elseif key == 'enableAudio' then
if g_sounds then g_sounds.setAudioEnabled(value)
g_sounds.setAudioEnabled(value)
end
if value then if value then
audioButton:setIcon('/images/topbuttons/audio') audioButton:setIcon('/images/topbuttons/audio')
else else
audioButton:setIcon('/images/topbuttons/audio_mute') audioButton:setIcon('/images/topbuttons/audio_mute')
end end
elseif key == 'enableMusicSound' then elseif key == 'enableMusicSound' then
if g_sounds then g_sounds.getChannel(SoundChannels.Music):setEnabled(value)
g_sounds.getChannel(SoundChannels.Music):setEnabled(value)
end
elseif key == 'musicSoundVolume' then elseif key == 'musicSoundVolume' then
if g_sounds then g_sounds.getChannel(SoundChannels.Music):setGain(value/100)
g_sounds.getChannel(SoundChannels.Music):setGain(value/100) audioPanel:getChildById('musicSoundVolumeLabel'):setText(tr('Music volume: %d', value))
end
soundPanel:getChildById('musicSoundVolumeLabel'):setText(tr('Music volume: %d', value))
elseif key == 'showLeftPanel' then elseif key == 'showLeftPanel' then
modules.game_interface.getLeftPanel():setOn(value) modules.game_interface.getLeftPanel():setOn(value)
elseif key == 'backgroundFrameRate' then elseif key == 'backgroundFrameRate' then
@ -233,18 +222,12 @@ function setOption(key, value, force)
gameMapPanel:setDrawNames(value) gameMapPanel:setDrawNames(value)
elseif key == 'displayHealth' then elseif key == 'displayHealth' then
gameMapPanel:setDrawHealthBars(value) gameMapPanel:setDrawHealthBars(value)
elseif key == 'displayMana' then
gameMapPanel:setDrawManaBar(value)
elseif key == 'displayText' then elseif key == 'displayText' then
gameMapPanel:setDrawTexts(value) gameMapPanel:setDrawTexts(value)
elseif key == 'dontStretchShrink' then elseif key == 'dontStretchShrink' then
addEvent(function() addEvent(function()
modules.game_interface.updateStretchShrink() modules.game_interface.updateStretchShrink()
end) end)
elseif key == 'turnDelay' then
generalPanel:getChildById('turnDelayLabel'):setText(tr('Turn delay: %sms', value))
elseif key == 'hotkeyDelay' then
generalPanel:getChildById('hotkeyDelayLabel'):setText(tr('Hotkey delay: %sms', value))
end end
-- change value for keybind updates -- change value for keybind updates

View File

@ -2,7 +2,7 @@ Module
name: client_options name: client_options
description: Create the options window description: Create the options window
author: edubart, BeniS author: edubart, BeniS
website: https://github.com/edubart/otclient website: www.otclient.info
sandboxed: true sandboxed: true
scripts: [ options ] scripts: [ options ]
@onLoad: init() @onLoad: init()

View File

@ -19,7 +19,7 @@ function AddServer.add()
local added, error = ServerList.add(host, port, protocol) local added, error = ServerList.add(host, port, protocol)
if not added then if not added then
displayErrorBox(tr('Error'), tr(error)) displayErrorBox(tr('Add Error'), tr(error))
else else
AddServer.hide() AddServer.hide()
end end

View File

@ -12,9 +12,7 @@ function ServerList.init()
serverTextList = serverListWindow:getChildById('serverList') serverTextList = serverListWindow:getChildById('serverList')
servers = g_settings.getNode('ServerList') or {} servers = g_settings.getNode('ServerList') or {}
if servers then ServerList.load()
ServerList.load()
end
end end
function ServerList.terminate() function ServerList.terminate()
@ -26,8 +24,8 @@ function ServerList.terminate()
end end
function ServerList.load() function ServerList.load()
for host, server in pairs(servers) do for k,server in pairs(servers) do
ServerList.add(host, server.port, server.protocol, true) ServerList.add(k, server.port, server.protocol, true)
end end
end end
@ -45,9 +43,7 @@ function ServerList.select()
end end
function ServerList.add(host, port, protocol, load) function ServerList.add(host, port, protocol, load)
if not host or not port or not protocol then if not load and servers[host] then
return false, 'Failed to load settings'
elseif not load and servers[host] then
return false, 'Server already exists' return false, 'Server already exists'
elseif host == '' or port == '' then elseif host == '' or port == '' then
return false, 'Required fields are missing' return false, 'Required fields are missing'

View File

@ -2,7 +2,7 @@ Module
name: client_serverlist name: client_serverlist
description: Manages a server list of previously entered servers description: Manages a server list of previously entered servers
author: BeniS author: BeniS
website: https://github.com/edubart/otclient website: www.otclient.info
dependencies: dependencies:
- client_entergame - client_entergame

View File

@ -0,0 +1,123 @@
UUID = nil
HOST = 'otclient.herokuapp.com'
PORT = 80
FIRST_REPORT_DELAY = 15
REPORT_DELAY = 60
sendReportEvent = nil
firstReportEvent = nil
function initUUID()
UUID = g_settings.getString('report-uuid')
if not UUID or #UUID ~= 36 then
UUID = g_crypt.genUUID()
g_settings.set('report-uuid', UUID)
end
end
function init()
connect(g_game, { onGameStart = onGameStart,
onGameEnd = onGameEnd })
initUUID()
end
function terminate()
disconnect(g_game, { onGameStart = onGameStart,
onGameEnd = onGameEnd })
removeEvent(firstReportEvent)
removeEvent(sendReportEvent)
end
function configure(host, port, delay)
if not host then return end
HOST = host
PORT = port or PORT
REPORT_DELAY = delay or REPORT_DELAY
end
function sendReport()
if not HOST then return end
local protocolHttp = ProtocolHttp.create()
protocolHttp.onConnect = onConnect
protocolHttp.onRecv = onRecv
protocolHttp.onError = onError
protocolHttp:connect(HOST, PORT)
end
function onGameStart()
if not HOST then return end
removeEvent(firstReportEvent)
removeEvent(sendReportEvent)
firstReportEvent = addEvent(sendReport, FIRST_REPORT_DELAY*1000)
sendReportEvent = cycleEvent(sendReport, REPORT_DELAY*1000)
end
function onGameEnd()
removeEvent(firstReportEvent)
removeEvent(sendReportEvent)
end
function onConnect(protocol)
if not g_game.isOnline() then
protocol:disconnect()
return
end
local post = ''
post = post .. 'uid=' .. UUID
post = post .. '&report_delay=' .. REPORT_DELAY
post = post .. '&os=' .. g_app.getOs()
post = post .. '&graphics_vendor=' .. g_graphics.getVendor()
post = post .. '&graphics_renderer=' .. g_graphics.getRenderer()
post = post .. '&graphics_version=' .. g_graphics.getVersion()
post = post .. '&painter_engine=' .. g_graphics.getPainterEngine()
post = post .. '&fps=' .. g_app.getBackgroundPaneFps()
post = post .. '&max_fps=' .. g_app.getBackgroundPaneMaxFps()
post = post .. '&fullscreen=' .. tostring(g_window.isFullscreen())
post = post .. '&window_width=' .. g_window.getWidth()
post = post .. '&window_height=' .. g_window.getHeight()
post = post .. '&player_name=' .. g_game.getCharacterName()
post = post .. '&world_name=' .. g_game.getWorldName()
post = post .. '&otserv_host=' .. G.host
post = post .. '&otserv_port=' .. G.port
post = post .. '&otserv_protocol=' .. g_game.getProtocolVersion()
post = post .. '&otserv_client=' .. g_game.getClientVersion()
post = post .. '&build_version=' .. g_app.getVersion()
post = post .. '&build_revision=' .. g_app.getBuildRevision()
post = post .. '&build_commit=' .. g_app.getBuildCommit()
post = post .. '&build_date=' .. g_app.getBuildDate()
post = post .. '&display_width=' .. g_window.getDisplayWidth()
post = post .. '&display_height=' .. g_window.getDisplayHeight()
post = post .. '&cpu=' .. g_platform.getCPUName()
post = post .. '&mem=' .. g_platform.getTotalSystemMemory()
post = post .. '&os_name=' .. g_platform.getOSName()
post = post .. getAdditionalData()
local message = ''
message = message .. "POST /report HTTP/1.1\r\n"
message = message .. "Host: " .. HOST .. "\r\n"
message = message .. "Accept: */*\r\n"
message = message .. "Connection: close\r\n"
message = message .. "Content-Type: application/x-www-form-urlencoded\r\n"
message = message .. "Content-Length: " .. post:len() .. "\r\n\r\n"
message = message .. post
protocol:send(message)
protocol:recv()
end
function getAdditionalData()
return ''
end
function onRecv(protocol, message)
if string.find(message, 'HTTP/1.1 200 OK') then
--pinfo('Stats sent to server successfully!')
end
protocol:disconnect()
end
function onError(protocol, message, code)
pdebug('Could not send statistics: ' .. message)
end

View File

@ -0,0 +1,9 @@
Module
name: client_stats
description: Sends client statistics to a server
author: baxnie
website: www.otclient.info
sandboxed: true
scripts: [ stats ]
@onLoad: init()
@onUnload: terminate()

View File

@ -2,7 +2,7 @@ Module
name: client_styles name: client_styles
description: Load client fonts and styles description: Load client fonts and styles
author: edubart author: edubart
website: https://github.com/edubart/otclient website: www.otclient.info
scripts: [ styles ] scripts: [ styles ]
sandboxed: true sandboxed: true
@onLoad: init() @onLoad: init()

View File

@ -30,10 +30,6 @@ local allLines = {}
-- private functions -- private functions
local function navigateCommand(step) local function navigateCommand(step)
if commandTextEdit:isMultiline() then
return
end
local numCommands = #commandHistory local numCommands = #commandHistory
if numCommands > 0 then if numCommands > 0 then
currentHistoryIndex = math.min(math.max(currentHistoryIndex + step, 0), numCommands) currentHistoryIndex = math.min(math.max(currentHistoryIndex + step, 0), numCommands)
@ -100,29 +96,16 @@ local function completeCommand()
end end
end end
local function doCommand(textWidget) local function doCommand()
local currentCommand = textWidget:getText() local currentCommand = commandTextEdit:getText()
executeCommand(currentCommand) executeCommand(currentCommand)
textWidget:clearText()
if commandTextEdit then
commandTextEdit:clearText()
end
return true return true
end end
local function addNewline(textWidget)
if not textWidget:isOn() then
textWidget:setOn(true)
end
textWidget:appendText('\n')
end
local function onCommandChange(textWidget, newText, oldText)
local _, newLineCount = string.gsub(newText, '\n', '\n')
textWidget:setHeight((newLineCount + 1) * textWidget.baseHeight)
if newLineCount == 0 and textWidget:isOn() then
textWidget:setOn(false)
end
end
local function onLog(level, message, time) local function onLog(level, message, time)
if disabled then return end if disabled then return end
-- avoid logging while reporting logs (would cause a infinite loop) -- avoid logging while reporting logs (would cause a infinite loop)
@ -146,8 +129,6 @@ function init()
commandHistory = g_settings.getList('terminal-history') commandHistory = g_settings.getList('terminal-history')
commandTextEdit = terminalWindow:getChildById('commandTextEdit') commandTextEdit = terminalWindow:getChildById('commandTextEdit')
commandTextEdit:setHeight(commandTextEdit.baseHeight)
connect(commandTextEdit, {onTextChange = onCommandChange})
g_keyboard.bindKeyPress('Up', function() navigateCommand(1) end, commandTextEdit) g_keyboard.bindKeyPress('Up', function() navigateCommand(1) end, commandTextEdit)
g_keyboard.bindKeyPress('Down', function() navigateCommand(-1) end, commandTextEdit) g_keyboard.bindKeyPress('Down', function() navigateCommand(-1) end, commandTextEdit)
g_keyboard.bindKeyPress('Ctrl+C', g_keyboard.bindKeyPress('Ctrl+C',
@ -157,7 +138,6 @@ function init()
return true return true
end, commandTextEdit) end, commandTextEdit)
g_keyboard.bindKeyDown('Tab', completeCommand, commandTextEdit) g_keyboard.bindKeyDown('Tab', completeCommand, commandTextEdit)
g_keyboard.bindKeyPress('Shift+Enter', addNewline, commandTextEdit)
g_keyboard.bindKeyDown('Enter', doCommand, commandTextEdit) g_keyboard.bindKeyDown('Enter', doCommand, commandTextEdit)
g_keyboard.bindKeyDown('Escape', hide, terminalWindow) g_keyboard.bindKeyDown('Escape', hide, terminalWindow)
@ -313,7 +293,7 @@ function addLine(text, color)
end end
function executeCommand(command) function executeCommand(command)
if command == nil or #string.gsub(command, '\n', '') == 0 then return end if command == nil or #command == 0 then return end
-- add command line -- add command line
addLine("> " .. command, "#ffffff") addLine("> " .. command, "#ffffff")

View File

@ -2,7 +2,7 @@ Module
name: client_terminal name: client_terminal
description: Terminal for executing lua functions description: Terminal for executing lua functions
author: edubart author: edubart
website: https://github.com/edubart/otclient website: www.otclient.info
scripts: [ terminal ] scripts: [ terminal ]
sandboxed: true sandboxed: true
@onLoad: init() @onLoad: init()

View File

@ -47,7 +47,7 @@ UIWindow
anchors.left: parent.left anchors.left: parent.left
anchors.right: terminalScroll.left anchors.right: terminalScroll.left
anchors.top: terminalScroll.top anchors.top: terminalScroll.top
anchors.bottom: commandTextEdit.top anchors.bottom: commandSymbolLabel.top
layout: layout:
type: verticalBox type: verticalBox
align-bottom: true align-bottom: true
@ -80,25 +80,14 @@ UIWindow
UITextEdit UITextEdit
id: commandTextEdit id: commandTextEdit
background: #aaaaaa11 height: 12
border-color: #aaaaaa88
&baseHeight: 12
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.left: commandSymbolLabel.right anchors.left: commandSymbolLabel.right
anchors.right: terminalScroll.left anchors.right: parent.right
margin-left: 1 margin-left: 1
padding-left: 2
font: terminus-10px font: terminus-10px
selection-color: black selection-color: black
selection-background-color: white selection-background-color: white
border-width-left: 0
border-width-top: 0
multiline: false
$on:
border-width-left: 1
border-width-top: 1
multiline: true
ResizeBorder ResizeBorder
id: bottomResizeBorder id: bottomResizeBorder

View File

@ -51,8 +51,6 @@ function init()
pingLabel = topMenu:getChildById('pingLabel') pingLabel = topMenu:getChildById('pingLabel')
fpsLabel = topMenu:getChildById('fpsLabel') fpsLabel = topMenu:getChildById('fpsLabel')
g_keyboard.bindKeyDown('Ctrl+Shift+T', toggle)
if g_game.isOnline() then if g_game.isOnline() then
online() online()
end end
@ -166,22 +164,3 @@ end
function getTopMenu() function getTopMenu()
return topMenu return topMenu
end end
function toggle()
local menu = getTopMenu()
if not menu then
return
end
if menu:isVisible() then
menu:hide()
modules.client_background.getBackground():addAnchor(AnchorTop, 'parent', AnchorTop)
modules.game_interface.getRootPanel():addAnchor(AnchorTop, 'parent', AnchorTop)
modules.game_interface.getShowTopMenuButton():show()
else
menu:show()
modules.client_background.getBackground():addAnchor(AnchorTop, 'topMenu', AnchorBottom)
modules.game_interface.getRootPanel():addAnchor(AnchorTop, 'topMenu', AnchorBottom)
modules.game_interface.getShowTopMenuButton():hide()
end
end

View File

@ -2,7 +2,7 @@ Module
name: client_topmenu name: client_topmenu
description: Create the top menu description: Create the top menu
author: edubart author: edubart
website: https://github.com/edubart/otclient website: www.otclient.info
scripts: [ topmenu ] scripts: [ topmenu ]
sandboxed: true sandboxed: true
@onLoad: init() @onLoad: init()

View File

@ -2,7 +2,7 @@ Module
name: corelib name: corelib
description: Contains core lua classes, functions and constants used by other modules description: Contains core lua classes, functions and constants used by other modules
author: OTClient team author: OTClient team
website: https://github.com/edubart/otclient website: www.otclient.info
reloadable: false reloadable: false
@onLoad: | @onLoad: |
@ -10,7 +10,6 @@ Module
dofile 'string' dofile 'string'
dofile 'table' dofile 'table'
dofile 'bitwise' dofile 'bitwise'
dofile 'struct'
dofile 'const' dofile 'const'
dofile 'util' dofile 'util'

View File

@ -26,11 +26,6 @@ local function retranslateKeyComboDesc(keyComboDesc)
if keyComboDesc == nil then if keyComboDesc == nil then
error('Unable to translate key combo \'' .. keyComboDesc .. '\'') error('Unable to translate key combo \'' .. keyComboDesc .. '\'')
end end
if type(keyComboDesc) == 'number' then
keyComboDesc = tostring(keyComboDesc)
end
local keyCombo = {} local keyCombo = {}
for i,currentKeyDesc in ipairs(keyComboDesc:split('+')) do for i,currentKeyDesc in ipairs(keyComboDesc:split('+')) do
for keyCode, keyDesc in pairs(KeyCodeDescs) do for keyCode, keyDesc in pairs(KeyCodeDescs) do

View File

@ -1,173 +0,0 @@
Struct = {}
function Struct.pack(format, ...)
local stream = {}
local vars = {...}
local endianness = true
for i = 1, format:len() do
local opt = format:sub(i, i)
if opt == '>' then
endianness = false
elseif opt:find('[bBhHiIlL]') then
local n = opt:find('[hH]') and 2 or opt:find('[iI]') and 4 or opt:find('[lL]') and 8 or 1
local val = tonumber(table.remove(vars, 1))
if val < 0 then
val = val + 2 ^ (n * 8 - 1)
end
local bytes = {}
for j = 1, n do
table.insert(bytes, string.char(val % (2 ^ 8)))
val = math.floor(val / (2 ^ 8))
end
if not endianness then
table.insert(stream, string.reverse(table.concat(bytes)))
else
table.insert(stream, table.concat(bytes))
end
elseif opt:find('[fd]') then
local val = tonumber(table.remove(vars, 1))
local sign = 0
if val < 0 then
sign = 1
val = -val
end
local mantissa, exponent = math.frexp(val)
if val == 0 then
mantissa = 0
exponent = 0
else
mantissa = (mantissa * 2 - 1) * math.ldexp(0.5, (opt == 'd') and 53 or 24)
exponent = exponent + ((opt == 'd') and 1022 or 126)
end
local bytes = {}
if opt == 'd' then
val = mantissa
for i = 1, 6 do
table.insert(bytes, string.char(math.floor(val) % (2 ^ 8)))
val = math.floor(val / (2 ^ 8))
end
else
table.insert(bytes, string.char(math.floor(mantissa) % (2 ^ 8)))
val = math.floor(mantissa / (2 ^ 8))
table.insert(bytes, string.char(math.floor(val) % (2 ^ 8)))
val = math.floor(val / (2 ^ 8))
end
table.insert(bytes, string.char(math.floor(exponent * ((opt == 'd') and 16 or 128) + val) % (2 ^ 8)))
val = math.floor((exponent * ((opt == 'd') and 16 or 128) + val) / (2 ^ 8))
table.insert(bytes, string.char(math.floor(sign * 128 + val) % (2 ^ 8)))
val = math.floor((sign * 128 + val) / (2 ^ 8))
if not endianness then
table.insert(stream, string.reverse(table.concat(bytes)))
else
table.insert(stream, table.concat(bytes))
end
elseif opt == 's' then
table.insert(stream, tostring(table.remove(vars, 1)))
table.insert(stream, string.char(0))
elseif opt == 'c' then
local n = format:sub(i + 1):match('%d+')
local length = tonumber(n)
if length > 0 then
local str = tostring(table.remove(vars, 1))
if length - str:len() > 0 then
str = str .. string.rep(' ', length - str:len())
end
table.insert(stream, str:sub(1, length))
end
i = i + n:len()
end
end
return table.concat(stream)
end
function Struct.unpack(format, stream)
local vars = {}
local iterator = 1
local endianness = true
for i = 1, format:len() do
local opt = format:sub(i, i)
if opt == '>' then
endianness = false
elseif opt:find('[bBhHiIlL]') then
local n = opt:find('[hH]') and 2 or opt:find('[iI]') and 4 or opt:find('[lL]') and 8 or 1
local signed = opt:lower() == opt
local val = 0
for j = 1, n do
local byte = string.byte(stream:sub(iterator, iterator))
if endianness then
val = val + byte * (2 ^ ((j - 1) * 8))
else
val = val + byte * (2 ^ ((n - j) * 8))
end
iterator = iterator + 1
end
if signed then
val = val - 2 ^ (n * 8 - 1)
end
table.insert(vars, val)
elseif opt:find('[fd]') then
local n = (opt == 'd') and 8 or 4
local x = stream:sub(iterator, iterator + n - 1)
iterator = iterator + n
if not endianness then
x = string.reverse(x)
end
local sign = 1
local mantissa = string.byte(x, (opt == 'd') and 7 or 3) % ((opt == 'd') and 16 or 128)
for i = n - 2, 1, -1 do
mantissa = mantissa * (2 ^ 8) + string.byte(x, i)
end
if string.byte(x, n) > 127 then
sign = -1
end
local exponent = (string.byte(x, n) % 128) * ((opt == 'd') and 16 or 2) + math.floor(string.byte(x, n - 1) / ((opt == 'd') and 16 or 128))
if exponent == 0 then
table.insert(vars, 0.0)
else
mantissa = (math.ldexp(mantissa, (opt == 'd') and -52 or -23) + 1) * sign
table.insert(vars, math.ldexp(mantissa, exponent - ((opt == 'd') and 1023 or 127)))
end
elseif opt == 's' then
local bytes = {}
for j = iterator, stream:len() do
if stream:sub(j, j) == string.char(0) then
break
end
table.insert(bytes, stream:sub(j, j))
end
local str = table.concat(bytes)
iterator = iterator + str:len() + 1
table.insert(vars, str)
elseif opt == 'c' then
local n = format:sub(i + 1):match('%d+')
table.insert(vars, stream:sub(iterator, iterator + tonumber(n)))
iterator = iterator + tonumber(n)
i = i + n:len()
end
end
return unpack(vars)
end

View File

@ -10,24 +10,13 @@ local function moveToolTip(first)
if not first and (not toolTipLabel:isVisible() or toolTipLabel:getOpacity() < 0.1) then return end if not first and (not toolTipLabel:isVisible() or toolTipLabel:getOpacity() < 0.1) then return end
local pos = g_window.getMousePosition() local pos = g_window.getMousePosition()
local windowSize = g_window.getSize()
local labelSize = toolTipLabel:getSize()
pos.x = pos.x + 1
pos.y = pos.y + 1 pos.y = pos.y + 1
local xdif = g_window.getSize().width - (pos.x + toolTipLabel:getWidth())
if windowSize.width - (pos.x + labelSize.width) < 10 then if xdif < 10 then
pos.x = pos.x - labelSize.width - 3 pos.x = pos.x - toolTipLabel:getWidth() - 3
else else
pos.x = pos.x + 10 pos.x = pos.x + 10
end end
if windowSize.height - (pos.y + labelSize.height) < 10 then
pos.y = pos.y - labelSize.height - 3
else
pos.y = pos.y + 10
end
toolTipLabel:setPosition(pos) toolTipLabel:setPosition(pos)
end end
@ -62,6 +51,7 @@ function g_tooltip.init()
toolTipLabel:setBackgroundColor('#111111cc') toolTipLabel:setBackgroundColor('#111111cc')
toolTipLabel:setTextAlign(AlignCenter) toolTipLabel:setTextAlign(AlignCenter)
toolTipLabel:hide() toolTipLabel:hide()
toolTipLabel.onMouseMove = function() moveToolTip() end
end) end)
end end
@ -88,18 +78,10 @@ function g_tooltip.display(text)
toolTipLabel:enable() toolTipLabel:enable()
g_effects.fadeIn(toolTipLabel, 100) g_effects.fadeIn(toolTipLabel, 100)
moveToolTip(true) moveToolTip(true)
connect(rootWidget, {
onMouseMove = moveToolTip,
})
end end
function g_tooltip.hide() function g_tooltip.hide()
g_effects.fadeOut(toolTipLabel, 100) g_effects.fadeOut(toolTipLabel, 100)
disconnect(rootWidget, {
onMouseMove = moveToolTip,
})
end end

View File

@ -19,14 +19,13 @@ function UIComboBox:clearOptions()
self:clearText() self:clearText()
end end
function UIComboBox:isOption(text) function UIComboBox:getOption(text)
if not self.options then return false end if not self.options then return nil end
for i,v in ipairs(self.options) do for i,v in ipairs(self.options) do
if v.text == text then if v.text == text then
return true return nil
end end
end end
return false
end end
function UIComboBox:setOption(text, dontSignal) function UIComboBox:setOption(text, dontSignal)

View File

@ -3,7 +3,6 @@ UIMiniWindow = extends(UIWindow, "UIMiniWindow")
function UIMiniWindow.create() function UIMiniWindow.create()
local miniwindow = UIMiniWindow.internalCreate() local miniwindow = UIMiniWindow.internalCreate()
miniwindow.UIMiniWindowContainer = true
return miniwindow return miniwindow
end end

View File

@ -69,7 +69,7 @@ function UIMiniWindowContainer:fitAll(noRemoveChild)
end end
local child = children[i] local child = children[i]
if child ~= noRemoveChild and child:isVisible() then if child ~= noRemoveChild then
local childHeight = child:getHeight() local childHeight = child:getHeight()
sumHeight = sumHeight - childHeight sumHeight = sumHeight - childHeight
table.insert(removeChildren, child) table.insert(removeChildren, child)
@ -83,7 +83,7 @@ function UIMiniWindowContainer:fitAll(noRemoveChild)
end end
function UIMiniWindowContainer:onDrop(widget, mousePos) function UIMiniWindowContainer:onDrop(widget, mousePos)
if widget.UIMiniWindowContainer then if widget:getClassName() == 'UIMiniWindow' then
local oldParent = widget:getParent() local oldParent = widget:getParent()
if oldParent == self then if oldParent == self then
return true return true

View File

@ -6,7 +6,7 @@ local function onTabClick(tab)
tab.tabBar:selectTab(tab) tab.tabBar:selectTab(tab)
end end
local function updateMargins(tabBar) local function updateMargins(tabBar, ignored)
if #tabBar.tabs == 0 then return end if #tabBar.tabs == 0 then return end
local currentMargin = 0 local currentMargin = 0
@ -17,19 +17,19 @@ local function updateMargins(tabBar)
end end
local function updateNavigation(tabBar) local function updateNavigation(tabBar)
if tabBar.prevNavigation then if prevNavigation then
if #tabBar.preTabs > 0 or table.find(tabBar.tabs, tabBar.currentTab) ~= 1 then if #tabBar.preTabs > 0 or table.find(tabBar.tabs, tabBar.currentTab) ~= 1 then
tabBar.prevNavigation:enable() prevNavigation:enable()
else else
tabBar.prevNavigation:disable() prevNavigation:disable()
end end
end end
if tabBar.nextNavigation then if nextNavigation then
if #tabBar.postTabs > 0 or table.find(tabBar.tabs, tabBar.currentTab) ~= #tabBar.tabs then if #tabBar.postTabs > 0 or table.find(tabBar.tabs, tabBar.currentTab) ~= #tabBar.tabs then
tabBar.nextNavigation:enable() nextNavigation:enable()
else else
tabBar.nextNavigation:disable() nextNavigation:disable()
end end
end end
end end
@ -187,7 +187,7 @@ local function onTabDragMove(tab, mousePos, mouseMoved)
end end
local function tabBlink(tab, step) local function tabBlink(tab, step)
local step = step or 0 step = step or 0
tab:setOn(not tab:isOn()) tab:setOn(not tab:isOn())
removeEvent(tab.blinkEvent) removeEvent(tab.blinkEvent)
@ -218,19 +218,6 @@ function UIMoveableTabBar.create()
return tabbar return tabbar
end end
function UIMoveableTabBar:onDestroy()
if self.prevNavigation then
self.prevNavigation:disable()
end
if self.nextNavigation then
self.nextNavigation:disable()
end
self.nextNavigation = nil
self.prevNavigation = nil
end
function UIMoveableTabBar:setContentWidget(widget) function UIMoveableTabBar:setContentWidget(widget)
self.contentWidget = widget self.contentWidget = widget
if #self.tabs > 0 then if #self.tabs > 0 then
@ -309,11 +296,8 @@ function UIMoveableTabBar:moveTab(tab, units)
end end
function UIMoveableTabBar:onStyleApply(styleName, styleNode) function UIMoveableTabBar:onStyleApply(styleName, styleNode)
if styleNode['movable'] then if styleNode['moveable'] then
self.tabsMoveable = styleNode['movable'] self.tabsMoveable = styleNode['moveable']
end
if styleNode['tab-spacing'] then
self:setTabSpacing(styleNode['tab-spacing'])
end end
end end
@ -334,12 +318,9 @@ function UIMoveableTabBar:removeTab(tab)
end end
if self.currentTab == tab then if self.currentTab == tab then
self:selectPrevTab()
if #self.tabs == 1 then if #self.tabs == 1 then
self.currentTab = nil self.currentTab = nil
elseif index == #self.tabs then
self:selectPrevTab()
else
self:selectNextTab()
end end
end end
table.remove(tabTable, index) table.remove(tabTable, index)
@ -388,11 +369,6 @@ function UIMoveableTabBar:selectTab(tab)
tab:setOn(false) tab:setOn(false)
tab.blinking = false tab.blinking = false
if tab.blinkEvent then
removeEvent(tab.blinkEvent)
tab.blinkEvent = nil
end
local parent = tab:getParent() local parent = tab:getParent()
parent:focusChild(tab, MouseFocusReason) parent:focusChild(tab, MouseFocusReason)
updateNavigation(self) updateNavigation(self)
@ -491,14 +467,14 @@ function UIMoveableTabBar:getCurrentTab()
end end
function UIMoveableTabBar:setNavigation(prevButton, nextButton) function UIMoveableTabBar:setNavigation(prevButton, nextButton)
self.prevNavigation = prevButton prevNavigation = prevButton
self.nextNavigation = nextButton nextNavigation = nextButton
if self.prevNavigation then if prevNavigation then
self.prevNavigation.onClick = function() self:selectPrevTab() end prevNavigation.onClick = function() self:selectPrevTab() end
end end
if self.nextNavigation then if nextNavigation then
self.nextNavigation.onClick = function() self:selectNextTab() end nextNavigation.onClick = function() self:selectNextTab() end
end end
updateNavigation(self) updateNavigation(self)
end end

View File

@ -8,7 +8,6 @@ function UIPopupMenu.create()
local layout = UIVerticalLayout.create(menu) local layout = UIVerticalLayout.create(menu)
layout:setFitChildren(true) layout:setFitChildren(true)
menu:setLayout(layout) menu:setLayout(layout)
menu.isGameMenu = false
return menu return menu
end end
@ -35,7 +34,6 @@ function UIPopupMenu:display(pos)
rootWidget:addChild(self) rootWidget:addChild(self)
self:setPosition(pos) self:setPosition(pos)
self:grabMouse() self:grabMouse()
self:focus()
--self:grabKeyboard() --self:grabKeyboard()
currentMenu = self currentMenu = self
end end
@ -78,10 +76,6 @@ function UIPopupMenu:addSeparator()
g_ui.createWidget(self:getStyleName() .. 'Separator', self) g_ui.createWidget(self:getStyleName() .. 'Separator', self)
end end
function UIPopupMenu:setGameMenu(state)
self.isGameMenu = state
end
function UIPopupMenu:onDestroy() function UIPopupMenu:onDestroy()
if currentMenu == self then if currentMenu == self then
currentMenu = nil currentMenu = nil
@ -111,12 +105,4 @@ local function onRootGeometryUpdate()
currentMenu:destroy() currentMenu:destroy()
end end
end end
connect(rootWidget, { onGeometryChange = onRootGeometryUpdate} )
local function onGameEnd()
if currentMenu and currentMenu.isGameMenu then
currentMenu:destroy()
end
end
connect(rootWidget, { onGeometryChange = onRootGeometryUpdate })
connect(g_game, { onGameEnd = onGameEnd } )

View File

@ -28,7 +28,7 @@ local function calcValues(self)
proportion = math.min(math.max(self.step, 1), range)/range proportion = math.min(math.max(self.step, 1), range)/range
end end
local px = math.max(proportion * pxrange, 6) local px = math.max(proportion * pxrange, 10)
px = px - px % 2 + 1 px = px - px % 2 + 1
local offset = 0 local offset = 0
@ -126,8 +126,8 @@ end
function UIScrollBar:onSetup() function UIScrollBar:onSetup()
self.setupDone = true self.setupDone = true
local sliderButton = self:getChildById('sliderButton') local sliderButton = self:getChildById('sliderButton')
g_mouse.bindAutoPress(self:getChildById('decrementButton'), function() self:onDecrement() end, 300) g_mouse.bindAutoPress(self:getChildById('decrementButton'), function() self:decrement() end, 300)
g_mouse.bindAutoPress(self:getChildById('incrementButton'), function() self:onIncrement() end, 300) g_mouse.bindAutoPress(self:getChildById('incrementButton'), function() self:increment() end, 300)
g_mouse.bindPressMove(sliderButton, function(mousePos, mouseMoved) parseSliderPos(self, sliderButton, mousePos, mouseMoved) end) g_mouse.bindPressMove(sliderButton, function(mousePos, mouseMoved) parseSliderPos(self, sliderButton, mousePos, mouseMoved) end)
g_mouse.bindPress(sliderButton, function(mousePos, mouseButton) parseSliderPress(self, sliderButton, mousePos, mouseButton) end) g_mouse.bindPress(sliderButton, function(mousePos, mouseButton) parseSliderPress(self, sliderButton, mousePos, mouseButton) end)
@ -158,26 +158,6 @@ function UIScrollBar:onStyleApply(styleName, styleNode)
end end
end end
function UIScrollBar:onDecrement()
if g_keyboard.isCtrlPressed() then
self:decrement(self.value)
elseif g_keyboard.isShiftPressed() then
self:decrement(10)
else
self:decrement()
end
end
function UIScrollBar:onIncrement()
if g_keyboard.isCtrlPressed() then
self:increment(self.maximum)
elseif g_keyboard.isShiftPressed() then
self:increment(10)
else
self:increment()
end
end
function UIScrollBar:decrement(count) function UIScrollBar:decrement(count)
count = count or self.step count = count or self.step
self:setValue(self.value - count) self:setValue(self.value - count)
@ -284,4 +264,4 @@ function UIScrollBar:getStep() return self.step end
function UIScrollBar:getOrientation() return self.orientation end function UIScrollBar:getOrientation() return self.orientation end
function UIScrollBar:getShowValue() return self.showValue end function UIScrollBar:getShowValue() return self.showValue end
function UIScrollBar:getSymbol() return self.symbol end function UIScrollBar:getSymbol() return self.symbol end
function UIScrollBar:getMouseScroll() return self.mouseScroll end function UIScrollBar:getMouseScroll() return self.mouseScroll end

View File

@ -12,7 +12,7 @@ function UISpinBox.create()
spinbox.step = 1 spinbox.step = 1
spinbox.firstchange = true spinbox.firstchange = true
spinbox.mouseScroll = true spinbox.mouseScroll = true
spinbox:setText("1") spinbox:setText("0")
spinbox:setValue(1) spinbox:setValue(1)
return spinbox return spinbox
end end
@ -23,7 +23,7 @@ function UISpinBox:onSetup()
end end
function UISpinBox:onMouseWheel(mousePos, direction) function UISpinBox:onMouseWheel(mousePos, direction)
if not self.mouseScroll then if not self.mouseScroll then
return false return false
end end
if direction == MouseWheelUp then if direction == MouseWheelUp then
@ -66,15 +66,7 @@ function UISpinBox:onTextChange(text, oldText)
end end
function UISpinBox:onValueChange(value) function UISpinBox:onValueChange(value)
-- nothing to do -- nothing todo
end
function UISpinBox:onFocusChange(focused)
if not focused then
if self:getText():len() == 0 then
self:setText(self.minimum)
end
end
end end
function UISpinBox:onStyleApply(styleName, styleNode) function UISpinBox:onStyleApply(styleName, styleNode)
@ -117,16 +109,14 @@ function UISpinBox:down()
self:setValue(self.value - self.step) self:setValue(self.value - self.step)
end end
function UISpinBox:setValue(value, dontSignal) function UISpinBox:setValue(value)
value = value or 0 value = value or 0
value = math.max(math.min(self.maximum, value), self.minimum) value = math.max(math.min(self.maximum, value), self.minimum)
if value == self.value then return end if value == self.value then return end
self.value = value
if self:getText():len() > 0 then if self:getText():len() > 0 then
self:setText(value) self:setText(value)
end end
self.value = value
local upButton = self:getChildById('up') local upButton = self:getChildById('up')
local downButton = self:getChildById('down') local downButton = self:getChildById('down')
@ -137,9 +127,7 @@ function UISpinBox:setValue(value, dontSignal)
downButton:setEnabled(self.maximum ~= self.minimum and self.value ~= self.minimum) downButton:setEnabled(self.maximum ~= self.minimum and self.value ~= self.minimum)
end end
if not dontSignal then signalcall(self.onValueChange, self, value)
signalcall(self.onValueChange, self, value)
end
end end
function UISpinBox:getValue() function UISpinBox:getValue()

View File

@ -38,7 +38,6 @@ function UITabBar:addTab(text, panel, icon)
end end
local tab = g_ui.createWidget(self:getStyleName() .. 'Button', self.buttonsPanel) local tab = g_ui.createWidget(self:getStyleName() .. 'Button', self.buttonsPanel)
panel.isTab = true panel.isTab = true
tab.tabPanel = panel tab.tabPanel = panel
tab.tabBar = self tab.tabBar = self
@ -77,13 +76,7 @@ function UITabBar:removeTab(tab)
local index = table.find(self.tabs, tab) local index = table.find(self.tabs, tab)
if index == nil then return end if index == nil then return end
if self.currentTab == tab then if self.currentTab == tab then
if #self.tabs == 1 then self:selectPrevTab()
self.currentTab = nil
elseif index == #self.tabs then
self:selectPrevTab()
else
self:selectNextTab()
end
end end
table.remove(self.tabs, index) table.remove(self.tabs, index)
tab:destroy() tab:destroy()

View File

@ -3,45 +3,33 @@
TODO: TODO:
* Make table headers more robust. * Make table headers more robust.
* Get dynamic row heights working with text wrapping. * Get dynamic row heights working with text wrapping.
* Every second row different background color applied.
]] ]]
TABLE_SORTING_ASC = 0
TABLE_SORTING_DESC = 1
UITable = extends(UIWidget, "UITable") UITable = extends(UIWidget, "UITable")
-- Initialize default values local HEADER_ID = 'row0'
function UITable.create() function UITable.create()
local table = UITable.internalCreate() local table = UITable.internalCreate()
table.headerRow = nil table.headerRow = nil
table.headerColumns = {}
table.dataSpace = nil table.dataSpace = nil
table.rows = {} table.rows = {}
table.rowBaseStyle = nil table.rowBaseStyle = nil
table.columns = {} table.columns = {}
table.columnWidth = {}
table.columBaseStyle = nil table.columBaseStyle = nil
table.headerRowBaseStyle = nil table.headerRowBaseStyle = nil
table.headerColumnBaseStyle = nil table.headerColumnBaseStyle = nil
table.selectedRow = nil table.selectedRow = nil
table.defaultColumnWidth = 80
table.sortColumn = -1
table.sortType = TABLE_SORTING_ASC
table.autoSort = false
return table return table
end end
-- Clear table values
function UITable:onDestroy() function UITable:onDestroy()
for _,row in pairs(self.rows) do for k,row in pairs(self.rows) do
row.onClick = nil row.onClick = nil
end end
self.rows = {} self.rows = {}
self.columns = {} self.columns = {}
self.headerRow = nil self.headerRow = {}
self.headerColumns = {}
self.columnWidth = {}
self.selectedRow = nil self.selectedRow = nil
if self.dataSpace then if self.dataSpace then
@ -50,58 +38,36 @@ function UITable:onDestroy()
end end
end end
-- Detect if a header is already defined
function UITable:onSetup()
local header = self:getChildById('header')
if header then
self:setHeader(header)
end
end
-- Parse table related styles
function UITable:onStyleApply(styleName, styleNode) function UITable:onStyleApply(styleName, styleNode)
for name, value in pairs(styleNode) do for name, value in pairs(styleNode) do
if value ~= false then if name == 'table-data' then
if name == 'table-data' then addEvent(function()
addEvent(function() self:setTableData(self:getParent():getChildById(value))
self:setTableData(self:getParent():getChildById(value)) end)
end) elseif name == 'column-style' then
elseif name == 'column-style' then addEvent(function()
addEvent(function() self:setColumnStyle(value)
self:setColumnStyle(value) end)
end) elseif name == 'row-style' then
elseif name == 'row-style' then addEvent(function()
addEvent(function() self:setRowStyle(value)
self:setRowStyle(value) end)
end) elseif name == 'header-column-style' then
elseif name == 'header-column-style' then addEvent(function()
addEvent(function() self:setHeaderColumnStyle(value)
self:setHeaderColumnStyle(value) end)
end) elseif name == 'header-row-style' then
elseif name == 'header-row-style' then addEvent(function()
addEvent(function() self:setHeaderRowStyle(value)
self:setHeaderRowStyle(value) end)
end)
end
end end
end end
end end
function UITable:setColumnWidth(width)
if self:hasHeader() then return end
self.columnWidth = width
end
function UITable:setDefaultColumnWidth(width)
self.defaultColumnWidth = width
end
-- Check if the table has a header
function UITable:hasHeader() function UITable:hasHeader()
return self.headerRow ~= nil return self.headerRow ~= nil
end end
-- Clear all rows
function UITable:clearData() function UITable:clearData()
if not self.dataSpace then if not self.dataSpace then
return return
@ -112,42 +78,16 @@ function UITable:clearData()
self.rows = {} self.rows = {}
end end
-- Set existing child as header function UITable:addHeaderRow(data)
function UITable:setHeader(headerWidget)
self:removeHeader()
if self.dataSpace then
local newHeight = self.dataSpace:getHeight()-headerRow:getHeight()-self.dataSpace:getMarginTop()
self.dataSpace:applyStyle({ height = newHeight })
end
self.headerColumns = {}
self.columnWidth = {}
for colId, column in pairs(headerWidget:getChildren()) do
column.colId = colId
column.table = self
table.insert(self.columnWidth, column:getWidth())
table.insert(self.headerColumns, column)
end
self.headerRow = headerWidget
end
-- Create and add header from table data
function UITable:addHeader(data)
if not data or type(data) ~= 'table' then if not data or type(data) ~= 'table' then
g_logger.error('UITable:addHeaderRow - table columns must be provided in a table') g_logger.error('UITable:addHeaderRow - table columns must be provided in a table')
return return
end end
self:removeHeader()
-- build header columns -- build header columns
local columns = {} local columns = {}
for colId, column in pairs(data) do for _, column in pairs(data) do
local col = g_ui.createWidget(self.headerColumnBaseStyle) local col = g_ui.createWidget(self.headerColumnBaseStyle)
col.colId = colId
col.table = self
for type, value in pairs(column) do for type, value in pairs(column) do
if type == 'width' then if type == 'width' then
col:setWidth(value) col:setWidth(value)
@ -164,37 +104,26 @@ function UITable:addHeader(data)
-- create a new header -- create a new header
local headerRow = g_ui.createWidget(self.headerRowBaseStyle, self) local headerRow = g_ui.createWidget(self.headerRowBaseStyle, self)
local newHeight = self.dataSpace:getHeight()-headerRow:getHeight()-self.dataSpace:getMarginTop() local newHeight = (self.dataSpace:getHeight()-headerRow:getHeight())-self.dataSpace:getMarginTop()
self.dataSpace:applyStyle({ height = newHeight }) self.dataSpace:applyStyle({ height = newHeight })
headerRow:setId('header') headerRow:setId(HEADER_ID)
self.headerColumns = {}
self.columnWidth = {}
for _, column in pairs(columns) do for _, column in pairs(columns) do
headerRow:addChild(column) headerRow:addChild(column)
table.insert(self.columnWidth, column:getWidth()) self.columns[HEADER_ID] = column
table.insert(self.headerColumns, column)
end end
headerRow.onClick = function(headerRow) self:selectRow(headerRow) end
self.headerRow = headerRow self.headerRow = headerRow
return headerRow return headerRow
end end
-- Remove header function UITable:removeHeaderRow()
function UITable:removeHeader() self.headerRow:destroy()
if self:hasHeader() then self.headerRow = nil
if self.dataSpace then
local newHeight = self.dataSpace:getHeight()+self.headerRow:getHeight()+self.dataSpace:getMarginTop()
self.dataSpace:applyStyle({ height = newHeight })
end
self.headerColumns = {}
self.columnWidth = {}
self.headerRow:destroy()
self.headerRow = nil
end
end end
function UITable:addRow(data, height) function UITable:addRow(data, ref, height)
if not self.dataSpace then if not self.dataSpace then
g_logger.error('UITable:addRow - table data space has not been set, cannot add rows.') g_logger.error('UITable:addRow - table data space has not been set, cannot add rows.')
return return
@ -205,123 +134,41 @@ function UITable:addRow(data, height)
end end
local row = g_ui.createWidget(self.rowBaseStyle) local row = g_ui.createWidget(self.rowBaseStyle)
row.table = self if ref then row.ref = ref end
if height then row:setHeight(height) end if height then row:setHeight(height) end
local rowId = #self.rows + 1 local rowId = #self.rows
row.rowId = rowId row:setId('row'..(rowId < 1 and 1 or rowId))
row:setId('row'..rowId)
row:updateBackgroundColor()
self.columns[rowId] = {} for _, column in pairs(data) do
for colId, column in pairs(data) do
local col = g_ui.createWidget(self.columBaseStyle, row) local col = g_ui.createWidget(self.columBaseStyle, row)
if column.width then for type, value in pairs(column) do
col:setWidth(column.width) if type == 'width' then
else col:setWidth(value)
col:setWidth(self.columnWidth[colId] or self.defaultColumnWidth) elseif type == 'height' then
col:setHeight(value)
elseif type == 'text' then
col:setText(value)
end
end end
if column.height then self.columns[rowId] = col
col:setHeight(column.height)
end
if column.text then
col:setText(column.text)
end
if column.sortvalue then
col.sortvalue = column.sortvalue
else
col.sortvalue = column.text or 0
end
table.insert(self.columns[rowId], col)
end end
row.onFocusChange = function(row, focused)
if focused then self:selectRow(row) end
end
self.dataSpace:addChild(row) self.dataSpace:addChild(row)
table.insert(self.rows, row) table.insert(self.rows, row)
if self.autoSort then
self:sort()
end
return row return row
end end
-- Update row indices and background color
function UITable:updateRows()
for rowId = 1, #self.rows do
local row = self.rows[rowId]
row.rowId = rowId
row:setId('row'..rowId)
row:updateBackgroundColor()
end
end
-- Removes the given row widget from the table
function UITable:removeRow(row) function UITable:removeRow(row)
if self.selectedRow == row then if self.selectedRow == row then
self:selectRow(nil) self:selectRow(nil)
end end
row.onClick = nil row.onClick = nil
row.table = nil table.removevalue(self.rows, row)
table.remove(self.columns, row.rowId)
table.remove(self.rows, row.rowId)
self.dataSpace:removeChild(row)
self:updateRows()
end
function UITable:toggleSorting(enabled)
self.autoSort = enabled
end
function UITable:setSorting(colId, sortType)
self.headerColumns[colId]:focus()
if sortType then
self.sortType = sortType
elseif self.sortColumn == colId then
if self.sortType == TABLE_SORTING_ASC then
self.sortType = TABLE_SORTING_DESC
else
self.sortType = TABLE_SORTING_ASC
end
else
self.sortType = TABLE_SORTING_ASC
end
self.sortColumn = colId
end
function UITable:sort()
if self.sortColumn <= 0 then
return
end
if self.sortType == TABLE_SORTING_ASC then
table.sort(self.rows, function(rowA, b)
return rowA:getChildByIndex(self.sortColumn).sortvalue < b:getChildByIndex(self.sortColumn).sortvalue
end)
else
table.sort(self.rows, function(rowA, b)
return rowA:getChildByIndex(self.sortColumn).sortvalue > b:getChildByIndex(self.sortColumn).sortvalue
end)
end
if self.dataSpace then
for _, child in pairs(self.dataSpace:getChildren()) do
self.dataSpace:removeChild(child)
end
end
self:updateRows()
self.columns = {}
for _, row in pairs(self.rows) do
if self.dataSpace then
self.dataSpace:addChild(row)
end
self.columns[row.rowId] = {}
for _, column in pairs(row:getChildren()) do
table.insert(self.columns[row.rowId], column)
end
end
end end
function UITable:selectRow(selectedRow) function UITable:selectRow(selectedRow)
@ -342,34 +189,21 @@ function UITable:selectRow(selectedRow)
end end
function UITable:setTableData(tableData) function UITable:setTableData(tableData)
local headerHeight = 0
if self.headerRow then
headerHeight = self.headerRow:getHeight()
end
self.dataSpace = tableData self.dataSpace = tableData
self.dataSpace:applyStyle({ height = self:getHeight()-headerHeight-self:getMarginTop() }) self.dataSpace:applyStyle({ height = self:getHeight() })
end end
function UITable:setRowStyle(style, dontUpdate) function UITable:setRowStyle(style)
self.rowBaseStyle = style self.rowBaseStyle = style
for _, row in pairs(self.rows) do
if not dontUpdate then row:setStyle(style)
for _, row in pairs(self.rows) do
row:setStyle(style)
end
end end
end end
function UITable:setColumnStyle(style, dontUpdate) function UITable:setColumnStyle(style)
self.columBaseStyle = style self.columBaseStyle = style
for _, col in pairs(self.columns) do
if not dontUpdate then col:setStyle(style)
for _, columns in pairs(self.columns) do
for _, col in pairs(columns) do
col:setStyle(style)
end
end
end end
end end
@ -382,51 +216,7 @@ end
function UITable:setHeaderColumnStyle(style) function UITable:setHeaderColumnStyle(style)
self.headerColumnBaseStyle = style self.headerColumnBaseStyle = style
for _, col in pairs(self.headerColumns) do if table.haskey(HEADER_ID) then
col:setStyle(style) self.columns[HEADER_ID]:setStyle(style)
end
end
UITableRow = extends(UIWidget, "UITableRow")
function UITableRow:onFocusChange(focused)
if focused then
if self.table then self.table:selectRow(self) end
end
end
function UITableRow:onStyleApply(styleName, styleNode)
for name,value in pairs(styleNode) do
if name == 'even-background-color' then
self.evenBackgroundColor = value
elseif name == 'odd-background-color' then
self.oddBackgroundColor = value
end
end
end
function UITableRow:updateBackgroundColor()
self.backgroundColor = nil
local isEven = (self.rowId % 2 == 0)
if isEven and self.evenBackgroundColor then
self.backgroundColor = self.evenBackgroundColor
elseif not isEven and self.oddBackgroundColor then
self.backgroundColor = self.oddBackgroundColor
end
if self.backgroundColor then
self:mergeStyle({ ['background-color'] = self.backgroundColor })
end
end
UITableHeaderColumn = extends(UIButton, "UITableHeaderColumn")
function UITableHeaderColumn:onClick()
if self.table then
self.table:setSorting(self.colId)
self.table:sort()
end end
end end

View File

@ -296,16 +296,6 @@ function numbertoboolean(number)
end end
end end
function protectedcall(func, ...)
local status, ret = pcall(func, ...)
if status then
return ret
end
perror(ret)
return false
end
function signalcall(param, ...) function signalcall(param, ...)
if type(param) == 'function' then if type(param) == 'function' then
local status, ret = pcall(param, ...) local status, ret = pcall(param, ...)
@ -323,7 +313,7 @@ function signalcall(param, ...)
perror(ret) perror(ret)
end end
end end
elseif param ~= nil then elseif func ~= nil then
error('attempt to call a non function value') error('attempt to call a non function value')
end end
return false return false

View File

@ -244,32 +244,26 @@ function doCreatureFitFilters(creature)
local localPlayer = g_game.getLocalPlayer() local localPlayer = g_game.getLocalPlayer()
if pos.z ~= localPlayer:getPosition().z or not creature:canBeSeen() then return false end if pos.z ~= localPlayer:getPosition().z or not creature:canBeSeen() then return false end
return true
end
function doShowCreatureAtBattle(creature) local hidePlayers = hidePlayersButton:isChecked()
if doCreatureFitFilters(creature) then local hideNPCs = hideNPCsButton:isChecked()
local hidePlayers = hidePlayersButton:isChecked() local hideMonsters = hideMonstersButton:isChecked()
local hideNPCs = hideNPCsButton:isChecked() local hideSkulls = hideSkullsButton:isChecked()
local hideMonsters = hideMonstersButton:isChecked() local hideParty = hidePartyButton:isChecked()
local hideSkulls = hideSkullsButton:isChecked()
local hideParty = hidePartyButton:isChecked()
if hidePlayers and creature:isPlayer() then if hidePlayers and creature:isPlayer() then
return false return false
elseif hideNPCs and creature:isNpc() then elseif hideNPCs and creature:isNpc() then
return false return false
elseif hideMonsters and creature:isMonster() then elseif hideMonsters and creature:isMonster() then
return false return false
elseif hideSkulls and creature:isPlayer() and creature:getSkull() == SkullNone then elseif hideSkulls and creature:isPlayer() and creature:getSkull() == SkullNone then
return false return false
elseif hideParty and creature:getShield() > ShieldWhiteBlue then elseif hideParty and creature:getShield() > ShieldWhiteBlue then
return false return false
end
return true
end end
return false
return true
end end
function onCreatureHealthPercentChange(creature, health) function onCreatureHealthPercentChange(creature, health)
@ -458,7 +452,7 @@ function addCreature(creature)
end end
local localPlayer = g_game.getLocalPlayer() local localPlayer = g_game.getLocalPlayer()
battleButton:setVisible(localPlayer:hasSight(creature:getPosition()) and creature:canBeSeen() and doShowCreatureAtBattle(creature)) battleButton:setVisible(localPlayer:hasSight(creature:getPosition()) and creature:canBeSeen())
end end
function removeAllCreatures() function removeAllCreatures()
@ -490,10 +484,10 @@ function onBattleButtonMouseRelease(self, mousePosition, mouseButton)
if ((g_mouse.isPressed(MouseLeftButton) and mouseButton == MouseRightButton) if ((g_mouse.isPressed(MouseLeftButton) and mouseButton == MouseRightButton)
or (g_mouse.isPressed(MouseRightButton) and mouseButton == MouseLeftButton)) then or (g_mouse.isPressed(MouseRightButton) and mouseButton == MouseLeftButton)) then
mouseWidget.cancelNextRelease = true mouseWidget.cancelNextRelease = true
g_game.look(self.creature, true) g_game.look(self.creature)
return true return true
elseif mouseButton == MouseLeftButton and g_keyboard.isShiftPressed() then elseif mouseButton == MouseLeftButton and g_keyboard.isShiftPressed() then
g_game.look(self.creature, true) g_game.look(self.creature)
return true return true
elseif mouseButton == MouseRightButton and not g_mouse.isPressed(MouseLeftButton) then elseif mouseButton == MouseRightButton and not g_mouse.isPressed(MouseLeftButton) then
modules.game_interface.createThingMenu(mousePosition, nil, nil, self.creature) modules.game_interface.createThingMenu(mousePosition, nil, nil, self.creature)

View File

@ -2,7 +2,7 @@ Module
name: game_battle name: game_battle
description: Manage battle window description: Manage battle window
author: andrefaramir, BeniS author: andrefaramir, BeniS
website: https://github.com/edubart/otclient website: www.otclient.info
sandboxed: true sandboxed: true
scripts: [ battle ] scripts: [ battle ]
@onLoad: init() @onLoad: init()

View File

@ -2,7 +2,7 @@ Module
name: game_bugreport name: game_bugreport
description: Bug report interface (Ctrl+Z) description: Bug report interface (Ctrl+Z)
author: edubart author: edubart
website: https://github.com/edubart/otclient website: www.otclient.info
scripts: [ bugreport ] scripts: [ bugreport ]
sandboxed: true sandboxed: true
@onLoad: init() @onLoad: init()

View File

@ -15,8 +15,7 @@ fightModeRadioGroup = nil
pvpModeRadioGroup = nil pvpModeRadioGroup = nil
function init() function init()
combatControlsButton = modules.client_topmenu.addRightGameToggleButton('combatControlsButton', combatControlsButton = modules.client_topmenu.addRightGameToggleButton('combatControlsButton', tr('Combat Controls'), '/images/topbuttons/combatcontrols', toggle)
tr('Combat Controls'), '/images/topbuttons/combatcontrols', toggle)
combatControlsButton:setOn(true) combatControlsButton:setOn(true)
combatControlsWindow = g_ui.loadUI('combatcontrols', modules.game_interface.getRightPanel()) combatControlsWindow = g_ui.loadUI('combatcontrols', modules.game_interface.getRightPanel())
combatControlsWindow:disableResize() combatControlsWindow:disableResize()

View File

@ -2,7 +2,7 @@ Module
name: game_combatcontrols name: game_combatcontrols
description: Combat controls window description: Combat controls window
author: edubart, BeniS author: edubart, BeniS
website: https://github.com/edubart/otclient website: www.otclient.info
sandboxed: true sandboxed: true
scripts: [ combatcontrols ] scripts: [ combatcontrols ]
@onLoad: init() @onLoad: init()

View File

@ -25,7 +25,7 @@ MainWindow
Label Label
id: openPrivateChannelWithLabel id: openPrivateChannelWithLabel
!text: tr('Open a private message channel') .. ':' !text: tr('Open a private message channel:')
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
anchors.bottom: next.top anchors.bottom: next.top

View File

@ -35,7 +35,7 @@ MainWindow
width: 180 width: 180
Label Label
!text: tr('Ignored Players') .. ':' !text: tr('Ignored Players:')
anchors.left: parent.left anchors.left: parent.left
anchors.top: prev.bottom anchors.top: prev.bottom
margin-top: 10 margin-top: 10
@ -108,7 +108,7 @@ MainWindow
width: 180 width: 180
Label Label
!text: tr('Allowed Players') .. ':' !text: tr('Allowed Players:')
anchors.top: prev.bottom anchors.top: prev.bottom
anchors.left: prev.left anchors.left: prev.left
margin-top: 10 margin-top: 10

View File

@ -3,7 +3,7 @@ SpeakTypesSettings = {
say = { speakType = MessageModes.Say, color = '#FFFF00' }, say = { speakType = MessageModes.Say, color = '#FFFF00' },
whisper = { speakType = MessageModes.Whisper, color = '#FFFF00' }, whisper = { speakType = MessageModes.Whisper, color = '#FFFF00' },
yell = { speakType = MessageModes.Yell, color = '#FFFF00' }, yell = { speakType = MessageModes.Yell, color = '#FFFF00' },
broadcast = { speakType = MessageModes.GamemasterBroadcast, color = '#F55E5E' }, broadcast = { speakType = MessageModes.GamemasterPrivateFrom, color = '#F55E5E' },
private = { speakType = MessageModes.PrivateTo, color = '#5FF7F7', private = true }, private = { speakType = MessageModes.PrivateTo, color = '#5FF7F7', private = true },
privateRed = { speakType = MessageModes.GamemasterTo, color = '#F55E5E', private = true }, privateRed = { speakType = MessageModes.GamemasterTo, color = '#F55E5E', private = true },
privatePlayerToPlayer = { speakType = MessageModes.PrivateTo, color = '#9F9DFD', private = true }, privatePlayerToPlayer = { speakType = MessageModes.PrivateTo, color = '#9F9DFD', private = true },
@ -38,7 +38,6 @@ SpeakTypes = {
[MessageModes.RVRChannel] = SpeakTypesSettings.channelWhite, [MessageModes.RVRChannel] = SpeakTypesSettings.channelWhite,
[MessageModes.RVRContinue] = SpeakTypesSettings.rvrContinue, [MessageModes.RVRContinue] = SpeakTypesSettings.rvrContinue,
[MessageModes.RVRAnswer] = SpeakTypesSettings.rvrAnswerFrom, [MessageModes.RVRAnswer] = SpeakTypesSettings.rvrAnswerFrom,
[MessageModes.NpcFromStartBlock] = SpeakTypesSettings.privateNpcToPlayer,
-- ignored types -- ignored types
[MessageModes.Spell] = SpeakTypesSettings.none, [MessageModes.Spell] = SpeakTypesSettings.none,
@ -52,13 +51,6 @@ SayModes = {
[3] = { speakTypeDesc = 'yell', icon = '/images/game/console/yell' } [3] = { speakTypeDesc = 'yell', icon = '/images/game/console/yell' }
} }
ChannelEventFormats = {
[ChannelEvent.Join] = '%s joined the channel.',
[ChannelEvent.Leave] = '%s left the channel.',
[ChannelEvent.Invite] = '%s has been invited to the channel.',
[ChannelEvent.Exclude] = '%s has been removed from the channel.',
}
MAX_HISTORY = 500 MAX_HISTORY = 500
MAX_LINES = 100 MAX_LINES = 100
HELP_CHANNEL = 9 HELP_CHANNEL = 9
@ -105,8 +97,7 @@ function init()
onRuleViolationCancel = onRuleViolationCancel, onRuleViolationCancel = onRuleViolationCancel,
onRuleViolationLock = onRuleViolationLock, onRuleViolationLock = onRuleViolationLock,
onGameStart = online, onGameStart = online,
onGameEnd = offline, onGameEnd = offline
onChannelEvent = onChannelEvent,
}) })
consolePanel = g_ui.loadUI('console', modules.game_interface.getBottomPanel()) consolePanel = g_ui.loadUI('console', modules.game_interface.getBottomPanel())
@ -114,6 +105,7 @@ function init()
consoleContentPanel = consolePanel:getChildById('consoleContentPanel') consoleContentPanel = consolePanel:getChildById('consoleContentPanel')
consoleTabBar = consolePanel:getChildById('consoleTabBar') consoleTabBar = consolePanel:getChildById('consoleTabBar')
consoleTabBar:setContentWidget(consoleContentPanel) consoleTabBar:setContentWidget(consoleContentPanel)
consoleTabBar:setTabSpacing(-1)
channels = {} channels = {}
consolePanel.onKeyPress = function(self, keyCode, keyboardModifiers) consolePanel.onKeyPress = function(self, keyCode, keyboardModifiers)
@ -122,10 +114,13 @@ function init()
local tab = consoleTabBar:getCurrentTab() local tab = consoleTabBar:getCurrentTab()
if not tab then return false end if not tab then return false end
local selection = tab.tabPanel:getChildById('consoleBuffer').selectionText local consoleBuffer = tab.tabPanel:getChildById('consoleBuffer')
if not selection then return false end if not consoleBuffer then return false end
g_window.setClipboardText(selection) local consoleLabel = consoleBuffer:getFocusedChild()
if not consoleLabel or not consoleLabel:hasSelection() then return false end
g_window.setClipboardText(consoleLabel:getSelection())
return true return true
end end
@ -153,27 +148,6 @@ function init()
end end
end end
function clearSelection(consoleBuffer)
for _,label in pairs(consoleBuffer:getChildren()) do
label:clearSelection()
end
consoleBuffer.selectionText = nil
consoleBuffer.selection = nil
end
function selectAll(consoleBuffer)
clearSelection(consoleBuffer)
if consoleBuffer:getChildCount() > 0 then
local text = {}
for _,label in pairs(consoleBuffer:getChildren()) do
label:selectAll()
table.insert(text, label:getSelection())
end
consoleBuffer.selectionText = table.concat(text, '\n')
consoleBuffer.selection = { first = consoleBuffer:getChildIndex(consoleBuffer:getFirstChild()), last = consoleBuffer:getChildIndex(consoleBuffer:getLastChild()) }
end
end
function toggleChat() function toggleChat()
if consoleToggleChat:isChecked() then if consoleToggleChat:isChecked() then
disableChat() disableChat()
@ -190,18 +164,12 @@ function enableChat()
g_keyboard.unbindKeyUp("Space") g_keyboard.unbindKeyUp("Space")
g_keyboard.unbindKeyUp("Enter") g_keyboard.unbindKeyUp("Enter")
g_keyboard.unbindKeyUp("Escape")
gameInterface.unbindWalkKey("W") gameInterface.unbindWalkKey("W")
gameInterface.unbindWalkKey("D") gameInterface.unbindWalkKey("D")
gameInterface.unbindWalkKey("S") gameInterface.unbindWalkKey("S")
gameInterface.unbindWalkKey("A") gameInterface.unbindWalkKey("A")
gameInterface.unbindWalkKey("E")
gameInterface.unbindWalkKey("Q")
gameInterface.unbindWalkKey("C")
gameInterface.unbindWalkKey("Z")
consoleToggleChat:setTooltip(tr("Disable chat mode, allow to walk using ASDW")) consoleToggleChat:setTooltip(tr("Disable chat mode, allow to walk using ASDW"))
end end
@ -219,18 +187,12 @@ function disableChat()
end end
g_keyboard.bindKeyUp("Space", quickFunc) g_keyboard.bindKeyUp("Space", quickFunc)
g_keyboard.bindKeyUp("Enter", quickFunc) g_keyboard.bindKeyUp("Enter", quickFunc)
g_keyboard.bindKeyUp("Escape", quickFunc)
gameInterface.bindWalkKey("W", North) gameInterface.bindWalkKey("W", North)
gameInterface.bindWalkKey("D", East) gameInterface.bindWalkKey("D", East)
gameInterface.bindWalkKey("S", South) gameInterface.bindWalkKey("S", South)
gameInterface.bindWalkKey("A", West) gameInterface.bindWalkKey("A", West)
gameInterface.bindWalkKey("E", NorthEast)
gameInterface.bindWalkKey("Q", NorthWest)
gameInterface.bindWalkKey("C", SouthEast)
gameInterface.bindWalkKey("Z", SouthWest)
consoleToggleChat:setTooltip(tr("Enable chat mode")) consoleToggleChat:setTooltip(tr("Enable chat mode"))
end end
@ -248,8 +210,7 @@ function terminate()
onRuleViolationCancel = onRuleViolationCancel, onRuleViolationCancel = onRuleViolationCancel,
onRuleViolationLock = onRuleViolationLock, onRuleViolationLock = onRuleViolationLock,
onGameStart = online, onGameStart = online,
onGameEnd = offline, onGameEnd = offline
onChannelEvent = onChannelEvent,
}) })
if g_game.isOnline() then clear() end if g_game.isOnline() then clear() end
@ -272,13 +233,7 @@ function terminate()
violationWindow:destroy() violationWindow:destroy()
end end
consoleTabBar = nil
consoleContentPanel = nil
consoleToggleChat = nil
consoleTextEdit = nil
consolePanel:destroy() consolePanel:destroy()
consolePanel = nil
ownPrivateName = nil ownPrivateName = nil
Console = nil Console = nil
@ -333,14 +288,11 @@ function clear()
channels = {} channels = {}
consoleTabBar:removeTab(defaultTab) consoleTabBar:removeTab(defaultTab)
defaultTab = nil
consoleTabBar:removeTab(serverTab) consoleTabBar:removeTab(serverTab)
serverTab = nil
local npcTab = consoleTabBar:getTab('NPCs') local npcTab = consoleTabBar:getTab('NPCs')
if npcTab then if npcTab then
consoleTabBar:removeTab(npcTab) consoleTabBar:removeTab(npcTab)
npcTab = nil
end end
if violationReportTab then if violationReportTab then
@ -553,8 +505,6 @@ function addTabText(text, speaktype, tab, creatureName)
label:setColor(speaktype.color) label:setColor(speaktype.color)
consoleTabBar:blinkTab(tab) consoleTabBar:blinkTab(tab)
label.highlightInfo = {}
-- Overlay for consoleBuffer which shows highlighted words only -- Overlay for consoleBuffer which shows highlighted words only
if speaktype.npcChat and (g_game.getCharacterName() ~= creatureName or g_game.getCharacterName() == 'Account Manager') then if speaktype.npcChat and (g_game.getCharacterName() ~= creatureName or g_game.getCharacterName() == 'Account Manager') then
@ -584,10 +534,6 @@ function addTabText(text, speaktype, tab, creatureName)
local dataBlock = { _start = highlightData[(i-1)*3+1], _end = highlightData[(i-1)*3+2], words = highlightData[(i-1)*3+3] } local dataBlock = { _start = highlightData[(i-1)*3+1], _end = highlightData[(i-1)*3+2], words = highlightData[(i-1)*3+3] }
local lastBlockEnd = (highlightData[(i-2)*3+2] or 1) local lastBlockEnd = (highlightData[(i-2)*3+2] or 1)
for i = dataBlock._start, dataBlock._end do
label.highlightInfo[i] = dataBlock.words
end
for letter = lastBlockEnd, dataBlock._start-1 do for letter = lastBlockEnd, dataBlock._start-1 do
local tmpChar = string.byte(drawText:sub(letter, letter)) local tmpChar = string.byte(drawText:sub(letter, letter))
local fillChar = (tmpChar == 10 or tmpChar == 32) and string.char(tmpChar) or string.char(127) local fillChar = (tmpChar == 10 or tmpChar == 32) and string.char(tmpChar) or string.char(127)
@ -611,109 +557,12 @@ function addTabText(text, speaktype, tab, creatureName)
end end
label.name = creatureName label.name = creatureName
consoleBuffer.onMouseRelease = function(self, mousePos, mouseButton) label.onMouseRelease = function (self, mousePos, mouseButton)
processMessageMenu(mousePos, mouseButton, nil, nil, nil, tab) processMessageMenu(mousePos, mouseButton, creatureName, text, self, tab)
end
label.onMouseRelease = function(self, mousePos, mouseButton)
if mouseButton == MouseLeftButton then
local position = label:getTextPos(mousePos)
if position and label.highlightInfo[position] then
sendMessage(label.highlightInfo[position], npcTab)
end
elseif mouseButton == MouseRightButton then
processMessageMenu(mousePos, mouseButton, creatureName, text, self, tab)
end
end
label.onMousePress = function(self, mousePos, button)
if button == MouseLeftButton then clearSelection(consoleBuffer) end
end
label.onDragEnter = function(self, mousePos)
clearSelection(consoleBuffer)
return true
end
label.onDragLeave = function(self, droppedWidget, mousePos)
local text = {}
for selectionChild = consoleBuffer.selection.first, consoleBuffer.selection.last do
local label = self:getParent():getChildByIndex(selectionChild)
table.insert(text, label:getSelection())
end
consoleBuffer.selectionText = table.concat(text, '\n')
return true
end
label.onDragMove = function(self, mousePos, mouseMoved)
local parent = self:getParent()
local parentRect = parent:getPaddingRect()
local selfIndex = parent:getChildIndex(self)
local child = parent:getChildByPos(mousePos)
-- find bonding children
if not child then
if mousePos.y < self:getY() then
for index = selfIndex - 1, 1, -1 do
local label = parent:getChildByIndex(index)
if label:getY() + label:getHeight() > parentRect.y then
if (mousePos.y >= label:getY() and mousePos.y <= label:getY() + label:getHeight()) or index == 1 then
child = label
break
end
else
child = parent:getChildByIndex(index + 1)
break
end
end
elseif mousePos.y > self:getY() + self:getHeight() then
for index = selfIndex + 1, parent:getChildCount(), 1 do
local label = parent:getChildByIndex(index)
if label:getY() < parentRect.y + parentRect.height then
if (mousePos.y >= label:getY() and mousePos.y <= label:getY() + label:getHeight()) or index == parent:getChildCount() then
child = label
break
end
else
child = parent:getChildByIndex(index - 1)
break
end
end
else
child = self
end
end
if not child then return false end
local childIndex = parent:getChildIndex(child)
-- remove old selection
clearSelection(consoleBuffer)
-- update self selection
local textBegin = self:getTextPos(self:getLastClickPosition())
local textPos = self:getTextPos(mousePos)
self:setSelection(textBegin, textPos)
consoleBuffer.selection = { first = math.min(selfIndex, childIndex), last = math.max(selfIndex, childIndex) }
-- update siblings selection
if child ~= self then
for selectionChild = consoleBuffer.selection.first + 1, consoleBuffer.selection.last - 1 do
parent:getChildByIndex(selectionChild):selectAll()
end
local textPos = child:getTextPos(mousePos)
if childIndex > selfIndex then
child:setSelection(0, textPos)
else
child:setSelection(string.len(child:getText()), textPos)
end
end
return true
end end
if consoleBuffer:getChildCount() > MAX_LINES then if consoleBuffer:getChildCount() > MAX_LINES then
local child = consoleBuffer:getFirstChild() consoleBuffer:getFirstChild():destroy()
clearSelection(consoleBuffer)
child:destroy()
end end
end end
@ -729,10 +578,7 @@ end
function processChannelTabMenu(tab, mousePos, mouseButton) function processChannelTabMenu(tab, mousePos, mouseButton)
local menu = g_ui.createWidget('PopupMenu') local menu = g_ui.createWidget('PopupMenu')
menu:setGameMenu(true)
local worldName = g_game.getWorldName()
local characterName = g_game.getCharacterName()
channelName = tab:getText() channelName = tab:getText()
if tab ~= defaultTab and tab ~= serverTab then if tab ~= defaultTab and tab ~= serverTab then
menu:addOption(tr('Close'), function() removeTab(channelName) end) menu:addOption(tr('Close'), function() removeTab(channelName) end)
@ -742,28 +588,8 @@ function processChannelTabMenu(tab, mousePos, mouseButton)
if consoleTabBar:getCurrentTab() == tab then if consoleTabBar:getCurrentTab() == tab then
menu:addOption(tr('Clear Messages'), function() clearChannel(consoleTabBar) end) menu:addOption(tr('Clear Messages'), function() clearChannel(consoleTabBar) end)
menu:addOption(tr('Save Messages'), function()
local panel = consoleTabBar:getTabPanel(tab)
local consoleBuffer = panel:getChildById('consoleBuffer')
local lines = {}
for _,label in pairs(consoleBuffer:getChildren()) do
table.insert(lines, label:getText())
end
local filename = worldName .. ' - ' .. characterName .. ' - ' .. channelName .. '.txt'
local filepath = '/' .. filename
-- extra information at the beginning
table.insert(lines, 1, os.date('\nChannel saved at %a %b %d %H:%M:%S %Y'))
if g_resources.fileExists(filepath) then
table.insert(lines, 1, protectedcall(g_resources.readFileContents, filepath) or '')
end
g_resources.writeFileContents(filepath, table.concat(lines, '\n'))
modules.game_textmessage.displayStatusMessage(tr('Channel appended to %s', filename))
end)
end end
--menu:addOption(tr('Save Messages'), function() --[[TODO]] end)
menu:display(mousePos) menu:display(mousePos)
end end
@ -771,7 +597,6 @@ end
function processMessageMenu(mousePos, mouseButton, creatureName, text, label, tab) function processMessageMenu(mousePos, mouseButton, creatureName, text, label, tab)
if mouseButton == MouseRightButton then if mouseButton == MouseRightButton then
local menu = g_ui.createWidget('PopupMenu') local menu = g_ui.createWidget('PopupMenu')
menu:setGameMenu(true)
if creatureName and #creatureName > 0 then if creatureName and #creatureName > 0 then
if creatureName ~= g_game.getCharacterName() then if creatureName ~= g_game.getCharacterName() then
menu:addOption(tr('Message to ' .. creatureName), function () g_game.openPrivateChannel(creatureName) end) menu:addOption(tr('Message to ' .. creatureName), function () g_game.openPrivateChannel(creatureName) end)
@ -797,15 +622,12 @@ function processMessageMenu(mousePos, mouseButton, creatureName, text, label, ta
menu:addOption(tr('Copy name'), function () g_window.setClipboardText(creatureName) end) menu:addOption(tr('Copy name'), function () g_window.setClipboardText(creatureName) end)
end end
local selection = tab.tabPanel:getChildById('consoleBuffer').selectionText if label:hasSelection() then
if selection and #selection > 0 then menu:addOption(tr('Copy'), function() g_window.setClipboardText(label:getSelection()) end, '(Ctrl+C)')
menu:addOption(tr('Copy'), function() g_window.setClipboardText(selection) end, '(Ctrl+C)')
end end
if text then menu:addOption(tr('Copy message'), function() g_window.setClipboardText(text) end)
menu:addOption(tr('Copy message'), function() g_window.setClipboardText(text) end) menu:addOption(tr('Select all'), function() label:selectAll() end)
end if tab.violations then
menu:addOption(tr('Select all'), function() selectAll(tab.tabPanel:getChildById('consoleBuffer')) end)
if tab.violations and creatureName then
menu:addSeparator() menu:addSeparator()
menu:addOption(tr('Process') .. ' ' .. creatureName, function() processViolation(creatureName, text) end) menu:addOption(tr('Process') .. ' ' .. creatureName, function() processViolation(creatureName, text) end)
menu:addOption(tr('Remove') .. ' ' .. creatureName, function() g_game.closeRuleViolation(creatureName) end) menu:addOption(tr('Remove') .. ' ' .. creatureName, function() g_game.closeRuleViolation(creatureName) end)
@ -865,7 +687,7 @@ function sendMessage(message, tab)
end end
-- player used whisper -- player used whisper
chatCommandMessage = message:match("^%#[w|W] (.*)") local chatCommandMessage = message:match("^%#[w|W] (.*)")
if chatCommandMessage ~= nil then if chatCommandMessage ~= nil then
chatCommandSayMode = 'whisper' chatCommandSayMode = 'whisper'
message = chatCommandMessage message = chatCommandMessage
@ -873,28 +695,13 @@ function sendMessage(message, tab)
end end
-- player say -- player say
chatCommandMessage = message:match("^%#[s|S] (.*)") local chatCommandMessage = message:match("^%#[s|S] (.*)")
if chatCommandMessage ~= nil then if chatCommandMessage ~= nil then
chatCommandSayMode = 'say' chatCommandSayMode = 'say'
message = chatCommandMessage message = chatCommandMessage
channel = 0 channel = 0
end end
-- player red talk on channel
chatCommandMessage = message:match("^%#[c|C] (.*)")
if chatCommandMessage ~= nil then
chatCommandSayMode = 'channelRed'
message = chatCommandMessage
end
-- player broadcast
chatCommandMessage = message:match("^%#[b|B] (.*)")
if chatCommandMessage ~= nil then
chatCommandSayMode = 'broadcast'
message = chatCommandMessage
channel = 0
end
local findIni, findEnd, chatCommandInitial, chatCommandPrivate, chatCommandEnd, chatCommandMessage = message:find("([%*%@])(.+)([%*%@])(.*)") local findIni, findEnd, chatCommandInitial, chatCommandPrivate, chatCommandEnd, chatCommandMessage = message:find("([%*%@])(.+)([%*%@])(.*)")
if findIni ~= nil and findIni == 1 then -- player used private chat command if findIni ~= nil and findIni == 1 then -- player used private chat command
if chatCommandInitial == chatCommandEnd then if chatCommandInitial == chatCommandEnd then
@ -1000,7 +807,7 @@ function navigateMessageHistory(step)
end end
function applyMessagePrefixies(name, level, message) function applyMessagePrefixies(name, level, message)
if name and #name > 0 then if name then
if modules.client_options.getOption('showLevelsInConsole') and level > 0 then if modules.client_options.getOption('showLevelsInConsole') and level > 0 then
message = name .. ' [' .. level .. ']: ' .. message message = name .. ' [' .. level .. ']: ' .. message
else else
@ -1016,9 +823,7 @@ function onTalk(name, level, mode, message, channelId, creaturePos)
return return
end end
local isNpcMode = (mode == MessageModes.NpcFromStartBlock or mode == MessageModes.NpcFrom) if ignoreNpcMessages and mode == MessageModes.NpcFrom then return end
if ignoreNpcMessages and isNpcMode then return end
speaktype = SpeakTypes[mode] speaktype = SpeakTypes[mode]
@ -1034,7 +839,7 @@ function onTalk(name, level, mode, message, channelId, creaturePos)
if mode == MessageModes.Yell and isIgnoringYelling() then if mode == MessageModes.Yell and isIgnoringYelling() then
return return
elseif speaktype.private and isIgnoringPrivate() and not isNpcMode then elseif speaktype.private and isIgnoringPrivate() and mode ~= MessageModes.NpcFrom then
return return
elseif isIgnored(name) then elseif isIgnored(name) then
return return
@ -1047,21 +852,21 @@ function onTalk(name, level, mode, message, channelId, creaturePos)
if (mode == MessageModes.Say or mode == MessageModes.Whisper or mode == MessageModes.Yell or if (mode == MessageModes.Say or mode == MessageModes.Whisper or mode == MessageModes.Yell or
mode == MessageModes.Spell or mode == MessageModes.MonsterSay or mode == MessageModes.MonsterYell or mode == MessageModes.Spell or mode == MessageModes.MonsterSay or mode == MessageModes.MonsterYell or
mode == MessageModes.NpcFrom or mode == MessageModes.BarkLow or mode == MessageModes.BarkLoud or mode == MessageModes.NpcFrom or mode == MessageModes.BarkLow or mode == MessageModes.BarkLoud) and
mode == MessageModes.NpcFromStartBlock) and creaturePos then creaturePos then
local staticText = StaticText.create() -- Remove curly braces from screen message
-- Remove curly braces from screen message local staticMessage = message
local staticMessage = message if mode == MessageModes.NpcFrom then
if isNpcMode then local highlightData = getHighlightedText(staticMessage)
local highlightData = getHighlightedText(staticMessage) if #highlightData > 0 then
if #highlightData > 0 then for i = 1, #highlightData / 3 do
for i = 1, #highlightData / 3 do local dataBlock = { _start = highlightData[(i-1)*3+1], _end = highlightData[(i-1)*3+2], words = highlightData[(i-1)*3+3] }
local dataBlock = { _start = highlightData[(i-1)*3+1], _end = highlightData[(i-1)*3+2], words = highlightData[(i-1)*3+3] } staticMessage = staticMessage:gsub("{"..dataBlock.words.."}", dataBlock.words)
staticMessage = staticMessage:gsub("{"..dataBlock.words.."}", dataBlock.words) end
end end
end end
staticText:setColor(speaktype.color)
end local staticText = StaticText.create()
staticText:addMessage(name, mode, staticMessage) staticText:addMessage(name, mode, staticMessage)
g_map.addThing(staticText, creaturePos, -1) g_map.addThing(staticText, creaturePos, -1)
end end
@ -1215,15 +1020,15 @@ function loadCommunicationSettings()
local ignoreNode = g_settings.getNode('IgnorePlayers') local ignoreNode = g_settings.getNode('IgnorePlayers')
if ignoreNode then if ignoreNode then
for _, player in pairs(ignoreNode) do for i = 1, #ignoreNode do
table.insert(communicationSettings.ignoredPlayers, player) table.insert(communicationSettings.ignoredPlayers, ignoreNode[i])
end end
end end
local whitelistNode = g_settings.getNode('WhitelistedPlayers') local whitelistNode = g_settings.getNode('WhitelistedPlayers')
if whitelistNode then if whitelistNode then
for _, player in pairs(whitelistNode) do for i = 1, #whitelistNode do
table.insert(communicationSettings.whitelistedPlayers, player) table.insert(communicationSettings.whitelistedPlayers, whitelistNode[i])
end end
end end
@ -1459,19 +1264,3 @@ function offline()
end end
clear() clear()
end end
function onChannelEvent(channelId, name, type)
local fmt = ChannelEventFormats[type]
if not fmt then
print(('Unknown channel event type (%d).'):format(type))
return
end
local channel = channels[channelId]
if channel then
local tab = getTab(channel)
if tab then
addTabText(fmt:format(name), SpeakTypesSettings.channelOrange, tab)
end
end
end

View File

@ -2,7 +2,7 @@ Module
name: game_console name: game_console
description: Manage chat window description: Manage chat window
author: edubart, andrefaramir, baxnie, sn4ake, BeniS author: edubart, andrefaramir, baxnie, sn4ake, BeniS
website: https://github.com/edubart/otclient website: www.otclient.info
sandboxed: true sandboxed: true
scripts: [ console ] scripts: [ console ]
@onLoad: init() @onLoad: init()

View File

@ -10,9 +10,6 @@ ConsoleLabel < UITextEdit
change-cursor-image: false change-cursor-image: false
cursor-visible: false cursor-visible: false
editable: false editable: false
draggable: true
selectable: false
focusable: false
ConsolePhantomLabel < UILabel ConsolePhantomLabel < UILabel
font: verdana-11px-antialised font: verdana-11px-antialised
@ -84,8 +81,7 @@ Panel
margin-left: 5 margin-left: 5
margin-top: 3 margin-top: 3
margin-right: 5 margin-right: 5
tab-spacing: 2 moveable: true
movable: true
TabButton TabButton
id: nextChannelButton id: nextChannelButton

View File

@ -110,7 +110,6 @@ function onContainerOpen(container, previousContainer)
containerWindow:setText(name) containerWindow:setText(name)
containerItemWidget:setItem(container:getContainerItem()) containerItemWidget:setItem(container:getContainerItem())
containerItemWidget:setPhantom(true)
containerPanel:destroyChildren() containerPanel:destroyChildren()
for slot=0,container:getCapacity()-1 do for slot=0,container:getCapacity()-1 do

View File

@ -2,7 +2,7 @@ Module
name: game_containers name: game_containers
description: Manage containers description: Manage containers
author: edubart, baxnie author: edubart, baxnie
website: https://github.com/edubart/otclient website: www.otclient.info
sandboxed: true sandboxed: true
scripts: [containers] scripts: [containers]
@onLoad: init() @onLoad: init()

View File

@ -2,7 +2,7 @@ Module
name: game_cooldown name: game_cooldown
description: Spellcooldowns description: Spellcooldowns
author: OTClient team author: OTClient team
website: https://github.com/edubart/otclient website: www.otclient.info
sandboxed: true sandboxed: true
scripts: [ cooldown ] scripts: [ cooldown ]
@onLoad: init() @onLoad: init()

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