diff --git a/.gitmodules b/.gitmodules index 6cbadcbda9..57cb9759a3 100644 --- a/.gitmodules +++ b/.gitmodules @@ -935,6 +935,9 @@ [submodule "vendor/grammars/logtalk.tmbundle"] path = vendor/grammars/logtalk.tmbundle url = https://github.com/textmate/logtalk.tmbundle +[submodule "vendor/grammars/lpc-language-server"] + path = vendor/grammars/lpc-language-server + url = https://github.com/jlchmura/lpc-language-server.git [submodule "vendor/grammars/lua.tmbundle"] path = vendor/grammars/lua.tmbundle url = https://github.com/LuaLS/lua.tmbundle.git diff --git a/grammars.yml b/grammars.yml index 13979f0c14..2b4be396cf 100644 --- a/grammars.yml +++ b/grammars.yml @@ -886,6 +886,9 @@ vendor/grammars/logos: - source.logos vendor/grammars/logtalk.tmbundle: - source.logtalk +vendor/grammars/lpc-language-server: +- documentation.injection.lpc +- source.lpc.lang-server vendor/grammars/lua.tmbundle: - source.lua vendor/grammars/m3: diff --git a/lib/linguist/heuristics.yml b/lib/linguist/heuristics.yml index 17d6802916..a1e6eaf810 100644 --- a/lib/linguist/heuristics.yml +++ b/lib/linguist/heuristics.yml @@ -174,6 +174,11 @@ disambiguations: rules: - language: XML pattern: '^(\s*)(?i:\s*[a-z][a-z0-9_]*\s*\(' m68k: - '(?im)\bmoveq(?:\.l)?\s+#(?:\$-?[0-9a-f]{1,3}|%[0-1]{1,8}|-?[0-9]{1,3}),\s*d[0-7]\b' - '(?im)^\s*move(?:\.[bwl])?\s+(?:sr|usp),\s*[^\s]+' diff --git a/lib/linguist/languages.yml b/lib/linguist/languages.yml index 7ea73879c5..5c36cfb2d0 100644 --- a/lib/linguist/languages.yml +++ b/lib/linguist/languages.yml @@ -4046,6 +4046,15 @@ LOLCODE: tm_scope: source.lolcode ace_mode: text language_id: 192 +LPC: + type: programming + extensions: + - ".c" + - ".h" + tm_scope: source.lpc.lang-server + ace_mode: c_cpp + language_id: 397797394 + color: "#ffb100" LSL: type: programming tm_scope: source.lsl diff --git a/samples/LPC/area_env.h b/samples/LPC/area_env.h new file mode 100644 index 0000000000..213cef70fd --- /dev/null +++ b/samples/LPC/area_env.h @@ -0,0 +1,16 @@ +int minLevel; + +public int query_minLevel() { + return minLevel; +} +public void set_minLevel(int level) { + minLevel = level; +} + +public string query_label() { + return "Area Label"; +} + +public string canEnterArea() { + return this_player()->query_level() < minLevel ? "You are not experienced enough to enter this area." : 0; +} diff --git a/samples/LPC/connection.c b/samples/LPC/connection.c new file mode 100644 index 0000000000..0c460d9a5f --- /dev/null +++ b/samples/LPC/connection.c @@ -0,0 +1,11 @@ +/** + * query connection properties for a player + * @return a union type of either an int or an array of strings + */ +public * queryConnectionProperties() { + object p = this_player(); + if (!p) return 0; + + object conn = p->queryConnection(); + return conn->queryProperties(); +} diff --git a/samples/LPC/convo.c b/samples/LPC/convo.c new file mode 100644 index 0000000000..cfe1a3cbd2 --- /dev/null +++ b/samples/LPC/convo.c @@ -0,0 +1,123 @@ +/* + * LDMud mob dialog system + * Copyright 2022-2024 John Chmura + * + */ +#include "../../jgambit.h" +#include "./convo.h" + +private object owner; +private object parentConvo; +private object *childConvos = ({}); +private int auto_start = 1; +private int queue_status = 0; +private mixed *queue = ({}); +private int lastIdx=0; +private int convoId = random(10000)+1; +private int destructOnEnd = 0; + +private object currentPromptSet; +/** the last player to interact with this convo */ +private object lastPlayer; +private int waitForConvoToFinish = 0; + +private object onFinishOb; + +/* function declarations */ +public int execOp(mixed op); + + +/* debug output */ +private void debug(string s) { + if (CONVO_DEBUG) { + object j = find_player("jgambit"); + if (j) { + tell_object(j,COLORSTRING(sprintf("$PF[debug] %s\n", s), j)); + } + } +} + +/** returns 1 if the convo queue is running, otherwise 0*/ +public query_isRunning() { + return queue_status; +} + +public set_lastPlayer(object p) { + if (!living(p)) { + debug("Tried to set last player but wasn't living"); + return 0; + } + + debug(sprintf("Set last player to %s", p->query_name())); + lastPlayer = p; + return p; +} +public query_lastPlayer() { + return (!lastPlayer && parentConvo) + ? parentConvo->query_lastPlayer() + : lastPlayer; +} + +/** indicates if the convo should destruct when it is finished */ +public set_destructOnEnd(int flag) { + destructOnEnd = flag; +} + +set_parentConvo(object c) { + parentConvo=c; +} +object query_parentConvo() { return parentConvo; } + +/** The owner is the actor this convo corresponds to. Usually a monster. */ +set_owner(object o) { + owner = o; + return o; +} +object query_owner() { return owner; } + +/** the operation queue for this conversation. don't mess with this */ +set_queue(mixed *q) { + queue = q; + return q; +} +query_queue() { return queue; } + +/** + * sets the autostart flag. + * the default (1) will cause the convo to autostart when an operation is added + * otherwise you will have to manually call convo->start() + */ +set_auto_start(int s) { + auto_start = s; + return 1; +} +int query_auto_start() { return auto_start; } + +/** + * (Optional) + * Sets the object in which the "on_convoFinished(convoId)" function + * function will be called when the conversation ends. + * @param ob - object or string + */ +set_onFinishOb(mixed ob) { + if (objectp(ob)) + onFinishOb = object_name(ob); + else + onFinishOb = ob; + return convoId; +} +query_onFinishOb() { return onFinishOb; } + +query_convoId() { return convoId; } + +/** + * does some cleanup by destructing all child convos + */ +public destructConvos() { + foreach(object c in childConvos) { + if (c) c->destructConvos(); + destruct(c); + } + + childConvos -= ({ 0 }); +} diff --git a/samples/LPC/convoMatchset.c b/samples/LPC/convoMatchset.c new file mode 100644 index 0000000000..163c1dd00f --- /dev/null +++ b/samples/LPC/convoMatchset.c @@ -0,0 +1,28 @@ +/* + * LDMud mob dialog system + * Copyright 2022-2024 John Chmura + * + */ +#include "../../jgambit.h" + +private mixed *responses = ({}); +private int ttl = 0; +private mixed ttl_op; + +public match(string pattern, mixed response) { + responses += ({ + ({ pattern, response }) + }); + + return TO; +} + +public varargs timeout(int n, mixed op) { + ttl = n; + ttl_op = op; + return TO; +} + +public query_ttl() { return ttl; } +public query_ttl_op() { return ttl_op; } +public query_matchset() { return responses; } diff --git a/samples/LPC/globals.h b/samples/LPC/globals.h new file mode 100644 index 0000000000..4376f03372 --- /dev/null +++ b/samples/LPC/globals.h @@ -0,0 +1,15 @@ + +#ifndef GLOBAL_H + +#define GLOBAL_H + +#include +#include "../area.h" + +#define SETWRAP set_wrap_long(1) +#define WRAP(x) wrap_text(x) +#define AREAPATH "/d/area/" +#define ROOMPATH AREAPATH "rooms/" +#define TO this_object() + +#endif \ No newline at end of file diff --git a/samples/LPC/level_list.c b/samples/LPC/level_list.c new file mode 100644 index 0000000000..9379580010 --- /dev/null +++ b/samples/LPC/level_list.c @@ -0,0 +1,30 @@ +string short() { + return "A list of the top players" ; +} + +void long() { + cat("/SORT_LEVEL"); +} + +void init() { + add_action("read", "read"); +} + +int id(string str) { + return str == "list" || str == "top" || str == "top players" || + str == "list of top players" || str == "top list"; +} + +int read(string str) { + if (!id(str)) + return 0; + say(this_player()->query_name() + " reads the top list.\n"); + long(); + return 1; +} + +int query_weight() { return 1; } + +int get() { return 1; } + +int query_value() { return 5; } diff --git a/samples/LPC/players.c b/samples/LPC/players.c new file mode 100644 index 0000000000..9572f77169 --- /dev/null +++ b/samples/LPC/players.c @@ -0,0 +1,12 @@ + +function getPlayersByLevel(int minLevel) { + object* players = users(); + return filter(players, (: $1->query_level() >= minLevel :)); +} + +/** Schedule a shutdown for the near future. */ +void slow_shut_down (int minutes) { + filter(users(), #'tell_object, + "Game driver shouts: The memory is getting low !\n"); + "obj/shut"->shut(minutes); +} diff --git a/samples/LPC/startroom.c b/samples/LPC/startroom.c new file mode 100644 index 0000000000..44a18e8e80 --- /dev/null +++ b/samples/LPC/startroom.c @@ -0,0 +1,53 @@ +inherit "room/room"; + +#include "globals.h" + +void reset(int arg) { + ::reset(arg); + + SETWRAP; + + if(!arg) { + + set_light(1); + no_castle_flag = 1; + + short_desc = "Along the edge of a field."; + long_desc = + "You are standing along the western edge of the fields where the " + + "city grows its crops. " + + "A long, straight path heading east has been cut deep in to the middle " + + "of the crops. " + + "Far off to the west you see the tree line of a forest." + ; + + dest_dir = ({ + "room/crop", "east", + ROOMPATH + "treeline.c", "west" + }); + + items = ({ + ({"crops", "crop","field"}), + WRAP( + "A large field of crops that extends east as far as the eye can see. "+ + "There is a path heading east, in to the field." + ), + ({"tree", "trees", "tree line"}), + "The edge of a forest made up of some species of pine tree." + }); + + search_items = ({ + ({"crop", "crops", "field"}), "It looks like corn.", + }); + + sounds = + ({ + "", "You can hear the breeze rustling through the stalks in the field.", + }); + + if (!present("bulletin board")) { + move_object(AREAPATH+"obj/board.c", TO); + } + } +} + diff --git a/vendor/README.md b/vendor/README.md index da47065d96..00d2649491 100644 --- a/vendor/README.md +++ b/vendor/README.md @@ -335,6 +335,7 @@ This is a list of grammars that Linguist selects to provide syntax highlighting - **LFE:** [textmate/lisp.tmbundle](https://github.com/textmate/lisp.tmbundle) - **LLVM:** [whitequark/llvm.tmbundle](https://github.com/whitequark/llvm.tmbundle) - **LOLCODE:** [KrazIvan/LOLCODE-grammar-vscode](https://github.com/KrazIvan/LOLCODE-grammar-vscode) +- **LPC:** [jlchmura/lpc-language-server](https://github.com/jlchmura/lpc-language-server) - **LSL:** [textmate/secondlife-lsl.tmbundle](https://github.com/textmate/secondlife-lsl.tmbundle) - **LTspice Symbol:** [Alhadis/language-pcb](https://github.com/Alhadis/language-pcb) - **LabVIEW:** [textmate/xml.tmbundle](https://github.com/textmate/xml.tmbundle) diff --git a/vendor/grammars/lpc-language-server b/vendor/grammars/lpc-language-server new file mode 160000 index 0000000000..9ed1d0b84a --- /dev/null +++ b/vendor/grammars/lpc-language-server @@ -0,0 +1 @@ +Subproject commit 9ed1d0b84a088907b0da35b1722a98ea3e90eba5 diff --git a/vendor/licenses/git_submodule/lpc-language-server.dep.yml b/vendor/licenses/git_submodule/lpc-language-server.dep.yml new file mode 100644 index 0000000000..98cac3f6dc --- /dev/null +++ b/vendor/licenses/git_submodule/lpc-language-server.dep.yml @@ -0,0 +1,31 @@ +--- +name: lpc-language-server +version: 9ed1d0b84a088907b0da35b1722a98ea3e90eba5 +type: git_submodule +homepage: https://github.com/jlchmura/lpc-language-server.git +license: mit +licenses: +- sources: LICENSE + text: | + MIT License + + Copyright (c) 2023-2024 John Chmura + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +notices: []