ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/player.C
(Generate patch)

Comparing deliantra/server/server/player.C (file contents):
Revision 1.233 by root, Mon Oct 12 14:00:59 2009 UTC vs.
Revision 1.237 by root, Thu Nov 5 15:18:26 2009 UTC

1/* 1/*
2 * This file is part of Deliantra, the Roguelike Realtime MMORPG. 2 * This file is part of Deliantra, the Roguelike Realtime MMORPG.
3 * 3 *
4 * Copyright (©) 2005,2006,2007,2008 Marc Alexander Lehmann / Robin Redeker / the Deliantra team 4 * Copyright (©) 2005,2006,2007,2008,2009 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team 5 * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team
6 * Copyright (©) 1992,2007 Frank Tore Johansen 6 * Copyright (©) 1992,2007 Frank Tore Johansen
7 * 7 *
8 * Deliantra is free software: you can redistribute it and/or modify it under 8 * Deliantra is free software: you can redistribute it and/or modify it under
9 * the terms of the Affero GNU General Public License as published by the 9 * the terms of the Affero GNU General Public License as published by the
33#include <algorithm> 33#include <algorithm>
34#include <functional> 34#include <functional>
35 35
36playervec players; 36playervec players;
37 37
38void
39display_motd (const object *op)
40{
41 char buf[MAX_BUF];
42 char motd[HUGE_BUF];
43 FILE *fp;
44 int comp;
45 int size;
46
47 sprintf (buf, "%s/%s", settings.confdir, settings.motd);
48 if ((fp = open_and_uncompress (buf, 0, &comp)) == NULL)
49 return;
50
51 motd[0] = '\0';
52 size = 0;
53
54 while (fgets (buf, MAX_BUF, fp))
55 {
56 if (*buf == '#')
57 continue;
58
59 strncat (motd + size, buf, HUGE_BUF - size);
60 size += strlen (buf);
61 }
62
63 draw_ext_info (NDI_UNIQUE | NDI_GREEN, 0, op, MSG_TYPE_MOTD, MSG_SUBTYPE_NONE, motd, NULL);
64 close_and_delete (fp, comp);
65}
66
67void
68send_rules (const object *op)
69{
70 char buf[MAX_BUF];
71 char rules[HUGE_BUF];
72 FILE *fp;
73 int comp;
74 int size;
75
76 sprintf (buf, "%s/%s", settings.confdir, settings.rules);
77 if ((fp = open_and_uncompress (buf, 0, &comp)) == NULL)
78 return;
79
80 rules[0] = '\0';
81 size = 0;
82
83 while (fgets (buf, MAX_BUF, fp))
84 {
85 if (*buf == '#')
86 continue;
87
88 if (size + strlen (buf) >= HUGE_BUF)
89 {
90 LOG (llevDebug, "Warning, rules size is > %d bytes.\n", HUGE_BUF);
91 break;
92 }
93
94 strncat (rules + size, buf, HUGE_BUF - size);
95 size += strlen (buf);
96 }
97
98 draw_ext_info (NDI_UNIQUE | NDI_GREEN, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_RULES, rules, NULL);
99 close_and_delete (fp, comp);
100}
101
102void
103send_news (const object *op)
104{
105 char buf[MAX_BUF];
106 char news[HUGE_BUF];
107 char subject[MAX_BUF];
108 FILE *fp;
109 int comp;
110 int size;
111
112 sprintf (buf, "%s/%s", settings.confdir, settings.news);
113 if ((fp = open_and_uncompress (buf, 0, &comp)) == NULL)
114 return;
115
116 news[0] = '\0';
117 subject[0] = '\0';
118 size = 0;
119
120 while (fgets (buf, MAX_BUF, fp))
121 {
122 if (*buf == '#')
123 continue;
124
125 if (*buf == '%')
126 { /* send one news */
127 if (size > 0)
128 draw_ext_info_format (NDI_UNIQUE | NDI_GREEN, 0, op,
129 MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_NEWS,
130 "INFORMATION: %s\n%s", (char *)"%s\n%s",
131 subject, news); /*send previously read news */
132
133 strcpy (subject, buf + 1);
134 strip_endline (subject);
135 size = 0;
136 news[0] = '\0';
137 }
138 else
139 {
140 if (size + strlen (buf) >= HUGE_BUF)
141 {
142 LOG (llevDebug, "Warning, one news item has size > %d bytes.\n", HUGE_BUF);
143 break;
144 }
145 strncat (news + size, buf, HUGE_BUF - size);
146 size += strlen (buf);
147 }
148 }
149
150 draw_ext_info_format (NDI_UNIQUE | NDI_GREEN, 0, op,
151 MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_NEWS, "INFORMATION: %s\n%s\n", (char *)"%s\n%s", subject, news);
152 close_and_delete (fp, comp);
153}
154
155/* This loads the first map an puts the player on it. */ 38/* This loads the first map an puts the player on it. */
156static void 39static void
157set_first_map (object *op) 40set_first_map (object *op)
158{ 41{
159 op->contr->maplevel = first_map_path; 42 op->contr->maplevel = first_map_path;
253 esrv_send_inventory (ob, ob); 136 esrv_send_inventory (ob, ob);
254 esrv_add_spells (this, 0); 137 esrv_add_spells (this, 0);
255 138
256 activate (); 139 activate ();
257 140
258 send_rules (ob);
259 send_news (ob);
260 display_motd (ob);
261
262 INVOKE_PLAYER (CONNECT, this); 141 INVOKE_PLAYER (CONNECT, this);
263 INVOKE_PLAYER (LOGIN, this); 142 INVOKE_PLAYER (LOGIN, this);
264} 143}
265 144
266void 145void
282 ns->reset_stats (); 161 ns->reset_stats ();
283 ns->pl = 0; 162 ns->pl = 0;
284 ns = 0; 163 ns = 0;
285 } 164 }
286 165
287 observe = ob; 166 // this is important for the player scheduler to get the correct refcount
167 // when ns = 0
168 observe = viewpoint = ob;
288 169
289 deactivate (); 170 deactivate ();
290} 171}
291 172
292// the need for this function can be explained 173// the need for this function can be explained
293// by load_object not returning the object 174// by load_object not returning the object
294void 175void
295player::set_object (object *op) 176player::set_object (object *op)
296{ 177{
297 ob = observe = op; 178 ob = observe = viewpoint = op;
298 ob->contr = this; /* this aren't yet in archetype */ 179 ob->contr = this; /* this aren't yet in archetype */
299 180
300 ob->speed = 1.0f; 181 ob->speed = 1.0f;
301 ob->speed_left = 0.5f; 182 ob->speed_left = 0.5f;
302 183
331} 212}
332 213
333void 214void
334player::set_observe (object *op) 215player::set_observe (object *op)
335{ 216{
336 observe = op ? op : ob; 217 observe = viewpoint = op ? op : ob;
218 do_los = 1;
219}
220
221void
222player::set_viewpoint (object *op)
223{
224 viewpoint = op ? op : (object *)observe;
337 do_los = 1; 225 do_los = 1;
338} 226}
339 227
340player::player () 228player::player ()
341{ 229{
370 { 258 {
371 ob->destroy_inv (false); 259 ob->destroy_inv (false);
372 ob->destroy (); 260 ob->destroy ();
373 } 261 }
374 262
375 ob = observe = 0; 263 ob = observe = viewpoint = 0;
376} 264}
377 265
378player::~player () 266player::~player ()
379{ 267{
380 /* Clear item stack */ 268 /* Clear item stack */
1767 } 1655 }
1768 1656
1769 return true; 1657 return true;
1770} 1658}
1771 1659
1772/* find_key 1660static object *
1773 * We try to find a key for the door as passed. If we find a key
1774 * and successfully use it, we return the key, otherwise NULL
1775 * This function merges both normal and locked door, since the logic
1776 * for both is the same - just the specific key is different.
1777 * pl is the player,
1778 * inv is the objects inventory to searched
1779 * door is the door we are trying to match against.
1780 * This function can be called recursively to search containers.
1781 */
1782object *
1783find_key (object *pl, object *container, object *door) 1661find_key_ (object *pl, object *container, object *door)
1784{ 1662{
1785 object *tmp, *key; 1663 object *tmp, *key;
1786 1664
1787 /* Should not happen, but sanity checking is never bad */ 1665 /* Should not happen, but sanity checking is never bad */
1788 if (!container->inv) 1666 if (!container->inv)
1809 if (!tmp) 1687 if (!tmp)
1810 { 1688 {
1811 for (tmp = container->inv; tmp; tmp = tmp->below) 1689 for (tmp = container->inv; tmp; tmp = tmp->below)
1812 /* No reason to search empty containers */ 1690 /* No reason to search empty containers */
1813 if (tmp->type == CONTAINER && tmp->inv) 1691 if (tmp->type == CONTAINER && tmp->inv)
1814 if ((key = find_key (pl, tmp, door))) 1692 if ((key = find_key_ (pl, tmp, door)))
1815 return key; 1693 return key;
1816 1694
1817 if (!tmp) 1695 if (!tmp)
1818 return 0; 1696 return 0;
1819 } 1697 }
1838 * inv must have been an container and must have been active. 1716 * inv must have been an container and must have been active.
1839 * 1717 *
1840 * Change the color so that the message doesn't disappear with 1718 * Change the color so that the message doesn't disappear with
1841 * all the others. 1719 * all the others.
1842 */ 1720 */
1843 if (pl->contr->usekeys == key_inventory || 1721 if (pl->contr->usekeys == key_inventory
1844 !QUERY_FLAG (container, FLAG_APPLIED) || 1722 || !QUERY_FLAG (container, FLAG_APPLIED)
1845 (pl->contr->usekeys == keyrings && container->race != shstr_keys)) 1723 || (pl->contr->usekeys == keyrings && container->race != shstr_keys))
1846 { 1724 {
1847 new_draw_info_format (NDI_UNIQUE | NDI_BROWN, 0, pl, 1725 new_draw_info_format (NDI_UNIQUE | NDI_BROWN, 0, pl,
1848 "The %s in your %s vibrates as you approach the door", query_name (tmp), query_name (container)); 1726 "The %s in your %s vibrates as you approach the door", query_name (tmp), query_name (container));
1849 return NULL; 1727 return NULL;
1850 } 1728 }
1851 } 1729 }
1852 1730
1853 return tmp; 1731 return tmp;
1732}
1733
1734/* find_key
1735 * We try to find a key for the door as passed. If we find a key
1736 * and successfully use it, we return the key, otherwise NULL
1737 * This function merges both normal and locked door, since the logic
1738 * for both is the same - just the specific key is different.
1739 * pl is the player,
1740 * inv is the objects inventory to searched
1741 * door is the door we are trying to match against.
1742 * This function can be called recursively to search containers.
1743 */
1744object *
1745find_key (object *pl, object *container, object *door)
1746{
1747 if (door->slaying && is_match_expr (door->slaying))
1748 {
1749 // for match expressions, we try to find the key by applying the match
1750 // to the op itself, which is supposed to find the "key", instead
1751 // of searching through containers ourselves.
1752
1753 return match_one (door->slaying, container, door, pl, pl);
1754 }
1755 else
1756 return find_key_ (pl, container, door);
1854} 1757}
1855 1758
1856/* moved door processing out of move_player_attack. 1759/* moved door processing out of move_player_attack.
1857 * returns 1 if player has opened the door with a key 1760 * returns 1 if player has opened the door with a key
1858 * such that the caller should not do anything more, 1761 * such that the caller should not do anything more,

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines