Crossfire Server, Trunk
check_duplicate_skills.cpp
Go to the documentation of this file.
1 /*
2  * CrossFire, A Multiplayer game for X-windows
3  *
4  * Copyright (C) 2021 Crossfire Development Team
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  *
20  * The authors can be reached via e-mail at crossfire-devel@real-time.com
21  */
30 #include <stdlib.h>
31 #include <check.h>
32 #include <global.h>
33 #include <sproto.h>
34 #include <toolkit_common.h>
35 
36 static void setup(void) {
37 }
38 
39 static void teardown(void) {
40 }
41 
42 START_TEST(test_skills) {
43  // We will be using the halfling thief as our example, since both get stealing.
44  player *pl;
45  archetype *race_arch, *class_arch;
46  living stats;
47  int result, num_stealing = 0;
48  object *ob_inv;
49  socket_struct ns;
50 
51  ns.account_chars = NULL;
52 
53  race_arch = find_archetype("halfling_player");
54  fail_unless(race_arch != NULL, "Cannot find halfing arch to test on.");
55 
56  class_arch = find_archetype("thief_class");
57  fail_unless(class_arch != NULL, "Cannot find thief class to test on.");
58 
59  // Pretend we sent faces
60  ns.faces_sent = static_cast<uint8_t *>(calloc(sizeof(uint8_t), get_faces_count()));
61  fail_unless(ns.faces_sent != NULL, "Could not allocate socket space to remember what faces are sent.");
62 
64  fail_unless(pl != NULL, "Could not create a player to handle.");
65 
66  // This should ensure we don't get negative stats no matter what we choose.
67  stats.Str = stats.Dex = stats.Con = stats.Int = stats.Wis = stats.Pow = stats.Cha = 20;
68 
69  result = apply_race_and_class(pl->ob, race_arch, class_arch, &stats);
70  fail_unless(result == 0, "Could not apply race and class to player.");
71 
72  // Now we loop through the inventory of the object and look for the number of times we find stealing as a skill.
73  // We should find it exactly once.
74  ob_inv = pl->ob->inv;
75  while (ob_inv) {
76  if (ob_inv->type == SKILL && strcmp(ob_inv->arch->name, "skill_stealing") == 0) {
77  ++num_stealing;
78  }
79  ob_inv = ob_inv->below;
80  }
81 
82  fail_unless(num_stealing < 2, "Found duplicate stealing skills in player inventory.");
83  fail_unless(num_stealing > 0, "Failed to find any stealing skills in player inventory.");
84 
85  // Cleanup
86  free(ns.faces_sent);
87 }
88 END_TEST
89 
90 static Suite *bug_suite(void) {
91  Suite *s = suite_create("bug");
92  TCase *tc_core = tcase_create("Core");
93 
94  tcase_add_checked_fixture(tc_core, setup, teardown);
95 
96  suite_add_tcase(s, tc_core);
97  tcase_add_test(tc_core, test_skills);
98  tcase_set_timeout(tc_core, 0);
99 
100  return s;
101 }
102 
103 int main(void) {
104  int nf;
105  Suite *s = bug_suite();
106  SRunner *sr = srunner_create(s);
107 
108  srunner_set_fork_status(sr, CK_NOFORK);
109  cctk_setdatadir(SOURCE_ROOT "lib");
110  init(0, NULL);
111 
112  srunner_set_xml(sr, LOGDIR "/bugs/bugtrack/duplicate_skills.xml");
113  srunner_set_log(sr, LOGDIR "/bugs/bugtrack/duplicate_skills.out");
114  srunner_run_all(sr, CK_ENV); /*verbosity from env variable*/
115  nf = srunner_ntests_failed(sr);
116  srunner_free(sr);
117  return nf == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
118 }
ADD_PLAYER_NO_STATS_ROLL
#define ADD_PLAYER_NO_STATS_ROLL
Definition: player.h:247
main
int main(void)
Definition: check_duplicate_skills.cpp:103
global.h
player
Definition: player.h:105
cctk_setdatadir
void cctk_setdatadir(const char *datadir)
Definition: toolkit_common.cpp:69
socket_struct
Definition: newserver.h:89
object::arch
struct archetype * arch
Definition: object.h:422
setup
static void setup(void)
Definition: check_duplicate_skills.cpp:36
START_TEST
START_TEST(test_skills)
Definition: check_duplicate_skills.cpp:42
SKILL
@ SKILL
Definition: object.h:148
add_player
player * add_player(socket_struct *ns, int flags)
Definition: player.cpp:460
socket_struct::account_chars
Account_Chars * account_chars
Definition: newserver.h:127
toolkit_common.h
rotate-tower.result
bool result
Definition: rotate-tower.py:13
bug_suite
static END_TEST Suite * bug_suite(void)
Definition: check_duplicate_skills.cpp:90
ADD_PLAYER_NO_MAP
#define ADD_PLAYER_NO_MAP
Definition: player.h:246
object::below
object * below
Definition: object.h:295
object::type
uint8_t type
Definition: object.h:348
init
pluglist shows those as well as a short text describing each the list will simply appear empty The keyword for the Python plugin is Python plugout< keyword > Unloads a given identified by its _keyword_ So if you want to unload the Python you need to do plugout Python plugin< libname > Loads a given whose _filename_ is libname So in the case of you d have to do a plugin cfpython so Note that all filenames are relative to the default plugin it tries to load all available files in the SHARE plugins directory as plugin libraries It first displays the Initializing the plugin has the opportunity to signal itself by a message on the console Then the server displays an informative message containing both the plugin content and its keyword For the Python the standard load process thus GreenGoblin When a plugin has been it can request to be warned whenever a global event and are named freely by the developer If the directory doesn t nothing will happen< event name > can be init
Definition: plugins.txt:54
archetype
Definition: object.h:474
sproto.h
teardown
static void teardown(void)
Definition: check_duplicate_skills.cpp:39
living
Definition: living.h:35
ADD_PLAYER_NEW
#define ADD_PLAYER_NEW
Definition: player.h:245
apply_race_and_class
int apply_race_and_class(object *op, archetype *race, archetype *opclass, living *stats)
Definition: player.cpp:1479
find_archetype
archetype * find_archetype(const char *name)
Definition: assets.cpp:266
socket_struct::faces_sent
uint8_t * faces_sent
Definition: newserver.h:96
stats
Player Stats effect how well a character can survie and interact inside the crossfire world This section discusses the various stats
Definition: stats.txt:2
archetype::name
sstring name
Definition: object.h:475
get_faces_count
size_t get_faces_count()
Definition: assets.cpp:293
altar_valkyrie.pl
pl
Definition: altar_valkyrie.py:28