Control weather

  • JTP
  • Topic Author
  • Offline
  • Platinum Member
  • Platinum Member
More
6 years 10 months ago - 6 years 10 months ago #5628 by JTP
Control weather was created by JTP
Hey

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 ?
Last edit: 6 years 10 months ago by JTP.

Please Log in or Create an account to join the conversation.

  • JTP
  • Topic Author
  • Offline
  • Platinum Member
  • Platinum Member
More
6 years 10 months ago #5630 by JTP
Replied by JTP on topic Control weather
It is defined in spells.h
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.

More
6 years 10 months ago #5637 by WhiskyTest
Replied by WhiskyTest on topic Control weather
Yeah, I don't see the ASPELL for it. My guess is it is a placeholder for budding coders such as yourself to create the function.

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
  • Platinum Member
More
6 years 10 months ago #5638 by JTP
Replied by JTP on topic Control weather
Funny thing is though, that you can do

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.

More
6 years 10 months ago #5639 by WhiskyTest
Replied by WhiskyTest on topic Control weather
It basically just runs through the process of casting a spell that has no effect:

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.

More
6 years 10 months ago #5640 by Kyle
Replied by Kyle on topic Control weather
Yeah it's an unfinished spell. Funny how long it's been there. It goes way back to legacy CircleMUD.

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.

More
6 years 10 months ago #5641 by WhiskyTest
Replied by WhiskyTest on topic Control weather
Sounds good! I'll have a dabble as well and see if anything inspired comes up, I haven't tried coding any spells before so this should be interesting :)

Please Log in or Create an account to join the conversation.

More
6 years 10 months ago - 6 years 10 months ago #5642 by Kyle
Replied by Kyle on topic Control weather
If you're new to coding spells, take a look at the following to help you get started.

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;
  }
}
Last edit: 6 years 10 months ago by Kyle.

Please Log in or Create an account to join the conversation.

More
6 years 10 months ago #5643 by Kyle
Replied by Kyle on topic Control weather
Also, if you're keen I'm more than happy to back off and let you tackle this. But feel free to ask any questions if you get stuck along the way. I'm trying to get back into coding currently, and dialogue is a much more fun way to do it than just sitting reading code in isolation. :)

Please Log in or Create an account to join the conversation.

  • JTP
  • Topic Author
  • Offline
  • Platinum Member
  • Platinum Member
More
6 years 10 months ago #5644 by JTP
Replied by JTP on topic Control weather
Im sure if the two of you work together, then TBA will soon have a nice control weather spell

Please Log in or Create an account to join the conversation.

More
6 years 10 months ago - 6 years 10 months ago #5667 by WhiskyTest
Replied by WhiskyTest on topic Control weather
Cool lets do it together!
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 ?
Last edit: 6 years 10 months ago by WhiskyTest. Reason: add code tags

Please Log in or Create an account to join the conversation.

  • zusuk
  • zusuk's Avatar
  • Offline
  • Elite Member
  • Elite Member
  • LuminariMUD Developer
More
6 years 10 months ago #5668 by zusuk
Replied by zusuk on topic Control weather
That should not be necessary, there is a global char pointer that holds the argument you use to cast a spell, an example would be the spell locate object.

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.

More
6 years 10 months ago #5678 by WhiskyTest
Replied by WhiskyTest on topic Control weather
You're correct:
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
  • zusuk's Avatar
  • Offline
  • Elite Member
  • Elite Member
  • LuminariMUD Developer
More
6 years 10 months ago #5679 by zusuk
Replied by zusuk on topic Control weather
Well, if you take a look, nothing overwrites the global variable cast_arg.... So the argument is preserved for usage. Example:
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
The following user(s) said Thank You: WhiskyTest

Please Log in or Create an account to join the conversation.

More
6 years 10 months ago #5680 by WhiskyTest
Replied by WhiskyTest on topic Control weather
Mate that totally worked!
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
  • Platinum Member
More
6 years 10 months ago - 6 years 10 months ago #5681 by JTP
Replied by JTP on topic Control weather
How is the testing going ? Can you change weather ?

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.
Last edit: 6 years 10 months ago by JTP.

Please Log in or Create an account to join the conversation.

More
6 years 10 months ago - 6 years 10 months ago #5682 by Kyle
Replied by Kyle on topic Control weather

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.
Last edit: 6 years 10 months ago by Kyle.

Please Log in or Create an account to join the conversation.

  • JTP
  • Topic Author
  • Offline
  • Platinum Member
  • Platinum Member
More
6 years 10 months ago - 6 years 10 months ago #5684 by JTP
Replied by JTP on topic Control weather
Except call_lightning is just a damage spell, with no checks of weather in the standard tba code.
case SPELL_CALL_LIGHTNING:
  dam = dice(7, 8) + 7;
  break;
Last edit: 6 years 10 months ago by JTP.

Please Log in or Create an account to join the conversation.

More
6 years 10 months ago #5685 by Kyle
Replied by Kyle on topic Control weather
Good point. I just tested and it doesn't check if you are outside either. Note the discrepancy between this and the help files.

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
  • Platinum Member
More
6 years 10 months ago - 6 years 10 months ago #5686 by JTP
Replied by JTP on topic Control weather
But the control weather code now Works, and you can change the weather ?
Last edit: 6 years 10 months ago by JTP.

Please Log in or Create an account to join the conversation.

Time to create page: 0.262 seconds