All items done (excl. Lootboxes). On to the weapons now.
This commit is contained in:
parent
b6f434a28d
commit
9ce417a49d
28 changed files with 641 additions and 41 deletions
|
|
@ -17,3 +17,9 @@ user int swwm_msgduration = 5; // lifespan of other messages
|
|||
user int swwm_pickduration = 3; // lifespan of pickup messages
|
||||
server bool swwm_sharekeys = true; // share keys in mp
|
||||
user noarchive int swwm_lasttab = 0; // last selected tab in the menu
|
||||
user bool swwm_autousearmor = true; // automatically use armor items when possible
|
||||
user bool swwm_autousehealth = true; // automatically use health items when possible
|
||||
user bool swwm_autouseammo = true; // automatically use ammo fabricators when possible (excl. tier 4)
|
||||
server int swwm_enforceautousearmor = 0; // 1: server enforces auto use, -1: server enforces no auto use, 0: server respects user setting
|
||||
server int swwm_enforceautousehealth = 0; // likewise for health
|
||||
server int swwm_enforceautouseammo = 0; // likewise for fabricators
|
||||
|
|
|
|||
|
|
@ -53,6 +53,10 @@ Brightmap Texture "models/Lamp.png"
|
|||
{
|
||||
Map "models/Lamp_bright.png"
|
||||
}
|
||||
Brightmap Texture "models/Moth_Mashiro.png"
|
||||
{
|
||||
Map "models/Moth_Mashiro_bright.png"
|
||||
}
|
||||
|
||||
PointLight ARMORNUGGETLIGHT
|
||||
{
|
||||
|
|
|
|||
37
language.txt
37
language.txt
|
|
@ -32,8 +32,15 @@ SWWM_MAXPICK = "Max pickup messages";
|
|||
SWWM_CHATLEN = "Chat message duration";
|
||||
SWWM_MSGLEN = "General message duration";
|
||||
SWWM_PICKLEN = "Pickup message duration";
|
||||
SWWM_ITITLE = "Item Options";
|
||||
SWWM_ARMORUSE = "Automatically Use Armor";
|
||||
SWWM_HEALTHUSE = "Automatically Use Health";
|
||||
SWWM_AMMOUSE = "Automatically Use Fabricators";
|
||||
SWWM_CTITLE = "Multiplayer Options";
|
||||
SWWM_SKEYS = "Share Keys";
|
||||
SWWM_SVARMORUSE = "Enforce Armor Auto-Use";
|
||||
SWWM_SVHEALTHUSE = "Enforce Health Auto-Use";
|
||||
SWWM_SVAMMOUSE = "Enforce Fabricator Auto-Use";
|
||||
SWWM_MCREDS = "SWWM GZ Credits";
|
||||
SWWM_CLEAD = "Development Lead:";
|
||||
SWWM_CASSETS = "Additional Assets:";
|
||||
|
|
@ -50,9 +57,12 @@ SWWM_CCOMMUNITY1 = "All my amazing friends from the Doom community";
|
|||
SWWM_CCOMMUNITY2 = "(For helping me keep this whole thing rolling, and for all the time we've spent together)";
|
||||
SWWM_CCOMMUNITY3 = "(Here's to many more years of Dooming. Stay awesome, everyone!)";
|
||||
SWWM_CDEVS1 = "Randi, Graf, Rachael, Mental, dpJudas and the rest of the GZDoom dev team";
|
||||
SWWM_CDEVS2 = "(For their work on the source port that brough back my faith in modding. You guys rock!)";
|
||||
SWWM_CDEVS2 = "(For their work on the source port that brought back my faith in modding. You guys rock!)";
|
||||
SWWM_FORCEDISABLE = "Force Disable";
|
||||
SWWM_USERSET = "User Set";
|
||||
SWWM_FORCEENABLE = "Force Enable";
|
||||
TOOLTIP_SWWM_VOICETYPE = "Sets the voice pack for the player (clientside).";
|
||||
TOOLTIP_SWWM_MUTEPLAYER = "Control what gets muted, if you'd rather have a more silent protagonist.";
|
||||
TOOLTIP_SWWM_MUTEVOICE = "Control what gets muted, if you'd rather have a more silent protagonist.";
|
||||
TOOLTIP_SWWM_FLASHSTRENGTH = "Screen flashes usually happen when firing some weapons, you can lower this if these effects are harmful for you.";
|
||||
TOOLTIP_SWWM_HUDMARGIN = "Margin around HUD elements, in (scaled) pixels.";
|
||||
TOOLTIP_SWWM_MAXSHOWN = "Maximum messages (not lines) shown in the top left part of the HUD.";
|
||||
|
|
@ -62,6 +72,12 @@ TOOLTIP_SWWM_CHATDURATION = "Duration of chat messages in seconds.";
|
|||
TOOLTIP_SWWM_MSGDURATION = "Duration of obituaries and other messages in seconds.";
|
||||
TOOLTIP_SWWM_PICKDURATION = "Duration of pickup messages in seconds.";
|
||||
TOOLTIP_SWWM_SHAREKEYS = "When this is enabled, picking up a key item will send a copy to all other players.";
|
||||
TOOLTIP_SWWM_AUTOUSEARMOR = "When enabled, new armor items are automatically worn when picked up.";
|
||||
TOOLTIP_SWWM_AUTOUSEHEALTH = "When enabled, health items are automatically used if they can heal. This excludes Refreshers since they count as powerups.";
|
||||
TOOLTIP_SWWM_AUTOUSEAMMO = "When enabled, ammo fabricators are automatically used on pickup. This excludes Tier 4 fabricators since they count as powerups.";
|
||||
TOOLTIP_SWWM_ENFORCEAUTOUSEARMOR = "Enforce a specific armor auto-use setting for all players, or respects per-player settings.";
|
||||
TOOLTIP_SWWM_ENFORCEAUTOUSEHEALTH = "Enforce a specific health auto-use setting for all players, or respects per-player settings.";
|
||||
TOOLTIP_SWWM_ENFORCEAUTOUSEAMMO = "Enforce a specific ammo fabricator auto-use setting for all players, or respects per-player settings.";
|
||||
// knowledge base
|
||||
SWWM_COMINGSOON = "(coming soon)";
|
||||
SWWM_MISSTAB = "Mission";
|
||||
|
|
@ -389,8 +405,8 @@ SWWM_LORETXT_HAMMERSPACEEMBIGGENER =
|
|||
"Addendum: You may find these tucked away in certain spots throughout your mission.\n"
|
||||
"\n"
|
||||
"Saya's Note: Is that even a real word?";
|
||||
SWWM_LORETAG_AMMOFABRICATOR = "Ammo Fabricator";
|
||||
SWWM_LORETXT_AMMOFABRICATOR =
|
||||
SWWM_LORETAG_FABRICATOR = "Ammo Fabricator";
|
||||
SWWM_LORETXT_FABRICATOR =
|
||||
"Designation: Universal Ammo Fabricator\n"
|
||||
"Manufacturer: Cyrus Enterprises\n"
|
||||
"\n"
|
||||
|
|
@ -818,7 +834,8 @@ T_INVINCIBALL = "Fuckin' Invinciball";
|
|||
T_LAMP = "Lämp";
|
||||
I_LAMP = "Companion Lamp";
|
||||
T_MOTH = "Moth";
|
||||
T_MASHIRO = "White Moth";
|
||||
T_WMOTH = "White Moth";
|
||||
T_MASHIRO = "Mashiro";
|
||||
T_NUGGETH = "Health Nugget";
|
||||
T_NUGGETA = "Armor Nugget";
|
||||
T_OMNISIGHT = "Omnisight";
|
||||
|
|
@ -871,7 +888,15 @@ O_YNYKRONALT = "%o was spaghettified by %k.";
|
|||
O_POUND = "%o was very impressed by %k's landing.";
|
||||
O_DASH = "%o was discombobulated by a very fast moving %k.";
|
||||
O_MELEE = "%o was K.O.'d by %k.";
|
||||
O_LAMP = "%o was assaulted by %k's moths.";
|
||||
O_MOTH = "%%o was assaulted by %s's moths.";
|
||||
O_MOTH2 = "%o was assaulted by moths.";
|
||||
O_MASHIRO1 = "%o should have kept the lights on.";
|
||||
O_MASHIRO2 = "%o now belongs to Mashiro.";
|
||||
O_MASHIRO3 = "%o made a terrible mistake.";
|
||||
O_MASHIRO4 = "%o mysteriously disappeared.";
|
||||
O_MASHIRO5 = "%o is now part of a live-action recreation of Layers of White.";
|
||||
O_MASHIRO6 = "%o angered the wrong moth.";
|
||||
O_MASHIRO7 = "%o and Mashiro are now TOGETHER FOREVER.";
|
||||
// misc
|
||||
D_BLASTSUIT = "The Blast Suit broke down.";
|
||||
D_GHOSTARTI = "The Ghost Artifact ran out of energy.";
|
||||
|
|
|
|||
16
menudef.txt
16
menudef.txt
|
|
@ -6,6 +6,12 @@ OptionValue "SWWMVoice"
|
|||
3, "$SWWM_MUTELINERS"
|
||||
4, "$SWWM_MUTEALL"
|
||||
}
|
||||
OptionValue "SWWMEnforce"
|
||||
{
|
||||
-1, "$SWWM_FORCEDISABLE"
|
||||
0, "$SWWM_USERSET"
|
||||
1, "$SWWM_FORCEENABLE"
|
||||
}
|
||||
OptionMenu "SWWMOptionMenu"
|
||||
{
|
||||
Class "SWWMOptionMenu"
|
||||
|
|
@ -25,8 +31,16 @@ OptionMenu "SWWMOptionMenu"
|
|||
Slider "$SWWM_MSGLEN", "swwm_msgduration", 1, 30, 1, 0
|
||||
Slider "$SWWM_PICKLEN", "swwm_pickduration", 1, 30, 1, 0
|
||||
StaticText " "
|
||||
StaticText "$SWWM_ITITLE", "Gold"
|
||||
Option "$SWWM_ARMORUSE", "swwm_autousearmor", "YesNo"
|
||||
Option "$SWWM_HEALTHUSE", "swwm_autousehealth", "YesNo"
|
||||
Option "$SWWM_AMMOUSE", "swwm_autouseammo", "YesNo"
|
||||
StaticText " "
|
||||
StaticText "$SWWM_CTITLE", "Gold"
|
||||
Option "$SWWM_SKEYS", "swwm_sharekeys", "YesNo"
|
||||
Option "$SWWM_SVARMORUSE", "swwm_enforceautousearmor", "SWWMEnforce"
|
||||
Option "$SWWM_SVHEALTHUSE", "swwm_enforceautousehealth", "SWWMEnforce"
|
||||
Option "$SWWM_SVAMMOUSE", "swwm_enforceautouseammo", "SWWMEnforce"
|
||||
}
|
||||
OptionMenu "SWWMCreditsMenu"
|
||||
{
|
||||
|
|
@ -38,7 +52,7 @@ OptionMenu "SWWMCreditsMenu"
|
|||
StaticText " "
|
||||
StaticText "$SWWM_CASSETS", "Red"
|
||||
StaticText " "
|
||||
StaticText "Bethesda Softworks", "Gold"
|
||||
StaticText "Bethesda Game Studios", "Gold"
|
||||
StaticText "Fallout: New Vegas", "White"
|
||||
StaticText "Fallout 4", "White"
|
||||
StaticText " "
|
||||
|
|
|
|||
|
|
@ -185,6 +185,33 @@ Model "Omnisight"
|
|||
FrameIndex XZW1 A 0 0
|
||||
}
|
||||
|
||||
Model "LampMoth"
|
||||
{
|
||||
Path "models"
|
||||
Model 0 "Moth_d.3d"
|
||||
Skin 0 "Moth.png"
|
||||
Scale 0.005 0.005 0.005
|
||||
ZOffset 0.5
|
||||
USEACTORPITCH
|
||||
DONTCULLBACKFACES
|
||||
|
||||
FrameIndex XZW1 B 0 1
|
||||
FrameIndex XZW1 C 0 2
|
||||
}
|
||||
Model "LampMoth2"
|
||||
{
|
||||
Path "models"
|
||||
Model 0 "Moth_d.3d"
|
||||
Skin 0 "Moth_Mashiro.png"
|
||||
Scale 0.008 0.008 0.008
|
||||
ZOffset 0.5
|
||||
USEACTORPITCH
|
||||
DONTCULLBACKFACES
|
||||
|
||||
FrameIndex XZW1 B 0 1
|
||||
FrameIndex XZW1 C 0 2
|
||||
}
|
||||
|
||||
Model "CompanionLamp"
|
||||
{
|
||||
Path "models"
|
||||
|
|
|
|||
BIN
models/Moth.png
BIN
models/Moth.png
Binary file not shown.
|
Before Width: | Height: | Size: 9.8 KiB After Width: | Height: | Size: 9.6 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 9 KiB After Width: | Height: | Size: 9 KiB |
31
sndinfo.txt
31
sndinfo.txt
|
|
@ -316,12 +316,20 @@ $playeralias demolitionist neutral *pain50 demolitionist/pain
|
|||
$playeralias demolitionist neutral *pain25 demolitionist/hipain
|
||||
$playersound demolitionist neutral *usefail sounds/menu/failuse.ogg
|
||||
$playeralias demolitionist neutral *death demolitionist/death
|
||||
$playeralias demolitionist neutral *burndeath demolitionist/death
|
||||
$playeralias demolitionist neutral *xdeath demolitionist/xdeath
|
||||
$playeralias demolitionist neutral *gibbed demolitionist/xdeath
|
||||
$playeralias demolitionist neutral *crazydeath demolitionist/xdeath
|
||||
$playeralias demolitionist neutral *wimpydeath demolitionist/wdeath
|
||||
$playersound demolitionist neutral *land DSEMPTY
|
||||
$playersound demolitionist neutral *falling DSEMPTY
|
||||
$playersound demolitionist neutral *puzzfail sounds/menu/failuse.ogg
|
||||
$playersound demolitionist neutral *poison DSEMPTY
|
||||
$playersound demolitionist neutral *dive DSEMPTY
|
||||
$playersound demolitionist neutral *surface DSEMPTY
|
||||
$playersound demolitionist neutral *gasp DSEMPTY
|
||||
$playersound demolitionist neutral *taunt DSEMPTY
|
||||
$playersound demolitionist neutral *evillaugh DSEMPTY
|
||||
|
||||
explodium/casing1 sounds/explodiumgun/expl_case1.ogg
|
||||
explodium/casing2 sounds/explodiumgun/expl_case2.ogg
|
||||
|
|
@ -425,6 +433,29 @@ powerup/ragekit sounds/items/ragekiton.ogg
|
|||
powerup/ragekitact sounds/items/ragekitact.ogg
|
||||
powerup/ragekithit sounds/items/ragekithit.ogg
|
||||
powerup/ragekitend sounds/items/ragekitend.ogg
|
||||
powerup/omnisight sounds/items/omnisight.ogg
|
||||
|
||||
lamp/on sounds/items/lampon.ogg
|
||||
lamp/off sounds/items/lampoff.ogg
|
||||
lamp/appear sounds/items/lampappear.ogg
|
||||
lamp/disappear sounds/items/lampdisappear.ogg
|
||||
// maybe eventually
|
||||
//mashiro/see (some sort of creepy yandere girl giggling I guess)
|
||||
//mashiro/active (more creepy giggles?)
|
||||
//mashiro/attack (clawing)
|
||||
moth/scrape1 sounds/items/mothatk1.ogg
|
||||
moth/scrape2 sounds/items/mothatk2.ogg
|
||||
moth/scrape3 sounds/items/mothatk3.ogg
|
||||
moth/scrape4 sounds/items/mothatk4.ogg
|
||||
$random moth/scrape { moth/scrape1 moth/scrape2 moth/scrape3 moth/scrape4 }
|
||||
$limit moth/scrape 30
|
||||
moth/die1 sounds/items/mothdie1.ogg
|
||||
moth/die2 sounds/items/mothdie2.ogg
|
||||
$random moth/die { moth/die1 moth/die2 }
|
||||
moth/fly sounds/items/mothfly.ogg
|
||||
$limit moth/fly 30
|
||||
|
||||
fabricator/use sounds/items/makeammo.ogg
|
||||
|
||||
menu/activate sounds/hmenu/hmenu1.ogg
|
||||
menu/backup sounds/hmenu/hmenu2.ogg
|
||||
|
|
|
|||
BIN
sounds/items/lampappear.ogg
Normal file
BIN
sounds/items/lampappear.ogg
Normal file
Binary file not shown.
BIN
sounds/items/lampdisappear.ogg
Normal file
BIN
sounds/items/lampdisappear.ogg
Normal file
Binary file not shown.
BIN
sounds/items/lampoff.ogg
Normal file
BIN
sounds/items/lampoff.ogg
Normal file
Binary file not shown.
BIN
sounds/items/lampon.ogg
Normal file
BIN
sounds/items/lampon.ogg
Normal file
Binary file not shown.
BIN
sounds/items/makeammo.ogg
Normal file
BIN
sounds/items/makeammo.ogg
Normal file
Binary file not shown.
BIN
sounds/items/mothatk1.ogg
Normal file
BIN
sounds/items/mothatk1.ogg
Normal file
Binary file not shown.
BIN
sounds/items/mothatk2.ogg
Normal file
BIN
sounds/items/mothatk2.ogg
Normal file
Binary file not shown.
BIN
sounds/items/mothatk3.ogg
Normal file
BIN
sounds/items/mothatk3.ogg
Normal file
Binary file not shown.
BIN
sounds/items/mothatk4.ogg
Normal file
BIN
sounds/items/mothatk4.ogg
Normal file
Binary file not shown.
BIN
sounds/items/mothdie1.ogg
Normal file
BIN
sounds/items/mothdie1.ogg
Normal file
Binary file not shown.
BIN
sounds/items/mothdie2.ogg
Normal file
BIN
sounds/items/mothdie2.ogg
Normal file
Binary file not shown.
BIN
sounds/items/mothfly.ogg
Normal file
BIN
sounds/items/mothfly.ogg
Normal file
Binary file not shown.
BIN
sounds/items/omnisight.ogg
Normal file
BIN
sounds/items/omnisight.ogg
Normal file
Binary file not shown.
|
|
@ -767,9 +767,10 @@ Class YnykronAmmo : Ammo
|
|||
|
||||
Class AmmoFabricator : Inventory abstract
|
||||
{
|
||||
int budget;
|
||||
int budget, pertype;
|
||||
|
||||
Property Budget : budget;
|
||||
Property PerType : pertype;
|
||||
|
||||
override Inventory CreateCopy( Actor other )
|
||||
{
|
||||
|
|
@ -779,10 +780,80 @@ Class AmmoFabricator : Inventory abstract
|
|||
return Super.CreateCopy(other);
|
||||
}
|
||||
|
||||
bool FabricateAmmo()
|
||||
{
|
||||
Array<Class<Ammo> > available;
|
||||
// populate ammo production list
|
||||
for ( int i=0; i<AllActorClasses.Size(); i++ )
|
||||
{
|
||||
let a = (Class<Ammo>)(AllActorClasses[i]);
|
||||
// only direct descendants of ammo with a set price below our budget
|
||||
if ( !a || (a.GetParentClass() != 'Ammo') ) continue;
|
||||
let def = GetDefaultByType(a);
|
||||
if ( !(def.Stamina) || (def.Stamina > budget) ) continue;
|
||||
available.Push(a);
|
||||
}
|
||||
// start from lowest to highest needed until we fill the inventory or run out of budget
|
||||
bool given = false;
|
||||
int consumed = 0;
|
||||
String fabstr = "";
|
||||
bool comma = false;
|
||||
for ( int i=0; i<available.Size(); i++ )
|
||||
{
|
||||
int amt, lim;
|
||||
int cnt = 0;
|
||||
Ammo cur = Ammo(Owner.FindInventory(available[i]));
|
||||
if ( cur )
|
||||
{
|
||||
amt = cur.Amount;
|
||||
lim = cur.MaxAmount;
|
||||
}
|
||||
else
|
||||
{
|
||||
cur = Ammo(Spawn(available[i]));
|
||||
amt = cur.Amount = 0;
|
||||
lim = cur.MaxAmount;
|
||||
cur.AttachToOwner(Owner);
|
||||
}
|
||||
while ( (amt < lim) && (consumed+cur.default.Stamina < budget) && (cnt < pertype) )
|
||||
{
|
||||
consumed += cur.default.Stamina;
|
||||
amt = ++cur.Amount;
|
||||
cnt++;
|
||||
given = true;
|
||||
}
|
||||
if ( cnt > 0 )
|
||||
{
|
||||
if ( comma ) fabstr.AppendFormat(", %dx %s",cnt,cur.GetTag());
|
||||
else fabstr.AppendFormat("%dx %s",cnt,cur.GetTag());
|
||||
comma = true;
|
||||
}
|
||||
}
|
||||
if ( given ) PrintPickupMessage(true,fabstr);
|
||||
return given;
|
||||
}
|
||||
|
||||
override bool Use( bool pickup )
|
||||
{
|
||||
bool shouldautouse = false;
|
||||
if ( swwm_enforceautouseammo == 1 ) shouldautouse = true;
|
||||
else if ( swwm_enforceautouseammo == -1 ) shouldautouse = false;
|
||||
else shouldautouse = CVar.GetCVar('swwm_autouseammo',Owner.player).GetBool();
|
||||
if ( pickup && !shouldautouse ) return false;
|
||||
if ( FabricateAmmo() )
|
||||
{
|
||||
Owner.A_StartSound(UseSound,CHAN_ITEMEXTRA);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Default
|
||||
{
|
||||
+INVENTORY.INVBAR;
|
||||
+INVENTORY.AUTOACTIVATE;
|
||||
+FLOATBOB;
|
||||
Inventory.UseSound "fabricator/use";
|
||||
Inventory.MaxAmount 32;
|
||||
Inventory.InterHubAmount 32;
|
||||
FloatBobStrength 0.25;
|
||||
|
|
@ -803,7 +874,8 @@ Class FabricatorTier1 : AmmoFabricator
|
|||
Inventory.Icon "graphics/HUD/Icons/I_Fabricator1.png";
|
||||
Inventory.PickupMessage "$T_FABRICATOR1";
|
||||
Inventory.MaxAmount 30;
|
||||
AmmoFabricator.Budget 5000;
|
||||
AmmoFabricator.Budget 10000;
|
||||
AmmoFabricator.PerType 4;
|
||||
Stamina 3000;
|
||||
}
|
||||
}
|
||||
|
|
@ -815,7 +887,8 @@ Class FabricatorTier2 : AmmoFabricator
|
|||
Inventory.Icon "graphics/HUD/Icons/I_Fabricator2.png";
|
||||
Inventory.PickupMessage "$T_FABRICATOR2";
|
||||
Inventory.MaxAmount 20;
|
||||
AmmoFabricator.Budget 20000;
|
||||
AmmoFabricator.Budget 25000;
|
||||
AmmoFabricator.PerType 8;
|
||||
Stamina 12000;
|
||||
}
|
||||
}
|
||||
|
|
@ -828,6 +901,7 @@ Class FabricatorTier3 : AmmoFabricator
|
|||
Inventory.PickupMessage "$T_FABRICATOR3";
|
||||
Inventory.MaxAmount 10;
|
||||
AmmoFabricator.Budget 500000;
|
||||
AmmoFabricator.PerType 16;
|
||||
Stamina 480000;
|
||||
}
|
||||
}
|
||||
|
|
@ -839,7 +913,9 @@ Class FabricatorTier4 : AmmoFabricator
|
|||
Inventory.Icon "graphics/HUD/Icons/I_Fabricator4.png";
|
||||
Inventory.PickupMessage "$T_FABRICATOR4";
|
||||
Inventory.MaxAmount 5;
|
||||
AmmoFabricator.Budget -1;
|
||||
AmmoFabricator.Budget int.max;
|
||||
AmmoFabricator.PerType int.max;
|
||||
-INVENTORY.AUTOACTIVATE;
|
||||
Stamina 1920000;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -913,7 +913,7 @@ Class SWWMHandler : EventHandler
|
|||
if ( !hnd ) return 0;
|
||||
CVar voicetype = CVar.GetCVar('swwm_voicetype',players[consoleplayer]);
|
||||
// suppress non-rage comments when ragekit is active, only screaming allowed
|
||||
if ( players[consoleplayer].mo.FindInventory("RagekitPower") && (type != "ragekit") ) return 0;
|
||||
if ( players[consoleplayer].mo.FindInventory("RagekitPower") && (type != "ragekit") && (CVar.GetCVar('swwm_mutevoice',players[consoleplayer]).GetInt() < 2) ) return 0;
|
||||
int whichline;
|
||||
int countem = 0, i = 1;
|
||||
String testme, locme;
|
||||
|
|
@ -1054,6 +1054,14 @@ Class SWWMHandler : EventHandler
|
|||
PlayerEntered(e);
|
||||
}
|
||||
|
||||
override void WorldThingRevived( WorldEvent e )
|
||||
{
|
||||
if ( !(e.Thing is 'PlayerPawn') ) return;
|
||||
// reset uptime since player had just died
|
||||
SWWMStats s = SWWMStats.Find(e.Thing.player);
|
||||
if ( s ) s.lastspawn = gametic;
|
||||
}
|
||||
|
||||
override void WorldTick()
|
||||
{
|
||||
if ( !mutevoice ) mutevoice = CVar.GetCVar('swwm_mutevoice',players[consoleplayer]);
|
||||
|
|
@ -1520,8 +1528,8 @@ Class SWWMHandler : EventHandler
|
|||
}
|
||||
else if ( (e.Replacee == 'Soulsphere') || (e.Replacee == 'ArtiSuperHealth') )
|
||||
{
|
||||
if ( gameinfo.gametype&GAME_Heretic ) e.Replacement = 'RefresherItem';
|
||||
else e.Replacement = 'CubeHealthItem';
|
||||
if ( gameinfo.gametype&GAME_Hexen ) e.Replacement = 'CubeHealthItem';
|
||||
else e.Replacement = 'RefresherItem';
|
||||
}
|
||||
else if ( e.Replacee == 'ArtiHealingRadius' ) e.Replacement = 'RefresherItem';
|
||||
else if ( (e.Replacee == 'Megasphere') || (e.Replacee == 'ArtiEgg') || (e.Replacee == 'PlatinumHelm') ) e.Replacement = 'GrilledCheeseSandwich';
|
||||
|
|
|
|||
|
|
@ -191,7 +191,15 @@ Class SWWMStatusBar : BaseStatusBar
|
|||
Screen.DrawTexture(i.Icon,false,dx,dy,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_Alpha,Powerup(i).IsBlinking()?alpha*.5:alpha,DTA_TopOffset,0,DTA_LeftOffset,0);
|
||||
String nstr = String.Format("%ds",Powerup(i).EffectTics/Thinker.TICRATE);
|
||||
int len = mTewiFont.mFont.StringWidth(nstr);
|
||||
Screen.DrawText(mTewiFont.mFont,Font.CR_FIRE,(xx+30)-len,(yy+30)-11,nstr,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_Alpha,Powerup(i).IsBlinking()?alpha*.5:alpha);
|
||||
Screen.DrawText(mTewiFont.mFont,Font.CR_FIRE,(xx+30)-len,(yy+30)-11,nstr,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_Alpha,Powerup(i).IsBlinking()?alpha*.5:alpha);
|
||||
return;
|
||||
}
|
||||
if ( i is 'SWWMLamp' )
|
||||
{
|
||||
Screen.DrawTexture(i.Icon,false,dx,dy,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_Alpha,alpha,DTA_TopOffset,0,DTA_LeftOffset,0);
|
||||
String nstr = String.Format("%d%%",SWWMLamp(i).Charge);
|
||||
int len = mTewiFont.mFont.StringWidth(nstr);
|
||||
Screen.DrawText(mTewiFont.mFont,Font.CR_FIRE,(xx+30)-len,(yy+30)-11,nstr,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_Alpha,alpha);
|
||||
return;
|
||||
}
|
||||
Screen.DrawTexture(i.Icon,false,dx,dy,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_Alpha,alpha,DTA_TopOffset,0,DTA_LeftOffset,0);
|
||||
|
|
|
|||
|
|
@ -99,6 +99,11 @@ Class SWWMSpareArmor : Inventory abstract
|
|||
|
||||
override bool Use( bool pickup )
|
||||
{
|
||||
bool shouldautouse = false;
|
||||
if ( swwm_enforceautousearmor == 1 ) shouldautouse = true;
|
||||
else if ( swwm_enforceautousearmor == -1 ) shouldautouse = false;
|
||||
else shouldautouse = CVar.GetCVar('swwm_autousearmor',Owner.player).GetBool();
|
||||
if ( pickup && !shouldautouse ) return false;
|
||||
let cur = Owner.FindInventory(giveme);
|
||||
if ( !cur || (cur.Amount < cur.MaxAmount) )
|
||||
{
|
||||
|
|
@ -134,6 +139,11 @@ Class SWWMHealth : Inventory abstract
|
|||
|
||||
override bool Use( bool pickup )
|
||||
{
|
||||
bool shouldautouse = false;
|
||||
if ( swwm_enforceautousehealth == 1 ) shouldautouse = true;
|
||||
else if ( swwm_enforceautousehealth == -1 ) shouldautouse = false;
|
||||
else shouldautouse = CVar.GetCVar('swwm_autousehealth',Owner.player).GetBool();
|
||||
if ( pickup && !shouldautouse ) return false;
|
||||
if ( Owner.Health >= GetDefaultByType(giveme).MaxAmount ) return false;
|
||||
if ( UseSound ) Owner.A_StartSound(UseSound,CHAN_ITEMEXTRA,CHANF_DEFAULT,.6);
|
||||
SWWMHandler.DoFlash(Owner,Color(48,64,128,255),5);
|
||||
|
|
|
|||
|
|
@ -52,9 +52,9 @@ Class SWWMKnowledgeBaseMenu : GenericMenu
|
|||
override void Init( Menu parent )
|
||||
{
|
||||
Super.Init(parent);
|
||||
if ( gamestate != GS_LEVEL )
|
||||
if ( (gamestate != GS_LEVEL) || (players[consoleplayer].Health <= 0) )
|
||||
{
|
||||
// can't open this menu outside of the game
|
||||
// can't open this menu outside of the game or if dead
|
||||
Close();
|
||||
return;
|
||||
}
|
||||
|
|
@ -201,8 +201,8 @@ Class SWWMKnowledgeBaseMenu : GenericMenu
|
|||
if ( invlist[sel0] is 'Ammo' ) return true;
|
||||
lastuse = invlist[sel0].GetClass();
|
||||
lastuseamt = invlist[sel0].Amount;
|
||||
// don't check weapons
|
||||
if ( !(invlist[sel0] is 'Weapon') )
|
||||
// don't check weapons (or the lamp)
|
||||
if ( !(invlist[sel0] is 'Weapon') && !(invlist[sel0] is 'SWWMLamp') )
|
||||
checkuse = gametic+1;
|
||||
EventHandler.SendNetworkEvent(String.Format("swwmuseitem.%s",invlist[sel0].GetClassName()),consoleplayer);
|
||||
}
|
||||
|
|
@ -223,6 +223,13 @@ Class SWWMKnowledgeBaseMenu : GenericMenu
|
|||
override void Ticker()
|
||||
{
|
||||
Super.Ticker();
|
||||
if ( players[consoleplayer].Health <= 0 )
|
||||
{
|
||||
// ded
|
||||
MenuSound("menu/democlose");
|
||||
Close();
|
||||
return;
|
||||
}
|
||||
// mark lore entries as read
|
||||
if ( (curtab == TAB_LIBRARY) && (lorelib.ent.Size() > 0) && !lorelib.ent[sel0].read )
|
||||
EventHandler.SendNetworkEvent("swwmmarkloreread",consoleplayer,sel0);
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ Class Demolitionist : PlayerPawn
|
|||
Mass 500;
|
||||
PainChance 255;
|
||||
Player.DisplayName "Demolitionist";
|
||||
Player.StartItem "DeepImpact";
|
||||
Player.StartItem "ExplodiumGun";
|
||||
Player.ViewHeight 52;
|
||||
Player.AirCapacity 0;
|
||||
|
|
@ -40,6 +41,7 @@ Class Demolitionist : PlayerPawn
|
|||
Player.SoundClass "demolitionist";
|
||||
DamageFactor "Drowning", 0.0;
|
||||
DamageFactor "Poison", 0.0;
|
||||
DamageFactor "PoisonCloud", 0.0;
|
||||
DamageFactor "Falling", 0.0;
|
||||
+NOBLOOD;
|
||||
+DONTGIB;
|
||||
|
|
|
|||
|
|
@ -594,7 +594,7 @@ Class RagekitPower : Powerup
|
|||
if ( !(level.maptime%30) )
|
||||
{
|
||||
SWWMHandler.DoFlash(Owner,Color(16,255,0,0),5);
|
||||
if ( (Owner.player == players[consoleplayer]) && (gametic > lastrage) )
|
||||
if ( (Owner.player == players[consoleplayer]) && (gametic > lastrage) && (CVar.GetCVar('swwm_mutevoice',players[consoleplayer]).GetInt() < 2) )
|
||||
lastrage = SWWMHandler.AddOneliner("ragekit",5);
|
||||
Owner.A_QuakeEx(2,2,2,Random[Rage](1,2),0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:.5);
|
||||
}
|
||||
|
|
@ -671,13 +671,18 @@ Class Omnisight : Inventory
|
|||
{
|
||||
override bool Use( bool pickup )
|
||||
{
|
||||
level.allmap = true;
|
||||
if ( !level.allmap )
|
||||
{
|
||||
Owner.A_StartSound(UseSound,CHAN_ITEMEXTRA);
|
||||
level.allmap = true;
|
||||
}
|
||||
// not used up, must be kept for the targetting features to work
|
||||
return false;
|
||||
}
|
||||
Default
|
||||
{
|
||||
Tag "$T_OMNISIGHT";
|
||||
Inventory.UseSound "powerup/omnisight";
|
||||
Inventory.PickupSound "misc/p_pkup";
|
||||
Inventory.PickupMessage "$I_OMNISIGHT";
|
||||
Inventory.MaxAmount 1;
|
||||
|
|
@ -701,10 +706,249 @@ Class Omnisight : Inventory
|
|||
|
||||
Class LampMoth : Actor
|
||||
{
|
||||
Actor lamp;
|
||||
Vector3 trail, ofs;
|
||||
int lifespan;
|
||||
|
||||
Default
|
||||
{
|
||||
Tag "$T_MOTH";
|
||||
Radius 1;
|
||||
Height 2;
|
||||
Speed 2;
|
||||
DamageFunction 1;
|
||||
MeleeRange 16;
|
||||
Mass 10;
|
||||
Health 10;
|
||||
DeathSound "moth/die";
|
||||
BloodColor "20 10 10";
|
||||
MONSTER;
|
||||
-COUNTKILL;
|
||||
+THRUACTORS;
|
||||
+NOGRAVITY;
|
||||
+NOTELEPORT;
|
||||
+FLOAT;
|
||||
+NOPAIN;
|
||||
+FRIENDLY;
|
||||
+LOOKALLAROUND;
|
||||
+QUICKTORETALIATE;
|
||||
+INTERPOLATEANGLES;
|
||||
}
|
||||
override string GetObituary( Actor victim, Actor inflictor, Name mod, bool playerattack )
|
||||
{
|
||||
if ( master && master.player ) return String.Format(StringTable.Localize("$O_MOTH"),master.player.GetUserName());
|
||||
return StringTable.Localize("$O_MOTH2");
|
||||
}
|
||||
override void PostBeginPlay()
|
||||
{
|
||||
Super.PostBeginPlay();
|
||||
A_StartSound("moth/fly",CHAN_BODY,CHANF_LOOPING,.15,4.,FRandom[Moth](.8,1.2));
|
||||
if ( master && master.player ) SetFriendPlayer(master.player);
|
||||
else bFRIENDLY = false;
|
||||
}
|
||||
bool isEntranced()
|
||||
{
|
||||
if ( !lamp )
|
||||
{
|
||||
// look for nearby lamps
|
||||
let bi = BlockThingsIterator.Create(self,250);
|
||||
double mindist = 250.;
|
||||
while ( bi.Next() )
|
||||
{
|
||||
if ( !bi.Thing || !(bi.Thing is 'CompanionLamp') ) continue;
|
||||
Actor a = bi.Thing;
|
||||
double dist = Distance3D(a);
|
||||
if ( (a.frame == 0) || (dist > mindist) && !CheckSight(a) ) continue;
|
||||
mindist = dist;
|
||||
lamp = a;
|
||||
master = a.target;
|
||||
if ( CompanionLamp(lamp).moff.Find(self) == -1 )
|
||||
CompanionLamp(lamp).moff.Push(self);
|
||||
if ( master && master.player ) SetFriendPlayer(master.player);
|
||||
else bFRIENDLY = false;
|
||||
}
|
||||
}
|
||||
if ( !lamp || (lamp.frame == 0) || (Distance3D(lamp) > 250) || !CheckSight(lamp) ) return false;
|
||||
return true;
|
||||
}
|
||||
void A_SmoothWander()
|
||||
{
|
||||
if ( level.Vec3Diff(pos,trail).length() < speed )
|
||||
{
|
||||
double ang = FRandom[Moth](0,360);
|
||||
double pt = FRandom[Moth](-30,30);
|
||||
double dist = FRandom[Moth](20,40);
|
||||
ofs = (cos(ang)*cos(pt),sin(ang)*cos(pt),-sin(pt))*dist;
|
||||
}
|
||||
Vector3 newpos = level.Vec3Offset(pos,ofs);
|
||||
if ( level.IsPointInLevel(newpos) ) trail = newpos;
|
||||
if ( vel.length() > 0 )
|
||||
{
|
||||
Vector3 uvel = vel.unit();
|
||||
angle += Clamp(deltaangle(angle,atan2(uvel.y,uvel.x)),-5.,5.);
|
||||
pitch += Clamp(deltaangle(pitch,asin(-uvel.z)),-5.,5.);
|
||||
}
|
||||
vel *= .8;
|
||||
Vector3 dir = level.Vec3Diff(pos,trail);
|
||||
if ( dir.length() > 0 ) vel += dir.unit()*clamp(dir.length()*.05,.4*speed,.5*speed);
|
||||
}
|
||||
void A_SmoothChase()
|
||||
{
|
||||
if ( !target || (target.Health <= 0) )
|
||||
{
|
||||
A_ClearTarget();
|
||||
SetStateLabel("Spawn");
|
||||
return;
|
||||
}
|
||||
if ( CheckMeleeRange() )
|
||||
{
|
||||
SetStateLabel("Melee");
|
||||
return;
|
||||
}
|
||||
Vector3 dest = target.Vec3Offset(0,0,target.height*.75);
|
||||
Vector3 dir = level.Vec3Diff(pos,dest);
|
||||
Vector3 dirunit = dir.unit();
|
||||
FLineTraceData d;
|
||||
LineTrace(atan2(dirunit.y,dirunit.x),dir.length(),asin(-dirunit.z),data:d);
|
||||
if ( (d.HitType != TRACE_HitActor) && (d.HitActor != target) )
|
||||
{
|
||||
A_Chase();
|
||||
return;
|
||||
}
|
||||
if ( vel.length() > 0 )
|
||||
{
|
||||
Vector3 uvel = vel.unit();
|
||||
angle = atan2(uvel.y,uvel.x);
|
||||
pitch = asin(-uvel.z);
|
||||
}
|
||||
vel *= .8;
|
||||
if ( dir.length() > 0 ) vel += dir.unit()*clamp(dir.length()*.02,.3*speed,2.*speed);
|
||||
}
|
||||
void A_FollowLamp()
|
||||
{
|
||||
if ( !lamp )
|
||||
{
|
||||
SetStateLabel("Spawn");
|
||||
return;
|
||||
}
|
||||
double dst = level.Vec3Diff(pos,trail).length();
|
||||
if ( (dst < speed) || (dst > 50) )
|
||||
{
|
||||
double ang = FRandom[Moth](0,360);
|
||||
double pt = FRandom[Moth](-30,30);
|
||||
double dist = FRandom[Moth](20,30);
|
||||
ofs = (cos(ang)*cos(pt),sin(ang)*cos(pt),-sin(pt))*dist;
|
||||
}
|
||||
Vector3 newpos = level.Vec3Offset(lamp.Vec3Offset(0,0,lamp.height/2),ofs);
|
||||
if ( level.IsPointInLevel(newpos) ) trail = newpos;
|
||||
if ( vel.length() > 0 )
|
||||
{
|
||||
Vector3 uvel = vel.unit();
|
||||
angle = atan2(uvel.y,uvel.x);
|
||||
pitch = asin(-uvel.z);
|
||||
}
|
||||
vel *= .8;
|
||||
Vector3 dir = level.Vec3Diff(pos,trail);
|
||||
if ( dir.length() > 0 ) vel += dir.unit()*clamp(dir.length()*.02,.4*speed,2.*speed);
|
||||
Vector3 diff = level.Vec3Diff(pos,lamp.pos);
|
||||
if ( (diff.x > -8) && (diff.x < 8) && (diff.y > -8) && (diff.y < 8) && (diff.z > -4) && (diff.z < lamp.height+4) )
|
||||
{
|
||||
if ( diff.x < 0 ) vel.x -= .2;
|
||||
else vel.x += .2;
|
||||
if ( diff.y < 0 ) vel.y -= .2;
|
||||
else vel.y += .2;
|
||||
if ( diff.z < 0 ) vel.z -= .2;
|
||||
else vel.z += .2;
|
||||
}
|
||||
}
|
||||
void A_SmoothMove()
|
||||
{
|
||||
if ( vel.length() > 0 )
|
||||
{
|
||||
Vector3 uvel = vel.unit();
|
||||
angle = atan2(uvel.y,uvel.x);
|
||||
pitch = asin(-uvel.z);
|
||||
}
|
||||
vel *= .8;
|
||||
}
|
||||
void A_Scrape()
|
||||
{
|
||||
if ( CheckMeleeRange() )
|
||||
{
|
||||
A_FaceTarget(0,0);
|
||||
lifespan -= 5;
|
||||
Vector3 awaydir = level.Vec3Diff(target.Vec3Offset(0,0,target.height),pos).unit();
|
||||
vel += awaydir*32.;
|
||||
int dmg = target.DamageMobj(self,self,GetMissileDamage(0,0),'Melee',Random[Moth](0,8)?DMG_NO_PAIN:0);
|
||||
if ( !target.bNOBLOOD )
|
||||
{
|
||||
target.TraceBleed(dmg,self);
|
||||
target.SpawnBlood(pos,atan2(awaydir.y,awaydir.x)+180,dmg);
|
||||
}
|
||||
A_StartSound("moth/scrape",CHAN_WEAPON,CHANF_OVERLAP,.2,2.5);
|
||||
DamageMobj(target,target,1,'Melee');
|
||||
}
|
||||
}
|
||||
override void Tick()
|
||||
{
|
||||
Super.Tick();
|
||||
if ( isFrozen() || isEntranced() )
|
||||
{
|
||||
lifespan = 100;
|
||||
return;
|
||||
}
|
||||
if ( target && (target.Health > 0) ) lifespan = max(20,lifespan);
|
||||
lifespan--;
|
||||
if ( lifespan <= 0 )
|
||||
{
|
||||
let s = Spawn("SWWMSmallSmoke",pos);
|
||||
s.alpha *= .3;
|
||||
Destroy();
|
||||
}
|
||||
}
|
||||
States
|
||||
{
|
||||
Spawn:
|
||||
XZW1 B 0 A_JumpIf(isEntranced(),"See.Entranced");
|
||||
XZW1 BC 1
|
||||
{
|
||||
A_SmoothWander();
|
||||
A_Look();
|
||||
}
|
||||
Loop;
|
||||
See: // go for enemies
|
||||
XZW1 B 0 A_JumpIf(isEntranced(),"See.Entranced");
|
||||
XZW1 BC 1 A_SmoothChase();
|
||||
Loop;
|
||||
See.Entranced: // follow the lamp
|
||||
XZW1 B 0 A_JumpIf(!isEntranced(),"Spawn");
|
||||
XZW1 BC 1 A_FollowLamp();
|
||||
Loop;
|
||||
Melee:
|
||||
XZW1 B 0 A_Scrape();
|
||||
XZW1 BCBC 1 A_SmoothMove();
|
||||
Goto See;
|
||||
Death:
|
||||
TNT1 A 1
|
||||
{
|
||||
A_StartSound("moth/die",CHAN_VOICE,CHANF_OVERLAP,.6,2.5);
|
||||
let s = Spawn("SWWMSmallSmoke",pos);
|
||||
s.alpha *= .3;
|
||||
}
|
||||
Stop;
|
||||
}
|
||||
}
|
||||
|
||||
Class LampMoth2 : LampMoth
|
||||
{
|
||||
Default
|
||||
{
|
||||
Tag "$T_WMOTH";
|
||||
DamageFunction 3;
|
||||
Speed 3;
|
||||
Scale 1.5;
|
||||
Health 100;
|
||||
}
|
||||
}
|
||||
|
||||
Class LampMashiro : Actor abstract
|
||||
|
|
@ -761,20 +1005,46 @@ Class CompanionLamp : Actor
|
|||
Default
|
||||
{
|
||||
+NOGRAVITY;
|
||||
+NOCLIP;
|
||||
+SHOOTABLE;
|
||||
+NOTELEPORT;
|
||||
+NODAMAGE;
|
||||
+NOBLOOD;
|
||||
+DONTSPLASH;
|
||||
+FLOATBOB;
|
||||
+INTERPOLATEANGLES;
|
||||
+LOOKALLAROUND;
|
||||
Radius 4;
|
||||
Height 8;
|
||||
FloatBobStrength 0.5;
|
||||
Height 16;
|
||||
}
|
||||
action void A_Moth()
|
||||
// random chance to spawn moths
|
||||
void A_Moth()
|
||||
{
|
||||
// random chance to spawn moths
|
||||
// count up
|
||||
for ( int i=0; i<moff.Size(); i++ )
|
||||
{
|
||||
if ( moff[i] && (moff[i].lamp == self) && moff[i].isEntranced() ) continue;
|
||||
moff.Delete(i);
|
||||
i--;
|
||||
}
|
||||
if ( (GetAge()%35) || Random[Moth](0,9) || (moff.Size() >= 30) ) return;
|
||||
// spawn a moth at a random offset
|
||||
double ang = FRandom[Moth](0,360);
|
||||
double pt = FRandom[Moth](-30,30);
|
||||
double dist = FRandom[Moth](10,30);
|
||||
Vector3 ofs = (cos(ang)*cos(pt),sin(ang)*cos(pt),-sin(pt))*dist;
|
||||
Vector3 spawnpos = level.Vec3Offset(Vec3Offset(0,0,height/2),ofs);
|
||||
if ( !level.IsPointInLevel(spawnpos) ) return;
|
||||
let m = LampMoth(Spawn(Random[Moth](0,9)?"LampMoth":"LampMoth2",spawnpos));
|
||||
if ( !m.TestMobjLocation() )
|
||||
{
|
||||
m.Destroy();
|
||||
return;
|
||||
}
|
||||
let s = Spawn("SWWMSmallSmoke",m.pos);
|
||||
s.alpha *= .3;
|
||||
m.master = target;
|
||||
m.lamp = self;
|
||||
m.trail = m.pos;
|
||||
moff.Push(m);
|
||||
}
|
||||
override void PostBeginPlay()
|
||||
{
|
||||
|
|
@ -784,8 +1054,24 @@ Class CompanionLamp : Actor
|
|||
Destroy();
|
||||
return;
|
||||
}
|
||||
Spawn("SWWMItemFog",pos);
|
||||
Trail = pos;
|
||||
}
|
||||
// the stupidest thing ever, it's called BlockingLine but it's not always blocking us
|
||||
private bool BlockingLineIsBlocking()
|
||||
{
|
||||
if ( !BlockingLine ) return false;
|
||||
// one-sided
|
||||
if ( !BlockingLine.sidedef[1] ) return true;
|
||||
// blocks us
|
||||
if ( BlockingLine.flags&(Line.ML_BLOCKING|Line.ML_BLOCKEVERYTHING) ) return true;
|
||||
return false;
|
||||
}
|
||||
private int WhichBlockingLineSide()
|
||||
{
|
||||
if ( !BlockingLine ) return 0;
|
||||
return ((pos.y-BlockingLine.v1.p.y)*BlockingLine.delta.x+(BlockingLine.v1.p.x-pos.x)*BlockingLine.delta.y > double.epsilon);
|
||||
}
|
||||
override void Tick()
|
||||
{
|
||||
Super.Tick();
|
||||
|
|
@ -794,28 +1080,95 @@ Class CompanionLamp : Actor
|
|||
Destroy();
|
||||
return;
|
||||
}
|
||||
if ( isFrozen() ) return;
|
||||
// update trailing position
|
||||
bool foundspot = false;
|
||||
for ( int i=0; i<180; i++ )
|
||||
for ( int i=0; i<180; i+=5 )
|
||||
{
|
||||
for ( int j=1; j>=-1; j-=2 )
|
||||
{
|
||||
double ang = (target.angle-180)+i*j;
|
||||
Vector3 testpos = target.Vec3Offset(cos(ang)*32,sin(ang)*32,target.height-8);
|
||||
Vector3 testpos = level.Vec3Offset(target.pos,(cos(ang)*32,sin(ang)*32,target.height-8+1.5*sin(level.maptime*3.)));
|
||||
if ( !level.IsPointInLevel(testpos) ) continue;
|
||||
Vector3 oldpos = pos;
|
||||
Vector3 oldprev = prev;
|
||||
Actor oldblockingmobj = blockingmobj;
|
||||
Line oldblockingline = blockingline;
|
||||
Sector oldblockingfloor = blockingfloor, oldblockingceiling = blockingceiling;
|
||||
SetOrigin(testpos,false);
|
||||
if ( !TestMobjLocation() || BlockingLineIsBlocking() || BlockingFloor || BlockingCeiling )
|
||||
{
|
||||
SetOrigin(oldpos,false);
|
||||
prev = oldprev;
|
||||
blockingmobj = oldblockingmobj;
|
||||
blockingline = oldblockingline;
|
||||
blockingfloor = oldblockingfloor;
|
||||
blockingceiling = oldblockingceiling;
|
||||
continue;
|
||||
}
|
||||
SetOrigin(oldpos,false);
|
||||
prev = oldprev;
|
||||
blockingmobj = oldblockingmobj;
|
||||
blockingline = oldblockingline;
|
||||
blockingfloor = oldblockingfloor;
|
||||
blockingceiling = oldblockingceiling;
|
||||
Trail = testpos;
|
||||
foundspot = true;
|
||||
}
|
||||
// check at most for a 45 degree offset
|
||||
if ( foundspot && (i > 45) ) break;
|
||||
}
|
||||
Vector3 diff = level.Vec3Diff(pos,target.pos);
|
||||
if ( (diff.length() > 400) || !CheckSight(target) )
|
||||
{
|
||||
Actor f = Spawn("SWWMItemFog",pos);
|
||||
f.A_StartSound("lamp/disappear",CHAN_VOICE);
|
||||
SetOrigin(trail,false);
|
||||
angle = AngleTo(target);
|
||||
vel *= 0.;
|
||||
f = Spawn("SWWMItemFog",pos);
|
||||
f.A_StartSound("lamp/appear",CHAN_VOICE);
|
||||
return;
|
||||
}
|
||||
angle += Clamp(deltaangle(angle,AngleTo(target)),-5.,5.);
|
||||
vel *= .8;
|
||||
Vector3 newpos = Trail;
|
||||
Vector3 dir = level.Vec3Diff(pos,newpos);
|
||||
if ( dir.length() > 0 )
|
||||
vel += dir.unit()*min(dir.length()*.05,20.);
|
||||
Vector3 diff = pos-target.pos;
|
||||
bool blocked = false;
|
||||
if ( BlockingLine && BlockingLineIsBlocking() )
|
||||
{
|
||||
// push away from wall
|
||||
Vector3 normal = (-BlockingLine.delta.y,BlockingLine.delta.x,0).unit();
|
||||
if ( !WhichBlockingLineSide() ) normal *= -1;
|
||||
vel += 4.*normal;
|
||||
blocked = true;
|
||||
}
|
||||
if ( BlockingFloor )
|
||||
{
|
||||
// push away from floor
|
||||
Vector3 normal = BlockingFloor.floorplane.Normal;
|
||||
// find closest 3d floor for its normal
|
||||
for ( int i=0; i<BlockingFloor.Get3DFloorCount(); i++ )
|
||||
{
|
||||
if ( !(BlockingFloor.Get3DFloor(i).top.ZAtPoint(pos.xy) ~== floorz) ) continue;
|
||||
normal = -BlockingFloor.Get3DFLoor(i).top.Normal;
|
||||
break;
|
||||
}
|
||||
vel += 4.*normal;
|
||||
blocked = true;
|
||||
}
|
||||
if ( BlockingCeiling )
|
||||
{
|
||||
// push away from ceiling
|
||||
Vector3 normal = BlockingCeiling.ceilingplane.Normal;
|
||||
// find closest 3d floor for its normal
|
||||
for ( int i=0; i<BlockingCeiling.Get3DFloorCount(); i++ )
|
||||
{
|
||||
if ( !(BlockingCeiling.Get3DFloor(i).bottom.ZAtPoint(pos.xy) ~== ceilingz) ) continue;
|
||||
normal = -BlockingCeiling.Get3DFloor(i).bottom.Normal;
|
||||
break;
|
||||
}
|
||||
vel += 4.*normal;
|
||||
blocked = true;
|
||||
}
|
||||
if ( (diff.x > -16) && (diff.x < 16) && (diff.y > -16) && (diff.y < 16) && (diff.z > -16) && (diff.z < target.height+8) )
|
||||
{
|
||||
if ( diff.x < 0 ) vel.x -= .2;
|
||||
|
|
@ -824,16 +1177,38 @@ Class CompanionLamp : Actor
|
|||
else vel.y += .2;
|
||||
if ( diff.z < 0 ) vel.z -= .2;
|
||||
else vel.z += .2;
|
||||
blocked = true;
|
||||
}
|
||||
if ( blocked ) return;
|
||||
Vector3 dir = level.Vec3Diff(pos,trail);
|
||||
if ( dir.length() > 0 )
|
||||
vel += dir.unit()*min(dir.length()*.05,20.);
|
||||
}
|
||||
States
|
||||
{
|
||||
Spawn:
|
||||
XZW1 A 1 A_JumpIf(SWWMLamp(master)&&SWWMLamp(master).bActive,1);
|
||||
XZW1 A 1
|
||||
{
|
||||
if ( SWWMLamp(master) && SWWMLamp(master).bActive )
|
||||
{
|
||||
A_StartSound("lamp/on",CHAN_ITEMEXTRA);
|
||||
return ResolveState("Active");
|
||||
}
|
||||
return ResolveState(null);
|
||||
}
|
||||
Wait;
|
||||
Active:
|
||||
XZW1 B 1
|
||||
{
|
||||
A_Moth();
|
||||
if ( !SWWMLamp(master) || !SWWMLamp(master).bActive )
|
||||
{
|
||||
A_StartSound("lamp/off",CHAN_ITEMEXTRA);
|
||||
return ResolveState("Spawn");
|
||||
}
|
||||
return ResolveState(null);
|
||||
}
|
||||
Wait;
|
||||
XZW1 B 0 A_JumpIf(!SWWMLamp(master)||!SWWMLamp(master).bActive,"Spawn");
|
||||
XZW1 B 1 A_Moth();
|
||||
Loop;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -849,7 +1224,7 @@ Class SWWMLamp : Inventory
|
|||
override Inventory CreateCopy( Actor other )
|
||||
{
|
||||
// additional lore
|
||||
SWWMLoreLibrary.Add(other.player,"Lamp");
|
||||
SWWMLoreLibrary.Add(other.player,"MothLamp");
|
||||
return Super.CreateCopy(other);
|
||||
}
|
||||
override bool HandlePickup( Inventory item )
|
||||
|
|
@ -877,8 +1252,10 @@ Class SWWMLamp : Inventory
|
|||
thelamp = Spawn("CompanionLamp",Owner.Vec3Offset(cos(Owner.angle-180)*32,sin(Owner.angle-180)*32,Owner.height-8));
|
||||
thelamp.target = Owner;
|
||||
thelamp.master = self;
|
||||
let f = Spawn("SWWMItemFog",thelamp.pos);
|
||||
f.A_StartSound("lamp/appear",CHAN_VOICE);
|
||||
}
|
||||
if ( bActive && !(level.maptime%35) ) Charge--;
|
||||
if ( bActive && !(level.maptime%35) && !isFrozen() ) Charge--;
|
||||
if ( Charge <= 0 )
|
||||
{
|
||||
Amount--;
|
||||
|
|
@ -888,7 +1265,12 @@ Class SWWMLamp : Inventory
|
|||
override void DetachFromOwner()
|
||||
{
|
||||
Super.DetachFromOwner();
|
||||
if ( thelamp ) thelamp.Destroy();
|
||||
if ( thelamp )
|
||||
{
|
||||
let f = Spawn("SWWMItemFog",thelamp.pos);
|
||||
f.A_StartSound("lamp/disappear",CHAN_VOICE);
|
||||
thelamp.Destroy();
|
||||
}
|
||||
Icon = default.Icon;
|
||||
bActive = false;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue