generic gas #256
Aliases: generic gas, gas
19 verbs · 49 properties · 0 children
Verbs
| Verb | Spec | Flags | Definer | Lines |
|---|---|---|---|---|
creature_heartbeat | this none this | rxd | #256 | 18 |
heartbeat | this none this | rxd | #256 | 14 |
add_to | this none this | rxd | #256 | 35 |
moveto | this none this | rxd | #256 | 19 |
recycle | this none this | rxd | #256 | 2 |
on_spawn | this none this | rxd | #256 | 1 |
_flow | this none this | rxd | #256 | 70 |
_increase | this none this | rxd | #256 | 42 |
_flow_through | this none this | rxd | #256 | 30 |
_decrease | this none this | rxd | #256 | 33 |
look_place_msg | this none this | rxd | #256 | 13 |
amount | this none this | rxd | #256 | 10 |
hear_event_move | this none this | rxd | #256 | 0 |
hear_event_arrive | this none this | rxd | #256 | 0 |
inhaled_by | this none this | rxd | #256 | 17 |
tree_tag | this none this | rxd | #256 | 32 |
remove_from | this none this | rxd | #256 | 30 |
set_amount | this none this | rxd | #256 | 28 |
entomb | this none this | rxd | #256 | 3 |
Properties
| Property | Definer | Flags | Owner | Value |
|---|---|---|---|---|
drugs | #256 | rc | #361 | {} |
opaque | #256 | rc | #361 | 1 |
spread_rate | #256 | rc | #361 | 1 |
heart | #256 | rc | #361 | 0 |
last_heartbeat | #256 | rc | #361 | 0 |
descriptive_names | #256 | rc | #361 | {"gas"} |
closed_door_msg | #256 | rc | #361 | {"%Gas seeps in through %dt.", "%Gas filters in from %dt.", "%Gas rolls in from %dt."} |
open_door_msg | #256 | rc | #361 | {} |
through_msg | #256 | rc | #361 | {"%Gas drifts in from %dt.", "%Gas rolls in from %dt.", "%Gas billows in from %dt."} |
threshold | #256 | rc | #361 | 20 |
increase_msg | #256 | rc | #361 | {"You notice a growing haze of %gas.", "%Gas hangs thickly in the air.", "%Gas fills the air, obscuring your sight."} |
dissipate_msg | #256 | rc | #361 | "The last of the %gas dissipates." |
decrease_msg | #256 | rc | #361 | {"The %gas thins out into a haze.", "You notice some breaks in the %gas.", "The %gas swirls around you."} |
dissipation_inside | #256 | rc | #361 | 1 |
dissipation_outside | #256 | rc | #361 | 12 |
help_msg | #256 | rc | #361 | list of 72{"HELP! GAS! I mean hello, welcome to $gas help.", "", "INTRODUCTION: $gas is a complicated, psuedorealistic implementation of gas-like things. It can be fun for small things (farts, grenades, killing people). IT WILL BREAK EVERYTHING if you use it on a large scale. Use $decals for that.", "", "How $gas works:", " - Like $decals, $gases are instanced children which exist in a room. The ", " same prop, .accumulation, that holds the amount of $decal in a room, also ", " works for $gas.", "", " - $gases.yourgas:add_to(room, amount) adds a gas to a room. Gases can ", " only be in rooms, and never on (in?) people, unlike $decals.", "", " - $gas has a :heartbeat, which calls :_flow. Gases flow into other rooms ", " via exits, depending on how much is in a room. Except for special cases:", " level = (.accumulation / . threshold) (default 20)", " flow = level * .spread_rate (default 1)", "", " - The 'level' above, i.e., the level of gas thickness in a room, can be ", " affected (for flow calculation) by a closed door:", " effective_level = level - closed_door.filtration", "", " - After :_flow, $gas also dissipates a bit each heartbeat, inside the ", " amount is .dissipation_inside, outside is .dissipation_outside. Someday I ", " should use room.size...", "", "- .drugs should be in the form {drugspec, drugspec, ...}. Each drugspec can be", " a plain drug object, or a list, {drug, dose_chance [, dose_ratio]}. There is ", " a dose_chance/100 chance (default 100), each heartbeat, of inhaling ", " gasunits/dose_ratio (default 1) units of drug. Gasunits is given by the formula:", "", " gil_float_to_int(tofloat(.accumulation) / tofloat(.threshold))", "", " Which means that the inhalation is approximately equivalent to the 'gas level' above.", "", " - When a gas is inhaled, :inhaled_by(who, amount of gas) is called, which", " you can use if players are to inhale a gas directly (without it being ", " instantiated as a room object.) Gases are ingested with the inhalation", " $drug_vector, which you may also want to look at.", "", " Messages:", " Nearly all messages are level-dependent (see above). ", " For level-varying messages, the gas level is the index of the shown ", " messages (gas level 2 = msg[min(2,$)].)", "", " Also, \"%gas\" will be replaced, in all messages, by a random element ", " of .descriptive_names. \"%Gas\", with a capital G, capitalizes the ", " randomly-selected name.", "", " Level-varying messages:", " .decrease_msg -- shown when gas decreases to new level", " .increase_msg -- shown when gas increases to new level", " .through_msg -- shown in exit.otherside.location when gas comes ", " in through non-door exits.", " .open_door_msg -- as above, for open doors (if blank, uses through_msg)", " .closed_door_msg -- as above, closed doors, but also uses effective_level.", " .look_place_msg -- the usual, selected by level (if blank, uses increase_msg)", "", " Level-invariant messages; if lists, selects a random element:", " .onset_msg -- shown when the gas first accumulates (optional)", " .dissipate_msg -- shown when the gas amount hits 0", "", " Other properties:", " .description -- you know, for looking at", " .opaque -- if this is 0, no messages are ever shown.", " .max_accumulation -- if this gets hit, :_flow is immediately called with a ", " pressure argument, which ensures at least that much will flow out of the ", " room, if at all possible.", " .exclusive_to -- SET THIS, it does what it does for $decals", " .descriptive_names -- SET THIS, see above. Don't let it just be {\"gas\"}.", "", "IF THIS IS TOO MUCH, and I understand if it is, just take a look at #266737 (weed smoke), which was the first gas for hellmoo and has been tested extensively - and uses pretty much every feature.", "----"} |
dose_ratio | #256 | rc | #361 | 1 |
onset_msg | #256 | rc | #361 | "" |
debugger | #256 | rc | #361 | #-1 |
smell_msg | #256 | rc | #361 | "" |
floats | #256 | rc | #361 | 1 |
exclusive_to | #141 | rc | #361 | #57516 |
look_place_msg | #141 | rc | #361 | {"There is a light haze in the air.", "%Gas hangs thickly in the air.", "%Gas fills the air, obscuring your sight."} |
stick_time | #141 | r | #361 | <clear> |
lifespan | #141 | rc | #361 | <clear> |
accumulation | #141 | r | #361 | 0 |
junk_ok | #141 | rc | #361 | <clear> |
look_person_msg | #141 | rc | #361 | <clear> |
wipeable | #141 | rc | #361 | <clear> |
clean_msg | #141 | rc | #361 | <clear> |
clean_last_msg | #141 | rc | #361 | <clear> |
disperse_msg | #141 | rc | #361 | <clear> |
blood | #141 | rc | #361 | <clear> |
infect_chance | #141 | rc | #361 | 5 |
max_accumulation | #141 | rc | #361 | 100 |
nutrition | #141 | rc | #361 | <clear> |
lick_self_msg | #141 | rc | #361 | <clear> |
look_place_air_msg | #141 | rc | #361 | <clear> |
falls | #141 | rc | #361 | 0 |
aliases | #1 | rc | #361 | {"generic gas", "gas"} |
description | #1 | rc | #361 | "Nothing special, but it looks like you could choke on it." |
object_size | #1 | r | #29 | {20902, 1298434096} |
hidden_verbs | #1 | rc | #361 | <clear> |
phelp_msg | #1 | rc | #361 | <clear> |
weight | #1 | rc | #361 | <clear> |
owner_verbs | #1 | rc | #361 | <clear> |
plural_name | #1 | rc | #361 | <clear> |
client_image | #1 | rc | #361 | <clear> |
listening | #1 | rc | #361 | <clear> |
Ancestry
Ancestors (nearest first): #141 generic decal → #1 root
Children: none
Call graph
Source
creature_heartbeat
Referenced by
none
Source
1if (this.f || (!this.drugs)) 2return; 3endif 4who = args[1]; 5if ((who == this) || (!is_a(who, $creature))) 6"this actually happens"; 7return; 8endif 9if (is_a(who, #31501)) 10"robot, doesn't breathe!"; 11return; 12endif 13floatlevel = tofloat(this.accumulation) / tofloat(this.threshold); 14units = $math_utils:gil_float_to_int(floatlevel); 15if (units) 16this:inhaled_by(who, units); 17this:_decrease(units); 18endif
heartbeat
Referenced by
none
Source
1if (this.f) 2raise(E_PERM, "this shouldn't be heartbeating"); 3endif 4amt_left = this:_flow(); 5if (!amt_left) 6return; 7endif 8dsp = this.location.outdoor ? this.dissipation_outside | this.dissipation_inside; 9if (typeof(dsp) == FLOAT) 10dsp = $math_utils:gil_float_to_int(dsp); 11endif 12if (dsp) 13this:_decrease(dsp); 14endif
add_to
Referenced by
- #256:_flow_through line 30:
this:add_to - #256:set_amount line 27:
this:add_to
Source
1"$gas:add_to(OBJ dest [, INT amount [, OBJ source]]) => OBJ gas."; 2"Adds the amount to this type of gas if it already exists at dest. If this gas doesn't exist at dest, create a new gas object and move it."; 3{dest, ?amount = 1, ?source = #-1} = args; 4if (!valid(dest)) 5return; 6endif 7excluder = this.exclusive_to; 8if (valid(excluder) && (o = dest:occupants(excluder))) 9o = o[1]; 10if (is_a(excluder, o)) 11o:_increase(amount, source); 12return o; 13endif 14endif 15class = this.f ? this | parent(this); 16if (dest:acceptable(class)) 17if (gamevalid(o = $rpg:spawn(class))) 18if (!is_a(o, class)) 19#7195:tell("Got non-class ", $su:nn(o), " from spawn!"); 20return #-1; 21endif 22real_o = o:moveto(dest, amount, source); 23if (!is_a(real_o, class)) 24#7195:tell("Got non-class ", $su:nn(real_o), " from o:moveto!"); 25return #-1; 26endif 27if (o == real_o) 28o:_increase(amount, source); 29endif 30return real_o; 31else 32raise(E_INVARG, "Unable to spawn " + tostr(class)); 33return #-1; 34endif 35endif
moveto
Referenced by
none
Source
1{where, ?new_accum = this.accumulation, ?source = #-1} = args; 2if (!gamevalid(where)) 3raise(E_INVARG); 4endif 5if ((!this.f) && (other = where:occupants(this.exclusive_to))) 6for x in (other) 7if (!gamevalid(x)) 8#7195:tell("Got invalid ", $su:nn(x), " from occupants in gas:moveto"); 9move(this, where); 10endif 11endfor 12other = other[1]; 13other:_increase(new_accum, source); 14$rpg:junk(this); 15return other; 16else 17move(this, where); 18return this; 19endif
recycle
Referenced by
none
Source
1$heart:unregister(this); 2return pass(@args);
on_spawn
Referenced by
none
Source
1$heart:register(this);
_flow
Referenced by
- #256:heartbeat line 4:
this:_flow - #256:_increase line 36:
this:_flow
Source
1":_flow([INT pressure [, OBJ exit_from]]) - pump this out of its location"; 2{?pressure = 0, ?exit_from = #-1} = args; 3if (!is_a(this.location, $room)) 4#7195:tell("[g] gas in non-room: ", $su:nn(this.location)); 5return $recycler:_recycle(this); 6endif 7"return this.accumulation"; 8if (pressure < 0) 9raise(E_INVARG, "pressure", pressure); 10return 0; 11endif 12if (!pressure) 13pressure = max(0, this.accumulation - this.max_accumulation); 14endif 15"first, find levels"; 16exits = this.location:exits(); 17exits = {@exits, @this.location:occupants(#82484)}; 18flows = {}; 19rate = this.spread_rate; 20amt = this.accumulation; 21to_flow = 0; 22for e in (exits) 23if (e == exit_from) 24flows = {@flows, 0}; 25continue; 26endif 27level = amt / this.threshold; 28dest = valid(e.otherside) ? e.otherside.location | #-1; 29if (!valid(dest)) 30level = 0; 31elseif (is_a(e, $door) || is_a(e, $window)) 32if (!e.open) 33level = max(0, level - e.filtration); 34endif 35elseif (filt = `e.filtration ! E_PROPNF => 0') 36level = max(0, level - filt); 37endif 38if (valid(dest) && (destamt = this:amount(dest))) 39destlevel = destamt / this.threshold; 40if (valid(this.debugger)) 41this.debugger:tell("[g] from: ", $su:nn(this.location), " (", level, ") to ", $su:nn(dest), " (", destlevel, ")"); 42endif 43level = max(0, level - destlevel); 44endif 45f = max(level, rate * (level - 1)); 46flows = {@flows, f}; 47to_flow = to_flow + f; 48endfor 49if (!to_flow) 50return amt; 51endif 52levels_total = to_flow; 53to_flow = min(amt, to_flow + (pressure / 2)); 54rate = tofloat(rate); 55flowed = 0; 56for i in [1..length(flows)] 57if (!flows[i]) 58continue; 59endif 60adjusted = (tofloat(to_flow) / tofloat(levels_total)) * tofloat(flows[i]); 61exit = exits[i]; 62if (adjusted >= 1.0) 63level = max(1, toint(adjusted / rate)); 64adjusted = toint(adjusted); 65this:_flow_through(adjusted, level, exit); 66flowed = flowed + adjusted; 67endif 68$cu:sin(); 69endfor 70return this:_decrease(flowed);
_increase
Referenced by
none
Source
1":_increase(INT amt [, OBJ source]) => internal verb to increase gas instance accumulation."; 2{amt, ?source = #-1} = args; 3if (amt < 1) 4return this.accumulation; 5endif 6old_was_zero = this.accumulation == 0; 7oldlevel = this.accumulation / this.threshold; 8this.accumulation = this.accumulation + amt; 9if (valid(this.debugger)) 10this.debugger:tell("[g] ", this.location.name, " +", amt, " = ", this.accumulation, old_was_zero ? " (NEW)" | ""); 11endif 12newlevel = this.accumulation / this.threshold; 13if (this.opaque && (source != #-1)) 14if ((newlevel > oldlevel) && (length(this.increase_msg) > oldlevel)) 15msg = this.increase_msg[min(newlevel, $)]; 16name = this.descriptive_names[random($)]; 17namec = $su:capitalize(name); 18msg = $su:subst(msg, {{"%Gas", namec}, {"%gas", name}}, 1); 19this.location:announce_all(msg); 20elseif (old_was_zero) 21msg = this.onset_msg; 22if (msg) 23if (typeof(msg) == LIST) 24msg = msg[random($)]; 25endif 26name = this.descriptive_names[random($)]; 27namec = $su:capitalize(name); 28msg = $su:subst(msg, {{"%Gas", namec}, {"%gas", name}}, 1); 29this.location:announce_all(msg); 30endif 31endif 32endif 33over = this.accumulation - this.max_accumulation; 34if (over > 0) 35"force movement"; 36this:_flow(over, source); 37endif 38if (is_a(this, $gas)) 39return this.accumulation; 40else 41return 0; 42endif
_flow_through
Referenced by
- #256:_flow line 65:
this:_flow_through
Source
1{amount, level, exit} = args; 2target = exit.otherside.location; 3if (valid(this.debugger)) 4this.debugger:tell(tostr("[g] ", this.location.name, " -> ", target.name, " (", level, ")")); 5endif 6target_level = this:amount(target) / this.threshold; 7if ((target_level < level) && this.opaque) 8if (is_a(exit, $door)) 9if (exit.open) 10if (this.open_door_msg) 11msgs = this.open_door_msg; 12else 13msgs = this.through_msg; 14endif 15else 16msgs = this.closed_door_msg; 17endif 18else 19msgs = this.through_msg; 20endif 21if (target_level < length(msgs)) 22msg = msgs[min(level, $)]; 23name = this.descriptive_names[random($)]; 24namec = $su:capitalize(name); 25msg = $su:subst(msg, {{"%Gas", namec}, {"%gas", name}}, 1); 26msg = $su:ps(msg, #-1, exit.otherside, target); 27target:announce_all(msg); 28endif 29endif 30this:add_to(target, amount, exit.otherside);
_decrease
Referenced by
- #256:creature_heartbeat line 17:
this:_decrease - #256:heartbeat line 13:
this:_decrease - #256:_flow line 70:
this:_decrease
Source
1":_decrease(INT amt) => internal verb to decrease gas instance accumulation."; 2{amt} = args; 3if (amt < 1) 4return this.accumulation; 5endif 6oldlevel = this.accumulation / this.threshold; 7this.accumulation = max(0, this.accumulation - amt); 8if (valid(this.debugger)) 9this.debugger:tell(tostr("[g] ", this.location.name, " -", amt, " = ", this.accumulation)); 10endif 11newlevel = this.accumulation / this.threshold; 12msg = ""; 13if (this.opaque) 14if (((newlevel < oldlevel) && (newlevel > 0)) && (newlevel <= length(this.decrease_msg))) 15msg = this.decrease_msg[min(newlevel, $)]; 16elseif (!this.accumulation) 17msg = this.dissipate_msg; 18if (typeof(msg) == LIST) 19msg = msg[random($)]; 20endif 21endif 22endif 23if (msg) 24name = this.descriptive_names[random($)]; 25namec = $su:capitalize(name); 26msg = $su:subst(msg, {{"%Gas", namec}, {"%gas", name}}, 1); 27this.location:announce_all(msg); 28endif 29if (!this.accumulation) 30$rpg:junk(this); 31return 0; 32endif 33return this.accumulation;
look_place_msg
Referenced by
none
Source
1if (!this.opaque) 2return ""; 3endif 4level = this.accumulation / this.threshold; 5if (this.look_place_msg) 6msg = this.look_place_msg[max(1, min(level, $))]; 7else 8msg = this.increase_msg[max(1, min(level, $))]; 9endif 10name = this.descriptive_names[random($)]; 11namec = $su:capitalize(name); 12msg = $su:subst(msg, {{"%Gas", namec}, {"%gas", name}}, 1); 13return msg;
amount
Referenced by
- #256:_flow line 38:
this:amount - #256:_flow_through line 6:
this:amount
Source
1":amount(OBJ location) => amount of this gas at location"; 2{loc} = args; 3class = this.f ? this | parent(this); 4o = loc:occupants(class); 5if (o) 6o = o[1]; 7return o.accumulation; 8else 9return 0; 10endif
hear_event_move
Referenced by
none
Source
No program (verb defined but unprogrammed).
hear_event_arrive
Referenced by
none
Source
No program (verb defined but unprogrammed).
inhaled_by
Referenced by
- #256:creature_heartbeat line 16:
this:inhaled_by
Source
1":inhaled_by(OBJ creature, INT units) => cause effects of inhaling the gas to creature. units is in accumulation units of gas."; 2{who, units} = args; 3for drug in (this.drugs) 4dose_ratio = this.dose_ratio; 5if (typeof(drug) == LIST) 6{drug, dose_chance, ?dose_ratio = this.dose_ratio} = drug; 7if (random(100) > dose_chance) 8continue; 9endif 10endif 11doses = units / dose_ratio; 12"1 dose, orally, quiet"; 13if (valid(this.debugger)) 14this.debugger:tell("[g] ", who.name, " ingested ", doses, " of ", drug.name, " at ", who.location.name); 15endif 16who:ingest(drug, doses, $drug_vectors.inhalation, 1); 17endfor
tree_tag
Referenced by
none
Source
1thr = this.threshold; 2di = this.dissipation_inside; 3do = this.dissipation_outside; 4max = this.max_accumulation; 5opq = this.opaque; 6drugs = this.drugs; 7sr = this.spread_rate; 8r = tostr($ansi.cyan, $ansi.bold_on, "s", sr, " t", thr, " m", max, " d", di, "&", do); 9if (!opq) 10r = r + " (!opq)"; 11endif 12if (drugs) 13cleandrugs = {}; 14for d in (drugs) 15if (typeof(d) == LIST) 16cleandrugs = {@cleandrugs, d[1]}; 17else 18cleandrugs = {@cleandrugs, d}; 19endif 20endfor 21drugs = cleandrugs; 22r = (r + " ") + $ansi.bold_off; 23if (length(drugs) == 1) 24r = r + $su:left(drugs[1].name, -3); 25else 26r = r + $su:from_list($su:smart_abbrev($lu:map_prop(drugs, "name"), 3), "/"); 27endif 28endif 29if ((valid(this.exclusive_to) && (this.exclusive_to != this)) && ((!this.f) && (this.exclusive_to != parent(this)))) 30r = (r + " excl: ") + $su:nn(this.exclusive_to); 31endif 32return r + $ansi.reset;
remove_from
Referenced by
- #256:set_amount line 5:
this:remove_from
Source
1"$gas:remove_from(OBJ where [, INT amount]) => OBJ gas."; 2"Removes the amount (default 1) from this gas at where, if it exists there. #-1 is returned if no gas was there, or if the gas has now been decreased to 0."; 3{where, ?amount = 1} = args; 4if (!valid(where)) 5return #-1; 6endif 7excluder = this.exclusive_to; 8gas_obj = #-1; 9if (valid(excluder) && (o = where:occupants(excluder))) 10o = o[1]; 11if (is_a(o, excluder)) 12gas_obj = o; 13endif 14endif 15if (!valid(gas_obj)) 16class = this.f ? this | parent(this); 17if (o = where:occupants(class)) 18gas_obj = o[1]; 19endif 20endif 21if (!valid(gas_obj)) 22return #-1; 23else 24amt_left = gas_obj:_decrease(amount); 25if (!amt_left) 26return #-1; 27else 28return gas_obj; 29endif 30endif
set_amount
Referenced by
none
Source
1"$gas:set_amount(OBJ where, INT amount) => OBJ gas."; 2"Ensures that the amount of this gas at 'where' is 'amount'. Increases or decreases the gas there as necessary. The obj returned is the resulting gas object, or #-1 if amount is 0 (or less)."; 3{where, amount} = args; 4if (amount <= 0) 5this:remove_from(where, this.max_accumulation); 6endif 7gas_obj = #-1; 8excluder = this.exclusive_to; 9if (valid(excluder) && (o = where:occupants(excluder))) 10gas_obj = o[1]; 11else 12class = this.f ? this | parent(this); 13o = where:occupants(class); 14if (o) 15gas_obj = o[1]; 16endif 17endif 18if (valid(gas_obj)) 19inc_needed = amount - gas_obj.accumulation; 20if (inc_needed > 0) 21gas_obj:_increase(inc_needed); 22elseif (inc_needed < 0) 23gas_obj:_decrease(-inc_needed); 24endif 25return gas_obj; 26else 27return this:add_to(where, amount); 28endif
entomb
Referenced by
none
Source
1"Copied from generic gas (#57516):recycle by chill (#241405) Wed Jun 2 21:43:18 2010 CDT"; 2$heart:unregister(this); 3return pass(@args);