- Posts: 937
- Thank you received: 17
Control weather
- JTP
- Topic Author
- Offline
- Platinum Member
-
When i try
cast 'control weather' dhdhjf
or something else
Then it just says okay
If i use
cast 'control weather' worse or better
Then it stil just say okay
Nothing really seems to happend. Is there a fix to get it to work ?
Please Log in or Create an account to join the conversation.
- JTP
- Topic Author
- Offline
- Platinum Member
-
- Posts: 937
- Thank you received: 17
and in spell_parser.c
and assigned to a class in class.c
but i dont see the actual ASPELL(spell_control_weather) anywhere
HELP :)
Please Log in or Create an account to join the conversation.
- WhiskyTest
-
- Offline
- Platinum Member
-
- Posts: 345
- Thank you received: 73
Once you've written that, you add it to call_magic. Something like this:
if (IS_SET(SINFO.routines, MAG_MANUAL))
switch (spellnum) {
case SPELL_CONTROL_WEATHER: MANUAL_SPELL(spell_control_weather); break;
Please Log in or Create an account to join the conversation.
- JTP
- Topic Author
- Offline
- Platinum Member
-
- Posts: 937
- Thank you received: 17
cast 'control weather' worse or better
Just nothing happends. So somehow it must be in the code ? Just not as a ASPELL ?
Please Log in or Create an account to join the conversation.
- WhiskyTest
-
- Offline
- Platinum Member
-
- Posts: 345
- Thank you received: 73
do_cast : checks this is a legitimate spell, which it is because it has been defined in spells.h and spello. Spello gives it the mana cost and name and things like that.
Then
cast_spell : checks you are in the correct position - not sleeping etc. This is where the OK message comes from.
Then
call_magic : this does all the cool stuff. If the spell deals damage or casts armour and things like that. Because Control Weather is MAG_MANUAL it looks for the additional code to run - which happens to not exist.
Please Log in or Create an account to join the conversation.
- Kyle
- Offline
- Senior Member
-
- Posts: 50
- Thank you received: 2
We might as well come up with an implementation for the next TBA release (whenever that is planned for).
I'll throw something together this week, unless somebody beats me to it.
Please Log in or Create an account to join the conversation.
- WhiskyTest
-
- Offline
- Platinum Member
-
- Posts: 345
- Thank you received: 73
Please Log in or Create an account to join the conversation.
- Kyle
- Offline
- Senior Member
-
- Posts: 50
- Thank you received: 2
First, the definition of the weather_data structure (in structs.h), which is a data structure that defines how weather information is stored.
struct weather_data {
int pressure; /* How is the pressure ( Mb ) */
int change; /* How fast and what way does it change. */
int sky; /* How is the sky. */
int sunlight; /* And how much sun. */
};
Second, the declaration of the global variable weather_info, which is what actually uses the above structure to store the weather information, as it fluctuates in game, which is declared in db.c
struct weather_data weather_info; /* The infomation about the weather. */
Lastly, for examples on how to manipulate and use this data, check out the weather_change function (which is defined in weather.c).
void weather_change(void)
{
int diff;
int change;
if ((time_info.month >= 9) && (time_info.month <= 16))
diff = (weather_info.pressure > 985 ? -2 : 2);
else
diff = (weather_info.pressure > 1015 ? -2 : 2);
weather_info.change += (dice(1, 4) * diff + dice(2, 6) - dice(2, 6));
weather_info.change = MIN(weather_info.change, 12);
weather_info.change = MAX(weather_info.change, -12);
weather_info.pressure += weather_info.change;
weather_info.pressure = MIN(weather_info.pressure, 1040);
weather_info.pressure = MAX(weather_info.pressure, 960);
change = 0;
switch (weather_info.sky) {
case SKY_CLOUDLESS:
if (weather_info.pressure < 990)
change = 1;
else if (weather_info.pressure < 1010)
if (dice(1, 4) == 1)
change = 1;
break;
case SKY_CLOUDY:
if (weather_info.pressure < 970)
change = 2;
else if (weather_info.pressure < 990) {
if (dice(1, 4) == 1)
change = 2;
else
change = 0;
} else if (weather_info.pressure > 1030)
if (dice(1, 4) == 1)
change = 3;
break;
case SKY_RAINING:
if (weather_info.pressure < 970) {
if (dice(1, 4) == 1)
change = 4;
else
change = 0;
} else if (weather_info.pressure > 1030)
change = 5;
else if (weather_info.pressure > 1010)
if (dice(1, 4) == 1)
change = 5;
break;
case SKY_LIGHTNING:
if (weather_info.pressure > 1010)
change = 6;
else if (weather_info.pressure > 990)
if (dice(1, 4) == 1)
change = 6;
break;
default:
change = 0;
weather_info.sky = SKY_CLOUDLESS;
break;
}
switch (change) {
case 0:
break;
case 1:
send_to_outdoor("The sky starts to get cloudy.\r\n");
weather_info.sky = SKY_CLOUDY;
break;
case 2:
send_to_outdoor("It starts to rain.\r\n");
weather_info.sky = SKY_RAINING;
break;
case 3:
send_to_outdoor("The clouds disappear.\r\n");
weather_info.sky = SKY_CLOUDLESS;
break;
case 4:
send_to_outdoor("Lightning starts to show in the sky.\r\n");
weather_info.sky = SKY_LIGHTNING;
break;
case 5:
send_to_outdoor("The rain stops.\r\n");
weather_info.sky = SKY_CLOUDY;
break;
case 6:
send_to_outdoor("The lightning stops.\r\n");
weather_info.sky = SKY_RAINING;
break;
default:
break;
}
}
Please Log in or Create an account to join the conversation.
- Kyle
- Offline
- Senior Member
-
- Posts: 50
- Thank you received: 2
Please Log in or Create an account to join the conversation.
- JTP
- Topic Author
- Offline
- Platinum Member
-
- Posts: 937
- Thank you received: 17
Please Log in or Create an account to join the conversation.
- WhiskyTest
-
- Offline
- Platinum Member
-
- Posts: 345
- Thank you received: 73
I started familiarizing myself with the related functions, the reason there is no CW spell currently is because the spell routines do not handle arguments.
That is, if you type 'cast "spellname" argument' the functions treat argument as either a target object or character.
So the first changes required would be to allow arguments being passed through to spells that can be 'worse' 'better' and so on. A bigger change than I originally thought but it does expand the possibilities for future spells.
Example:
add char *argument to call_magic, MANUAL_SPELL, and ASPELL definitions.
int call_magic(struct char_data *caster, struct char_data *cvict, struct obj_data *ovict, int spellnum, int level, int casttype, char *argument)
#define MANUAL_SPELL(spellname, argument) spellname(level, caster, cvict, ovict, argument);
Then update each ASPELL to be ASPELL(spell_name, argument)
This works in the brief testing I've done.
But is there a better way to go about this before I get too far in ?
Please Log in or Create an account to join the conversation.
- zusuk
-
- Offline
- Elite Member
-
- LuminariMUD Developer
The variable is:
cast_arg2
Something like that, check out locate object though for an example of the argument being carried in.
Website
www.luminariMUD.com
Main Game Port
luminariMUD.com:4100
Please Log in or Create an account to join the conversation.
- WhiskyTest
-
- Offline
- Platinum Member
-
- Posts: 345
- Thank you received: 73
cast_arg2 gets copied to 't'
't' is then checked against get_obj_vis searches or people in room searches.
By the time we get down to cast_spell, which is the next step, 't' has been used to set either tch or tobj, and the function is called like this: cast_spell(ch, tch, tobj, spellnum)
Is it possible to send the value of 't' through to cast_spell via *tch or *tobj?
Something like: cast_spell(ch, tch, (struct obj_data) *t, spellnum) ?
We'd have to do that with call_magic as well.
Please Log in or Create an account to join the conversation.
- zusuk
-
- Offline
- Elite Member
-
- LuminariMUD Developer
ASPELL(spell_control_weather) {
char arg[MAX_INPUT_LENGTH] = {'\0'};
if (IS_NPC(ch) || !ch->desc)
return;
one_argument(cast_arg2, arg); /* THIS WILL WORK */
if (is_abbrev(arg, "worsen")) {
} else if (is_abbrev(arg, "improve")) {
} else {
send_to_char(ch, "You need to cast this spell with an argument of either, "
"'worsen' or 'improve' in order for it to be a success!\r\n");
return;
}
}
Sounds like a perfect situation to implement room events (if it hasn't been yet).
Website
www.luminariMUD.com
Main Game Port
luminariMUD.com:4100
Please Log in or Create an account to join the conversation.
- WhiskyTest
-
- Offline
- Platinum Member
-
- Posts: 345
- Thank you received: 73
Though I don't fully understand how it can access cast_arg2, I thought you had to send it to the function specifically - this will make me rethink a LOT of my previous code :D
So here is my draft, what do you guys think?
ASPELL(spell_control_weather)
{
int change = -1;
char arg[MAX_INPUT_LENGTH] = {'\0'};
if (IS_NPC(ch) || !ch->desc)
return;
/* Control Weather fails if you aren't outside */
if (ROOM_FLAGGED(IN_ROOM(ch), ROOM_INDOORS))
{
send_to_char(ch, "Try as you might, you cannot maintain your control of the weather while indoors.\r\n");
act("A crackle of blue energy appears around $n for a brief moment before it fizzes out.", TRUE, ch, 0, 0, TO_ROOM);
return;
}
one_argument(cast_arg2, arg); /* Thanks Zusuk! */
if (is_abbrev(arg, "worse"))
{
change = 1; /* this will increase weather_info.sky by one, making it worse */
weather_info.change -= dice(1, 6); /* weather_info.change being lower will slightly bias future natural weather shifts towards worse weather */
} else if (is_abbrev(arg, "better"))
{
change = -1; /* this will decrease weather_info.sky by one, making it better */
weather_info.change += dice(1, 6); /* weather_info.change being higher will slightly bias future natural weather shifts towards better weather */
}
else
{
send_to_char(ch, "You need to cast this spell with an argument of either, "
"'worse' or 'better' in order for it to be a success!\r\n");
return;
}
send_to_char(ch, "You unleash a crackle of blue energy into the atmosphere!\r\n");
act("$n unleashes a crackle of blue energy which dissolves into the air around $m!", TRUE, ch, 0, 0, TO_ROOM);
/* Send to Outdoors each cast may be too spammy? */
if (change == -1)
send_to_outdoor("The weather seems to be improving.\r\n");
else
send_to_outdoor("The weather darkens.\r\n");
/* applies the changes to weather */
weather_info.sky += change;
weather_info.sky = MIN(MAX(weather_info.sky, SKY_CLOUDLESS), SKY_LIGHTNING);
}
Please Log in or Create an account to join the conversation.
- JTP
- Topic Author
- Offline
- Platinum Member
-
- Posts: 937
- Thank you received: 17
If you can, then it could be cool if a spell only can be cast in a certant weather type. Ie lightning bolt requires cloudy weather etc.
Please Log in or Create an account to join the conversation.
- Kyle
- Offline
- Senior Member
-
- Posts: 50
- Thank you received: 2
If you can, then it could be cool if a spell only can be cast in a certant weather type. Ie lightning bolt requires cloudy weather etc.
This is the principle behind the call lightning spell for clerics. The idea is that mages can create a lightning bolt so do not need to depend on weather, whereas clerics have to manipulate the existing weather because they do not share any such power.
Though I don't fully understand how it can access cast_arg2, I thought you had to send it to the function specifically - this will make me rethink a LOT of my previous code :D
The fact that cast_arg2 is a global variable is the reason that it can be accessed in any file by any function, so long as the file knows it exists.
Note that while these seems to make things simpler, and might make it seem tempting to make more variable global, it is in general a bad habit to get into, and should only be done in certain circumstances.
Historical Note: Jamdog added the global variable cast_arg2 (there seemed no other reasonable thing to do without adding very ugly code) in 2008 in order to improve upon the what was at the time a very flawed locate_object spell which originally did a poor job of responding to what the caster was actually searching for. It turns out to be a valuable tool in all cases where the argument passed to a spell cannot be converted to an item in the same room as the caster.
Please Log in or Create an account to join the conversation.
- JTP
- Topic Author
- Offline
- Platinum Member
-
- Posts: 937
- Thank you received: 17
case SPELL_CALL_LIGHTNING:
dam = dice(7, 8) + 7;
break;
Please Log in or Create an account to join the conversation.
- Kyle
- Offline
- Senior Member
-
- Posts: 50
- Thank you received: 2
I didn't even notice this as I had removed both spells from my MUD. Perhaps the spell is just unfinished, like the call weather spell, or maybe it was just overlooked.
Anyways, it's an easy exercise to make the spell work like its help file (much easier than fixing control weather) or whatever other behaviour you want.
Please Log in or Create an account to join the conversation.
- JTP
- Topic Author
- Offline
- Platinum Member
-
- Posts: 937
- Thank you received: 17
Please Log in or Create an account to join the conversation.