16 Commits

Author SHA1 Message Date
Copilot 552461df51 Fix all compiler warnings in build output (#176)
Agent-Logs-Url: https://github.com/tbamud/tbamud/sessions/d031438d-2711-4447-b3df-9819d95d4058

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: welcor <357770+welcor@users.noreply.github.com>
2026-04-21 23:50:55 +02:00
Thomas Arp 10251814f6 Potential fix for code scanning alert no. 55: Call to alloca in a loop (#175)
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-04-21 23:20:23 +02:00
Thomas Arp d4089c58e8 Potential fix for code scanning alert no. 73: Potential use after free (#168)
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-04-21 23:15:35 +02:00
Thomas Arp a465860553 Potential fix for code scanning alert no. 70: Incorrect return-value check for a 'scanf'-like function (#169)
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-04-21 23:14:48 +02:00
Thomas Arp b9f49478a3 Potential fix for code scanning alert no. 1: Workflow does not contain permissions (#170)
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-04-21 23:14:01 +02:00
Thomas Arp 171381f0ea Potential fix for code scanning alert no. 5: Redundant null check due to previous dereference (#174)
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-04-21 23:13:20 +02:00
Thomas Arp dbd6bfc103 Potential fix for code scanning alert no. 4: Redundant null check due to previous dereference (#173)
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-04-21 23:12:55 +02:00
Thomas Arp 1dfbe0fa83 Potential fix for code scanning alert no. 3: Redundant null check due to previous dereference (#172)
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-04-21 23:10:46 +02:00
Thomas Arp 039e45c5ef Potential fix for code scanning alert no. 2: Redundant null check due to previous dereference (#171)
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-04-21 23:10:26 +02:00
Thomas Arp 862c887b54 Better naming in do_drink. An unlimited source is never empty. (#167)
* Better naming in do_drink. An unlimited source is never empty.
* Add guard for negative amount when drinking from infinite source
* Allow drinking from unlimited containers with current value of 0
* Fix unlimited drink container definition to allow negative current values

Tested manually on localhost. 

Fixes #156


Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-21 22:36:56 +02:00
Copilot 8548bbea99 Fix questmaster holding items: extract object after AQ_OBJ_RETURN quest completion (#165)
* Initial plan

* Fix questmaster holding items: call extract_obj after AQ_OBJ_RETURN quest completion

Agent-Logs-Url: https://github.com/tbamud/tbamud/sessions/f860d259-a59a-4c9b-a2b2-1f7a3a51990a

Co-authored-by: welcor <357770+welcor@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: welcor <357770+welcor@users.noreply.github.com>
2026-04-19 02:05:31 +02:00
Thomas Arp 28622d9fe2 Add initialization and build instructions to AGENTS.md (#166)
Added instructions for initializing and building the repository for agents
2026-04-19 02:03:34 +02:00
Thomas Arp ce423e919f Fix for code scanning alert no. 74: Potential use after free (#164)
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-04-19 01:37:10 +02:00
Thomas Arp 6b2d800c53 Add CodeQL analysis workflow configuration (#163)
* Add CodeQL analysis workflow configuration

* Change CodeQL build mode from autobuild to manual

* Fix exit code in CodeQL workflow

Remove exit code 1 to allow successful completion of the job.
2026-04-19 01:07:22 +02:00
MBourne 0d5d2bc435 Cedit Player Kill and Player Thief (#160) -- WhiskyTest
* cedit configuration for player kill and steal

* tidy up pk_allowed
2026-02-04 00:55:59 +01:00
Thomas Arp 4e1680db1a KAIZEN remove webster from CMakeLists.txt (#158) 2025-11-07 23:53:23 +01:00
30 changed files with 387 additions and 147 deletions
+4 -1
View File
@@ -3,9 +3,12 @@ name: C/C++ CI
on: on:
push: push:
branches: [ "master" ] branches: [ "master" ]
pull_request: pull_request_target:
branches: [ "master" ] branches: [ "master" ]
permissions:
contents: read
jobs: jobs:
build: build:
+96
View File
@@ -0,0 +1,96 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL Advanced"
on:
push:
branches: [ "master" ]
schedule:
- cron: '42 10 * * 4'
jobs:
analyze:
name: Analyze (${{ matrix.language }})
# Runner size impacts CodeQL analysis time. To learn more, please see:
# - https://gh.io/recommended-hardware-resources-for-running-codeql
# - https://gh.io/supported-runners-and-hardware-resources
# - https://gh.io/using-larger-runners (GitHub.com only)
# Consider using larger runners or machines with greater resources for possible analysis time improvements.
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
permissions:
# required for all workflows
security-events: write
# required to fetch internal or private CodeQL packs
packages: read
# only required for workflows in private repositories
actions: read
contents: read
strategy:
fail-fast: false
matrix:
include:
- language: actions
build-mode: none
- language: c-cpp
build-mode: manual
# CodeQL supports the following values keywords for 'language': 'actions', 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'rust', 'swift'
# Use `c-cpp` to analyze code written in C, C++ or both
# Use 'java-kotlin' to analyze code written in Java, Kotlin or both
# Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both
# To learn more about changing the languages that are analyzed or customizing the build mode for your analysis,
# see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning.
# If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how
# your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages
steps:
- name: Checkout repository
uses: actions/checkout@v4
# Add any setup steps before running the `github/codeql-action/init` action.
# This includes steps like installing compilers or runtimes (`actions/setup-node`
# or others). This is typically only required for manual builds.
# - name: Setup runtime (example)
# uses: actions/setup-example@v1
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v4
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
# If the analyze step fails for one of the languages you are analyzing with
# "We were unable to automatically build your code", modify the matrix above
# to set the build mode to "manual" for that language. Then modify this step
# to build your code.
# ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
- name: Run manual build steps
if: matrix.build-mode == 'manual'
shell: bash
run: |
./configure
cd src && touch .accepted && make
exit
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v4
with:
category: "/language:${{matrix.language}}"
+14
View File
@@ -0,0 +1,14 @@
# To initialize the repository:
Run these commands from the project directory.
```shell
./configure && touch src/.accepted # the src/.accepted file must exist to build.
```
# To build the code:
```shell
cd src # make must be run from the src dir
make # builds all changed source files.
```
+2 -2
View File
@@ -700,8 +700,8 @@ trigger variables.
4.15. I want to expand the ability to pk in my MUD, allowing ASSASSINS 4.15. I want to expand the ability to pk in my MUD, allowing ASSASSINS
that'll be able to PK without getting flagged. How can I do this? that'll be able to PK without getting flagged. How can I do this?
With tbaMUD simply enter Cedit (configuration editor) and select Game Play With tbaMUD simply enter Cedit (configuration editor), select Game Play
Options. Then enable Player Killing. (G). Select Player Killing Allowed (A) and choose (3) 'Free for all!'.
4.16. Why does it say ``Connection closed by foreign host.'' and not 4.16. Why does it say ``Connection closed by foreign host.'' and not
display the ``Byebye!'' message I'm trying to send before cutting display the ``Byebye!'' message I'm trying to send before cutting
+79 -59
View File
@@ -777,6 +777,15 @@ void weight_change_object(struct obj_data *obj, int weight)
} }
} }
#define DRINK_CON_MAX(cont) (GET_OBJ_VAL((cont), 0))
#define DRINK_CON_NOW(cont) (GET_OBJ_VAL((cont), 1))
#define DRINK_CON_TYPE(cont) (GET_OBJ_VAL((cont), 2))
#define DRINK_CON_POISON(cont) (GET_OBJ_VAL((cont), 3))
#define LIMITED_DRINK_CONTAINER(cont) (DRINK_CON_MAX((cont)) >= 0 && DRINK_CON_NOW((cont)) >= 0)
#define EMPTY_DRINK_CONTAINER(cont) (LIMITED_DRINK_CONTAINER((cont)) && DRINK_CON_NOW((cont)) < 1)
void name_from_drinkcon(struct obj_data *obj) void name_from_drinkcon(struct obj_data *obj)
{ {
const char *liqname; const char *liqname;
@@ -788,13 +797,12 @@ void name_from_drinkcon(struct obj_data *obj)
if (obj->name == obj_proto[GET_OBJ_RNUM(obj)].name) if (obj->name == obj_proto[GET_OBJ_RNUM(obj)].name)
obj->name = strdup(obj_proto[GET_OBJ_RNUM(obj)].name); obj->name = strdup(obj_proto[GET_OBJ_RNUM(obj)].name);
liqname = drinknames[GET_OBJ_VAL(obj, 2)]; liqname = drinknames[DRINK_CON_TYPE(obj)];
remove_from_string(obj->name, liqname); remove_from_string(obj->name, liqname);
new_name = right_trim_whitespace(obj->name); new_name = right_trim_whitespace(obj->name);
free(obj->name); free(obj->name);
obj->name = new_name; obj->name = new_name;
} }
void name_to_drinkcon(struct obj_data *obj, int type) void name_to_drinkcon(struct obj_data *obj, int type)
@@ -813,6 +821,7 @@ void name_to_drinkcon(struct obj_data *obj, int type)
obj->name = new_name; obj->name = new_name;
} }
ACMD(do_drink) ACMD(do_drink)
{ {
char arg[MAX_INPUT_LENGTH]; char arg[MAX_INPUT_LENGTH];
@@ -873,7 +882,7 @@ ACMD(do_drink)
send_to_char(ch, "Your stomach can't contain anymore!\r\n"); send_to_char(ch, "Your stomach can't contain anymore!\r\n");
return; return;
} }
if (GET_OBJ_VAL(temp, 1) < 1) { if (EMPTY_DRINK_CONTAINER(temp)) {
send_to_char(ch, "It is empty.\r\n"); send_to_char(ch, "It is empty.\r\n");
return; return;
} }
@@ -884,33 +893,38 @@ ACMD(do_drink)
if (subcmd == SCMD_DRINK) { if (subcmd == SCMD_DRINK) {
char buf[MAX_STRING_LENGTH]; char buf[MAX_STRING_LENGTH];
snprintf(buf, sizeof(buf), "$n drinks %s from $p.", drinks[GET_OBJ_VAL(temp, 2)]); snprintf(buf, sizeof(buf), "$n drinks %s from $p.", drinks[DRINK_CON_TYPE(temp)]);
act(buf, TRUE, ch, temp, 0, TO_ROOM); act(buf, TRUE, ch, temp, 0, TO_ROOM);
send_to_char(ch, "You drink the %s.\r\n", drinks[GET_OBJ_VAL(temp, 2)]); send_to_char(ch, "You drink the %s.\r\n", drinks[DRINK_CON_TYPE(temp)]);
if (drink_aff[GET_OBJ_VAL(temp, 2)][DRUNK] > 0) if (drink_aff[DRINK_CON_TYPE(temp)][DRUNK] > 0)
amount = (25 - GET_COND(ch, THIRST)) / drink_aff[GET_OBJ_VAL(temp, 2)][DRUNK]; amount = (25 - GET_COND(ch, THIRST)) / drink_aff[DRINK_CON_TYPE(temp)][DRUNK];
else else
amount = rand_number(3, 10); amount = rand_number(3, 10);
} else { } else {
act("$n sips from $p.", TRUE, ch, temp, 0, TO_ROOM); act("$n sips from $p.", TRUE, ch, temp, 0, TO_ROOM);
send_to_char(ch, "It tastes like %s.\r\n", drinks[GET_OBJ_VAL(temp, 2)]); send_to_char(ch, "It tastes like %s.\r\n", drinks[DRINK_CON_TYPE(temp)]);
amount = 1; amount = 1;
} }
amount = MIN(amount, GET_OBJ_VAL(temp, 1)); /* For limited drink containers with remaining contents, don't drink more
* than the amount currently in the container. Unlimited containers are
* handled separately and are not clamped here.
*/
if (LIMITED_DRINK_CONTAINER(temp))
amount = MIN(amount, DRINK_CON_NOW(temp));
/* You can't subtract more than the object weighs, unless its unlimited. */ /* You can't subtract more than the object weighs, unless its unlimited. */
if (GET_OBJ_VAL(temp, 0) > 0) { if (LIMITED_DRINK_CONTAINER(temp)) {
weight = MIN(amount, GET_OBJ_WEIGHT(temp)); weight = MIN(amount, GET_OBJ_WEIGHT(temp));
weight_change_object(temp, -weight); /* Subtract amount */ weight_change_object(temp, -weight); /* Subtract amount */
} }
gain_condition(ch, DRUNK, drink_aff[GET_OBJ_VAL(temp, 2)][DRUNK] * amount / 4); gain_condition(ch, DRUNK, drink_aff[DRINK_CON_TYPE(temp)][DRUNK] * amount / 4);
gain_condition(ch, HUNGER, drink_aff[GET_OBJ_VAL(temp, 2)][HUNGER] * amount / 4); gain_condition(ch, HUNGER, drink_aff[DRINK_CON_TYPE(temp)][HUNGER] * amount / 4);
gain_condition(ch, THIRST, drink_aff[GET_OBJ_VAL(temp, 2)][THIRST] * amount / 4); gain_condition(ch, THIRST, drink_aff[DRINK_CON_TYPE(temp)][THIRST] * amount / 4);
if (GET_COND(ch, DRUNK) > 10) if (GET_COND(ch, DRUNK) > 10)
send_to_char(ch, "You feel drunk.\r\n"); send_to_char(ch, "You feel drunk.\r\n");
@@ -921,7 +935,7 @@ ACMD(do_drink)
if (GET_COND(ch, HUNGER) > 20) if (GET_COND(ch, HUNGER) > 20)
send_to_char(ch, "You are full.\r\n"); send_to_char(ch, "You are full.\r\n");
if (GET_OBJ_VAL(temp, 3) && GET_LEVEL(ch) < LVL_IMMORT) { /* The crap was poisoned ! */ if (DRINK_CON_POISON(temp) && GET_LEVEL(ch) < LVL_IMMORT) { /* The crap was poisoned ! */
send_to_char(ch, "Oops, it tasted rather strange!\r\n"); send_to_char(ch, "Oops, it tasted rather strange!\r\n");
act("$n chokes and utters some strange sounds.", TRUE, ch, 0, 0, TO_ROOM); act("$n chokes and utters some strange sounds.", TRUE, ch, 0, 0, TO_ROOM);
@@ -932,12 +946,13 @@ ACMD(do_drink)
affect_join(ch, &af, FALSE, FALSE, FALSE, FALSE); affect_join(ch, &af, FALSE, FALSE, FALSE, FALSE);
} }
/* Empty the container (unless unlimited), and no longer poison. */ /* Empty the container (unless unlimited), and no longer poison. */
if (GET_OBJ_VAL(temp, 0) > 0) { if (LIMITED_DRINK_CONTAINER(temp)) {
GET_OBJ_VAL(temp, 1) -= amount; amount = MIN(amount, DRINK_CON_NOW(temp)); // never subtract more than the current amount
if (!GET_OBJ_VAL(temp, 1)) { /* The last bit */ DRINK_CON_NOW(temp) -= amount;
if (!DRINK_CON_NOW(temp)) { /* The last bit */
name_from_drinkcon(temp); name_from_drinkcon(temp);
GET_OBJ_VAL(temp, 2) = 0; DRINK_CON_TYPE(temp) = 0;
GET_OBJ_VAL(temp, 3) = 0; DRINK_CON_POISON(temp) = 0;
} }
} }
return; return;
@@ -1064,7 +1079,7 @@ ACMD(do_pour)
return; return;
} }
} }
if (GET_OBJ_VAL(from_obj, 1) == 0) { if (EMPTY_DRINK_CONTAINER(from_obj)) {
act("The $p is empty.", FALSE, ch, from_obj, 0, TO_CHAR); act("The $p is empty.", FALSE, ch, from_obj, 0, TO_CHAR);
return; return;
} }
@@ -1074,19 +1089,22 @@ ACMD(do_pour)
return; return;
} }
if (!str_cmp(arg2, "out")) { if (!str_cmp(arg2, "out")) {
if (GET_OBJ_VAL(from_obj, 0) > 0) { if (!LIMITED_DRINK_CONTAINER(from_obj)) {
act("$n empties $p.", TRUE, ch, from_obj, 0, TO_ROOM); send_to_char(ch, "You can't pour that out! There's simply too much in it.\r\n");
act("You empty $p.", FALSE, ch, from_obj, 0, TO_CHAR); return;
weight_change_object(from_obj, -GET_OBJ_VAL(from_obj, 1)); /* Empty */
name_from_drinkcon(from_obj);
GET_OBJ_VAL(from_obj, 1) = 0;
GET_OBJ_VAL(from_obj, 2) = 0;
GET_OBJ_VAL(from_obj, 3) = 0;
} }
else
send_to_char(ch, "You can't possibly pour that container out!\r\n"); /* pour out */
act("$n empties $p.", TRUE, ch, from_obj, 0, TO_ROOM);
act("You empty $p.", FALSE, ch, from_obj, 0, TO_CHAR);
weight_change_object(from_obj, -DRINK_CON_NOW(from_obj)); /* Empty */
name_from_drinkcon(from_obj);
DRINK_CON_NOW(from_obj) = 0;
DRINK_CON_TYPE(from_obj) = 0;
DRINK_CON_POISON(from_obj) = 0;
return; return;
} }
@@ -1094,8 +1112,7 @@ ACMD(do_pour)
send_to_char(ch, "You can't find it!\r\n"); send_to_char(ch, "You can't find it!\r\n");
return; return;
} }
if ((GET_OBJ_TYPE(to_obj) != ITEM_DRINKCON) && if ((GET_OBJ_TYPE(to_obj) != ITEM_DRINKCON) && (GET_OBJ_TYPE(to_obj) != ITEM_FOUNTAIN)) {
(GET_OBJ_TYPE(to_obj) != ITEM_FOUNTAIN)) {
send_to_char(ch, "You can't pour anything into that.\r\n"); send_to_char(ch, "You can't pour anything into that.\r\n");
return; return;
} }
@@ -1104,59 +1121,62 @@ ACMD(do_pour)
send_to_char(ch, "A most unproductive effort.\r\n"); send_to_char(ch, "A most unproductive effort.\r\n");
return; return;
} }
if ((GET_OBJ_VAL(to_obj, 0) < 0) || if (!EMPTY_DRINK_CONTAINER(to_obj) && DRINK_CON_TYPE(to_obj) != DRINK_CON_TYPE(from_obj)) {
(!(GET_OBJ_VAL(to_obj, 1) < GET_OBJ_VAL(to_obj, 0)))) {
send_to_char(ch, "There is already another liquid in it!\r\n"); send_to_char(ch, "There is already another liquid in it!\r\n");
return; return;
} }
if (!(GET_OBJ_VAL(to_obj, 1) < GET_OBJ_VAL(to_obj, 0))) { // Not allowed to fill an unlimited container, or a container that is already full.
if (!LIMITED_DRINK_CONTAINER(to_obj) || DRINK_CON_NOW(to_obj) >= DRINK_CON_MAX(to_obj)) {
send_to_char(ch, "There is no room for more.\r\n"); send_to_char(ch, "There is no room for more.\r\n");
return; return;
} }
if (subcmd == SCMD_POUR) if (subcmd == SCMD_POUR)
send_to_char(ch, "You pour the %s into the %s.", drinks[GET_OBJ_VAL(from_obj, 2)], arg2); send_to_char(ch, "You pour the %s into the %s.\r\n", drinks[DRINK_CON_TYPE(from_obj)], arg2);
if (subcmd == SCMD_FILL) { if (subcmd == SCMD_FILL) {
act("You gently fill $p from $P.", FALSE, ch, to_obj, from_obj, TO_CHAR); act("You gently fill $p from $P.", FALSE, ch, to_obj, from_obj, TO_CHAR);
act("$n gently fills $p from $P.", TRUE, ch, to_obj, from_obj, TO_ROOM); act("$n gently fills $p from $P.", TRUE, ch, to_obj, from_obj, TO_ROOM);
} }
/* New alias */ /* New alias */
if (GET_OBJ_VAL(to_obj, 1) == 0) if (EMPTY_DRINK_CONTAINER(to_obj))
name_to_drinkcon(to_obj, GET_OBJ_VAL(from_obj, 2)); name_to_drinkcon(to_obj, DRINK_CON_TYPE(from_obj));
/* First same type liq. */ /* First same type liq. */
GET_OBJ_VAL(to_obj, 2) = GET_OBJ_VAL(from_obj, 2); DRINK_CON_TYPE(to_obj) = DRINK_CON_TYPE(from_obj);
/* Then how much to pour */ /* Then how much to pour */
if (GET_OBJ_VAL(from_obj, 0) > 0) { if (LIMITED_DRINK_CONTAINER(from_obj)) {
GET_OBJ_VAL(from_obj, 1) -= (amount = amount = MIN(DRINK_CON_NOW(from_obj), DRINK_CON_MAX(to_obj) - DRINK_CON_NOW(to_obj));
(GET_OBJ_VAL(to_obj, 0) - GET_OBJ_VAL(to_obj, 1))); DRINK_CON_NOW(from_obj) -= amount;
DRINK_CON_NOW(to_obj) += amount;
GET_OBJ_VAL(to_obj, 1) = GET_OBJ_VAL(to_obj, 0); if (DRINK_CON_NOW(from_obj) == 0) { /* It was emptied */
if (GET_OBJ_VAL(from_obj, 1) < 0) { /* There was too little */
GET_OBJ_VAL(to_obj, 1) += GET_OBJ_VAL(from_obj, 1);
amount += GET_OBJ_VAL(from_obj, 1);
name_from_drinkcon(from_obj); name_from_drinkcon(from_obj);
GET_OBJ_VAL(from_obj, 1) = 0; DRINK_CON_NOW(from_obj) = 0;
GET_OBJ_VAL(from_obj, 2) = 0; DRINK_CON_TYPE(from_obj) = 0;
GET_OBJ_VAL(from_obj, 3) = 0; DRINK_CON_POISON(from_obj) = 0;
} }
} } else {
else { amount = DRINK_CON_MAX(to_obj) - DRINK_CON_NOW(to_obj);
GET_OBJ_VAL(to_obj, 1) = GET_OBJ_VAL(to_obj, 0); DRINK_CON_NOW(to_obj) = DRINK_CON_MAX(to_obj);
amount = GET_OBJ_VAL(to_obj, 0);
} }
/* Poisoned? */ /* Poisoned? */
GET_OBJ_VAL(to_obj, 3) = (GET_OBJ_VAL(to_obj, 3) || GET_OBJ_VAL(from_obj, 3)) DRINK_CON_POISON(to_obj) = (DRINK_CON_POISON(to_obj) || DRINK_CON_POISON(from_obj));
;
/* Weight change, except for unlimited. */ /* Weight change, except for unlimited. */
if (GET_OBJ_VAL(from_obj, 0) > 0) { if (LIMITED_DRINK_CONTAINER(from_obj)) {
weight_change_object(from_obj, -amount); weight_change_object(from_obj, -amount);
} }
weight_change_object(to_obj, amount); /* Add weight */ weight_change_object(to_obj, amount); /* Add weight */
} }
#undef DRINK_CON_MAX
#undef DRINK_CON_NOW
#undef DRINK_CON_TYPE
#undef DRINK_CON_POISON
#undef LIMITED_DRINK_CONTAINER
#undef EMPTY_DRINK_CONTAINER
static void wear_message(struct char_data *ch, struct obj_data *obj, int where) static void wear_message(struct char_data *ch, struct obj_data *obj, int where)
{ {
const char *wear_messages[][2] = { const char *wear_messages[][2] = {
+5 -3
View File
@@ -54,7 +54,7 @@ ACMD(do_assist)
else if (!CAN_SEE(ch, opponent)) else if (!CAN_SEE(ch, opponent))
act("You can't see who is fighting $M!", FALSE, ch, 0, helpee, TO_CHAR); act("You can't see who is fighting $M!", FALSE, ch, 0, helpee, TO_CHAR);
/* prevent accidental pkill */ /* prevent accidental pkill */
else if (!CONFIG_PK_ALLOWED && !IS_NPC(opponent)) else if (!pk_allowed(ch, opponent))
send_to_char(ch, "You cannot kill other players.\r\n"); send_to_char(ch, "You cannot kill other players.\r\n");
else { else {
send_to_char(ch, "You join the fight!\r\n"); send_to_char(ch, "You join the fight!\r\n");
@@ -82,8 +82,10 @@ ACMD(do_hit)
} else if (AFF_FLAGGED(ch, AFF_CHARM) && (ch->master == vict)) } else if (AFF_FLAGGED(ch, AFF_CHARM) && (ch->master == vict))
act("$N is just such a good friend, you simply can't hit $M.", FALSE, ch, 0, vict, TO_CHAR); act("$N is just such a good friend, you simply can't hit $M.", FALSE, ch, 0, vict, TO_CHAR);
else { else {
if (!CONFIG_PK_ALLOWED && !IS_NPC(vict) && !IS_NPC(ch)) if (!pk_allowed(ch, vict)) {
check_killer(ch, vict); send_to_char(ch, "Player killing is not allowed.\r\n");
return;
}
if ((GET_POS(ch) == POS_STANDING) && (vict != FIGHTING(ch))) { if ((GET_POS(ch) == POS_STANDING) && (vict != FIGHTING(ch))) {
if (GET_DEX(ch) > GET_DEX(vict) || (GET_DEX(ch) == GET_DEX(vict) && rand_number(1, 2) == 1)) /* if faster */ if (GET_DEX(ch) > GET_DEX(vict) || (GET_DEX(ch) == GET_DEX(vict) && rand_number(1, 2) == 1)) /* if faster */
+21 -4
View File
@@ -154,6 +154,7 @@ ACMD(do_steal)
send_to_char(ch, "You have no idea how to do that.\r\n"); send_to_char(ch, "You have no idea how to do that.\r\n");
return; return;
} }
if (ROOM_FLAGGED(IN_ROOM(ch), ROOM_PEACEFUL)) { if (ROOM_FLAGGED(IN_ROOM(ch), ROOM_PEACEFUL)) {
send_to_char(ch, "This room just has such a peaceful, easy feeling...\r\n"); send_to_char(ch, "This room just has such a peaceful, easy feeling...\r\n");
return; return;
@@ -169,20 +170,26 @@ ACMD(do_steal)
return; return;
} }
/* Check if player stealing is allowed */
if (!IS_NPC(vict)) {
if (CONFIG_PT_SETTING == CONFIG_PT_OFF) {
send_to_char(ch, "Stealing from players is not allowed.\r\n");
return;
}
pcsteal = (CONFIG_PT_SETTING == CONFIG_PT_LIMITED);
}
/* 101% is a complete failure */ /* 101% is a complete failure */
percent = rand_number(1, 101) - dex_app_skill[GET_DEX(ch)].p_pocket; percent = rand_number(1, 101) - dex_app_skill[GET_DEX(ch)].p_pocket;
if (GET_POS(vict) < POS_SLEEPING) if (GET_POS(vict) < POS_SLEEPING)
percent = -1; /* ALWAYS SUCCESS, unless heavy object. */ percent = -1; /* ALWAYS SUCCESS, unless heavy object. */
if (!CONFIG_PT_ALLOWED && !IS_NPC(vict))
pcsteal = 1;
if (!AWAKE(vict)) /* Easier to steal from sleeping people. */ if (!AWAKE(vict)) /* Easier to steal from sleeping people. */
percent -= 50; percent -= 50;
/* No stealing if not allowed. If it is no stealing from Imm's or Shopkeepers. */ /* No stealing if not allowed. If it is no stealing from Imm's or Shopkeepers. */
if (GET_LEVEL(vict) >= LVL_IMMORT || pcsteal || GET_MOB_SPEC(vict) == shop_keeper) if (GET_LEVEL(vict) >= LVL_IMMORT || GET_MOB_SPEC(vict) == shop_keeper)
percent = 101; /* Failure */ percent = 101; /* Failure */
if (str_cmp(obj_name, "coins") && str_cmp(obj_name, "gold")) { if (str_cmp(obj_name, "coins") && str_cmp(obj_name, "gold")) {
@@ -221,6 +228,12 @@ ACMD(do_steal)
if (percent > GET_SKILL(ch, SKILL_STEAL)) { if (percent > GET_SKILL(ch, SKILL_STEAL)) {
ohoh = TRUE; ohoh = TRUE;
send_to_char(ch, "Oops..\r\n"); send_to_char(ch, "Oops..\r\n");
/* Player got caught and stealing is limited via cedit */
if ( (pcsteal) && (!PLR_FLAGGED(ch, PLR_THIEF))) {
SET_BIT_AR(PLR_FLAGS(ch), PLR_THIEF);
}
act("$n tried to steal something from you!", FALSE, ch, 0, vict, TO_VICT); act("$n tried to steal something from you!", FALSE, ch, 0, vict, TO_VICT);
act("$n tries to steal something from $N.", TRUE, ch, 0, vict, TO_NOTVICT); act("$n tries to steal something from $N.", TRUE, ch, 0, vict, TO_NOTVICT);
} else { /* Steal the item */ } else { /* Steal the item */
@@ -242,6 +255,10 @@ ACMD(do_steal)
} else { /* Steal some coins */ } else { /* Steal some coins */
if (AWAKE(vict) && (percent > GET_SKILL(ch, SKILL_STEAL))) { if (AWAKE(vict) && (percent > GET_SKILL(ch, SKILL_STEAL))) {
ohoh = TRUE; ohoh = TRUE;
/* Player got caught and stealing is limited via cedit */
if ( (pcsteal) && (!PLR_FLAGGED(ch, PLR_THIEF))) {
SET_BIT_AR(PLR_FLAGS(ch), PLR_THIEF);
}
send_to_char(ch, "Oops..\r\n"); send_to_char(ch, "Oops..\r\n");
act("You discover that $n has $s hands in your wallet.", FALSE, ch, 0, vict, TO_VICT); act("You discover that $n has $s hands in your wallet.", FALSE, ch, 0, vict, TO_VICT);
act("$n tries to steal gold from $N.", TRUE, ch, 0, vict, TO_NOTVICT); act("$n tries to steal gold from $N.", TRUE, ch, 0, vict, TO_NOTVICT);
+1 -1
View File
@@ -56,7 +56,7 @@ ACMD(do_action)
if (!action->char_found) if (!action->char_found)
*arg = '\0'; *arg = '\0';
if (action->char_found && argument) if (action->char_found)
one_argument(argument, arg); one_argument(argument, arg);
else else
*arg = '\0'; *arg = '\0';
+4 -1
View File
@@ -2396,7 +2396,10 @@ ACMD(do_wizutil)
act("A sudden fireball conjured from nowhere thaws $n!", FALSE, vict, 0, 0, TO_ROOM); act("A sudden fireball conjured from nowhere thaws $n!", FALSE, vict, 0, 0, TO_ROOM);
break; break;
case SCMD_UNAFFECT: case SCMD_UNAFFECT:
if (vict->affected || AFF_FLAGS(vict)) { for (taeller = 0; taeller < AF_ARRAY_MAX; taeller++)
if (AFF_FLAGS(vict)[taeller])
break;
if (vict->affected || taeller < AF_ARRAY_MAX) {
while (vict->affected) while (vict->affected)
affect_remove(vict, vict->affected); affect_remove(vict, vict->affected);
for(taeller=0; taeller < AF_ARRAY_MAX; taeller++) for(taeller=0; taeller < AF_ARRAY_MAX; taeller++)
+3 -3
View File
@@ -374,9 +374,9 @@ SPECIAL(king_welmar)
"$n proclaims 'principe dignos'." "$n proclaims 'principe dignos'."
}; };
const char bedroom_path[] = "s33004o1c1S."; static const char bedroom_path[] = "s33004o1c1S.";
const char throne_path[] = "W3o3cG52211rg."; static const char throne_path[] = "W3o3cG52211rg.";
const char monolog_path[] = "ABCDPPPP."; static const char monolog_path[] = "ABCDPPPP.";
static const char *path; static const char *path;
static int path_index; static int path_index;
+47 -13
View File
@@ -79,8 +79,8 @@ static void cedit_setup(struct descriptor_data *d)
/* Copy the current configuration from the config_info to this one and copy /* Copy the current configuration from the config_info to this one and copy
* the game play options from the configuration info struct. */ * the game play options from the configuration info struct. */
OLC_CONFIG(d)->play.pk_allowed = CONFIG_PK_ALLOWED; OLC_CONFIG(d)->play.pk_setting = CONFIG_PK_SETTING;
OLC_CONFIG(d)->play.pt_allowed = CONFIG_PT_ALLOWED; OLC_CONFIG(d)->play.pt_setting = CONFIG_PT_SETTING;
OLC_CONFIG(d)->play.level_can_shout = CONFIG_LEVEL_CAN_SHOUT; OLC_CONFIG(d)->play.level_can_shout = CONFIG_LEVEL_CAN_SHOUT;
OLC_CONFIG(d)->play.holler_move_cost = CONFIG_HOLLER_MOVE_COST; OLC_CONFIG(d)->play.holler_move_cost = CONFIG_HOLLER_MOVE_COST;
OLC_CONFIG(d)->play.tunnel_size = CONFIG_TUNNEL_SIZE; OLC_CONFIG(d)->play.tunnel_size = CONFIG_TUNNEL_SIZE;
@@ -183,8 +183,8 @@ static void cedit_save_internally(struct descriptor_data *d)
/* see if we need to reassign spec procs on rooms */ /* see if we need to reassign spec procs on rooms */
int reassign = (CONFIG_DTS_ARE_DUMPS != OLC_CONFIG(d)->play.dts_are_dumps); int reassign = (CONFIG_DTS_ARE_DUMPS != OLC_CONFIG(d)->play.dts_are_dumps);
/* Copy the data back from the descriptor to the config_info structure. */ /* Copy the data back from the descriptor to the config_info structure. */
CONFIG_PK_ALLOWED = OLC_CONFIG(d)->play.pk_allowed; CONFIG_PK_SETTING = OLC_CONFIG(d)->play.pk_setting;
CONFIG_PT_ALLOWED = OLC_CONFIG(d)->play.pt_allowed; CONFIG_PT_SETTING = OLC_CONFIG(d)->play.pt_setting;
CONFIG_LEVEL_CAN_SHOUT = OLC_CONFIG(d)->play.level_can_shout; CONFIG_LEVEL_CAN_SHOUT = OLC_CONFIG(d)->play.level_can_shout;
CONFIG_HOLLER_MOVE_COST = OLC_CONFIG(d)->play.holler_move_cost; CONFIG_HOLLER_MOVE_COST = OLC_CONFIG(d)->play.holler_move_cost;
CONFIG_TUNNEL_SIZE = OLC_CONFIG(d)->play.tunnel_size; CONFIG_TUNNEL_SIZE = OLC_CONFIG(d)->play.tunnel_size;
@@ -339,9 +339,9 @@ int save_config( IDXTYPE nowhere )
); );
fprintf(fl, "* Is player killing allowed on the mud?\n" fprintf(fl, "* Is player killing allowed on the mud?\n"
"pk_allowed = %d\n\n", CONFIG_PK_ALLOWED); "pk_setting = %d\n\n", CONFIG_PK_SETTING);
fprintf(fl, "* Is player thieving allowed on the mud?\n" fprintf(fl, "* Is player thieving allowed on the mud?\n"
"pt_allowed = %d\n\n", CONFIG_PT_ALLOWED); "pt_setting = %d\n\n", CONFIG_PT_SETTING);
fprintf(fl, "* What is the minimum level a player can shout/gossip/etc?\n" fprintf(fl, "* What is the minimum level a player can shout/gossip/etc?\n"
"level_can_shout = %d\n\n", CONFIG_LEVEL_CAN_SHOUT); "level_can_shout = %d\n\n", CONFIG_LEVEL_CAN_SHOUT);
fprintf(fl, "* How many movement points does shouting cost the player?\n" fprintf(fl, "* How many movement points does shouting cost the player?\n"
@@ -608,8 +608,10 @@ static void cedit_disp_menu(struct descriptor_data *d)
static void cedit_disp_game_play_options(struct descriptor_data *d) static void cedit_disp_game_play_options(struct descriptor_data *d)
{ {
int m_opt; int m_opt, pk_setting, pt_setting;
m_opt = OLC_CONFIG(d)->play.map_option; m_opt = OLC_CONFIG(d)->play.map_option;
pk_setting = OLC_CONFIG(d)->play.pk_setting;
pt_setting = OLC_CONFIG(d)->play.pt_setting;
get_char_colors(d->character); get_char_colors(d->character);
clear_screen(d); clear_screen(d);
@@ -644,8 +646,8 @@ static void cedit_disp_game_play_options(struct descriptor_data *d)
"%s8%s) Scripts on PC's : %s%s\r\n" "%s8%s) Scripts on PC's : %s%s\r\n"
"%sQ%s) Exit To The Main Menu\r\n" "%sQ%s) Exit To The Main Menu\r\n"
"Enter your choice : ", "Enter your choice : ",
grn, nrm, cyn, CHECK_VAR(OLC_CONFIG(d)->play.pk_allowed), grn, nrm, cyn, pk_setting == 0 ? "Off" : (pk_setting == 1 ? "Limited" : (pk_setting == 2 ? "Free-for-all" : "Invalid!")),
grn, nrm, cyn, CHECK_VAR(OLC_CONFIG(d)->play.pt_allowed), grn, nrm, cyn, pt_setting == 0 ? "Off" : (pt_setting == 1 ? "Limited" : (pt_setting == 2 ? "Free-for-all" : "Invalid!")),
grn, nrm, cyn, OLC_CONFIG(d)->play.level_can_shout, grn, nrm, cyn, OLC_CONFIG(d)->play.level_can_shout,
grn, nrm, cyn, OLC_CONFIG(d)->play.holler_move_cost, grn, nrm, cyn, OLC_CONFIG(d)->play.holler_move_cost,
grn, nrm, cyn, OLC_CONFIG(d)->play.tunnel_size, grn, nrm, cyn, OLC_CONFIG(d)->play.tunnel_size,
@@ -883,13 +885,21 @@ void cedit_parse(struct descriptor_data *d, char *arg)
switch (*arg) { switch (*arg) {
case 'a': case 'a':
case 'A': case 'A':
TOGGLE_VAR(OLC_CONFIG(d)->play.pk_allowed); write_to_output(d, "1) No Player Killing\r\n");
break; write_to_output(d, "2) Limited Player Killing\r\n");
write_to_output(d, "3) Free-for-all!\r\n");
write_to_output(d, "Enter choice: ");
OLC_MODE(d) = CEDIT_PK_SETTING;
return;
case 'b': case 'b':
case 'B': case 'B':
TOGGLE_VAR(OLC_CONFIG(d)->play.pt_allowed); write_to_output(d, "1) No Player Thieving\r\n");
break; write_to_output(d, "2) Limited Player Thieving\r\n");
write_to_output(d, "3) Free-for-all!\r\n");
write_to_output(d, "Enter choice: ");
OLC_MODE(d) = CEDIT_PT_SETTING;
return;
case 'c': case 'c':
case 'C': case 'C':
@@ -1708,6 +1718,30 @@ void cedit_parse(struct descriptor_data *d, char *arg)
} }
break; break;
case CEDIT_PK_SETTING:
if (!*arg || (atoi(arg) < 0) || (atoi(arg) > 3) ) {
write_to_output(d,
"That is an invalid choice!\r\n"
"Select 1, 2 or 3 (0 to cancel) :");
} else {
if ((atoi(arg) >= 1) && (atoi(arg) <= 3))
OLC_CONFIG(d)->play.pk_setting = (atoi(arg) - 1);
cedit_disp_game_play_options(d);
}
break;
case CEDIT_PT_SETTING:
if (!*arg || (atoi(arg) < 0) || (atoi(arg) > 3) ) {
write_to_output(d,
"That is an invalid choice!\r\n"
"Select 1, 2 or 3 (0 to cancel) :");
} else {
if ((atoi(arg) >= 1) && (atoi(arg) <= 3))
OLC_CONFIG(d)->play.pt_setting = (atoi(arg) - 1);
cedit_disp_game_play_options(d);
}
break;
default: /* We should never get here, but just in case... */ default: /* We should never get here, but just in case... */
cleanup_olc(d, CLEANUP_CONFIG); cleanup_olc(d, CLEANUP_CONFIG);
mudlog(BRF, LVL_BUILDER, TRUE, "SYSERR: OLC: cedit_parse(): Reached default case!"); mudlog(BRF, LVL_BUILDER, TRUE, "SYSERR: OLC: cedit_parse(): Reached default case!");
+18 -8
View File
@@ -39,15 +39,25 @@
/* Can Scripts be attached to players? */ /* Can Scripts be attached to players? */
int script_players = NO; int script_players = NO;
/* pk_allowed sets the tone of the entire game. If pk_allowed is set to NO, /* pk_setting sets the tone of the entire game.
* then players will not be allowed to kill, summon, charm, or sleep other *
* players, as well as a variety of other "asshole player" protections. However, * CONFIG_PK_OFF 0 Players are prevented from damaging or fighting other players in code
* if you decide you want to have an all-out knock-down drag-out PK Mud, just * CONFIG_PK_LIMITED 1 Players may damage and fight but will be flagged PLR_KILLER
* set pk_allowed to YES - and anything goes. */ * CONFIG_PK_FREEFORALL 2 No restrictions or flags for player damaging or killing
int pk_allowed = NO; *
* If pk_setting is set to 0, then players will not be allowed to kill, summon, charm, or sleep other
* players, as well as a variety of other "asshole player" protections.
* However, if you decide you want to have an all-out knock-down drag-out PK Mud, just
* set pk_setting to 2 - and anything goes. */
int pk_setting = 0;
/* Is playerthieving allowed? */ /* Is playerthieving allowed?
int pt_allowed = NO; *
* CONFIG_PT_OFF 0 Players are prevented from stealing from other players in code
* CONFIG_PT_LIMITED 1 Players may steal from other players but will be flagged PLR_THIEF if caught
* CONFIG_PT_FREEFORALL 2 No restrictions or flags for player stealing
*/
int pt_setting = 0;
/* Minimum level a player must be to shout/holler/gossip/auction. */ /* Minimum level a player must be to shout/holler/gossip/auction. */
int level_can_shout = 1; int level_can_shout = 1;
+2 -2
View File
@@ -14,9 +14,9 @@
#define _CONFIG_H_ #define _CONFIG_H_
/* Global variable declarations, all settable by cedit */ /* Global variable declarations, all settable by cedit */
extern int pk_allowed; extern int pk_setting;
extern int script_players; extern int script_players;
extern int pt_allowed; extern int pt_setting;
extern int level_can_shout; extern int level_can_shout;
extern int holler_move_cost; extern int holler_move_cost;
extern int tunnel_size; extern int tunnel_size;
+6 -6
View File
@@ -3838,8 +3838,8 @@ static void load_default_config( void )
/* This function is called only once, at boot-time. We assume config_info is /* This function is called only once, at boot-time. We assume config_info is
* empty. -Welcor */ * empty. -Welcor */
/* Game play options. */ /* Game play options. */
CONFIG_PK_ALLOWED = pk_allowed; CONFIG_PK_SETTING = pk_setting;
CONFIG_PT_ALLOWED = pt_allowed; CONFIG_PT_SETTING = pt_setting;
CONFIG_LEVEL_CAN_SHOUT = level_can_shout; CONFIG_LEVEL_CAN_SHOUT = level_can_shout;
CONFIG_HOLLER_MOVE_COST = holler_move_cost; CONFIG_HOLLER_MOVE_COST = holler_move_cost;
CONFIG_TUNNEL_SIZE = tunnel_size; CONFIG_TUNNEL_SIZE = tunnel_size;
@@ -4113,12 +4113,12 @@ void load_config( void )
break; break;
case 'p': case 'p':
if (!str_cmp(tag, "pk_allowed")) if (!str_cmp(tag, "pk_setting"))
CONFIG_PK_ALLOWED = num; CONFIG_PK_SETTING = num;
else if (!str_cmp(tag, "protocol_negotiation")) else if (!str_cmp(tag, "protocol_negotiation"))
CONFIG_PROTOCOL_NEGOTIATION = num; CONFIG_PROTOCOL_NEGOTIATION = num;
else if (!str_cmp(tag, "pt_allowed")) else if (!str_cmp(tag, "pt_setting"))
CONFIG_PT_ALLOWED = num; CONFIG_PT_SETTING = num;
break; break;
case 'r': case 'r':
+6 -3
View File
@@ -147,7 +147,7 @@ void greet_memory_mtrigger(char_data *actor)
{ {
trig_data *t; trig_data *t;
char_data *ch; char_data *ch;
struct script_memory *mem; struct script_memory *mem, *next_mem;
char buf[MAX_INPUT_LENGTH]; char buf[MAX_INPUT_LENGTH];
int command_performed = 0; int command_performed = 0;
@@ -159,7 +159,8 @@ void greet_memory_mtrigger(char_data *actor)
AFF_FLAGGED(ch, AFF_CHARM)) AFF_FLAGGED(ch, AFF_CHARM))
continue; continue;
/* find memory line with command only */ /* find memory line with command only */
for (mem = SCRIPT_MEM(ch); mem && SCRIPT_MEM(ch); mem=mem->next) { for (mem = SCRIPT_MEM(ch); mem && SCRIPT_MEM(ch); mem = next_mem) {
next_mem = mem->next;
if (char_script_id(actor)!=mem->id) continue; if (char_script_id(actor)!=mem->id) continue;
if (mem->cmd) { if (mem->cmd) {
command_interpreter(ch, mem->cmd); /* no script */ command_interpreter(ch, mem->cmd); /* no script */
@@ -245,7 +246,8 @@ void entry_memory_mtrigger(char_data *ch)
for (actor = world[IN_ROOM(ch)].people; actor && SCRIPT_MEM(ch); for (actor = world[IN_ROOM(ch)].people; actor && SCRIPT_MEM(ch);
actor = actor->next_in_room) { actor = actor->next_in_room) {
if (actor!=ch && SCRIPT_MEM(ch)) { if (actor!=ch && SCRIPT_MEM(ch)) {
for (mem = SCRIPT_MEM(ch); mem && SCRIPT_MEM(ch); mem = mem->next) { for (mem = SCRIPT_MEM(ch); mem && SCRIPT_MEM(ch); ) {
struct script_memory *next_mem = mem->next;
if (char_script_id(actor)==mem->id) { if (char_script_id(actor)==mem->id) {
struct script_memory *prev; struct script_memory *prev;
if (mem->cmd) command_interpreter(ch, mem->cmd); if (mem->cmd) command_interpreter(ch, mem->cmd);
@@ -270,6 +272,7 @@ void entry_memory_mtrigger(char_data *ch)
if (mem->cmd) free(mem->cmd); if (mem->cmd) free(mem->cmd);
free(mem); free(mem);
} }
mem = next_mem;
} /* for (mem =..... */ } /* for (mem =..... */
} }
} }
+2 -2
View File
@@ -465,7 +465,7 @@ void find_replacement(void *go, struct script_data *sc, trig_data *trig,
* will return the number of bags of gold. * will return the number of bags of gold.
* Addition inspired by Jamie Nelson */ * Addition inspired by Jamie Nelson */
else if (!str_cmp(var, "findmob")) { else if (!str_cmp(var, "findmob")) {
if (!field || !*field || !subfield || !*subfield) { if (!*field || !subfield || !*subfield) {
script_log("findmob.vnum(mvnum) - illegal syntax"); script_log("findmob.vnum(mvnum) - illegal syntax");
strcpy(str, "0"); strcpy(str, "0");
} else { } else {
@@ -486,7 +486,7 @@ void find_replacement(void *go, struct script_data *sc, trig_data *trig,
} }
/* Addition inspired by Jamie Nelson. */ /* Addition inspired by Jamie Nelson. */
else if (!str_cmp(var, "findobj")) { else if (!str_cmp(var, "findobj")) {
if (!field || !*field || !subfield || !*subfield) { if (!*field || !subfield || !*subfield) {
script_log("findobj.vnum(ovnum) - illegal syntax"); script_log("findobj.vnum(ovnum) - illegal syntax");
strcpy(str, "0"); strcpy(str, "0");
} else { } else {
+34 -12
View File
@@ -110,10 +110,13 @@ void update_pos(struct char_data *victim)
void check_killer(struct char_data *ch, struct char_data *vict) void check_killer(struct char_data *ch, struct char_data *vict)
{ {
if (PLR_FLAGGED(vict, PLR_KILLER) || PLR_FLAGGED(vict, PLR_THIEF)) if (PLR_FLAGGED(vict, PLR_KILLER) || PLR_FLAGGED(vict, PLR_THIEF)) {
return;
if (PLR_FLAGGED(ch, PLR_KILLER) || IS_NPC(ch) || IS_NPC(vict) || ch == vict)
return; return;
}
if (PLR_FLAGGED(ch, PLR_KILLER) || IS_NPC(ch) || IS_NPC(vict) || ch == vict){
return;
}
SET_BIT_AR(PLR_FLAGS(ch), PLR_KILLER); SET_BIT_AR(PLR_FLAGS(ch), PLR_KILLER);
send_to_char(ch, "If you want to be a PLAYER KILLER, so be it...\r\n"); send_to_char(ch, "If you want to be a PLAYER KILLER, so be it...\r\n");
@@ -122,6 +125,22 @@ void check_killer(struct char_data *ch, struct char_data *vict)
GET_NAME(ch), GET_NAME(vict), world[IN_ROOM(vict)].name); GET_NAME(ch), GET_NAME(vict), world[IN_ROOM(vict)].name);
} }
bool pk_allowed(struct char_data *ch, struct char_data *victim)
{
/* NPCs are never restricted */
if (IS_NPC(ch) || IS_NPC(victim))
return true;
if (CONFIG_PK_SETTING == CONFIG_PK_OFF)
return false;
if (CONFIG_PK_SETTING == CONFIG_PK_LIMITED)
check_killer(ch, victim);
return true;
}
/* start one char fighting another (yes, it is horrible, I know... ) */ /* start one char fighting another (yes, it is horrible, I know... ) */
void set_fighting(struct char_data *ch, struct char_data *vict) void set_fighting(struct char_data *ch, struct char_data *vict)
{ {
@@ -133,6 +152,12 @@ void set_fighting(struct char_data *ch, struct char_data *vict)
return; return;
} }
if (!pk_allowed(ch, vict)) {
send_to_char(ch, "Player killing is not permitted.\r\n");
return;
}
ch->next_fighting = combat_list; ch->next_fighting = combat_list;
combat_list = ch; combat_list = ch;
@@ -142,8 +167,6 @@ void set_fighting(struct char_data *ch, struct char_data *vict)
FIGHTING(ch) = vict; FIGHTING(ch) = vict;
GET_POS(ch) = POS_FIGHTING; GET_POS(ch) = POS_FIGHTING;
if (!CONFIG_PK_ALLOWED)
check_killer(ch, vict);
} }
/* remove a char from the list of fighting chars */ /* remove a char from the list of fighting chars */
@@ -603,6 +626,12 @@ int damage(struct char_data *ch, struct char_data *victim, int dam, int attackty
return (-1); /* -je, 7/7/92 */ return (-1); /* -je, 7/7/92 */
} }
/* Check for PK if this is not a PK MUD */
if (!pk_allowed(ch, victim)) {
send_to_char(ch, "Player killing is not permitted.\r\n");
return (0);
}
/* peaceful rooms */ /* peaceful rooms */
if (ch->nr != real_mobile(DG_CASTER_PROXY) && if (ch->nr != real_mobile(DG_CASTER_PROXY) &&
ch != victim && ROOM_FLAGGED(IN_ROOM(ch), ROOM_PEACEFUL)) { ch != victim && ROOM_FLAGGED(IN_ROOM(ch), ROOM_PEACEFUL)) {
@@ -650,13 +679,6 @@ int damage(struct char_data *ch, struct char_data *victim, int dam, int attackty
if (AFF_FLAGGED(victim, AFF_SANCTUARY) && dam >= 2) if (AFF_FLAGGED(victim, AFF_SANCTUARY) && dam >= 2)
dam /= 2; dam /= 2;
/* Check for PK if this is not a PK MUD */
if (!CONFIG_PK_ALLOWED) {
check_killer(ch, victim);
if (PLR_FLAGGED(ch, PLR_KILLER) && (ch != victim))
dam = 0;
}
/* Set the maximum damage per round and subtract the hit points */ /* Set the maximum damage per round and subtract the hit points */
dam = MAX(MIN(dam, 100), 0); dam = MAX(MIN(dam, 100), 0);
GET_HIT(victim) -= dam; GET_HIT(victim) -= dam;
+1
View File
@@ -34,6 +34,7 @@ void set_fighting(struct char_data *ch, struct char_data *victim);
int skill_message(int dam, struct char_data *ch, struct char_data *vict, int skill_message(int dam, struct char_data *ch, struct char_data *vict,
int attacktype); int attacktype);
void stop_fighting(struct char_data *ch); void stop_fighting(struct char_data *ch);
bool pk_allowed(struct char_data *ch, struct char_data *victim);
/* Global variables */ /* Global variables */
+2 -2
View File
@@ -367,7 +367,7 @@ void parse_edit_action(int command, char *string, struct descriptor_data *d)
s++; s++;
temp = *s; temp = *s;
*s = '\0'; *s = '\0';
char buf3[9]; char buf3[13];
sprintf(buf3, "%4d: ", (i - 1)); sprintf(buf3, "%4d: ", (i - 1));
strncat(buf, buf3, sizeof(buf) - strlen(buf) - 1); strncat(buf, buf3, sizeof(buf) - strlen(buf) - 1);
strncat(buf, t, sizeof(buf) - strlen(buf) - 1); strncat(buf, t, sizeof(buf) - strlen(buf) - 1);
@@ -421,7 +421,7 @@ void parse_edit_action(int command, char *string, struct descriptor_data *d)
strncat(buf, *d->str, sizeof(buf) - strlen(buf) - 1); strncat(buf, *d->str, sizeof(buf) - strlen(buf) - 1);
*s = temp; *s = temp;
strncat(buf, buf2, sizeof(buf) - strlen(buf) - 1); strncat(buf, buf2, sizeof(buf) - strlen(buf) - 1);
if (s && *s) if (*s)
strncat(buf, s, sizeof(buf) - strlen(buf) - 1); strncat(buf, s, sizeof(buf) - strlen(buf) - 1);
RECREATE(*d->str, char, strlen(buf) + 3); RECREATE(*d->str, char, strlen(buf) + 3);
+2 -1
View File
@@ -1612,8 +1612,9 @@ void nanny(struct descriptor_data *d, char *arg)
if (load_result == CLASS_UNDEFINED) { if (load_result == CLASS_UNDEFINED) {
write_to_output(d, "\r\nThat's not a class.\r\nClass: "); write_to_output(d, "\r\nThat's not a class.\r\nClass: ");
return; return;
} else } else {
GET_CLASS(d->character) = load_result; GET_CLASS(d->character) = load_result;
}
if (d->olc) { if (d->olc) {
free(d->olc); free(d->olc);
+2 -2
View File
@@ -473,7 +473,7 @@ void mag_affects(int level, struct char_data *ch, struct char_data *victim,
break; break;
case SPELL_SLEEP: case SPELL_SLEEP:
if (!CONFIG_PK_ALLOWED && !IS_NPC(ch) && !IS_NPC(victim)) if ((CONFIG_PK_SETTING == CONFIG_PK_OFF) && !IS_NPC(ch) && !IS_NPC(victim))
return; return;
if (MOB_FLAGGED(victim, MOB_NOSLEEP)) if (MOB_FLAGGED(victim, MOB_NOSLEEP))
return; return;
@@ -650,7 +650,7 @@ void mag_areas(int level, struct char_data *ch, int spellnum, int savetype)
continue; continue;
if (!IS_NPC(tch) && GET_LEVEL(tch) >= LVL_IMMORT) if (!IS_NPC(tch) && GET_LEVEL(tch) >= LVL_IMMORT)
continue; continue;
if (!CONFIG_PK_ALLOWED && !IS_NPC(ch) && !IS_NPC(tch)) if ((CONFIG_PK_SETTING == CONFIG_PK_OFF) && !IS_NPC(ch) && !IS_NPC(tch))
continue; continue;
if (!IS_NPC(ch) && IS_NPC(tch) && AFF_FLAGGED(tch, AFF_CHARM)) if (!IS_NPC(ch) && IS_NPC(tch) && AFF_FLAGGED(tch, AFF_CHARM))
continue; continue;
+2
View File
@@ -380,6 +380,8 @@ extern const char *nrm, *grn, *cyn, *yel;
#define CEDIT_MAP_SIZE 55 #define CEDIT_MAP_SIZE 55
#define CEDIT_MINIMAP_SIZE 56 #define CEDIT_MINIMAP_SIZE 56
#define CEDIT_DEBUG_MODE 57 #define CEDIT_DEBUG_MODE 57
#define CEDIT_PK_SETTING 58
#define CEDIT_PT_SETTING 59
/* Hedit Submodes of connectedness. */ /* Hedit Submodes of connectedness. */
#define HEDIT_CONFIRM_SAVESTRING 0 #define HEDIT_CONFIRM_SAVESTRING 0
+15 -10
View File
@@ -2102,20 +2102,25 @@ static void ExecuteMSDPPair( descriptor_t *apDescriptor, const char *apVariable,
!strcmp(apDescriptor->pProtocol->pVariables[i]->pValueString, "Unknown") ) !strcmp(apDescriptor->pProtocol->pVariables[i]->pValueString, "Unknown") )
{ {
/* Store the new value if it's valid */ /* Store the new value if it's valid */
char *pBuffer = alloca(VariableNameTable[i].Max+1); char *pBuffer = malloc(VariableNameTable[i].Max + 1);
int j; /* Loop counter */ int j; /* Loop counter */
for ( j = 0; j < VariableNameTable[i].Max && *apValue != '\0'; ++apValue ) if ( pBuffer != NULL )
{ {
if ( isprint(*apValue) ) for ( j = 0; j < VariableNameTable[i].Max && *apValue != '\0'; ++apValue )
pBuffer[j++] = *apValue; {
} if ( isprint(*apValue) )
pBuffer[j++] = '\0'; pBuffer[j++] = *apValue;
}
pBuffer[j++] = '\0';
if ( j >= VariableNameTable[i].Min ) if ( j >= VariableNameTable[i].Min )
{ {
free(apDescriptor->pProtocol->pVariables[i]->pValueString); free(apDescriptor->pProtocol->pVariables[i]->pValueString);
apDescriptor->pProtocol->pVariables[i]->pValueString = AllocString(pBuffer); apDescriptor->pProtocol->pVariables[i]->pValueString = AllocString(pBuffer);
}
free(pBuffer);
} }
} }
} }
+4 -2
View File
@@ -410,8 +410,10 @@ void autoquest_trigger_check(struct char_data *ch, struct char_data *vict,
break; break;
case AQ_OBJ_RETURN: case AQ_OBJ_RETURN:
if (IS_NPC(vict) && (GET_MOB_VNUM(vict) == QST_RETURNMOB(rnum))) if (IS_NPC(vict) && (GET_MOB_VNUM(vict) == QST_RETURNMOB(rnum)))
if (object && (GET_OBJ_VNUM(object) == QST_TARGET(rnum))) if (object && (GET_OBJ_VNUM(object) == QST_TARGET(rnum))) {
generic_complete_quest(ch); generic_complete_quest(ch);
extract_obj(object);
}
break; break;
case AQ_ROOM_CLEAR: case AQ_ROOM_CLEAR:
if (QST_TARGET(rnum) == world[IN_ROOM(ch)].number) { if (QST_TARGET(rnum) == world[IN_ROOM(ch)].number) {
@@ -648,7 +650,7 @@ static void quest_show(struct char_data *ch, mob_vnum qm)
send_to_char(ch, "There are no quests available here at the moment.\r\n"); send_to_char(ch, "There are no quests available here at the moment.\r\n");
} }
static void quest_stat(struct char_data *ch, char argument[MAX_STRING_LENGTH]) static void quest_stat(struct char_data *ch, char *argument)
{ {
qst_rnum rnum; qst_rnum rnum;
mob_rnum qmrnum; mob_rnum qmrnum;
+1 -1
View File
@@ -1052,7 +1052,7 @@ static void read_line(FILE *shop_f, const char *string, void *data)
{ {
char buf[READ_SIZE]; char buf[READ_SIZE];
if (!get_line(shop_f, buf) || !sscanf(buf, string, data)) { if (!get_line(shop_f, buf) || sscanf(buf, string, data) != 1) {
log("SYSERR: Error in shop #%d, near '%s' with '%s'", SHOP_NUM(top_shop), buf, string); log("SYSERR: Error in shop #%d, near '%s' with '%s'", SHOP_NUM(top_shop), buf, string);
exit(1); exit(1);
} }
+2 -2
View File
@@ -202,9 +202,9 @@ SPECIAL(mayor)
{ {
char actbuf[MAX_INPUT_LENGTH]; char actbuf[MAX_INPUT_LENGTH];
const char open_path[] = static const char open_path[] =
"W3a3003b33000c111d0d111Oe333333Oe22c222112212111a1S."; "W3a3003b33000c111d0d111Oe333333Oe22c222112212111a1S.";
const char close_path[] = static const char close_path[] =
"W3a3003b33000c111d0d111CE333333CE22c222112212111a1S."; "W3a3003b33000c111d0d111CE333333CE22c222112212111a1S.";
static const char *path = NULL; static const char *path = NULL;
+2 -2
View File
@@ -120,7 +120,7 @@ ASPELL(spell_summon)
return; return;
} }
if (!CONFIG_PK_ALLOWED) { if (CONFIG_PK_SETTING == CONFIG_PK_OFF) {
if (MOB_FLAGGED(victim, MOB_AGGRESSIVE)) { if (MOB_FLAGGED(victim, MOB_AGGRESSIVE)) {
act("As the words escape your lips and $N travels\r\n" act("As the words escape your lips and $N travels\r\n"
"through time and space towards you, you realize that $E is\r\n" "through time and space towards you, you realize that $E is\r\n"
@@ -265,7 +265,7 @@ ASPELL(spell_charm)
else if (AFF_FLAGGED(victim, AFF_CHARM) || level < GET_LEVEL(victim)) else if (AFF_FLAGGED(victim, AFF_CHARM) || level < GET_LEVEL(victim))
send_to_char(ch, "You fail.\r\n"); send_to_char(ch, "You fail.\r\n");
/* player charming another player - no legal reason for this */ /* player charming another player - no legal reason for this */
else if (!CONFIG_PK_ALLOWED && !IS_NPC(victim)) else if ((CONFIG_PK_SETTING == CONFIG_PK_OFF) && !IS_NPC(victim))
send_to_char(ch, "You fail - shouldn't be doing it anyway.\r\n"); send_to_char(ch, "You fail - shouldn't be doing it anyway.\r\n");
else if (circle_follow(victim, ch)) else if (circle_follow(victim, ch))
send_to_char(ch, "Sorry, following in circles is not allowed.\r\n"); send_to_char(ch, "Sorry, following in circles is not allowed.\r\n");
+2 -2
View File
@@ -1291,8 +1291,8 @@ struct recent_player
* variables. */ * variables. */
struct game_data struct game_data
{ {
int pk_allowed; /**< Is player killing allowed? */ int pk_setting; /**< Is player killing allowed? */
int pt_allowed; /**< Is player thieving allowed? */ int pt_setting; /**< Is player thieving allowed? */
int level_can_shout; /**< Level player must be to shout. */ int level_can_shout; /**< Level player must be to shout. */
int holler_move_cost; /**< Cost to holler in move points. */ int holler_move_cost; /**< Cost to holler in move points. */
int tunnel_size; /**< Number of people allowed in a tunnel.*/ int tunnel_size; /**< Number of people allowed in a tunnel.*/
-1
View File
@@ -9,7 +9,6 @@ set(TOOLS
sign sign
split split
wld2html wld2html
webster
) )
# common includes and flags # common includes and flags
+8 -2
View File
@@ -939,9 +939,15 @@ do \
#define CONFIG_CONFFILE config_info.CONFFILE #define CONFIG_CONFFILE config_info.CONFFILE
/** Player killing allowed or not? */ /** Player killing allowed or not? */
#define CONFIG_PK_ALLOWED config_info.play.pk_allowed #define CONFIG_PK_SETTING config_info.play.pk_setting
#define CONFIG_PK_OFF 0 /* Players are prevented from damaging or fighting other players in code */
#define CONFIG_PK_LIMITED 1 /* Players may damage and fight but will be flagged PLR_KILLER */
#define CONFIG_PK_FREEFORALL 2 /* No restrictions or flags for player damaging or killing */
/** Player thieving allowed or not? */ /** Player thieving allowed or not? */
#define CONFIG_PT_ALLOWED config_info.play.pt_allowed #define CONFIG_PT_SETTING config_info.play.pt_setting
#define CONFIG_PT_OFF 0 /* Players are prevented from stealing from other players in code */
#define CONFIG_PT_LIMITED 1 /* Players may steal from other players but will be flagged PLR_THIEF if caught */
#define CONFIG_PT_FREEFORALL 2 /* No restrictions or flags for player stealing */
/** What level to use the shout command? */ /** What level to use the shout command? */
#define CONFIG_LEVEL_CAN_SHOUT config_info.play.level_can_shout #define CONFIG_LEVEL_CAN_SHOUT config_info.play.level_can_shout
/** How many move points does holler cost? */ /** How many move points does holler cost? */