From c47ecb18c9fcecd413c0597a9f0a6ed21efe5b48 Mon Sep 17 00:00:00 2001 From: hgn Date: Sat, 8 Feb 2025 13:41:54 +0000 Subject: [PATCH] removed multi-worlds. (broke: all shop types, world networking, achievement models, challenges, npcs) --- content_skaterift/maps/dev_heaven/main.mdl | Bin 853584 -> 890960 bytes content_skaterift/metascenes/intro.ms | Bin 13320 -> 13240 bytes content_skaterift/models/rs_tape.mdl | Bin 0 -> 37256 bytes skaterift_blender/sr_main.py | 2 + skaterift_blender/sr_mdl.py | 1 + src/addon.c | 34 +- src/array_file.c | 3 + src/client.c | 5 +- src/client.h | 3 +- src/ent_challenge.c | 58 ++- src/ent_challenge.h | 1 - src/ent_miniworld.c | 28 +- src/ent_npc.c | 317 ---------------- src/ent_npc.h | 28 -- src/ent_objective.c | 21 +- src/ent_region.c | 14 +- src/ent_route.c | 10 +- src/ent_skateshop.c | 55 ++- src/ent_skateshop.h | 2 +- src/ent_tornado.c | 6 +- src/entity.c | 2 - src/entity.h | 3 +- src/gui.h | 83 ++--- src/menu.c | 257 +++++-------- src/metascene.c | 4 + src/metascene.h | 1 + src/network.c | 18 +- src/player.c | 57 ++- src/player.h | 1 - src/player_dead.c | 12 +- src/player_glide.c | 15 +- src/player_ragdoll.c | 2 +- src/player_remote.c | 92 ++--- src/player_remote.h | 9 +- src/player_render.c | 4 +- src/player_replay.c | 26 +- src/player_skate.c | 19 +- src/player_walk.c | 4 +- src/save.c | 217 +++++++---- src/save.h | 7 +- src/skaterift.c | 224 +++--------- src/skaterift.h | 6 +- src/skaterift_script.c | 74 ++-- src/skaterift_script.h | 1 + src/vehicle.c | 6 +- src/workshop.c | 6 +- src/world.c | 104 ++---- src/world.h | 94 +++-- src/world_audio.c | 21 +- src/world_entity.c | 96 +++-- src/world_entity.h | 3 + src/world_events.c | 32 ++ src/world_events.h | 3 + src/world_gate.c | 106 +----- src/world_load.c | 407 ++++++++++----------- src/world_load.h | 10 +- src/world_map.c | 25 +- src/world_map.h | 1 - src/world_render.c | 121 +++--- src/world_routes.c | 35 +- src/world_routes.h | 2 +- src/world_routes_ui.c | 4 +- src/world_sfd.c | 11 +- src/world_volumes.c | 23 +- src/world_water.c | 4 +- 65 files changed, 1148 insertions(+), 1692 deletions(-) create mode 100644 content_skaterift/models/rs_tape.mdl delete mode 100644 src/ent_npc.c delete mode 100644 src/ent_npc.h create mode 100644 src/world_events.c create mode 100644 src/world_events.h diff --git a/content_skaterift/maps/dev_heaven/main.mdl b/content_skaterift/maps/dev_heaven/main.mdl index c96de6007c2d9e1290aced98fc9b90f668aa07d1..30f138cd5e87b958bc1906e6b61fea8a299d0188 100644 GIT binary patch delta 36382 zcmb7t3w&c$oqy7I`hKKM)1*n-G;Py&n!ej4Ac`O$A~?geOotKL8bfadW;)Z9=^c<& zP@awue1eECL=;d&DebvwXFwEzb$8KqA3j*!|L)(v>#pna`K!ZzfA^l-o~F4?Z2P)JoN$dEBQTbGmlk7kIc;9XnOR~uReW2 z^~@sDJ95JUULXC?FUreqyyk}J2ab4n*i+%c_ty4(45oP~o?4^A&mSkcabc3IE#{9}hk9Z*NSfS*VYbkstr;_R#T#`Vf_QJKSXY?VBG8 z|MF9((&BGQgFpAtyTY#<;E}$(D}#RXhr$;gKb1V^#>{JNNiUfgcD7mec)e2_r%&?7&y7-D_(z|v41J!D zf=mD7_NTz4j)Kx(7w_ssM}WWd(ATy)X(l}7krppQr0FsshQFjhzl%3-jhdo?2cIH- z>a0e?Sg(LgBFctAlu$N!%HWU5r=QD^K9@hrN;UZJpZ+itgIX{Bp=Y4K?^R>M=;?3c zG5(E2L?E%vG^V}rf62u4o8a;A{c`a$YK^x`WSqf6zw8d*{}^%W;$`^ z;tYG@#hEc1Jmw#h>8QI|ol3J~*sekU^Pe0aeEb&^-M^9}MirnM2QMj9^^jD2gl1AX zWqGY%x-&fRU_n}jbW`=dwtK=e1>XyiqLZ3II=ncw6JFM9U^KUjO^{6n;<%^U&p-J0 z{dynz!`tQ}Da*0EYwFFwKxyun8MDEQ^TbZPysJc}(+}JomKPmcbGw=&rqb6iRUb*C z;T$+~fB0k?ywSY!sn2{Y%*N`TRTn23e=iSQ9n?jXPQy9$;3u{jvcOXXejMsaJFldw zXzKW<8oXw}kgh^x~x!rgs-PX8d z)5+Eg3L^g353J`r^<_hqOB^;L-e}a2!lLVdB7WCAq0hg>pevbsGHAWgL~DVrw)Z{s z$dgZhdYy*Z`oq7zK2-O%rd>LtIJJv-*@)pkt{e}))wVuC8j;9ggr@@i-IQ4!HQC_R z)vx#&S?xqCUf)yg?Um44jB6mSe%a!Cyw(iq>+*+Ksm7IeyuSJ{YMf05_qje24mvM* zjwJMht0Mg+FFe0z1>SPadEvYZZdKFY!lVBgw%M2d;jZulZ`P_4#TVXQ8LTb+&md{C zMomyQbbdJSquOVwK-u7_0`fUm4Tin|hC91{)&I|*SDxIf38)4)d@-cRzzquU&;|DsC-e%k3I~aE1^-h-!UTlJcU#npFf2pqb|8(AmLa&+rao5gCTwQ^eGct$`3^KYtx zVE)yuG!dy=vvf9`)b&0SUbi3U_JD1?oZd)O(|ULK>(Uu@HKU1To8k7*f2T1jjX!=z zxb%2_cy|Wr)2B35yo{+gHG_0DCXBeb6bqCNFWLk4N?(&dC7!aE%alQ?nJyDP)egw< znu#TyNK=*4Oc|tV$(it)iYDuJx}9yDPNb=Nex?k>t=Zfs&tEUP;l~~`H$G?vcZd;TF1+~N~EU_SJYx3n|OTnDrw*P8_$;Ptbu?RwPX=*q$NW_ z^49KEWZ0!9^Gw7VWP=waIy3s=?*=cJT0hZ{CsY9IpHKnStMAuS8PxqcmcLZIKJHWT z>9*fulc{)lSBZ9JkZQwefApm%b;D%3PAXc_sGynfYX1|rPMH`eQPI|$36I5QP2Z>x zFa78hFtY!zi8Eaa!>*kTCYH6-0|p_3U3e_VYug7HeEjJQsoP`99HT%zSJLM8lj{_Q zA4BUl;q|>A>6RMY08jZ7gTD96$iVT`1XPG@@YwCH3FiyzbiQySKVLAi|E~%5|1Aci zag1@lCLAzq;f;nd73ibd0ftN`7#SIMHbGYQf3?Xp3GIdF?GNkr+FxRBhm~thv<+vn z|BLCvdLF#!%P&5Gri=WT?EmRZEMf*b7!2?j_gkYTTRaVW-TuE_B7+R5K)M+%n+%|o zu4Q4u;qpgAVWwNlWUU5l>jzt{Y%PtowJqZ_GL>H*_?fz2-@{tHgCP^1Dj?dD zGvH-1x3B5DU6O*xkZw7q^kDQwK2w2o+i*5`sBi@mu8KT)s&F-v@p(-*K8tum`#)?rYl89lsq;RssFqTrHiq4B zO)x%Z#8U-eMU!>oGweO|V{8qFC38(MK4-*>os?4cHr)xH)OkXeKLBEz5rg)V%Akj9 zc)eF|hwhEn`^3~&s|KD7!In(+eur_|gV+Sw;KgBV zfR}fye$)iINDUZv;KjY%<*$6S>%{(q+QxerpSM;^4KMG_0PFVF>X&T>`eK$1{mh;5t=9)`xPKC~BJlRq*M_kMdZ z=mio*`qhcYCl10k{D(bk!(s&lyz$kkEfGON0)t??O_{iay`P9TQew3V%i2{d*kZ?a z8;5shAc`~_JV{C)#)kMU`E$7n#^)UcO1GV+iACI~cy4=S>(XkvPM2z7Aw1@P%>t5+ z0duu}$z)Y;ci`8J_KL!pP*!-1GFiVIo)rTfrE=TtE_}MZB08ylHyn8FDmE%2m~K&j zy=LSR1D_}i7ZD&Bl`h%TKdiE=hUm%vSy22HR`3rz)hKn3Ea z)vdeXdlg9Sf83t0ij>-Sr-*jec&AABGOcQI748kI>2ph|+J|uQS>AQLPHfy1n~otZ zo||H`!o!54U)=^C^-n3$t_;K)!1DPNx7`|!0x^S(c#=Pz*>DA9H6sJZ^KqXQo(jZG zx4ZCiI?E?Dft~^RwV#uQHKuqy0}h6>H=Z|{thU+x6(3bMmqrr{C8|q^{F(5=jR-Y; z;z?g1wg0QeXZ@;l1_muDY*h3Mido@>J0>cg+mhD}?f=4Y{7wb~^E?%cn^vFGFEYdU z{B5IoLZ4S;{G*Vp7=)wL=U^!v=eFT>qYS7(d@kQ%gj9k_shGz1)~=IQ5c>#*NQv2AS}p!U9uo zMCQh4Lyd*jd;M^l7_!0Z8dMf|*(9n&B7@Peq^Xx1pI2e)g}p~rLLx?nNy2lRQX0Ix z`>HgoR{G87Gz`1(;@qB1fyBj0hOJk>`D|DNDiAk5uV#a%8goNqM!Y)y#nmjE3}BMc zZ$7WWnB32e&xRGCOQ_s1nTk(u{}(P0uF_3rZhSV(K)AG;6`m@fUE!49Sf!iH+Tc5B zm;u#*8=teni=C9x=EmpU!&skx#WvFlLr>$0h46Z>&K9rt30PLYsT!ZLBa-(pK5un8 zk-_Lb@WoUff$! z*GH~i9`mYVYX93Sy{vN zd&X*$T`FrI8c}<7y6=F%sH9&s))+G2=}bs(W4flRwWe_s%VGxEFbFpq$(Wom14>`F z4X45H{{9cuKp)3x7(}*w-x`0$A`*_xvdTcX5uxJwS21?){itmy zf8jzwW(KW6w=AXlygaQODn8xR zt{uIqC$I8zsSN3sW8o|~E4(<2#q@U%W8VJaL?JR5S+~VrP1R3lS{0=uj+z~Ky8oZf zI4s=j-O=fcOsi1Q^n1fQ@J1&p`o$)?|F1Iek5HuVr6{s+tTg_;-)HkmrQvMMN!wNv_)$a|f>1%k|c-+(aEt*y-lf70;T3+>uOT+Gsr^QT> z`FFqY&4+dV5emcAPwdqqes{0dvKNTARDHh*+=;t4y zFtnnHGb6{V_J2bL;R4}mHW|>|u3N>j!T%;GZ~ZHkRebY7zXxnsAaU`?7O$J#(&C|i zyeW#5YOLFO(=w#sVW80O0k7ht5>N7vP#9JKRy6&NsEU^}F$mY`$h7(t{|JR)2Esky zZ1AxEYZrm(ejk}upX48*FwB5zAedq^;;G5>PP#2=eb}eD|4$5ho9$-U{qF_DPL~Z{ zY=VO_E&_jxE&{_AYh+p#`vgA8kP$CdK*Xmr^{V4vtbxd|SAqET{MBsmVw0ud<+PvO z5Ia!{Lt4DPn$cp04-Rzkk5Cwz^|n`6*#EO(5VvO8;KjY)o_Kx!6{kj#!N|}kj+$)n z;%X`4Wh3LWxPFTaMtD&T&j!y|SM~cpSv7$;(}@`vNl2WyjPbhsF>q5A1pe>)RfQtm zZZ~zk&xB9iE2?<1{~K+mg)5V)#v*2r&P*phEl|1|lh!Mq_ovBV$LgA@#F~F4s~;LMYywe*N-a=238kvxnF_Q| z)-M9X4v23uMEFM{47Xas)+sBz*eBAZPx{9W5s95H9YZQ!ln_42Fu}hOVORlCi3MKX zVldKT#l2rP8Hg3gjK}yFMGDKLe(lz<2GkGq-EJyA-ENogf~9n4`f{4j>56TZnnAkV zajJoWf0DtlQ;QZBE0r#l;lmF+QS|Kxp0K>~j>IEBx3nbwn=S3~Tk!ri(D~ebJKPKSyY46VLeM*SobD(0B2a|K>3(w00Z}=qa#S($ zlS}2HZ?bzpO;jv;fk%}LNr9wt3Fw_5iX(|pxE@B~YFOgt|6{4ie>Yw)Pdou{OTD%w1>on*P=qk|FAbKZ1#a#)S;(l@ugRTbY@%sC|gwhKM zUj0i;UgD8|vsB9O2Pg)b14X%ihQCud`N_QwG!J?&=vt7(-^srKA{=4JPcD7yo-lg6 z{!a1NgKhxbNMA<3K4E^wVly9296n*`ZITgu5=3l7*MLrdD4gC;B%b(pOHJaNuUM>! zyiH4szZ8LYg6;y5pWHIg-Jlv!HTPF10-InwXVYRmd@sW81AQDs{hj>e(m0^L?gX9U zesVtsx*wDP5fAyveE{?c&?iB+a6h>>C+0UTZHc~DEv52f&eVNQ?0rLZr6dO^mPykj{M}3 z@HRjsSP~rk{i=r~xd|evl5~j(MBvjPiqpe45>G5zYJ4vs=zE|SIej1Q4>+BHOYtux zE^9@P@B6JKul5zZzsl*a;r@vHiNmv&ngcJv`x@wPLF9iKM9{zCesX^dB8(nS7(MJK z@c%vNr<~pgm&VjwBJeL3+sr?~`!mqbK?I?we*_U5y_26X6#om*FZnz92}AJ|_Bwwj zKM}?M3-|v^;#JfnaqBV5M7NBv{{;OPr+Ru1o35V>WE_sm(^nhMM&Qz57bM1FGfxJ%)d#H(j4w)ap}35eW$P#LHkL=f_m zTLG#BRe}B+Igp>+--D{*_rY!9esXIPhre57OFZ;lw4@dBbs!rjJ6vlb@Vvzl{R5yb zyt+Z;C-;ANmH^6sL#lVIhQtL6Jo53l_J9UL)%3K|d;Z#S51D#4`gH>*!k% z_)gHpAo8CNx&U+$_mg`mh%kCQVJ=PlZpl((c{jY5gRV&YZouN0*$?jl&?JbWt^n-= zy^Ft-pD+|Z1-gpAlb(ee9BEY|!e-sckM z-eR#e&BJ>oh;ky5Krs-7(|as&_!f(M<~DSo4})$*5V=R-9tACej&VP^$3Zk=%0PF4 z$WQJP!sDQ2P!9K#YX;o}IssZql&u%pWO|iB#UKm!lY0_GLyDk;AwRjLpqoLrfCxi= zaz6;V6|?}lf&0n*E6|5P9|nB}MI%4Cp9bA##>{X#0zSg&qj2v4-3dbER=6H^7sBoa zIYHzn*8#d7^a0R4+)wVkoXGz%?kD#YC-Q&XoJhWCsrG*y{`*1qaW}!;2jG5!`^ilt zluIqa#MK|PI0Fyk{R^Nka`#Jczs%otKe=B4JxXzjbKhmDkssu*UxiD4avuUwRwPT3 zBl*dtEFS}rTuF}PCzslRWKM1HHPGWAiqpgOFbdbhz7GF4%%;TGzi+YozJ(Ve3Vedo zQ#|ZxxZegnlQ0iM6{OcS&^l-p#P~b;Def82v)oUv0wRnaufIQ?ICt1$lWEuy(a3zB z(+hCF2cmEaBmZgsuKUS-5%hgf60`~W0e>g|OCaJQ4Ef3ZA&4+~Jl+e`fR_^2-wKWC zo0mbYd)K-p&-_}V>hCNytucU!B+f*P8=#+pD4gDZYX0!-pDdtaP|3Gv|5SR5MZSI^ zI;(9l%%(ikGhd21m8mH6*gf_+JM%dAd8|&W(>r5#IPFe5I~#CR|M|~sw^m; z-J_t!Bp=iprKehI7%Chwdp%B>WI_Bkh{ophz^l~=HQDrdJ@!r1!0NPlZB7?utwwsB zBu^9orS&)+-~tHM@_11#tDXxL$_jbf9LRy$z)h($a3V3SBwo9W8mdA^+W3Q)DrTiZ zc{L2ZGmqDX8Y6W|1`UBM9gqtO!KT6cePv)098Ro zSv)qaS|lel0br;LWP|#lu@tRbYARNHk_3mK)2K4#u231&IJ@FN77nTe3gWbpywO8! zkPq)|ND+MkVN?c96ilY>Yxh#+Jz6?m=K}Mxd2f4@x1D+0o!%xdTY+z(z0=#<-Z`sg zcGh9HOZ}br9q#OB^Q^O9>FgWs8}1xdmiqhp*|3IkHrQjyF=ifSW+p|=V+CUc2gc0F z0%nenMa+beUq9REXed~=6j&;mrP87l#40VUavm?`m6l4yQYq9kPQX#98#u+ILPIaLPMdPP|lD%n==%e&o||a=dk=KkcowIEIAsk$?cX( z^GmDZRi$ybCnifPic71Ql~rw&7FU((g|{w5tuc%R2eUft4r_8*a@f5NmqW%V0$5GU z8}lxBJ3QW`)azB+J6Nx`x1+bC9hB7aYH4nco|zi$AHwg(LX`C@qpY9D`Mk~H#RYRw z*gR$42%C%O!4@F*BJ;KcTU)%zB8e?lmQ=D5JWj{tvdUyxQDvE4&a-X4mPz;Qywc#b zxs%RHcLQ@Xr(3bPF__(2G1^*vQFkovZtZOKvsQO2Tk4E=vR3Br^s`QXYmZ;6&RKt} zFUF*vSPu&v8dQ3uvEbm?$l%yuFvQ3=KZxYyKffM|h4M~>p3lqA3$Z+9}csqO+}3oFRjxsoqm6`&aqMFVD+(PM>BJ5G&|zcaPg-h zx;p&L9n95{ob6zf9kC8yN1%fRSjQRJ#{r!ki_*+!pgS-hX9Gi{%FyV*=)lkb8x4%o zJFiktXXo^2{!)H!bc#(ZB=d94MeINkGv}JjxkW6$NK34zyDM&u#%GzWh}mXY2`j3$ zRa>i>)mB+nU1lq@R&R-0?(OMfi&N}GgR8;C8r-hpe z)vvTJv@W;$yIbYfKBe2=?Pr61thG91UYfNOZQ2m1TwHlz&)gnPP? z{&@Ice}8mJ^7*@%l#D8qfu2CuMxd*s&EFO1(n>WH><`3N0t=?u(70(}oDGZ&u#xdl zz(l@rHX;Wk4jdR@CV7TQFa{M$xuuJ_tgxc6f)!U3ma^PpQ*o|}t0-QmVDXA-rLLm7 zLaM8|km27ftw7Z%V7vl{*Iy}_Qx>Z??C5l) zM44U5D*lbznm4m(L5r)7ReQ zv%8!=ZB;z`mUF`K{Yv-p>~wekFzat0Xdmuv@9S+JV7*Jd49_x|6s2Jn8(v_;EO$6Q z98TsAhjYX6VQH9!CvxKxVJ*wIo_j7UU<>;Sm{h>Z3Rp=2t0t$cgcXz&C?#7nSoO+m zHLGRSwaMyQ)=*pBP`eSM*Qr`A%=6ECixO+uaJFntw#>>colPx@yNR`E^Ju3O?^}!p zTUapJ)7KV^276er53568ko9!-XhnJZ+uphuosKMpBIB`0C?_%$8Xp#ji5;s#M_H+t>ZRpWZVvSh^$zr& z9_Urbr^I`;$crz$fX#;gW-`qC_$BYSFc~d7eV}Z%tf)-hEGj4~fJfPyk}kRE9g8e# zJ0L@qfTDE3R_5FX9m8s?jzgQVR@PSPP$yeqvDwL`R%fTz+1WbX>TPwi&UO~X%HVGA zi`sZ0stgpYbr*p7#p@;SLu>KSM!A>T_(?<)zpI<+F**h;Di;pcIWOETL zu;xgJjhR+0zw4c`*|uc7O=it)Y_YjbX>Mz7OEyEud_BG5vP(PI zf`V0eZm5?{1z50S2>L?DP)A^h3-UdeT{b@?vzh$x{`^rkogW@Dg@;B>`7AsIAJhci zb@yF<*=%e&o{t5BRa6yKlvS{zGFHK?RTX9Oq*bY~>H4{5id9>AlLbS6cK!+6)gYyi%*T9dDhWL*1=f4G+BM3O1<>_7C=N(t~~( z9xOILIL4>3$$jr(@}x3m&SU00GxV~&*}Oq>Uep}RgSuwcmW8uZ`}ZA)u~|!HvZS)c zQn_fU+{mkBHI>PwN;Rh%=~(?-eS_3M%9xwg*SJ|jy%KjP8yekw^}XuKE9d=fvwn!U z+1=)s+Ip0>9)AyBd*q~FTb|AyJa8qGAmISCvHgLCSr!-y4Ti8tj|4_oXecl=qGlJu zfC;VS6h=eP!f?s~F&9pn@1Zk9>8 zMM`c_?gqM1QE^dm?lQEqid=|!YX^V!y7$eoiXyo>T3u3&)q4RdnyvbDta_!op_gTH1LhSuBeJjDK z5jNQuVY88uAXejuGAu>LB5Wiwto7ux3)jUWax6YS8&RYJs0|TIPKhPYBIQNOv8I)m z6lz`K?Df}OSFXg%Syj0dtFKwEYK&G*)k8t6DzC#It5VC_sKgtY)VR{ve9YsEwfQ`a zv1T9X623N1vqyzMv|WmiEp%-Lx&n(`y~#kABKHP*x$NwRg|-@>T{?QCvbKD=mX*u(tad}HZDjSe^Yxg|%IjH! z*1h73N7-y+3u|oIj7M9NZJrjTQE4O1O^aV%T%7Nby5e2ET|sDT(AbutKlB9KdV;-e z!LHy?P{ZAHe31=}%a~f(P>wP*9wKdRC?_-?VmWLa+fJ^poj87sN%^tj{DoqcUtCq3 z&#FqR@{3E0m3;WI)l`$KiZiK7s^s^_I<7~2DY42yfE36mK{^T${S+4@pihlD=%ad#=tYBv! z#-BN?43kHh4x5L^%zV|m<;3!o5?wB++$_M#tyDtIsI-(VmRSn6RgDj>$Tv+^F4Q{f zVYP_Esdd)6E1j&ilGQ4Uwa!XSPj*Z3Ik&%MuFbvRZfSM5xRurweK#?}OYkuAC=RQtVOSj;b=wDTjwxRB z+YWEr(GGUNI|nhdjrj#d^;@tL9n6QlWIQ~pwTV>E0YHHVX?aK4sh5tHWP(o9hqCc7eKrJ|^$ zx&r=6sCNu%hd%ynl8wo>6)1N$MRqR2ak`y~t-%JXQG+(~oxS6>54CR6roOXPaktL1 z*3)k2bgf!Goy!|hHZ|CTP5og13TO-q$VLz2lD_Nq+oEhNk4<7f&q8@gGs_F*nemqw zGKb9UgjSuqK5|c3cYI_~iuu}n*xR>tK(k=Y3mrY!=eKn{D|MU`h$B z3}90q7zjY82*_AH0tz3DSiXl}j_}%@yIY&O+gm5QTUmE&H%25@m!#Cqd(-{*-mOdxD*KlP*(9{M{=vDy(Ltqea00&y zSLhP=-ZLGKMJAT>B6$T9dFGNy$UFk|j;JJ$Ya$Pvy0@gJB+jNuqmXN2<YttUu&IDocb7>Cf%ZOLvkyP@UUiV`{8MBWL$~<#K%v?{YtYx*{n#hX69dlqS4jt zSGtm1!T8jDAD`Tajwk`BaQI~-Y#eXn2S=0vz65?szW=^xA;T$m9M8={HeQ%xDvTFm zd12F0ZOec5(~0|7tQdRH;?jz_imE!Obj5WQc!wcixuTj?a5KW*PM+TE^e51;+y1K9lxD+Ar~ z!2IyUz{CKf=kNp@m|(-PVJ_;2KKY61+4+Krf+SRp+=ASKiFiptQKYB<+fk*YKow#M zW=ZH4OVzd5ke1_#Z7AMXN@}aiOKP>wCZGM>r#}^E(H7Rw*ua`t0}KH4Y;2M6+Td?N znARen|IDZSEY{-hW3zGW`TP9IzPP_H*rnhlsGHnA|JhF`=SGsj5lnob5f&R!pmMMX z{&+f%eD*VvlA{zVIjk_5BSYB5g|VE%;{7W#RpoqF%BHK>e5@*2Q%Cv*ZA|N8RdsW! zM@yzL&Kf<@M!Toc4i8NI^D&PPzjlwS(WBd1zVx{Vr`lufU91-}U+}f}wqq5U?`7@1 z-M#IBUI|HI|Nr{gFFpLZf${i2I0|(GyZ+(uaB>{xfbsd^FdLR)d_noj=Re1$AnM|R za6EUJ6&I8hm(7>40$7HM3yKSp`t)}8(MKNMAC;6Ct7c`jWpR6LjM>oymDMo3vC3NK zmi5gkIprp2lanD@`-1poov;ch zoqQ#K?2BJW2FH@p*gWZXV|Xk^LSrm4rbNcL(7*PjFD&ef=P*me!g4IoL-3menwMcn zX5~2+tv6J~s#rbNoGDgcMZZ#g)q+y5G$O3FQPcCzKK_+2FV;7b9lWIt+f@$~5KmiU z+k6`wgdj}oFW-3dE0arYQtxap>lh05qC@n;L0crdXdA07Y zLkTNZ6=pqw(;b|iz>mWctyoWe?J+h_XAs`FGrrIyGjFmJd)R60WS#A;IA_pgKGmtj zI;CU%I9cc%obH6F8|Mszbl}j*XX$T!{cAA>4PT%nRDk0IM&}A_5)Z|q;Ap|3mRjw9Pe1W>*u-mVaE`$62XhgY7B+{EMtllpo5^!TrH}7SgJauV4z1pn6~*tLl2Rk6kIX zMoSgg4s@}fefC@5v?if`Sh2x!MO_XYHeju>Vv7awBSeJtJd1Fi1$g)=KWm`KG z$XxD-BS7i)Y8iIN=DYi2{oVcDI9b5b*ss9bpX|m-1J^>s#fFI$8;ri4Z5q`^{|N88tu%8in|vglT^*>|3qlq=&lOm{Z6Vr!^@ z%|NkLVpr>i-O0`MZT8*o#Icj@^t=7ijK8PV-Gi-dvmcHdHUykb__gXKSHClNaB-?< zL>U|!3(j z4`MevQ4}qj9G%D=#hJrIEFGr8s`mIXq2+*qLM9He=n)9 zXp;@{RT^w74O2E4$eUcONrv9n1kFUt^~Izz&El>8DSs;t7jWW`#HkLHk-qL$1(pOA z)F;IUH|P4;;7H#Ho~&;K>c|Mp3KN4ol^<+wOwU3EiAQjr10yr+2a!AlhYyjZ2n+`i zEw3M(*^JiA$~C3srR5Mb{t9bw?7(UY@vD>3?9AbB|W3DDj4Eq0HfB(f~e3}j= zI=eer`${(yKjmn9CsdU_*3C@{KYHo=ahQ__aWF9)=^GxzE*HW-#wPlpl_dGv9#Iw| zQY03E^&nEfND0I-1s>Sn&f{c4EBxR7@Fit__W9cB^4fA%E3@)s30$R|$G-d$TaH2r zX=&V`J#7P>NGSBWy~BO&l^@Pdx8TqL7HJ$pbhY`DZApKZf4Qwo(fUZROA2=3go62F z2R5z@TDqGmU=C diC^cJ%~juWWajvxYooKXM{k@lEx10DbX delta 363 zcmcbx!R$hhiCr!O1A_t(^8v985NGD4q*efF7${(5V7S1_zyPEeic5+z^U{l9QVb64 z6YZo}Z%8mOh)s+Yw^{(y4^+tjSds{q z-NbZ(brVN|=;R5q6_XX@6gCIQ1#wLO70E2tq|v6q*rvhMror5%!P2I|+NQzQrop~V qgM*`|y@Ho>dj&7o0k8HGSzJKO4a7X#Ph{~na8AE5oi~kX)hYn%b5iU8 diff --git a/content_skaterift/metascenes/intro.ms b/content_skaterift/metascenes/intro.ms index 553827b61266f23507fc2fb481811f9a79db34ea..34889773d788d2db1c1467aa1e120842d39a1920 100644 GIT binary patch literal 13240 zcmeHO3tUr2)*p}}A_xd5A_zV}#0MckMUvbb5Rv*SRq?I7L0U*K0nz$O>jP`8rCMFP zYD>{t8(M`BEnsp7-F{uVsEe+(T3d>>zPifVUAs~hv*+Yta?y47_v?Q9?eE*nFNbqy z=70Y)XYSl{&&<6z6GB2k{6T_1^5xk%%RpPx94A5=LEuMJ#mannp2}K90=g061Gxy0 zLRA`87g;MCpCJT(#M@j~tjx%I(OT#2N=RQIw4C>1&hlJkMq!Sr`am=xo^TXkJ};|8 zxirVxVw=$14-a!)zFbwDAk0lxp`+O|XZ1PyYGAT`98iTt_=aLNQLkDVT`)Ab9<~`KV z)_v5_#sk#A{o(Y^1u8{}JUc2&6_qb9Rw_n4H#2#{^ihhuJhUILBhFu(_m~!f;QT=` zLNd=%$XJrI^#F9X<)p5-5DNyYQ5r$cf;=f9AKqJ-igrm8`VGMcLu}y5OvM zY!_~IQ`-21c6ULIwcT-WY;AYQQ}|dj9VveTUxOWAq8(q%Q}`xZ_;x;l?}8m4`VNFN zf+Tj~>wq$=9nZtD6*sdB4yp)_3HmQgc#JXvGmuh*N(q*Bh>H`LYlwu@gIN1|tImq-V^zJ|>l|}o@K!u z*yckk1%>pl*|F3f*XL6?*K=SV9?nRy*?H#Xkv(}f;#DICyYq2$OInrwgk-<}BBZ#ekPNbs7 znS|C5*;%c*Tu@6$1xP5!-^U#~x!Z8?xF?-V_KNLs6K-qt^{OmsQ2iIuknq(kY3v~+ z!DDoAso^%V;>#eb&+BzRx*24_TK&aliyc#TK%2e5 z9$ULcV|M`|nQ#r#E$7R?);f?lUjKgG6ij~)&-@(Lr*>Cc9^e`QBM<@x+OXknlxrE+ZEs2Y#D%c~ejWk1oq!7fPCvv#-YlL; z|078~vZ_9CZZa)pLZJMJmZ%jl#-V_>;jYi`ri-2Vws!pt8QcG-2$r;L1uj`FQNO^$ ziNz}xhaH`;IUb}z%-ERa<? z@N0a(CadU8D}4g#U(-8zep0r)FDo3{%Dj5mopxS6%{cs;c@F-6@oPzoyy?Y{Lz&{$ zpK%8!p4Jk2;iBsszde-ZSf z1^WkfRDeA;JFXO^iPjA8pq=_;EyvCRTpeKAKrk+{;ZiU7(ARywThm40vq z*D2U;x|UQF@cdP4ZVz_T2~R5d{6lW6Ur)e=Lf>$$QpdyXTO2CuWiGA< z-JrfV+~cxZdpibrYq-JUgN9}05$w6O!&$QVib$O;0BpI%ezVQaL?&<|YJrp53EIQ5 z^VRC*=YgxyvK}$x6nhMk+pX?~Z;B<{!o@29*H}$jh5~K~^wBncz<-F4s2V3y2hRsA z$LC91G--5(KH6}1PkT_~DknBz-fnKVe_z1i^=bmq@o=XaZwa5fmd5nklB110wH$DF zp`Y(SyTyRD@%_1ZHnV?cqI6G)fbBUy8gLH3hU4S#YYxAL^PsE$bNDs0@3{V{zr zmaW0k>sw-Z`{-TY8|;|sNn3K6Qq?$(DUCN7_ z9*fsr=}s$$52v}GpX2eJZVh6xV&)mj0$0$E?60MB=7!PABbn6Y>U?}=KazeoH%fgj zC|K{5c72t{A?EycU)nr&K3lO8*P1q*=W`+SlxL=4Y0X4x_^KD!h;d6eJoC-_nl`Kp z+4AfM009&FS=rLs@@*=*n0y~1pCil1Ah}Q9(p`p zyA5$hN-ar$m)Gv3$N+XAdqDE+_A8uk3+@k9K;LkU$?tG^IMoSjW)Za7|>`B4wR z5#S32j44KaG=8$(XSmr9Zb?5>xKppvaZny9Bq?73AAejPkJkdVL~tB%jXXOv-(HZs zet!w`@t}SjsVMzzazxd!&zP2;u|+HM1TY<$UO9=hVW)3jbk zrm)vO=?AznY!5gwj<(^tGbz%&HK(KsFApx^Hpa0jfN>I?DRJVBU)g8B5%{OAgZBoD zYRu>3p2#HZpCxbRY^y#TcW2tmdiS&mH0r@1;QItH-Z&<_b`Ncg*S(Qvg0cKDz6Yu@*~X|sD2`}^Nc<@vSV zzSFoB+g+vk;mhcDg$LB3uOe`b@ja4l{y7r?T<>y-Bbuz&6L5|H5clu$Ycsb-uuk0q z4XZLUxWrD}Z-RX!St88mbvk=H3V%8(%J&!3T@ByXzR!&UoDA$r2V2lD*zA4fxX#e2 z_*UBEGcomvM?d+?{8~!pF2k&Tt0WJv1#&cLCGdg2kj=op@y6MOR8)5u*Wen|vJQ3l zHM}kkzxL0?YmVnzsAX)*~wkp9?q^b3;|q#kO<}gS17b?!xj-y_d?v?1D_559kja#o*@b|z~0Y!>+% z0oMX@4EkwncS6BcuB!j5%y+O~ai$I9Nj0_!eA*a$+=h|kwC;j;nLieu(cXMc1vnXS z;q`Un;cDJI!nAJnVE$AgGu%kTadG%H9LN7{zXtQglu}bq9>W9B@#d0WC!n5{I@P41 z+@!H=iPt?D;w?HJH6eh%I?Q0ggErwoBR=j|zmimGzB^{o@u=ay84^%yG?^xyntI5j z328`(HsN(9otjEb8hO(19W(J*bUbS0L5)19k;h!#kT5X*0IkyKOd5GGk38BLqZ_b4 z79Ecoc~Bz{YUDAOHzXXKjd-0&BM;`+ArU0}Y#Ki6*93uv1&%e14^Chj?e7Du@VsRD zu2o%h8Q=Gl`1M!_Y2jd}@i>Oq?-M(4YzTR+{mXddt$4zB*;o(zWsk1MDPO1Y?<*r3 e-(34ff>q2I(_c0A!^6c~Vx}|s2|I|*j=ur>V~vXd literal 13320 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 diff --git a/content_skaterift/models/rs_tape.mdl b/content_skaterift/models/rs_tape.mdl new file mode 100644 index 0000000000000000000000000000000000000000..d0214fe74f013a0b8b9dbb2d93e312ed3efb1a53 GIT binary patch literal 37256 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 literal 0 HcmV?d00001 diff --git a/skaterift_blender/sr_main.py b/skaterift_blender/sr_main.py index 87fee3f..b76873d 100644 --- a/skaterift_blender/sr_main.py +++ b/skaterift_blender/sr_main.py @@ -1938,6 +1938,7 @@ class SR_OBJECT_ENT_CHALLENGE(bpy.types.PropertyGroup):#{ reset_event: bpy.props.IntProperty( name="Event/Method" ) time_limit: bpy.props.BoolProperty( name="Time Limit" ) + is_story: bpy.props.BoolProperty( name="Is story event" ) first: bpy.props.PointerProperty( \ type=bpy.types.Object, name="First Objective", \ @@ -1954,6 +1955,7 @@ class SR_OBJECT_ENT_CHALLENGE(bpy.types.PropertyGroup):#{ layout.prop( data[0], 'camera' ) layout.prop( data[0], 'first' ) layout.prop( data[0], 'time_limit' ) + layout.prop( data[0], 'is_story' ) SR_OBJECT_ENT_VOLUME.inspect_target( layout, data, 'target' ) SR_OBJECT_ENT_VOLUME.inspect_target( layout, data, 'reset' ) #} diff --git a/skaterift_blender/sr_mdl.py b/skaterift_blender/sr_mdl.py index 9ef0740..d67e595 100644 --- a/skaterift_blender/sr_mdl.py +++ b/skaterift_blender/sr_mdl.py @@ -848,6 +848,7 @@ def _mdl_compiler_compile_entities(): challenge.flags = 0x00 challenge.camera = sr_entity_id( obj_data.camera ) if obj_data.time_limit: challenge.flags |= 0x01 + if obj_data.is_story: challenge.flags |= 0x02 challenge.status = 0 sr_ent_push( challenge ) #} diff --git a/src/addon.c b/src/addon.c index 671d7d4..11fe3ed 100644 --- a/src/addon.c +++ b/src/addon.c @@ -81,19 +81,22 @@ u32 addon_match( addon_alias *alias ) foldername_djb2 = vg_strdjb2( alias->foldername ); u32 count = 0; - for( u32 i=0; counttype]; i++ ){ + for( u32 i=0; counttype]; i++ ) + { addon_reg *reg = &addon_system.registry[i]; - if( reg->alias.type == alias->type ){ - - if( alias->workshop_id ){ + if( reg->alias.type == alias->type ) + { + if( alias->workshop_id ) + { if( alias->workshop_id == reg->alias.workshop_id ) return count; } - else{ - if( reg->foldername_hash == foldername_djb2 ){ - if( !strcmp( reg->alias.foldername, alias->foldername ) ){ + else + { + if( reg->foldername_hash == foldername_djb2 ) + { + if( !strcmp( reg->alias.foldername, alias->foldername ) ) return count; - } } } @@ -109,11 +112,13 @@ u32 addon_match( addon_alias *alias ) */ void addon_alias_uid( addon_alias *alias, char buf[ADDON_UID_MAX] ) { - if( alias->workshop_id ){ + if( alias->workshop_id ) + { snprintf( buf, 128, "sr%03d-steam-"PRINTF_U64, alias->type, alias->workshop_id ); } - else { + else + { snprintf( buf, 128, "sr%03d-local-%s", alias->type, alias->foldername ); } @@ -853,16 +858,17 @@ u16 addon_cache_create_viewer( enum addon_type type, u16 reg_id ) vg_pool *pool = &cache->pool; u16 cache_id = addon_cache_fetch( type, reg_id ); - if( !cache_id ){ + if( !cache_id ) + { cache_id = addon_cache_alloc( type, reg_id ); - if( cache_id ){ + if( cache_id ) + { SDL_AtomicLock( &addon_system.sl_cache_using_resources ); addon_cache_entry *entry = vg_pool_item( pool, cache_id ); - if( entry->state == k_addon_cache_state_loaded ){ + if( entry->state == k_addon_cache_state_loaded ) addon_cache_free_item( type, cache_id ); - } entry->state = k_addon_cache_state_load_request; SDL_AtomicUnlock( &addon_system.sl_cache_using_resources ); diff --git a/src/array_file.c b/src/array_file.c index 676bcd2..9bdb590 100644 --- a/src/array_file.c +++ b/src/array_file.c @@ -87,6 +87,9 @@ void af_load_array_file( array_file_context *ctx, array_file_ptr *out_ptr, void *af_arritm( array_file_ptr *arr, u32 index ) { + if( index >= arr->count ) + vg_fatal_error( "Index out of range (%u >= %u)\n", index, arr->count ); + return ((u8 *)arr->data) + index*arr->stride; } diff --git a/src/client.c b/src/client.c index 6b2b119..0896d89 100644 --- a/src/client.c +++ b/src/client.c @@ -14,12 +14,13 @@ const char* __asan_default_options() { return "detect_leaks=0"; } struct game_client g_client = { - .demo_mode = 1 + .demo_mode = 1, + .unreadyness = 2 /* once for client, once for world switcher */ }; static void async_client_ready( void *payload, u32 size ) { - g_client.loaded = 1; + g_client.unreadyness --; if( network_client.auto_connect ) network_client.user_intent = k_server_intent_online; diff --git a/src/client.h b/src/client.h index d3f3608..5b0b24a 100644 --- a/src/client.h +++ b/src/client.h @@ -9,7 +9,8 @@ struct game_client { - bool loaded, demo_mode, nosteam; + bool demo_mode, nosteam; + u32 unreadyness; } extern g_client; diff --git a/src/ent_challenge.c b/src/ent_challenge.c index 3e5c317..6181adf 100644 --- a/src/ent_challenge.c +++ b/src/ent_challenge.c @@ -26,10 +26,34 @@ entity_call_result ent_challenge_call( world_instance *world, ent_call *call ) } else if( call->function == 1 ) /* view() */ { + if( localplayer.subsystem == k_player_subsystem_walk ) + { + if( world_set_event( k_world_event_challenge ) ) + { + _world.active_challenge = challenge; + gui_helper_reset( 1 ); + vg_str text; + if( gui_new_helper( input_button_list[k_srbind_maccept], &text )) + vg_strcat( &text, "Start" ); + } + } + + return k_entity_call_result_OK; + } + else if( call->function == -1 ) /* unview() */ + { + if( world_clear_event( k_world_event_challenge ) ) + { + _world.active_challenge = NULL; + gui_helper_reset( k_gui_helper_mode_clear ); + } + return k_entity_call_result_OK; + +#if 0 if( (localplayer.subsystem == k_player_subsystem_walk) && - (world_static.challenge_target == NULL) ) + (_world.challenge_target == NULL) ) { - world_static.challenge_target = NULL; + _world.challenge_target = NULL; world_entity_set_focus( call->id ); world_entity_focus_modal(); @@ -41,11 +65,13 @@ entity_call_result ent_challenge_call( world_instance *world, ent_call *call ) vg_strcat( &text, "Exit" ); } return k_entity_call_result_OK; +#endif } else return k_entity_call_result_unhandled; } +#if 0 void ent_challenge_preupdate( ent_focus_context *ctx ) { world_instance *world = ctx->world; @@ -72,8 +98,8 @@ void ent_challenge_preupdate( ent_focus_context *ctx ) f32 max_dist = 100.0f; if( min_dist2 > max_dist*max_dist ){ - world_static.challenge_target = NULL; - world_static.challenge_timer = 0.0f; + _world.challenge_target = NULL; + _world.challenge_timer = 0.0f; world_entity_clear_focus(); audio_lock(); audio_oneshot_3d( &audio_challenge[6], localplayer.rb.co, @@ -85,12 +111,14 @@ void ent_challenge_preupdate( ent_focus_context *ctx ) world_entity_focus_camera( world, challenge->camera ); - if( mdl_entity_id_type( challenge->first ) == k_ent_objective ){ - if( button_down( k_srbind_maccept ) ){ + if( mdl_entity_id_type( challenge->first ) == k_ent_objective ) + { + if( button_down( k_srbind_maccept ) ) + { u32 index = mdl_entity_id_id( challenge->first ); - world_static.challenge_target = af_arritm( &world->ent_objective, + _world.challenge_target = af_arritm( &world->ent_objective, index ); - world_static.challenge_timer = 0.0f; + _world.challenge_timer = 0.0f; world_entity_exit_modal(); gui_helper_clear(); @@ -108,10 +136,21 @@ void ent_challenge_preupdate( ent_focus_context *ctx ) return; } } + else + { + if( button_down( k_srbind_maccept ) ) + { + ent_call call; + call.data = NULL; + call.function = challenge->target_event; + call.id = challenge->target; + entity_call( world, &call ); + } + } if( button_down( k_srbind_mback ) ) { - world_static.challenge_target = NULL; + _world.challenge_target = NULL; world_entity_exit_modal(); world_entity_clear_focus(); gui_helper_clear(); @@ -125,3 +164,4 @@ void ent_challenge_preupdate( ent_focus_context *ctx ) static void ent_challenge_render( ent_challenge *challenge ){ } +#endif diff --git a/src/ent_challenge.h b/src/ent_challenge.h index f53c956..73641bd 100644 --- a/src/ent_challenge.h +++ b/src/ent_challenge.h @@ -1,5 +1,4 @@ #pragma once #include "entity.h" -void ent_challenge_preupdate( ent_focus_context *ctx ); entity_call_result ent_challenge_call( world_instance *world, ent_call *call ); diff --git a/src/ent_miniworld.c b/src/ent_miniworld.c index f83c037..0342926 100644 --- a/src/ent_miniworld.c +++ b/src/ent_miniworld.c @@ -11,10 +11,11 @@ struct global_miniworld global_miniworld; entity_call_result ent_miniworld_call( world_instance *world, ent_call *call ) { +#if 0 ent_miniworld *miniworld = af_arritm( &world->ent_miniworld, mdl_entity_id_id(call->id) ); - int world_id = world - world_static.instances; + int world_id = world - _world.instances; if( call->function == 0 ) /* zone() */ { @@ -24,7 +25,7 @@ entity_call_result ent_miniworld_call( world_instance *world, ent_call *call ) mdl_transform_m4x3( &miniworld->transform, global_miniworld.mmdl ); global_miniworld.active = miniworld; - gui_helper_clear(); + gui_helper_reset( k_gui_helper_mode_black_bars ); vg_str text; if( gui_new_helper( input_button_list[k_srbind_miniworld_resume], &text )) @@ -35,7 +36,7 @@ entity_call_result ent_miniworld_call( world_instance *world, ent_call *call ) else if( call->function == 1 ) { global_miniworld.active = NULL; - gui_helper_clear(); + gui_helper_reset( k_gui_helper_mode_clear ); if( miniworld->proxy ) { @@ -47,12 +48,14 @@ entity_call_result ent_miniworld_call( world_instance *world, ent_call *call ) return k_entity_call_result_OK; } else +#endif return k_entity_call_result_unhandled; } static void miniworld_icon( vg_camera *cam, enum gui_icon icon, v3f pos, f32 size) { +#if 0 m4x3f mmdl; v3_copy( cam->transform[2], mmdl[2] ); mmdl[2][1] = 0.0f; @@ -72,11 +75,13 @@ static void miniworld_icon( vg_camera *cam, enum gui_icon icon, mdl_submesh *sm = gui.icons[ icon ]; if( sm ) mdl_draw_submesh( sm ); +#endif } void ent_miniworld_render( world_instance *host_world, vg_camera *cam ) { - if( host_world != &world_static.instances[k_world_purpose_hub] ) +#if 0 + if( host_world != &_world.instances[k_world_purpose_hub] ) return; ent_miniworld *miniworld = global_miniworld.active; @@ -84,7 +89,7 @@ void ent_miniworld_render( world_instance *host_world, vg_camera *cam ) if( !miniworld ) return; - world_instance *dest_world = &world_static.instances[k_world_purpose_client]; + world_instance *dest_world = &_world.instances[k_world_purpose_client]; int rendering = 1; if( dest_world->status != k_world_status_loaded ) @@ -153,18 +158,20 @@ void ent_miniworld_render( world_instance *host_world, vg_camera *cam ) shader_model_font_uColour( colour ); miniworld_icon( cam, k_gui_icon_rift_run, route->board_transform[3],1.0f); } +#endif } void ent_miniworld_preupdate(void) { +#if 0 world_instance *hub = world_current_instance(), - *dest = &world_static.instances[k_world_purpose_client]; + *dest = &_world.instances[k_world_purpose_client]; ent_miniworld *miniworld = global_miniworld.active; if( (localplayer.subsystem != k_player_subsystem_walk) || (global_miniworld.transition) || - (world_static.active_instance != k_world_purpose_hub) || + (_world.active_instance != k_world_purpose_hub) || (!miniworld) || (dest->status != k_world_status_loaded) || (skaterift.activity != k_skaterift_default)) { @@ -175,7 +182,7 @@ void ent_miniworld_preupdate(void) { if( skaterift.demo_mode ) { - if( world_static.instance_addons[1]->flags & ADDON_REG_PREMIUM ) + if( _world.instance_addons[1]->flags & ADDON_REG_PREMIUM ) { menu_open( k_menu_page_premium ); return; @@ -189,15 +196,17 @@ void ent_miniworld_preupdate(void) world_switch_instance(1); srinput.state = k_input_state_resume; menu.disable_open = 0; - gui_helper_clear(); + gui_helper_reset( k_gui_helper_mode_clear ); audio_lock(); audio_oneshot( &audio_ui[2], 1.0f, 0.0f ); audio_unlock(); } +#endif } void ent_miniworld_goback(void) { +#if 0 audio_lock(); audio_oneshot( &audio_ui[2], 1.0f, 0.0f ); audio_unlock(); @@ -208,4 +217,5 @@ void ent_miniworld_goback(void) global_miniworld.cam = g_render.cam; vg_m4x3_transform_camera( global_miniworld.mmdl, &global_miniworld.cam ); world_switch_instance(0); +#endif } diff --git a/src/ent_npc.c b/src/ent_npc.c deleted file mode 100644 index 2fe394c..0000000 --- a/src/ent_npc.c +++ /dev/null @@ -1,317 +0,0 @@ -#include "vg/vg_mem.h" -#include "ent_npc.h" -#include "shaders/model_character_view.h" -#include "input.h" -#include "player.h" -#include "gui.h" - -struct npc npc_gumpa, npc_slowmo, npc_volc_flight; -static struct skeleton_anim gumpa_idle; -static struct skeleton_anim slowmo_momentum, slowmo_slide, slowmo_rewind, - anim_tutorial_cam; -static float slowmo_opacity = 0.0f; -static f64 volc_start_preview = 0.0; - -void npc_load_model( struct npc *npc, const char *path ) -{ - vg_linear_clear( vg_mem.scratch ); - - mdl_context *meta = &npc->meta; - mdl_open( meta, path, vg_mem.rtmemory ); - mdl_load_metadata_block( meta, vg_mem.rtmemory ); - - struct skeleton *sk = &npc->skeleton; - skeleton_setup( sk, meta, 0, vg_mem.rtmemory ); - - u32 mtx_size = sizeof(m4x3f)*sk->bone_count; - npc->final_mtx = vg_linear_alloc( vg_mem.rtmemory, mtx_size ); - - if( meta->texture_count ) - { - mdl_texture *tex0 = &meta->textures[ 0 ]; - void *data = vg_linear_alloc( vg_mem.scratch, tex0->file.pack_size ); - mdl_fread_pack_file( meta, &tex0->file, data ); - - vg_tex2d_load_qoi_async( data, tex0->file.pack_size, - VG_TEX2D_NEAREST|VG_TEX2D_CLAMP, - &npc->texture ); - } - else - { - npc->texture = vg.tex_missing; - } - - mdl_async_load_glmesh( meta, &npc->mesh, NULL ); - mdl_close( meta ); -} - -void npc_init(void) -{ -#if 0 - npc_load_model( &npc_gumpa, "models/gumpa.mdl" ); - gumpa_idle = skeleton_get_anim( &npc_gumpa.skeleton, "gumpa_idle" ); - - npc_load_model( &npc_slowmo, "models/slowmos.mdl" ); - slowmo_momentum = - skeleton_get_anim( &npc_slowmo.skeleton, "slowmo_momentum" ); - slowmo_slide = skeleton_get_anim( &npc_slowmo.skeleton, "slowmo_slide" ); - slowmo_rewind = skeleton_get_anim( &npc_slowmo.skeleton, "slowmo_rewind" ); - - npc_load_model( &npc_volc_flight, "models/volc_flight.mdl" ); - anim_tutorial_cam = - skeleton_get_anim( &npc_volc_flight.skeleton, "tutorial" ); -#endif -} - -static struct npc *npc_resolve( u32 id ) -{ - if( id == 1 ) return &npc_gumpa; - else if( id == 2 ) return &npc_slowmo; - else if( id == 3 ) return &npc_volc_flight; - else return NULL; -} - -static entity_call_result npc_slowmo_call( ent_npc *npc, ent_call *call ) -{ - return 0; - - if( call->function == 0 ) - { - gui_helper_clear(); - vg_str text; - - if( npc->context == 2 ) - { - if( gui_new_helper( input_axis_list[k_sraxis_grab], &text )) - vg_strcat( &text, "Crouch (store energy)" ); - if( gui_new_helper( input_joy_list[k_srjoystick_steer], &text )) - vg_strcat( &text, "Slide" ); - } - else if( npc->context == 1 ) - { - if( gui_new_helper( input_axis_list[k_sraxis_grab], &text )) - vg_strcat( &text, "Crouch (store energy)" ); - } - else if( npc->context == 3 ) - { - if( gui_new_helper( input_button_list[k_srbind_reset], &text )) - vg_strcat( &text, "Rewind time" ); - if( gui_new_helper( input_button_list[k_srbind_replay_resume], &text )) - vg_strcat( &text, "Resume" ); - } - return k_entity_call_result_OK; - } - else if( call->function == -1 ) - { - world_entity_clear_focus(); - gui_helper_clear(); - return k_entity_call_result_OK; - } - else - return k_entity_call_result_unhandled; -} - -entity_call_result ent_npc_call( world_instance *world, ent_call *call ) -{ - return 0; - - u32 index = mdl_entity_id_id( call->id ); - ent_npc *npc = af_arritm( &world->ent_npc, index ); - - if( npc->id == 2 ) - { - return npc_slowmo_call( npc, call ); - } - else if( npc->id == 3 ) - { - if( call->function == 0 ) - { - world_entity_set_focus( call->id ); - gui_helper_clear(); - vg_str text; - if( gui_new_helper( input_button_list[k_srbind_maccept], &text )) - vg_strcat( &text, "Preview course" ); - return k_entity_call_result_OK; - } - else if( call->function == -1 ) - { - world_entity_clear_focus(); - gui_helper_clear(); - return k_entity_call_result_OK; - } - else - return k_entity_call_result_unhandled; - } - else if( npc->id == 4 ) - { - if( call->function == 0 ) - { - gui_helper_clear(); - vg_str text; - if( gui_new_helper( input_button_list[k_srbind_camera], &text )) - vg_strcat( &text, "First/Thirdperson" ); - return k_entity_call_result_OK; - } - else if( call->function == -1 ) - { - gui_helper_clear(); - return k_entity_call_result_OK; - } - else - return k_entity_call_result_unhandled; - } - else - { - if( call->function == 0 ) - { - world_entity_set_focus( call->id ); - gui_helper_clear(); - vg_str text; - if( gui_new_helper( input_button_list[k_srbind_maccept], &text )) - vg_strcat( &text, "Talk to ???" ); - return k_entity_call_result_OK; - } - else if( call->function == -1 ) - { - world_entity_clear_focus(); - gui_helper_clear(); - return k_entity_call_result_OK; - } - else - return k_entity_call_result_unhandled; - } -} - -void ent_npc_preupdate( ent_focus_context *ctx ) -{ - return; - - world_instance *world = ctx->world; - ent_npc *ent = af_arritm( &world->ent_npc, ctx->index ); - - if( !ctx->active ) - { - if( button_down(k_srbind_maccept) ) - { - world_entity_focus_modal(); - gui_helper_clear(); - vg_str text; - if( gui_new_helper( input_button_list[k_srbind_mback], &text )) - vg_strcat( &text, "leave" ); - - volc_start_preview = vg.time; - } - - return; - } - - if( ent->id == 3 ) - { - player_pose pose; - struct skeleton *sk = &npc_volc_flight.skeleton; - - f64 t = (vg.time - volc_start_preview) * 0.5; - skeleton_sample_anim_clamped( sk, &anim_tutorial_cam, t, pose.keyframes ); - -#if 0 - ent_camera *cam = af_arritm( &world->ent_camera, - mdl_entity_id_id(ent->camera) ); - v3_copy( pose.keyframes[0].co, cam->co ); - - v4f qp; - q_axis_angle( qp, (v3f){1,0,0}, VG_TAUf*0.25f ); - q_mul( pose.keyframes[0].q, qp, cam->transform.q ); - q_normalize( cam->transform.q ); - - v3_add( ent->transform.co, cam->transform.co, cam->transform.co ); -#endif - } - - world_entity_focus_camera( world, ent->camera ); - - if( button_down( k_srbind_mback ) ) - { - world_entity_exit_modal(); - world_entity_clear_focus(); - gui_helper_clear(); - } -} - -void npc_update( ent_npc *ent ) -{ - return; - - if( ent->id == 3 ) return; - if( ent->id == 4 ) return; - - struct npc *npc_def = npc_resolve( ent->id ); - VG_ASSERT( npc_def ); - - player_pose pose; - struct skeleton *sk = &npc_def->skeleton; - pose.type = k_player_pose_type_ik; - pose.board.lean = 0.0f; - - if( ent->id == 1 ) - { - skeleton_sample_anim( sk, &gumpa_idle, vg.time, pose.keyframes ); - } - else if( ent->id == 2 ) - { - struct skeleton_anim *anim = NULL; - if( ent->context == 1 ) anim = &slowmo_momentum; - else if( ent->context == 2 ) anim = &slowmo_slide; - else if( ent->context == 3 ) anim = &slowmo_rewind; - - VG_ASSERT( anim ); - - f32 t = vg.time*0.5f, - animtime = fmodf( t*anim->framerate, anim->strip->length ), - lt = animtime / (f32)anim->strip->length; - skeleton_sample_anim( sk, anim, t, pose.keyframes ); - slowmo_opacity = vg_clampf(fabsf(lt-0.5f)*9.0f-3.0f,0,1); - } - - v3_copy( ent->transform.co, pose.root_co ); - v4_copy( ent->transform.q, pose.root_q ); - apply_full_skeleton_pose( &npc_def->skeleton, &pose, npc_def->final_mtx ); -} - -void npc_render( ent_npc *ent, world_instance *world, vg_camera *cam ) -{ - return; - - if( ent->id == 3 ) return; - if( ent->id == 4 ) return; - - struct npc *npc_def = npc_resolve( ent->id ); - VG_ASSERT( npc_def ); - - shader_model_character_view_use(); - - glActiveTexture( GL_TEXTURE0 ); - glBindTexture( GL_TEXTURE_2D, npc_def->texture ); - shader_model_character_view_uTexMain( 0 ); - shader_model_character_view_uCamera( cam->transform[3] ); - shader_model_character_view_uPv( cam->mtx.pv ); - - if( ent->id == 2 ) - { - shader_model_character_view_uDepthMode( 2 ); - shader_model_character_view_uDitherCutoff( slowmo_opacity ); - } - else - { - shader_model_character_view_uDepthMode( 0 ); - } - - WORLD_BIND_LIGHT_BUFFERS_UB0_TEX234( world, model_character_view ); - - glUniformMatrix4x3fv( _uniform_model_character_view_uTransforms, - npc_def->skeleton.bone_count, - 0, - (const GLfloat *)npc_def->final_mtx ); - - mesh_bind( &npc_def->mesh ); - mesh_draw( &npc_def->mesh ); -} diff --git a/src/ent_npc.h b/src/ent_npc.h deleted file mode 100644 index c20cc97..0000000 --- a/src/ent_npc.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once -#include "player_render.h" -#include "entity.h" - -struct npc -{ - glmesh mesh; - GLuint texture; - - mdl_context meta; - struct skeleton skeleton; - - m4x3f *final_mtx; -} -extern npc_gumpa; - -enum npc_id -{ - k_npc_id_none = 0, - k_npc_id_gumpa = 1 -}; - -void npc_load_model( struct npc *npc, const char *path ); -void ent_npc_preupdate( ent_focus_context *context ); -entity_call_result ent_npc_call( world_instance *world, ent_call *call ); -void npc_update( ent_npc *ent ); -void npc_render( ent_npc *ent, world_instance *world, vg_camera *cam ); -void npc_init(void); diff --git a/src/ent_objective.c b/src/ent_objective.c index 1e43e87..886329c 100644 --- a/src/ent_objective.c +++ b/src/ent_objective.c @@ -9,12 +9,11 @@ static void ent_objective_pass( world_instance *world, ent_objective *objective ){ - if( objective->id_next ){ - world_static.challenge_timer += objective->filter; - + if( objective->id_next ) + { u32 index = mdl_entity_id_id( objective->id_next ); ent_objective *next = af_arritm( &world->ent_objective, index ); - world_static.challenge_target = next; + _world.challenge_target = next; objective->flags |= k_ent_objective_passed; if( next->filter & k_ent_objective_filter_passthrough ) @@ -32,9 +31,8 @@ static void ent_objective_pass( world_instance *world, audio_lock(); audio_oneshot( &audio_challenge[2], 1.0f, 0.0f ); audio_unlock(); - world_static.challenge_target = NULL; - world_static.challenge_timer = 0.0f; - world_static.focused_entity = 0; + _world.challenge_target = NULL; + //_world.focused_entity = 0; if( objective->id_win ){ ent_call call; @@ -93,9 +91,9 @@ entity_call_result ent_objective_call( world_instance *world, ent_call *call ) return k_entity_call_result_OK; } - if( world_static.challenge_target ) + if( _world.challenge_target ) { - if( (world_static.challenge_target == objective) && + if( (_world.challenge_target == objective) && ent_objective_check_filter( objective )){ ent_objective_pass( world, objective ); } @@ -106,9 +104,8 @@ entity_call_result ent_objective_call( world_instance *world, ent_call *call ) 30.0f, 1.0f ); audio_unlock(); vg_error( "challenge failed\n" ); - world_static.challenge_target = NULL; - world_static.challenge_timer = 0.0f; - world_static.focused_entity = 0; + _world.challenge_target = NULL; + //_world.focused_entity = 0; } } diff --git a/src/ent_region.c b/src/ent_region.c index 4f4e27b..4a64020 100644 --- a/src/ent_region.c +++ b/src/ent_region.c @@ -144,21 +144,23 @@ void ent_region_re_eval( world_instance *world ) } } - u32 instance_id = world - world_static.instances; - - if( world_static.instance_addons[instance_id]->flags & ADDON_REG_MTZERO ){ - if( world_total & k_ent_route_flag_achieve_gold ){ + if( _world.main.addon->flags & ADDON_REG_MTZERO ) + { + if( world_total & k_ent_route_flag_achieve_gold ) + { steam_set_achievement( "MTZERO_GOLD" ); steam_store_achievements(); } - if( world_total & k_ent_route_flag_achieve_silver ){ + if( world_total & k_ent_route_flag_achieve_silver ) + { steam_set_achievement( "MTZERO_SILVER" ); steam_store_achievements(); } } - if( world_static.instance_addons[instance_id]->flags & ADDON_REG_CITY ){ + if( _world.main.addon->flags & ADDON_REG_CITY ) + { steam_set_achievement( "CITY_COMPLETE" ); steam_store_achievements(); } diff --git a/src/ent_route.c b/src/ent_route.c index 141adbd..5ba4544 100644 --- a/src/ent_route.c +++ b/src/ent_route.c @@ -13,6 +13,7 @@ entity_call_result ent_route_call( world_instance *world, ent_call *call ) { /* view() */ if( localplayer.subsystem == k_player_subsystem_walk ) { +#if 0 world_entity_set_focus( call->id ); world_entity_focus_modal(); @@ -29,6 +30,7 @@ entity_call_result ent_route_call( world_instance *world, ent_call *call ) if( gui_new_helper( input_button_list[k_srbind_mback], &text ) ) vg_strcat( &text, "Exit" ); +#endif } return k_entity_call_result_OK; @@ -50,7 +52,7 @@ void ent_route_preupdate( ent_focus_context *ctx ) if( __builtin_expect( world->meta.version >= 103, 1 ) ) cam_id = route->id_camera; - world_entity_focus_camera( world, cam_id ); + //world_entity_focus_camera( world, cam_id ); if( button_down( k_srbind_mleft ) ){ world_sfd.view_weekly = 1; @@ -67,9 +69,9 @@ void ent_route_preupdate( ent_focus_context *ctx ) if( button_down( k_srbind_mback ) ) { - world_entity_exit_modal(); - world_entity_clear_focus(); - gui_helper_clear(); + //world_entity_exit_modal(); + //world_entity_clear_focus(); + gui_helper_reset( k_gui_helper_mode_clear ); return; } } diff --git a/src/ent_skateshop.c b/src/ent_skateshop.c index e75af5f..0de8a03 100644 --- a/src/ent_skateshop.c +++ b/src/ent_skateshop.c @@ -220,7 +220,10 @@ void ent_skateshop_preupdate( ent_focus_context *ctx ) /* camera positioning */ ent_camera *ref = af_arritm( &world->ent_camera, mdl_entity_id_id(shop->id_camera) ); + +#if 0 v3_copy( ref->r, world_static.focus_cam.angles ); +#endif v3f lookat; if( shop->type == k_skateshop_type_boardshop || @@ -244,8 +247,10 @@ void ent_skateshop_preupdate( ent_focus_context *ctx ) q_axis_angle( localplayer.rb.q, (v3f){0.0f,1.0f,0.0f}, atan2f(lookat[0],lookat[2]) ); +#if 0 v3_copy( ref->co, world_static.focus_cam.pos ); world_static.focus_cam.fov = ref->fov; +#endif /* input */ if( shop->type == k_skateshop_type_boardshop ){ @@ -287,10 +292,9 @@ void ent_skateshop_preupdate( ent_focus_context *ctx ) localplayer.board_view_slot = cache_id; network_send_item( k_netmsg_playeritem_board ); - world_entity_exit_modal(); - world_entity_clear_focus(); - gui_helper_clear(); - skaterift_autosave(1); + //world_entity_exit_modal(); + //world_entity_clear_focus(); + gui_helper_reset( k_gui_helper_mode_clear ); return; } } @@ -335,12 +339,14 @@ void ent_skateshop_preupdate( ent_focus_context *ctx ) if( button_down( k_srbind_maccept ) ){ network_send_item( k_netmsg_playeritem_player ); - world_entity_exit_modal(); - world_entity_clear_focus(); - gui_helper_clear(); + //world_entity_exit_modal(); + //world_entity_clear_focus(); + gui_helper_reset( k_gui_helper_mode_clear ); } } - else if( shop->type == k_skateshop_type_worldshop ){ + else if( shop->type == k_skateshop_type_worldshop ) + { +#if 0 int browseable = 0, loadable = 0; @@ -383,11 +389,14 @@ void ent_skateshop_preupdate( ent_focus_context *ctx ) } } - if( loadable ){ - if( button_down( k_srbind_maccept ) ){ - skaterift_change_world_start( selected_world ); + if( loadable ) + { + if( button_down( k_srbind_maccept ) ) + { + skaterift_switch_world_start( selected_world ); } } +#endif } else if( shop->type == k_skateshop_type_server ){ f64 delta = vg.time_real - network_client.last_intent_change; @@ -414,19 +423,24 @@ void ent_skateshop_preupdate( ent_focus_context *ctx ) if( shop->type == k_skateshop_type_charshop ) network_send_item( k_netmsg_playeritem_player ); +#if 0 world_entity_exit_modal(); world_entity_clear_focus(); - gui_helper_clear(); +#endif + gui_helper_reset( k_gui_helper_mode_clear ); return; } } -void skateshop_world_preupdate( world_instance *world ) +void skateshop_world_preupdate(void) { - for( u32 i=0; ient_skateshop); i++ ){ + world_instance *world = &_world.main; + for( u32 i=0; ient_skateshop); i++ ) + { ent_skateshop *shop = af_arritm( &world->ent_skateshop, i ); - if( shop->type == k_skateshop_type_server ){ + if( shop->type == k_skateshop_type_server ) + { f32 a = network_client.user_intent; vg_slewf( &network_client.fintent, a, vg.time_frame_delta ); @@ -441,8 +455,9 @@ void skateshop_world_preupdate( world_instance *world ) } } -static void skateshop_render_boardshop( ent_skateshop *shop ){ - world_instance *world = world_current_instance(); +static void skateshop_render_boardshop( ent_skateshop *shop ) +{ + world_instance *world = &_world.main; u32 slot_count = VG_ARRAY_LEN(global_skateshop.shop_view_slots); ent_marker *mark_rack = af_arritm( &world->ent_marker, @@ -597,7 +612,7 @@ static void skateshop_render_charshop( ent_skateshop *shop ){ } static void skateshop_render_worldshop( ent_skateshop *shop ){ - world_instance *world = world_current_instance(); + world_instance *world = &_world.main; ent_marker *mark_display = af_arritm( &world->ent_marker, mdl_entity_id_id(shop->worlds.id_display)), @@ -813,9 +828,11 @@ entity_call_result ent_skateshop_call( world_instance *world, ent_call *call ) vg_info( "Entering skateshop\n" ); +#if 0 world_entity_set_focus( call->id ); world_entity_focus_modal(); - gui_helper_clear(); +#endif + gui_helper_reset( k_gui_helper_mode_black_bars ); if( shop->type == k_skateshop_type_boardshop ) { diff --git a/src/ent_skateshop.h b/src/ent_skateshop.h index 2f8e3a6..9dad972 100644 --- a/src/ent_skateshop.h +++ b/src/ent_skateshop.h @@ -49,6 +49,6 @@ void ent_skateshop_preupdate( ent_focus_context *ctx ); void skateshop_render( ent_skateshop *shop ); void skateshop_render_nonfocused( world_instance *world, vg_camera *cam ); void skateshop_autostart_loading(void); -void skateshop_world_preupdate( world_instance *world ); +void skateshop_world_preupdate(void); entity_call_result ent_skateshop_call( world_instance *world, ent_call *call ); void skateshop_world_preview_preupdate(void); diff --git a/src/ent_tornado.c b/src/ent_tornado.c index b255edd..920210a 100644 --- a/src/ent_tornado.c +++ b/src/ent_tornado.c @@ -17,7 +17,7 @@ void ent_tornado_init(void) void ent_tornado_debug(void) { - world_instance *world = world_current_instance(); + world_instance *world = &_world.main; for( u32 i=0; ient_marker); i ++ ) { ent_marker *marker = af_arritm( &world->ent_marker, i ); @@ -38,7 +38,7 @@ void ent_tornado_debug(void) void ent_tornado_forces( v3f co, v3f cv, v3f out_a ) { - world_instance *world = world_current_instance(); + world_instance *world = &_world.main; v3_zero( out_a ); for( u32 i=0; ient_marker); i ++ ) @@ -70,7 +70,7 @@ void ent_tornado_forces( v3f co, v3f cv, v3f out_a ) void ent_tornado_pre_update(void) { - world_instance *world = world_current_instance(); + world_instance *world = &_world.main; for( u32 i=0; ient_marker); i ++ ) { ent_marker *marker = af_arritm( &world->ent_marker, i ); diff --git a/src/entity.c b/src/entity.c index c27f754..dad26d2 100644 --- a/src/entity.c +++ b/src/entity.c @@ -10,7 +10,6 @@ #include "ent_miniworld.h" #include "ent_region.h" #include "ent_glider.h" -#include "ent_npc.h" #include "world_water.h" #include @@ -33,7 +32,6 @@ void entity_call( world_instance *world, ent_call *call ) [k_ent_miniworld] = ent_miniworld_call, [k_ent_region] = ent_region_call, [k_ent_glider] = ent_glider_call, - [k_ent_npc] = ent_npc_call, [k_ent_water] = ent_water_call, }; diff --git a/src/entity.h b/src/entity.h index e8243a1..5c4570d 100644 --- a/src/entity.h +++ b/src/entity.h @@ -564,7 +564,8 @@ struct ent_objective{ }; enum ent_challenge_flag { - k_ent_challenge_timelimit = 0x1 + k_ent_challenge_timelimit = 0x1, + k_ent_challenge_is_story = 0x2 }; struct ent_challenge{ diff --git a/src/gui.h b/src/gui.h index b888c2f..53dfbcc 100644 --- a/src/gui.h +++ b/src/gui.h @@ -34,8 +34,10 @@ enum gui_icon { #define GUI_HELPER_TEXT_LENGTH 32 -struct{ - struct gui_helper{ +struct +{ + struct gui_helper + { vg_input_op *binding; char text[GUI_HELPER_TEXT_LENGTH]; int greyed; @@ -43,9 +45,16 @@ struct{ helpers[4]; u32 helper_count; - int active_positional_helper; + enum gui_helper_mode + { + k_gui_helper_mode_default, + k_gui_helper_mode_black_bars, + k_gui_helper_mode_clear + } + helper_mode; - struct icon_call { + struct icon_call + { enum gui_icon icon; v4f location; v4f colour; @@ -72,12 +81,14 @@ struct{ } static gui = {.cur_icon_colour = {1.0f,1.0f,1.0f,1.0f},.colour_changed=1}; -static void gui_helper_clear(void){ +static void gui_helper_reset( enum gui_helper_mode mode ) +{ gui.helper_count = 0; - gui.active_positional_helper = 0; + gui.helper_mode = mode; } -static struct gui_helper *gui_new_helper( vg_input_op *bind, vg_str *out_text ){ +static struct gui_helper *gui_new_helper( vg_input_op *bind, vg_str *out_text ) +{ if( gui.helper_count >= VG_ARRAY_LEN(gui.helpers) ){ vg_error( "Too many helpers\n" ); return NULL; @@ -142,10 +153,6 @@ static void gui_render_icons(void) static void gui_draw( ui_context *ctx ) { - if( gui.active_positional_helper && - (v3_dist2(localplayer.rb.co,gui.trick_co) > 2.0f) ) - gui_helper_clear(); - /* helpers * ----------------------------------------------------------------- */ @@ -197,6 +204,17 @@ static void gui_draw( ui_context *ctx ) x += w + 32; } + if( (gui.helper_mode == k_gui_helper_mode_black_bars) && gui.helper_count ) + { + ui_rect box = { x, lwr[1], vg.window_x - x, height }; + ui_fill( ctx, box, ui_opacity( GUI_COL_DARK, 0.4f ) ); + + box[0] = 0; + box[1] = 0; + box[2] = vg.window_x; + ui_fill( ctx, box, ui_opacity( GUI_COL_DARK, 0.4f ) ); + } + vg_ui.frosting = gui.factive*0.015f; ui_flush( ctx, k_ui_shader_colour, NULL ); vg_ui.frosting = 0.0f; @@ -239,48 +257,6 @@ static int gui_location_print_ccmd( int argc, const char *argv[] ) return 0; } -static int gui_showtrick_ccmd( int argc, const char *argv[] ) -{ - if( argc == 1 ) - { - gui_helper_clear(); - vg_str text; - - if( !strcmp( argv[0], "pump" ) ){ - if( gui_new_helper( input_axis_list[k_sraxis_grab], &text ) ) - vg_strcat( &text, "Pump" ); - } - else if( !strcmp( argv[0], "flip" ) ){ - if( gui_new_helper( input_joy_list[k_srjoystick_steer], &text ) ) - vg_strcat( &text, "Flip" ); - } - else if( !strcmp( argv[0], "ollie" ) ){ - if( gui_new_helper( input_button_list[k_srbind_jump], &text ) ) - vg_strcat( &text, "Ollie" ); - } - else if( !strcmp( argv[0], "trick" ) ){ - if( gui_new_helper( input_button_list[k_srbind_trick0], &text ) ) - vg_strcat( &text, "Shuvit" ); - if( gui_new_helper( input_button_list[k_srbind_trick1], &text ) ) - vg_strcat( &text, "Kickflip" ); - if( gui_new_helper( input_button_list[k_srbind_trick2], &text ) ) - vg_strcat( &text, "Tre-Flip" ); - } - else if( !strcmp( argv[0], "misc" ) ){ - if( gui_new_helper( input_button_list[k_srbind_camera], &text ) ) - vg_strcat( &text, "Camera" ); - if( gui_new_helper( input_button_list[k_srbind_use], &text ) ) - vg_strcat( &text, "Skate/Walk" ); - } - else return 1; - - v3_copy( localplayer.rb.co, gui.trick_co ); - gui.active_positional_helper = 1; - return 0; - } - return 1; -} - static void gui_draw_icon( enum gui_icon icon, v2f co, f32 size ) { if( gui.icon_draw_count == VG_ARRAY_LEN(gui.icon_draw_buffer) ) @@ -318,7 +294,6 @@ static void gui_init(void) { font3d_load( &gui.font, "models/rs_font.mdl", vg_mem.rtmemory ); vg_console_reg_cmd( "gui_location", gui_location_print_ccmd, NULL ); - vg_console_reg_cmd( "showtrick", gui_showtrick_ccmd, NULL ); /* load icons */ void *alloc = vg_mem.rtmemory; diff --git a/src/menu.c b/src/menu.c index 8df3fc6..6f8c48d 100644 --- a/src/menu.c +++ b/src/menu.c @@ -292,24 +292,6 @@ static i32 menu_nav( i32 *p_row, int mv, i32 max ) return *p_row; } -static void menu_try_find_cam( i32 id ) -{ - world_instance *world = &world_static.instances[0]; - for( u32 i=0; ient_npc); i ++ ) - { - ent_npc *fnpc = af_arritm( &world->ent_npc, i ); - if( (fnpc->id == 50) && (fnpc->context == id) ) - { - if( mdl_entity_id_type(fnpc->camera) == k_ent_camera ) - { - u32 index = mdl_entity_id_id( fnpc->camera ); - menu.bg_cam = af_arritm( &world->ent_camera, index ); - menu.bg_blur = 0; - } - } - } -} - static void menu_link_modal( const char *url ) { menu.web_link = url; @@ -382,7 +364,7 @@ void menu_gui( ui_context *ctx ) if( menu.web_link ) { - menu_try_find_cam( 3 ); + //menu_try_find_cam( 3 ); ui_rect panel = { 0,0, 800, 200 }, screen = { 0,0, vg.window_x,vg.window_y }; @@ -544,7 +526,7 @@ void menu_gui( ui_context *ctx ) skaterift.activity = k_skaterift_default; } - menu_try_find_cam( 3 ); + //menu_try_find_cam( 3 ); goto menu_draw; } else if( menu.page == k_menu_page_premium ) @@ -702,188 +684,137 @@ void menu_gui( ui_context *ctx ) ui_px x = 8, y = height+8; - struct ui_vert *vs = - ui_fill( ctx, (ui_rect){ x,y, 0,height }, - world_static.active_instance? GUI_COL_DARK: GUI_COL_ACTIVE ); + struct ui_vert *vs = ui_fill( ctx, (ui_rect){ x,y, 0,height }, GUI_COL_DARK ); char buf[64]; vg_str str; vg_strnull( &str, buf, sizeof(buf) ); - vg_strcat( &str, "Hub World" ); - - if( world_static.active_instance ) - { - vg_strcat( &str, " (" ); - vg_input_string( &str, input_button_list[k_srbind_mhub], 1 ); - vg_strcatch( &str, '\x06' ); - vg_strcatch( &str, '\x00' ); - vg_strcat( &str, "\x1B[0m)" ); - } + + world_instance *world = &_world.main; + const char *world_name = af_str( &world->meta.af, world->info.pstr_name ); + vg_strnull( &str, buf, sizeof(buf) ); + vg_strcat( &str, world_name ); ui_px w = ui_text( ctx, (ui_rect){ x+8, y, 1000, height }, buf, 1, k_ui_align_middle_left, 0 ); + w *= ctx->font->sx; x += w + 16; vs[1].co[0] = x + 8; vs[2].co[0] = x; - x += 2; - - world_instance *world = &world_static.instances[1]; - if( world->status == k_world_status_loaded ) - { - const char *world_name = - af_str( &world->meta.af, world->info.pstr_name ); + x = 8; + y += 8 + height; - vg_strnull( &str, buf, sizeof(buf) ); - vg_strcat( &str, world_name ); + ui_rect stat_panel = { x,y, 256,vg.window_y-y }; + u32 c0 = ui_opacity( GUI_COL_DARK, 0.36f ); + vs = ui_fill( ctx, stat_panel, c0 ); - if( !world_static.active_instance && - (vg_input.display_input_method == k_input_method_controller) ) - { - vg_strcat( &str, " (" ); - vg_input_string( &str, input_button_list[k_srbind_mhub], 1 ); - vg_strcatch( &str, '\x06' ); - vg_strcatch( &str, '\x00' ); - vg_strcat( &str, "\x1B[0m)" ); - } + ui_rect_pad( stat_panel, (ui_px[2]){8,0} ); - vs = ui_fill( ctx, (ui_rect){ x,y, 1000,height }, - world_static.active_instance? GUI_COL_ACTIVE: GUI_COL_DARK ); - w = ui_text( ctx, (ui_rect){ x+16,y, 1000,height }, buf, - 1, k_ui_align_middle_left, 0 ); + for( u32 i=0; ient_region ); i ++ ) + { + ent_region *region = af_arritm( &world->ent_region, i ); - w = w*ctx->font->sx + 8*3; - x += w; + if( !region->zone_volume ) + continue; - if( button_down( k_srbind_mhub ) || - ui_button_base( ctx, (ui_rect){0,y,x,height} ) == k_ui_button_click ) - { - world_switch_instance( world_static.active_instance ^ 0x1 ); - skaterift.activity = k_skaterift_default; - world_map.view_ready = 0; - } + const char *title = af_str( &world->meta.af, region->pstr_title ); + ctx->font = &vgf_default_large; - vs[0].co[0] += 8; - vs[1].co[0] = x + 8; - vs[2].co[0] = x; - } + ui_rect title_box; + menu_standard_widget( ctx, stat_panel, title_box, 1 ); + + stat_panel[0] += 16; + stat_panel[2] -= 16; + ctx->font = &vgf_default_small; - x = 8; - y += 8 + height; + ent_volume *volume = af_arritm(&world->ent_volume, + mdl_entity_id_id(region->zone_volume)); - if( world_static.active_instance ) - { - ui_rect stat_panel = { x,y, 256,vg.window_y-y }; - u32 c0 = ui_opacity( GUI_COL_DARK, 0.36f ); - struct ui_vert *vs = ui_fill( ctx, stat_panel, c0 ); + u32 combined = k_ent_route_flag_achieve_gold | + k_ent_route_flag_achieve_silver; - ui_rect_pad( stat_panel, (ui_px[2]){8,0} ); + char buf[128]; + vg_str str; - for( u32 i=0; ient_region ); i ++ ) + for( u32 j=0; jent_route); j ++ ) { - ent_region *region = af_arritm( &world->ent_region, i ); + ent_route *route = af_arritm(&world->ent_route, j ); - if( !region->zone_volume ) + v3f local; + m4x3_mulv( volume->to_local, route->board_transform[3], local ); + if( !((fabsf(local[0]) <= 1.0f) && + (fabsf(local[1]) <= 1.0f) && + (fabsf(local[2]) <= 1.0f)) ) + { continue; + } - const char *title = af_str( &world->meta.af, region->pstr_title ); - ctx->font = &vgf_default_large; + combined &= route->flags; - ui_rect title_box; - menu_standard_widget( ctx, stat_panel, title_box, 1 ); - - stat_panel[0] += 16; - stat_panel[2] -= 16; - ctx->font = &vgf_default_small; + vg_strnull( &str, buf, sizeof(buf) ); + vg_strcat( &str, "(Race) " ); + vg_strcat( &str, af_str( &world->meta.af, route->pstr_name )); - ent_volume *volume = af_arritm(&world->ent_volume, - mdl_entity_id_id(region->zone_volume)); + if( route->flags & k_ent_route_flag_achieve_silver ) + vg_strcat( &str, " \xb3"); + if( route->flags & k_ent_route_flag_achieve_gold ) + vg_strcat( &str, "\xb3"); - u32 combined = k_ent_route_flag_achieve_gold | - k_ent_route_flag_achieve_silver; + ui_rect r; + ui_standard_widget( ctx, stat_panel, r, 1 ); + ui_text( ctx, r, buf, 1, k_ui_align_middle_left, + medal_colour( ctx, route->flags ) ); + } - char buf[128]; - vg_str str; + for( u32 j=0; jent_challenge); j ++ ) + { + ent_challenge *challenge = af_arritm( &world->ent_challenge, j ); - for( u32 j=0; jent_route); j ++ ) + v3f local; + m4x3_mulv( volume->to_local, challenge->transform.co, local ); + if( !((fabsf(local[0]) <= 1.0f) && + (fabsf(local[1]) <= 1.0f) && + (fabsf(local[2]) <= 1.0f)) ) { - ent_route *route = af_arritm(&world->ent_route, j ); - - v3f local; - m4x3_mulv( volume->to_local, route->board_transform[3], local ); - if( !((fabsf(local[0]) <= 1.0f) && - (fabsf(local[1]) <= 1.0f) && - (fabsf(local[2]) <= 1.0f)) ) - { - continue; - } - - combined &= route->flags; - - vg_strnull( &str, buf, sizeof(buf) ); - vg_strcat( &str, "(Race) " ); - vg_strcat( &str, af_str( &world->meta.af, route->pstr_name )); - - if( route->flags & k_ent_route_flag_achieve_silver ) - vg_strcat( &str, " \xb3"); - if( route->flags & k_ent_route_flag_achieve_gold ) - vg_strcat( &str, "\xb3"); - - ui_rect r; - ui_standard_widget( ctx, stat_panel, r, 1 ); - ui_text( ctx, r, buf, 1, k_ui_align_middle_left, - medal_colour( ctx, route->flags ) ); + continue; } - for( u32 j=0; jent_challenge); j ++ ) + vg_strnull( &str, buf, sizeof(buf) ); + vg_strcat( &str, af_str( &world->meta.af,challenge->pstr_alias)); + + u32 flags = 0x00; + if( challenge->status ) { - ent_challenge *challenge = af_arritm( &world->ent_challenge, j ); - - v3f local; - m4x3_mulv( volume->to_local, challenge->transform.co, local ); - if( !((fabsf(local[0]) <= 1.0f) && - (fabsf(local[1]) <= 1.0f) && - (fabsf(local[2]) <= 1.0f)) ) - { - continue; - } - - vg_strnull( &str, buf, sizeof(buf) ); - vg_strcat( &str, af_str( &world->meta.af,challenge->pstr_alias)); - - u32 flags = 0x00; - if( challenge->status ) - { - flags |= k_ent_route_flag_achieve_gold; - flags |= k_ent_route_flag_achieve_silver; - vg_strcat( &str, " \xb3\xb3" ); - } - - combined &= flags; - - ui_rect r; - ui_standard_widget( ctx, stat_panel, r, 1 ); - ui_text( ctx, r, buf, 1, - k_ui_align_middle_left, medal_colour( ctx, flags ) ); + flags |= k_ent_route_flag_achieve_gold; + flags |= k_ent_route_flag_achieve_silver; + vg_strcat( &str, " \xb3\xb3" ); } - stat_panel[0] -= 16; - stat_panel[2] += 16; - - u32 title_col = 0; - if( combined & k_ent_route_flag_achieve_gold ) - title_col = ui_colour( ctx, k_ui_yellow ); - else if( combined & k_ent_route_flag_achieve_silver ) - title_col = ui_colour( ctx, k_ui_fg ); + combined &= flags; - menu_heading( ctx, title_box, title, title_col ); + ui_rect r; + ui_standard_widget( ctx, stat_panel, r, 1 ); + ui_text( ctx, r, buf, 1, + k_ui_align_middle_left, medal_colour( ctx, flags ) ); } - vs[2].co[1] = stat_panel[1]; - vs[3].co[1] = stat_panel[1]; + stat_panel[0] -= 16; + stat_panel[2] += 16; + + u32 title_col = 0; + if( combined & k_ent_route_flag_achieve_gold ) + title_col = ui_colour( ctx, k_ui_yellow ); + else if( combined & k_ent_route_flag_achieve_silver ) + title_col = ui_colour( ctx, k_ui_fg ); + + menu_heading( ctx, title_box, title, title_col ); } + + vs[2].co[1] = stat_panel[1]; + vs[3].co[1] = stat_panel[1]; } else { @@ -991,7 +922,7 @@ void menu_gui( ui_context *ctx ) menu_heading( ctx, list, "Info", 0 ); if( menu.guide_sel == 1 ) { - menu_try_find_cam( 1 ); + //menu_try_find_cam( 1 ); ui_rect title; ui_split( inf, k_ui_axis_h, 28*2, 0, title, inf ); @@ -1023,7 +954,7 @@ void menu_gui( ui_context *ctx ) if( menu.guide_sel == 3 ) { - menu_try_find_cam( 2 ); + //menu_try_find_cam( 2 ); ui_rect title; ui_split( inf, k_ui_axis_h, 28*2, 0, title, inf ); @@ -1055,7 +986,7 @@ void menu_gui( ui_context *ctx ) menu_link_modal( "https://skaterift.com/index.php?page=movement" ); } - if( menu.guide_sel == 0 || menu.guide_sel > 3 ) menu_try_find_cam( 3 ); + //if( menu.guide_sel == 0 || menu.guide_sel > 3 ) menu_try_find_cam( 3 ); if( menu_button( ctx, list, R == 3, "Tricks \xb2" ) ) { diff --git a/src/metascene.c b/src/metascene.c index 31016f1..0680eb5 100644 --- a/src/metascene.c +++ b/src/metascene.c @@ -235,6 +235,7 @@ static void cutscene_load_thread( void *data ) _cutscene.instances[ i ].ref_id = ref_id; _cutscene.instances[ i ].skinning_data = NULL; + _cutscene.instances[ i ].disable_render = 0; } /* load model data */ @@ -386,6 +387,9 @@ static int cmd_cutscene_load( int argc, const char *argv[] ) void cutscene_render_instance( struct cs_instance *ins, world_instance *world, vg_camera *cam ) { + if( ins->disable_render ) + return; + struct model_ref *ref = &_cutscene.refs[ ins->ref_id ]; mdl_context *mdl = &ref->mdl; mesh_bind( &mdl->mesh ); diff --git a/src/metascene.h b/src/metascene.h index 7966515..fedc152 100644 --- a/src/metascene.h +++ b/src/metascene.h @@ -80,6 +80,7 @@ struct ms_curve_keyframe struct cs_instance { + bool disable_render; u32 ref_id; m4x3f *skinning_data; }; diff --git a/src/network.c b/src/network.c index 7a7e497..dbb5c5f 100644 --- a/src/network.c +++ b/src/network.c @@ -164,7 +164,7 @@ static void network_send_request( netmsg_request *req, vg_msg *body, static void network_scoreboard_callback( netmsg_request *res, vg_msg *body, u64 userdata ){ - world_instance *world = world_current_instance(); + world_instance *world = &_world.main; world_routes_recv_scoreboard( world, body, userdata, res->status ); if( userdata == world_sfd.active_route_board ) @@ -269,24 +269,26 @@ void network_send_item( enum netmsg_playeritem_type type ) item->client = 0; if( (type == k_netmsg_playeritem_world0) || - (type == k_netmsg_playeritem_world1) ){ - - enum world_purpose purpose = type - k_netmsg_playeritem_world0; - addon_reg *reg = world_static.instance_addons[ purpose ]; + (type == k_netmsg_playeritem_world1) ) + { + addon_reg *reg = _world.main.addon; if( reg ) addon_alias_uid( ®->alias, item->uid ); else item->uid[0] = '\0'; } - else{ + else + { u16 view_id = 0; enum addon_type addon_type = k_addon_type_none; - if( type == k_netmsg_playeritem_board ){ + if( type == k_netmsg_playeritem_board ) + { view_id = localplayer.board_view_slot; addon_type = k_addon_type_board; } - else if( type == k_netmsg_playeritem_player ){ + else if( type == k_netmsg_playeritem_player ) + { view_id = localplayer.playermodel_view_slot; addon_type = k_addon_type_player; } diff --git a/src/player.c b/src/player.c index 2a57488..55edf72 100644 --- a/src/player.c +++ b/src/player.c @@ -50,7 +50,7 @@ struct player_subsystem_interface *player_subsystems[] = int localplayer_cmd_respawn( int argc, const char *argv[] ) { ent_spawn *rp = NULL, *r; - world_instance *world = world_current_instance(); + world_instance *world = &_world.main; if( argc == 1 ){ rp = world_find_spawn_by_name( world, argv[0] ); @@ -171,7 +171,7 @@ void player__post_update(void) */ void player__pass_gate( u32 id ) { - world_instance *world = world_current_instance(); + world_instance *world = &_world.main; skaterift_record_frame( &player_replay.local, 1 ); /* update boundary hash (network animation) */ @@ -194,17 +194,9 @@ void player__pass_gate( u32 id ) m4x3_mulv( gate->transport, localplayer.cam.pos, localplayer.cam.pos ); if( gate->flags & k_ent_gate_nonlocal ) - { - world_default_spawn_pos( world, world->player_co ); - world_static.active_instance = gate->target; - player__clean_refs(); - - replay_clear( &player_replay.local ); - } + vg_error( "Nonlocal gates are deprecated!\n" ); else - { world_routes_activate_entry_gate( world, gate ); - } v3f v0; v3_angles_vector( localplayer.angles, v0 ); @@ -251,26 +243,24 @@ void player__im_gui( ui_context *ctx ) g_player_debugger[2] = 300; g_player_debugger[3] = 32; - player__debugtext( ctx, 2, "instance #%u", world_static.active_instance ); - char buf[96]; - for( u32 i=0; ialias, buf ); - else - strcpy( buf, "none" ); - - player__debugtext( ctx, 1, "world #%u: %s", i, buf ); - } + if( _world.main.addon ) + addon_alias_uid( &_world.main.addon->alias, buf ); + else + strcpy( buf, "none" ); + player__debugtext( ctx, 1, "world #%u: %s", 0, buf ); player__debugtext( ctx, 2, "director" ); - player__debugtext( ctx, 1, "activity: %s", + player__debugtext( ctx, 1, "client activity: %s", (const char *[]){ [k_skaterift_menu] = "menu", [k_skaterift_replay] = "replay", - [k_skaterift_ent_focus] = "ent_focus", [k_skaterift_default] = "default", } [skaterift.activity] ); + player__debugtext( ctx, 1, "world event: %s", + (const char *[]){ [k_world_event_none] = "no event", + [k_world_event_challenge] = "challenge", + } [_world.event] ); + player__debugtext( ctx, 1, "time_rate: %.4f", skaterift.time_rate ); player__debugtext( ctx, 2, "player" ); @@ -292,23 +282,18 @@ void player__setpos( v3f pos ) void player__clean_refs(void) { replay_clear( &player_replay.local ); - gui_helper_clear(); + gui_helper_reset( k_gui_helper_mode_clear ); - world_static.challenge_target = NULL; - world_static.challenge_timer = 0.0f; - world_static.active_trigger_volume_count = 0; - world_static.last_use = 0.0; + _world.challenge_target = NULL; + _world.challenge_timer = 0.0f; + _world.active_trigger_volume_count = 0; +#if 0 world_entity_exit_modal(); world_entity_clear_focus(); +#endif localplayer.boundary_hash ^= NETMSG_BOUNDARY_BIT; - - for( u32 i=0; istatus == k_world_status_loaded ){ - world_routes_clear( instance ); - } - } + world_routes_clear( &_world.main ); } void player__reset(void) diff --git a/src/player.h b/src/player.h index 47fabae..c7ded0f 100644 --- a/src/player.h +++ b/src/player.h @@ -88,7 +88,6 @@ struct localplayer int deferred_frame_record; int immobile; - int rewinded_since_last_gate; /* diff --git a/src/player_dead.c b/src/player_dead.c index a5b5882..7f1b5e9 100644 --- a/src/player_dead.c +++ b/src/player_dead.c @@ -22,7 +22,7 @@ void player__dead_update(void) { player_ragdoll_iter( &localplayer.ragdoll ); - world_instance *world = world_current_instance(); + world_instance *world = &_world.main; world_water_player_safe( world, 0.2f ); } @@ -46,7 +46,7 @@ void player__dead_post_update(void){ if( (skaterift.activity == k_skaterift_default) && button_down(k_srbind_dead_respawn) ){ ent_spawn *spawn = world_find_closest_spawn( - world_current_instance(), localplayer.rb.co ); + &_world.main, localplayer.rb.co ); if( spawn ){ v3_copy( spawn->transform.co, localplayer.rb.co ); @@ -173,17 +173,13 @@ void player__dead_transition( enum player_die_type type ) v3_copy( part->rb.v, player_dead.v_lpf ); v3_copy( part->rb.w, player_dead.w_lpf ); - gui_helper_clear(); + gui_helper_reset( k_gui_helper_mode_black_bars ); vg_str str; struct gui_helper *h; - if( (h = gui_new_helper(input_button_list[k_srbind_reset], &str) )){ + if( (h = gui_new_helper(input_button_list[k_srbind_reset], &str) )) vg_strcat( &str, "Rewind" ); - if( world_static.active_instance == k_world_purpose_hub ) - h->greyed = 1; - } - if( gui_new_helper(input_button_list[k_srbind_dead_respawn], &str )) vg_strcat( &str, "Spawn" ); } diff --git a/src/player_glide.c b/src/player_glide.c index d0c32df..e97ed31 100644 --- a/src/player_glide.c +++ b/src/player_glide.c @@ -206,7 +206,7 @@ bool glider_physics( v2f steer ) /* * collisions & constraints */ - world_instance *world = world_current_instance(); + world_instance *world = &_world.main; rb_solver_reset(); bool bottom_hit = 0; @@ -280,7 +280,7 @@ void player_glide_update(void) localplayer.glider_orphan = 1; } - if( !world_water_player_safe( world_current_instance(), 1.0f ) ) + if( !world_water_player_safe( &_world.main, 1.0f ) ) return; } @@ -484,16 +484,7 @@ void player_glide_transition(void) { localplayer.subsystem = k_player_subsystem_glide; localplayer.have_glider = 0; - world_static.challenge_target = NULL; - world_static.challenge_timer = 0.0f; - world_static.focused_entity = 0; - world_static.last_use = 0.0; - for( u32 i=0; istatus == k_world_status_loaded ){ - world_routes_clear( instance ); - } - } + world_routes_clear( &_world.main ); v3_copy( localplayer.rb.co, player_glide.rb.co ); diff --git a/src/player_ragdoll.c b/src/player_ragdoll.c index 4fa37cd..c79e7f8 100644 --- a/src/player_ragdoll.c +++ b/src/player_ragdoll.c @@ -350,7 +350,7 @@ void copy_localplayer_to_ragdoll( struct player_ragdoll *rd, */ void player_ragdoll_iter( struct player_ragdoll *rd ) { - world_instance *world = world_current_instance(); + world_instance *world = &_world.main; int run_sim = 0; ragdoll_frame ++; diff --git a/src/player_remote.c b/src/player_remote.c index c191c03..7a17046 100644 --- a/src/player_remote.c +++ b/src/player_remote.c @@ -26,31 +26,15 @@ static void player_remote_clear( struct network_player *player ) player->subsystem = k_player_subsystem_invalid; } -/* - * re-attatches addon_reg pointers on the remote client if we have the same - * world loaded. - */ -static void relink_remote_player_worlds( u32 client_id ){ +static void relink_remote_player_worlds( u32 client_id ) +{ struct network_player *player = &netplayers.list[client_id]; - addon_alias q[2]; - addon_uid_to_alias( player->items[k_netmsg_playeritem_world0], &q[0] ); - addon_uid_to_alias( player->items[k_netmsg_playeritem_world1], &q[1] ); - - /* - * currently in 10.23, the hub world will always be the same. - * this might but probably wont change in the future - */ - for( u32 i=0; iworld_match[i] = 0; + addon_alias q; + addon_uid_to_alias( player->items[k_netmsg_playeritem_world0], &q ); - if( reg ){ - if( addon_alias_eq( &q[i], &world_static.instance_addons[i]->alias ) ) - player->world_match[i] = 1; - } - } + if( addon_alias_eq( &q, &_world.main.addon->alias ) ) + player->same_world = 1; } /* @@ -61,7 +45,8 @@ static void relink_remote_player_worlds( u32 client_id ){ */ void relink_all_remote_player_worlds(void) { - for( u32 i=0; iactive ) relink_remote_player_worlds(i); @@ -339,7 +324,7 @@ void remote_player_send_playerframe(void) frame->inetmsg_id = k_inetmsg_playerframe; frame->client = 0xff; frame->subsystem = localplayer.subsystem; - frame->flags = world_static.active_instance; + frame->flags = 0; bitpack_ctx ctx = { .mode = k_bitpack_compress, @@ -422,11 +407,10 @@ static void pose_remote_player( u32 index, player_pose pose0, pose1, posed; sys0->pose( &f0->data, &pose0 ); - u8 instance_id = 0; - f32 t = 0.0f; - if( f1 ){ + if( f1 ) + { t = (buf->t - f0->timestamp) / (f1->timestamp - f0->timestamp); t = vg_clampf( t, 0.0f, 1.0f ); @@ -438,12 +422,12 @@ static void pose_remote_player( u32 index, if( bounds & NETMSG_BOUNDARY_BIT ) t = 1.0f; - if( bounds & NETMSG_GATE_BOUNDARY_BIT ){ + if( bounds & NETMSG_GATE_BOUNDARY_BIT ) + { /* TODO: Extra work retransforming the root_co, instance_id.. etc */ t = 1.0f; } - instance_id = f1->flags & NETMSG_PLAYERFRAME_INSTANCE_ID; lerp_player_pose( &pose0, &pose1, t, &posed ); effect_blink_apply( &player->effect_data.blink, &posed, vg.time_delta ); @@ -460,8 +444,8 @@ static void pose_remote_player( u32 index, memcpy( board_pose, &posed.board, sizeof(*board_pose) ); } - else { - instance_id = f0->flags & NETMSG_PLAYERFRAME_INSTANCE_ID; + else + { effect_blink_apply( &player->effect_data.blink, &pose0, vg.time_delta ); apply_full_skeleton_pose( sk, &pose0, final_mtx ); if( sys0->effects ) @@ -495,9 +479,6 @@ static void pose_remote_player( u32 index, } else player->render_glider = 0; - - if( player->world_match[ instance_id ] ) - player->active_world = &world_static.instances[ instance_id ]; } /* @@ -539,14 +520,14 @@ void animate_remote_player( u32 index ) } struct network_player *player = &netplayers.list[ index ]; - if( player->active != 2 ) - player->active_world = NULL; - if( minframe && maxframe ){ + if( minframe && maxframe ) + { pose_remote_player( index, minframe, maxframe ); buf->t += vg.time_frame_delta; } - else { + else + { buf->t = abs_max_time - 0.25; if( abs_max_frame ) @@ -578,14 +559,15 @@ void render_remote_players( world_instance *world, vg_camera *cam ) draw_list_count = 0, gliders = 0; - for( u32 i=0; iactive || player->isblocked ) continue; - if( player->active_world != world ) continue; + if( !player->same_world ) continue; #if 0 if( !player->isfriend && - (world-world_static.instances == k_world_purpose_hub)) continue; + (world-_world.instances == k_world_purpose_hub)) continue; #endif draw_list[draw_list_count ++] = i; @@ -656,15 +638,11 @@ static int remote_players_randomize( int argc, const char *argv[] ){ player->isblocked = vg_randu32(&vg.rand) & vg_randu32(&vg.rand) & vg_randu32(&vg.rand) & 0x1; - player->world_match[ 0 ] = vg_randu32(&vg.rand) & 0x1; - player->world_match[ 1 ] = 0; - if( player->world_match[0] ) - player->active_world = &world_static.instances[0]; - else - player->active_world = NULL; + player->same_world = vg_randu32(&vg.rand) & 0x1; - for( int i=0; iusername)-1; i ++ ){ + for( int i=0; iusername)-1; i ++ ) + { player->username[i] = 'a' + (vg_randu32(&vg.rand) % 30); player->username[i+1] = '\0'; @@ -900,18 +878,17 @@ void remote_players_imgui_lobby( ui_context *ctx ) struct network_player *player = &netplayers.list[i]; if( !player->active || player->isblocked ) continue; - int in_same_world = player->active_world == world_current_instance(); - if( !player->isfriend && !in_same_world ) + if( !player->isfriend && !player->same_world ) continue; - const char *location = in_same_world? "": "another world"; + const char *location = player->same_world? "": "another world"; if( player->region_flags & k_ent_region_flag_hasname ){ location = player->region; } ui_rect box = { x, y, width, height }; remote_player_gui_info( ctx, box, player->username, location, - player->isfriend, in_same_world ); + player->isfriend, player->same_world ); y += height + gap; } } @@ -930,17 +907,8 @@ void remote_players_imgui_world( ui_context *ctx, v3f co; remote_player_position( i, co ); - if( !player->active_world ) + if( !player->same_world ) continue; - if( !player->isfriend && - (world-world_static.instances == k_world_purpose_hub)) continue; - - /* their in our active subworld */ - if( player->active_world != world ) - { - m4x3_mulv( global_miniworld.mmdl, co, co ); - co[1] -= 2.0f; /* HACK lol */ - } f32 d2 = v3_dist2( co, localplayer.rb.co ); diff --git a/src/player_remote.h b/src/player_remote.h index 4bd7351..8857964 100644 --- a/src/player_remote.h +++ b/src/player_remote.h @@ -16,16 +16,15 @@ struct global_netplayers { - struct network_player { + struct network_player + { int active, isfriend, isblocked; u64 steamid; u16 board_view_slot, playermodel_view_slot; enum player_subsystem subsystem; - /* this is set IF they exist in a world that we have loaded */ - world_instance *active_world; - int world_match[ k_world_max ]; - u32 location_pstr; /* TODO: valid if active_world set. */ + bool same_world; + u32 location_pstr; char username[ NETWORK_USERNAME_MAX ]; char items[k_netmsg_playeritem_max][ADDON_UID_MAX]; diff --git a/src/player_render.c b/src/player_render.c index a2a775a..36f8c65 100644 --- a/src/player_render.c +++ b/src/player_render.c @@ -415,7 +415,7 @@ void player__pre_render(void) v3_zero( vp1 ); } - struct ub_world_lighting *ubo = &world_current_instance()->ub_lighting; + struct ub_world_lighting *ubo = &_world.main.ub_lighting; v3f *board_mtx = localplayer.final_mtx[ localplayer.id_board ]; m4x3_mulv( board_mtx, vp0, ubo->g_board_0 ); m4x3_mulv( board_mtx, vp1, ubo->g_board_1 ); @@ -585,7 +585,7 @@ void render_playermodel( vg_camera *cam, world_instance *world, void player__render( vg_camera *cam ) { - world_instance *world = world_current_instance(); + world_instance *world = &_world.main; SDL_AtomicLock( &addon_system.sl_cache_using_resources ); struct player_model *model = diff --git a/src/player_replay.c b/src/player_replay.c index 950ad78..a3e5b7d 100644 --- a/src/player_replay.c +++ b/src/player_replay.c @@ -441,7 +441,7 @@ void skaterift_record_frame( replay_buffer *replay, int force_gamestate ) replay_gamestate *gs = replay_frame_data( frame, k_replay_framedata_internal_gamestate ); - gs->current_run_version = world_static.current_run_version; + gs->current_run_version = _world.current_run_version; gs->drowned = localplayer.drowned; /* permanent block */ @@ -528,7 +528,7 @@ static void skaterift_restore_frame( replay_frame *frame ) replay_frame_data( frame, k_replay_framedata_internal_gamestate ); void *src = replay_frame_data( frame, k_replay_framedata_gamestate ); u16 src_size = frame->data_table[ k_replay_framedata_gamestate ][1]; - world_static.current_run_version = gs->current_run_version; + _world.current_run_version = gs->current_run_version; localplayer.drowned = gs->drowned; if(frame->system == k_player_subsystem_walk ){ @@ -604,17 +604,19 @@ static void skaterift_restore_frame( replay_frame *frame ) vg.time = frame->time; } -static void skaterift_replay_resume(void){ +static void skaterift_replay_resume(void) +{ replay_frame *prev = replay_find_recent_stateframe(&player_replay.local); - if( prev ){ + if( prev ) + { player_replay.replay_control = k_replay_control_resume; player_replay.resume_target = prev; player_replay.resume_begin = player_replay.local.cursor; player_replay.resume_transition = 0.0f; } - gui_helper_clear(); + gui_helper_reset( k_gui_helper_mode_clear ); } static void skaterift_replay_update_helpers(void); @@ -698,7 +700,7 @@ void skaterift_replay_pre_update(void) else skaterift.activity = k_skaterift_default; srinput.state = k_input_state_resume; - gui_helper_clear(); + gui_helper_reset( k_gui_helper_mode_clear ); } if( input ) @@ -731,7 +733,7 @@ static void skaterift_replay_update_helpers(void) static void replay_show_helpers(void) { - gui_helper_clear(); + gui_helper_reset( k_gui_helper_mode_default ); vg_str text; if( gui_new_helper( input_axis_list[k_sraxis_replay_h], &text ) ) @@ -753,7 +755,7 @@ static void replay_show_helpers(void) void skaterift_replay_post_render(void) { #ifndef SR_ALLOW_REWIND_HUB - if( world_static.active_instance != k_world_purpose_client ) + if( _world.active_instance != k_world_purpose_client ) return; #endif @@ -877,7 +879,7 @@ void skaterift_replay_imgui( ui_context *ctx ) player_replay.editor_mode ^= 0x1; if( player_replay.editor_mode ) - gui_helper_clear(); + gui_helper_reset( k_gui_helper_mode_clear ); else replay_show_helpers(); } @@ -1188,11 +1190,9 @@ void skaterift_replay_imgui( ui_context *ctx ) } ui_info( ctx, panel, "World settings" ); - f32 new_time = world_current_instance()->time; + f32 new_time = _world.main.time; if( ui_slider( ctx, panel, "Time of day", 0, 1, &new_time ) ) - { - world_current_instance()->time = new_time; - } + _world.main.time = new_time; ui_info( ctx, panel, "" ); if( ui_button( ctx, panel, "Exit editor (F1)" ) == k_ui_button_click ) diff --git a/src/player_skate.c b/src/player_skate.c index 9fc67ae..e408b5f 100644 --- a/src/player_skate.c +++ b/src/player_skate.c @@ -91,7 +91,7 @@ void player__skate_kill_audio(void){ * filters to the manifold afterwards */ static int skate_collide_smooth( m4x3f mtx, f32 r, rb_ct *man ){ - world_instance *world = world_current_instance(); + world_instance *world = &_world.main; int len = 0; len = rb_sphere__scene( mtx, r, NULL, world->geo_bh, man, @@ -125,7 +125,7 @@ struct grind_info static int skate_grind_scansq( v3f pos, v3f dir, float r, struct grind_info *inf ){ - world_instance *world = world_current_instance(); + world_instance *world = &_world.main; v4f plane; v3_copy( dir, plane ); @@ -369,7 +369,7 @@ static int create_jumps_to_hit_target( jump_info *jumps, void player__approximate_best_trajectory(void) { - world_instance *world0 = world_current_instance(); + world_instance *world0 = &_world.main; float k_trace_delta = vg.time_fixed_delta * 10.0f; struct player_skate_state *state = &player_skate.state; @@ -523,9 +523,6 @@ void player__approximate_best_trajectory(void) m4x3_mulv( gate->transport, co1, co1 ); m3x3_mulv( gate->transport, launch_v, launch_v); m4x3_mulv( gate->transport, launch_co, launch_co ); - - if( gate->flags & k_ent_gate_nonlocal ) - trace_world = &world_static.instances[ gate->target ]; } } @@ -1058,7 +1055,7 @@ static void skate_apply_handplant_model(void){ vg_line_arrow( co, dir, 0.13f, 0xff000000 ); ray_hit hit = { .dist = 2.0f }; - if( ray_world( world_current_instance(), co, dir, + if( ray_world( &_world.main, co, dir, &hit, k_material_flag_ghosts )) { vg_line( co, hit.pos, 0xff000000 ); vg_line_point( hit.pos, 0.1f, 0xff000000 ); @@ -1495,7 +1492,7 @@ void player__skate_post_update(void){ static int skate_compute_surface_alignment( v3f ra, u32 colour, v3f surface_normal, v3f axel_dir ){ - world_instance *world = world_current_instance(); + world_instance *world = &_world.main; v3f truck, left, right; m4x3_mulv( localplayer.rb.to_world, ra, truck ); @@ -1704,7 +1701,7 @@ static int skate_point_visible( v3f origin, v3f target ){ v3_muls( dir, 1.0f/ray.dist, dir ); ray.dist -= 0.025f; - if( ray_world( world_current_instance(), origin, dir, &ray, + if( ray_world( &_world.main, origin, dir, &ray, k_material_flag_walking ) ) return 0; @@ -2227,7 +2224,7 @@ static enum skate_activity skate_availible_grind(void){ void player__skate_update(void){ struct player_skate_state *state = &player_skate.state; - world_instance *world = world_current_instance(); + world_instance *world = &_world.main; if( state->activity == k_skate_activity_handplant ) return; @@ -3418,7 +3415,7 @@ void player__skate_pose( void *_animator, player_pose *pose ){ v3f dir; v3_muls( mmdl[1], -1.0f, dir ); ray_hit hit = { .dist = 1.5f }; - if(ray_world( world_current_instance(), sample_co, dir, &hit, 0 )){ + if(ray_world( &_world.main, sample_co, dir, &hit, 0 )){ vg_line_cross( hit.pos, 0xff0000ff, 0.05f ); vg_line( sample_co, hit.pos, 0xffffffff ); diff --git a/src/player_walk.c b/src/player_walk.c index cf0fa6d..2c78bb8 100644 --- a/src/player_walk.c +++ b/src/player_walk.c @@ -124,7 +124,7 @@ static void player_walk_drop_in_overhang_transform( f32 t, v3f co, v4f q ){ } static int player_walk_scan_for_drop_in(void){ - world_instance *world = world_current_instance(); + world_instance *world = &_world.main; v3f dir, center; q_mulv( localplayer.rb.q, (v3f){0.0f,0.0f,1.0f}, dir ); @@ -468,7 +468,7 @@ static void player_walk_update_generic(void){ v3_copy( localplayer.rb.co, w->state.prev_pos ); v3_zero( localplayer.rb.w ); - world_instance *world = world_current_instance(); + world_instance *world = &_world.main; if( !world_water_player_safe( world, 0.4f ) ) return; enum walk_activity prev_state = w->state.activity; diff --git a/src/save.c b/src/save.c index ca77353..1aa05c8 100644 --- a/src/save.c +++ b/src/save.c @@ -8,37 +8,38 @@ #include "player.h" static const char *str_skaterift_main_save = "save.bkv"; -static f64 last_autosave; +static f64 _last_autosave; void savedata_file_write( savedata_file *file ) { savedata_file *sav = file; FILE *fp = fopen( sav->path, "wb" ); - if( fp ){ + if( fp ) + { fwrite( sav->buf, sav->len, 1, fp ); fclose( fp ); vg_success( "savedata written to '%s'\n", sav->path ); } - else { + else vg_error( "Error writing savedata (%s)\n", sav->path ); - } } void savedata_group_write( savedata_group *group ) { - for( u32 i=0; ifile_count; i++ ){ + for( u32 i=0; ifile_count; i++ ) savedata_file_write( &group->files[i] ); - } } void savedata_file_read( savedata_file *file ) { FILE *fp = fopen( file->path, "rb" ); - if( fp ){ + if( fp ) + { file->len = fread( file->buf, 1, sizeof(file->buf), fp ); fclose( fp ); } - else{ + else + { file->len = 0; vg_warn( "Error reading savedata (%s)\n", file->path ); } @@ -64,54 +65,29 @@ static void skaterift_write_viewslot( vg_msg *msg, const char *key, skaterift_write_addon_alias( msg, key, ®->alias ); } -void skaterift_read_addon_alias( vg_msg *msg, const char *key, - enum addon_type type, - addon_alias *alias ) +static bool skaterift_read_addon_alias( vg_msg *msg, const char *key, + enum addon_type type, + addon_alias *alias ) { alias->foldername[0] = '\0'; alias->workshop_id = 0; alias->type = type; vg_msg_cmd kv; - if( vg_msg_getkvcmd( msg, key, &kv ) ){ - if( kv.code == k_vg_msg_kvstring ){ + if( vg_msg_getkvcmd( msg, key, &kv ) ) + { + if( kv.code == k_vg_msg_kvstring ) + { vg_strncpy( kv.value, alias->foldername, sizeof(alias->foldername), k_strncpy_allow_cutoff ); } else vg_msg_cast( kv.value, kv.code, &alias->workshop_id, k_vg_msg_u64 ); - } -} -static void skaterift_populate_world_savedata( savedata_file *file, - enum world_purpose which ){ - file->path[0] = '\0'; - file->len = 0; - addon_reg *reg = world_static.instance_addons[ which ]; - - if( !reg ){ - vg_error( "Tried to save unspecified world (reg was null)\n" ); - return; + return 1; } - skaterift_world_get_save_path( which, file->path ); - - vg_msg sav; - vg_msg_init( &sav, file->buf, sizeof(file->buf) ); - - world_instance *instance = &world_static.instances[which]; - world_entity_serialize( instance, &sav ); - - vg_msg_frame( &sav, "player" ); - { - vg_msg_wkvnum( &sav, "position", k_vg_msg_float|k_vg_msg_32b, 3, - (which == world_static.active_instance)? - localplayer.rb.co: - instance->player_co ); - } - vg_msg_end_frame( &sav ); - - file->len = sav.cur.co; + return 0; } static void skaterift_populate_main_savedata( savedata_file *file ) @@ -128,50 +104,76 @@ static void skaterift_populate_main_savedata( savedata_file *file ) localplayer.board_view_slot ); skaterift_write_viewslot( &sav, "playermodel", k_addon_type_player, localplayer.playermodel_view_slot ); + + addon_reg *reg = _world.main.addon; + if( reg ) + skaterift_write_addon_alias( &sav, "location", ®->alias ); + else + vg_error( "Tried to reference un-registered world in save file.\n" ); + } + vg_msg_end_frame( &sav ); + + /* script / story information */ + vg_msg_frame( &sav, "story" ); + { + skaterift_script_write_savedata( &sav ); } vg_msg_end_frame( &sav ); file->len = sav.cur.co; } -void skaterift_read_main_savedata( savedata_file *file ) +static void skaterift_populate_world_savedata( savedata_file *file ) { - strcpy( file->path, str_skaterift_main_save ); - savedata_file_read( file ); + file->path[0] = '\0'; + file->len = 0; + addon_reg *reg = _world.main.addon; + + if( !reg ) + { + vg_error( "Tried to save unspecified world (reg was null)\n" ); + return; + } + + skaterift_world_get_save_path( reg, file->path ); + + vg_msg sav; + vg_msg_init( &sav, file->buf, sizeof(file->buf) ); + + world_instance *instance = &_world.main; + world_entity_serialize( instance, &sav ); + + vg_msg_frame( &sav, "player" ); + { + vg_msg_wkvnum( &sav, "position", k_vg_msg_float|k_vg_msg_32b, 3, + localplayer.rb.co ); + } + vg_msg_end_frame( &sav ); + + file->len = sav.cur.co; } -int skaterift_autosave( int async ) +int skaterift_write_all_savedata( bool async ) { if( async ) - if( !vg_loader_availible() ) return 0; - - u32 save_files = 2; - if( world_static.instances[k_world_purpose_client].status - == k_world_status_loaded ){ - save_files ++; + { + if( !vg_loader_availible() ) + return 0; } - u32 size = sizeof(savedata_group) + sizeof(savedata_file) * save_files; - + u32 save_data_size = sizeof(savedata_group) + sizeof(savedata_file)*2; savedata_group *group; if( async ) { vg_linear_clear( vg_async.buffer ); - size = vg_align8( size ); - group = vg_linear_alloc( vg_async.buffer, size ); + group = vg_linear_alloc( vg_async.buffer, vg_align8(save_data_size) ); } else - group = alloca( size ); + group = alloca( save_data_size ); + group->file_count = 2; - group->file_count = save_files; skaterift_populate_main_savedata( &group->files[0] ); - skaterift_populate_world_savedata( &group->files[1], k_world_purpose_hub ); - - if( world_static.instances[ k_world_purpose_client ].status - == k_world_status_loaded ){ - skaterift_populate_world_savedata( &group->files[2], - k_world_purpose_client ); - } + skaterift_populate_world_savedata( &group->files[1] ); if( async ) vg_loader_start( (void *)savedata_group_write, group ); @@ -183,14 +185,89 @@ int skaterift_autosave( int async ) void skaterift_autosave_synchronous(void) { - skaterift_autosave(0); + skaterift_write_all_savedata( 0 ); +} + +void skaterift_autosave_update( void ) +{ + if( (vg.time - _last_autosave) > 60.0 ) + { + if( skaterift_write_all_savedata(1) ) + { + _last_autosave = vg.time; + } + } } -void skaterift_autosave_update(void) +void skaterift_load_mainsave(void) { - if( vg.time - last_autosave > 20.0 ){ - if( skaterift_autosave(1) ){ - last_autosave = vg.time; + savedata_file sav; + strcpy( sav.path, str_skaterift_main_save ); + savedata_file_read( &sav ); + + vg_msg kvsav; + vg_msg_init( &kvsav, sav.buf, sizeof(sav.buf) ); + + u32 ach; + vg_msg_getkvintg( &kvsav, "ach", k_vg_msg_u32, &ach, NULL ); + skaterift.achievements |= ach; + + u32 board_reg_id = time(NULL) % addon_count( k_addon_type_board, 0 ), + player_reg_id = (time(NULL)+44) % addon_count( k_addon_type_player, 0 ); + + vg_msg_cursor orig = kvsav.cur; + if( vg_msg_seekframe( &kvsav, "player" ) ) + { + addon_alias q; + u32 reg_id; + + /* board */ + if( skaterift_read_addon_alias( &kvsav, "board", k_addon_type_board, &q ) ) + { + reg_id = addon_match( &q ); + if( reg_id != 0xffffffff ) + board_reg_id = reg_id; } + + /* playermodel */ + if( skaterift_read_addon_alias( &kvsav, "playermodel", + k_addon_type_player, &q ) ) + { + reg_id = addon_match( &q ); + if( reg_id != 0xffffffff ) + player_reg_id = reg_id; + } + + if( skaterift_read_addon_alias( &kvsav, "location", k_addon_type_world, &q ) ) + { + vg_info( "Loading client world from save.\n" ); + + reg_id = addon_match( &q ); + if( reg_id != 0xffffffff ) + { + _world.switch_to_addon = + get_addon_from_index( k_addon_type_world, reg_id, 0 ); + } + else + { + char buf[ADDON_UID_MAX]; + addon_alias_uid( &q, buf ); + + vg_error( "While loading player location from save file, " + "couldn't find addon '%s'\n", buf ); + } + } + } + + localplayer.board_view_slot = + addon_cache_create_viewer( k_addon_type_board, board_reg_id ); + localplayer.playermodel_view_slot = + addon_cache_create_viewer( k_addon_type_player, player_reg_id ); + + kvsav.cur = orig; + + if( vg_msg_seekframe( &kvsav, "story" ) ) + { + } } diff --git a/src/save.h b/src/save.h index acda301..ba19ea9 100644 --- a/src/save.h +++ b/src/save.h @@ -19,11 +19,8 @@ struct savedata_group { void savedata_file_read( savedata_file *file ); void savedata_file_write( savedata_file *file ); void savedata_group_write( savedata_group *group ); -int skaterift_autosave(int async); void skaterift_autosave_synchronous(void); void skaterift_autosave_update(void); -void skaterift_read_addon_alias( vg_msg *msg, const char *key, - enum addon_type type, - addon_alias *alias ); -void skaterift_read_main_savedata( savedata_file *file ); +int skaterift_write_all_savedata( bool async ); +void skaterift_load_mainsave(void); diff --git a/src/skaterift.c b/src/skaterift.c index 1c2d437..e56ee07 100644 --- a/src/skaterift.c +++ b/src/skaterift.c @@ -42,7 +42,6 @@ #include "ent_tornado.h" #include "ent_miniworld.h" #include "ent_skateshop.h" -#include "ent_npc.h" #include "ent_camera.h" #include "world_map.h" #include "gui.h" @@ -52,63 +51,18 @@ #include "control_overlay.h" #include "client.h" #include "skaterift_script.h" +#include "ent_challenge.h" struct skaterift_globals skaterift = { .time_rate = 1.0f, - .hub_world = "maps/dev_hub", }; void game_launch_opt(void) { const char *arg; if( (arg = vg_long_opt_arg( "world", "Specify path to world to load" )) ) - skaterift.hub_world = arg; -} - -static void async_skaterift_player_start( void *payload, u32 size ){ - world_switch_instance(0); -} - -static void skaterift_restore_state(void) -{ - savedata_file sav; - skaterift_read_main_savedata( &sav ); - - vg_msg kvsav; - vg_msg_init( &kvsav, sav.buf, sizeof(sav.buf) ); - - u32 ach; - vg_msg_getkvintg( &kvsav, "ach", k_vg_msg_u32, &ach, NULL ); - skaterift.achievements |= ach; - - u32 board_reg_id = time(NULL) % addon_count( k_addon_type_board, 0 ), - player_reg_id = (time(NULL)+44) % addon_count( k_addon_type_player, 0 ); - - vg_msg_cursor orig = kvsav.cur; - if( vg_msg_seekframe( &kvsav, "player" ) ){ - addon_alias q; - - /* board */ - skaterift_read_addon_alias( &kvsav, "board", k_addon_type_board, &q ); - u32 reg_id = addon_match( &q ); - if( reg_id != 0xffffffff ) - board_reg_id = reg_id; - - /* playermodel */ - skaterift_read_addon_alias( &kvsav, "playermodel", - k_addon_type_player, &q ); - reg_id = addon_match( &q ); - if( reg_id != 0xffffffff ) - player_reg_id = reg_id; - } - - localplayer.board_view_slot = - addon_cache_create_viewer( k_addon_type_board, board_reg_id ); - localplayer.playermodel_view_slot = - addon_cache_create_viewer( k_addon_type_player, player_reg_id ); - - kvsav.cur = orig; + skaterift.override_load_world = arg; } static addon_reg *skaterift_mount_world_unloadable( const char *path, u32 ext ){ @@ -118,24 +72,17 @@ static addon_reg *skaterift_mount_world_unloadable( const char *path, u32 ext ){ return reg; } -static void skaterift_load_world_content(void){ +static void skaterift_load_world_content(void) +{ /* hub world */ - addon_reg *hub = skaterift_mount_world_unloadable( skaterift.hub_world, 0 ); - skaterift_mount_world_unloadable( "maps/mp_spawn", - ADDON_REG_CITY|ADDON_REG_PREMIUM ); - skaterift_mount_world_unloadable( "maps/mp_mtzero", - ADDON_REG_MTZERO|ADDON_REG_PREMIUM ); + _world.default_hub_addon = + skaterift_mount_world_unloadable( "maps/dev_hub", 0 ); + skaterift_mount_world_unloadable( "maps/dev_heaven", 0 ); + skaterift_mount_world_unloadable( "maps/mp_spawn", ADDON_REG_CITY|ADDON_REG_PREMIUM ); + skaterift_mount_world_unloadable( "maps/mp_mtzero", ADDON_REG_MTZERO|ADDON_REG_PREMIUM ); skaterift_mount_world_unloadable( "maps/dev_tutorial", 0 ); skaterift_mount_world_unloadable( "maps/dev_flatworld", 0 ); skaterift_mount_world_unloadable( "maps/mp_line1", ADDON_REG_PREMIUM ); - - world_static.load_state = k_world_loader_load; - - struct world_load_args args = { - .purpose = k_world_purpose_hub, - .reg = hub - }; - skaterift_world_load_thread( &args ); } static void skaterift_load_player_content(void) @@ -155,10 +102,12 @@ static void skaterift_load_player_content(void) void game_load(void) { _skaterift_script_init(); - vg_console_reg_cmd( "load_world", skaterift_load_world_command, NULL ); + + vg_loader_set_user_information( "Initializing subsystems" ); + + vg_console_reg_cmd( "switch_world", skaterift_switch_world_command, NULL ); vg_console_reg_var( "immobile", &localplayer.immobile, k_var_dtype_i32, 0 ); vg_loader_step( menu_init, NULL ); - vg_loader_step( control_overlay_init, NULL ); vg_loader_step( world_init, NULL ); vg_loader_step( vehicle_init, NULL ); @@ -166,7 +115,6 @@ void game_load(void) vg_loader_step( player_init, NULL ); vg_loader_step( player_ragdoll_init, NULL ); - vg_loader_step( npc_init, NULL ); vg_loader_step( cutscene_init, NULL ); /* content stuff */ @@ -177,26 +125,34 @@ void game_load(void) vg_loader_step( skaterift_replay_init, NULL ); vg_loader_step( skaterift_load_player_content, NULL ); + vg_loader_set_user_information( "Compiling shaders" ); vg_bake_shaders(); - vg_loader_step( audio_init, NULL ); + vg_loader_set_user_information( "Loading content files" ); + vg_loader_step( audio_init, NULL ); vg_loader_step( skaterift_load_world_content, NULL ); - vg_async_call( async_skaterift_player_start, NULL, 0 ); - vg_async_stall(); - vg_console_load_autos(); - addon_mount_content_folder( k_addon_type_player, - "playermodels", ".mdl" ); + vg_loader_set_user_information( "Mounting addons" ); + addon_mount_content_folder( k_addon_type_player, "playermodels", ".mdl" ); addon_mount_content_folder( k_addon_type_board, "boards", ".mdl" ); addon_mount_content_folder( k_addon_type_world, "maps", ".mdl" ); addon_mount_workshop_items(); vg_async_call( async_addon_reg_update, NULL, 0 ); vg_async_stall(); - skaterift_restore_state(); - update_ach_models(); + /* initializing / loading world. */ + vg_loader_set_user_information( "Loading savedata" ); + skaterift_load_mainsave(); + + if( !_world.switch_to_addon ) + { + vg_warn( "Falling back to default hub world...\n" ); + _world.switch_to_addon = _world.default_hub_addon; + } + world_switcher_thread( NULL ); + /* add autosave function to exit list */ vg_loader_step( NULL, skaterift_autosave_synchronous ); } @@ -217,9 +173,10 @@ void vg_pre_update(void) skaterift_preupdate_inputs(); steam_update(); - skaterift_change_client_world_preupdate(); + world_switcher_update(); - if( !g_client.loaded ) return; + if( g_client.unreadyness ) + return; //draw_origin_axis(); _skaterift_script_update(); @@ -251,7 +208,8 @@ void vg_pre_update(void) /* TODO: how can we compress this? */ ent_miniworld_preupdate(); - world_entity_focus_preupdate(); + world_events_update(); + //world_entity_focus_preupdate(); if( skaterift.activity != k_skaterift_menu ) { @@ -260,25 +218,27 @@ void vg_pre_update(void) skaterift_replay_pre_update(); remote_sfx_pre_update(); - skateshop_world_preupdate( world_current_instance() ); + skateshop_world_preupdate(); - world_update( world_current_instance(), localplayer.rb.co ); - audio_ambient_sprites_update( world_current_instance(), listen_co ); + world_update( &_world.main, localplayer.rb.co ); + audio_ambient_sprites_update( &_world.main, listen_co ); world_map_pre_update(); } void vg_fixed_update(void) { - if( !g_client.loaded ) return; + if( g_client.unreadyness ) + return; - world_routes_fixedupdate( world_current_instance() ); + world_routes_fixedupdate( &_world.main ); player__update(); vehicle_update_fixed(); } void vg_post_update(void) { - if( !g_client.loaded ) return; + if( g_client.unreadyness ) + return; player__post_update(); @@ -337,40 +297,16 @@ static void render_player_transparent(void) player__render( &small_cam ); } -static world_instance *get_view_world(void) -{ - if( (skaterift.activity & k_skaterift_menu) && - (menu.page == k_menu_page_main) && - (menu.main_index == k_menu_main_guide) ) - { - return &world_static.instances[0]; - } - - world_instance *view_world = world_current_instance(); - if( localplayer.gate_waiting && - (localplayer.gate_waiting->flags & k_ent_gate_nonlocal) ){ - view_world = &world_static.instances[world_static.active_instance ^ 0x1]; - } - - return view_world; -} - static void render_scene(void) { /* Draw world */ glEnable( GL_DEPTH_TEST ); - for( u32 i=0; istatus != k_world_status_loaded ) - return; - - t = vg_smoothstepf( t ); - - glEnable( GL_STENCIL_TEST ); - glDisable( GL_DEPTH_TEST ); - glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE ); - glStencilFunc( GL_ALWAYS, 1, 0xFF ); - glStencilMask( 0xFF ); - - shader_blit_transition_use(); - shader_blit_transition_uInverseRatio( (v2f){1.0f,1.0f} ); - shader_blit_transition_uT( -(sqrtf(2)+0.5f) * t ); - - render_fsquad(); - render_world( holdout_world, &global_miniworld.cam, 1, 0, 1, 1 ); } m4x3f *_TEMP_VAR = NULL; static void skaterift_composite_maincamera(void) { - vg_camera_lerp( &localplayer.cam, &world_static.focus_cam, - vg_smoothstepf(world_static.focus_strength), &g_render.cam ); +#if 0 + vg_camera_lerp( &localplayer.cam, &_world.focus_cam, + vg_smoothstepf(_world.focus_strength), &g_render.cam ); +#endif + + vg_camera_copy( &localplayer.cam, &g_render.cam ); if( skaterift.activity == k_skaterift_replay ) { @@ -544,12 +447,8 @@ static void render_main_game(void) /* --------------------------------------------------------------------- */ if( !menu_viewing_map() ) { - world_instance *world = world_current_instance(); + world_instance *world = &_world.main; render_world_cubemaps( world ); - - ent_gate *nlg = world->rendering_gate; - if( nlg && (nlg->flags & k_ent_gate_nonlocal) ) - render_world_cubemaps( &world_static.instances[nlg->target] ); } /* variable res target */ @@ -572,7 +471,7 @@ static void render_main_game(void) if( !global_miniworld.transition && !menu_viewing_map() ) { vg_framebuffer_bind( g_render.fb_main, k_render_scale ); - render_world_gates( get_view_world(), &g_render.cam ); + render_world_gates( &_world.main, &g_render.cam ); } /* composite */ @@ -590,7 +489,7 @@ static void render_main_game(void) void vg_render(void) { - if( !g_client.loaded ) + if( g_client.unreadyness ) { vg_loader_render(); return; @@ -619,12 +518,13 @@ void vg_render(void) void vg_gui( ui_context *ctx ) { - if( !g_client.loaded ) return; + if( g_client.unreadyness ) + return; gui_draw( ctx ); if( k_light_editor ) - imgui_world_light_edit( ctx, world_current_instance() ); + imgui_world_light_edit( ctx, &_world.main ); vg_ui.tex_bg = g_render.fb_main->attachments[0].id; vg_framebuffer_inverse_ratio( g_render.fb_main, vg_ui.bg_inverse_ratio ); @@ -632,7 +532,7 @@ void vg_gui( ui_context *ctx ) _cutscene_gui( ctx ); menu_gui( ctx ); player__im_gui( ctx ); - world_instance *world = world_current_instance(); + world_instance *world = &_world.main; world_routes_imgui( ctx, world ); skaterift_replay_imgui( ctx ); @@ -640,15 +540,13 @@ void vg_gui( ui_context *ctx ) if( menu_viewing_map() ) { - remote_players_imgui_world( ctx, world_current_instance(), - vg.pv, 2000.0f, 0 ); + remote_players_imgui_world( ctx, &_world.main, vg.pv, 2000.0f, 0 ); remote_players_imgui_lobby( ctx ); } else { remote_players_chat_imgui( ctx ); /* TODO: conditional */ - remote_players_imgui_world( ctx, world_current_instance(), - vg.pv, 100.0f, 1 ); + remote_players_imgui_world( ctx, &_world.main, vg.pv, 100.0f, 1 ); } } @@ -704,7 +602,7 @@ void vg_gui( ui_context *ctx ) #include "world_sfd.c" #include "world_volumes.c" #include "world_water.c" -#include "ent_npc.c" +#include "world_events.c" #include "array_file.c" #include "model.c" #include "metascene.c" diff --git a/src/skaterift.h b/src/skaterift.h index e480d2e..2e60d10 100644 --- a/src/skaterift.h +++ b/src/skaterift.h @@ -17,17 +17,17 @@ struct skaterift_globals f32 time_rate; enum skaterift_activity { - k_skaterift_default = 0x00, + k_skaterift_default = 0x00, /* regular playing */ k_skaterift_replay = 0x01, - k_skaterift_ent_focus = 0x02, k_skaterift_menu = 0x04, } activity; + GLuint rt_textures[k_skaterift_rt_max]; u32 achievements; int demo_mode; - const char *hub_world; + const char *override_load_world; } extern skaterift; diff --git a/src/skaterift_script.c b/src/skaterift_script.c index 755c853..003b43c 100644 --- a/src/skaterift_script.c +++ b/src/skaterift_script.c @@ -41,6 +41,7 @@ static bool _skaterift_script_bind_player(void) return 0; } + _cutscene.player_binding->disable_render = 1; return 1; } @@ -63,32 +64,29 @@ static void _skaterift_dialogue( struct sr_subtitle *subtitles, u32 *index, *index = i; } -static bool _skaterift_script_intro( enum escript_event ev, const char *inf ) +static bool _skaterift_generic_script_template( + enum escript_event ev, + const char *inf, + + const char *metascene_path, + struct sr_subtitle subtitles[], + bool freeze_player ) { static u32 state, subtitle_id; - static struct cs_instance *override_inst; if( ev == k_escript_event_call ) { state = k_escript_state_loading; - override_inst = NULL; subtitle_id = 0; - vg_info( "test:state = loading\n" ); + vg_info( "generic_template:state = loading\n" ); + + if( freeze_player ) + localplayer.immobile = 1; } if( ev == k_escript_event_cutscene_marker ) { - struct sr_subtitle EN[] = { - { "a1", KCOL_JESUS "Aww hello" }, - { "a2", KCOL_JESUS "welcome to heaven." }, - { "a3", KCOL_JESUS "Not quite your time yet," }, - { "a4", KCOL_JESUS "but if you wanna take a quick look around" }, - { "a5", KCOL_JESUS "then feel free to do so." }, - { "a6", KCOL_JESUS "We've got a great grift shop on the way out!" }, - { NULL, NULL }, - }; - _skaterift_dialogue( EN, &subtitle_id, inf ); - + _skaterift_dialogue( subtitles, &subtitle_id, inf ); return 0; } @@ -97,10 +95,10 @@ static bool _skaterift_script_intro( enum escript_event ev, const char *inf ) if( state == k_escript_state_loading ) { - if( cmd_cutscene_load( 1, (const char *[]){ "metascenes/intro.ms" } ) ) + if( cmd_cutscene_load( 1, (const char *[]){ metascene_path } ) ) { state = k_escript_state_initializing; - vg_info( "test:state = initializing\n" ); + vg_info( "generic_template:state = initializing\n" ); } } @@ -110,7 +108,7 @@ static bool _skaterift_script_intro( enum escript_event ev, const char *inf ) { _skaterift_script_bind_player(); state = k_escript_state_playing; - vg_info( "test:state = playing\n" ); + vg_info( "generic_template:state = playing\n" ); _cutscene_play(); } } @@ -120,8 +118,12 @@ static bool _skaterift_script_intro( enum escript_event ev, const char *inf ) if( _cutscene.state == k_cutscene_state_done ) { state = k_escript_state_end; - vg_info( "test:state = end\n" ); + vg_info( "generic_template:state = end\n" ); _cutscene_unload(); + + if( freeze_player ) + localplayer.immobile = 0; + return 1; } } @@ -129,6 +131,22 @@ static bool _skaterift_script_intro( enum escript_event ev, const char *inf ) return 0; } +static bool _skaterift_script_intro( enum escript_event ev, const char *inf ) +{ + struct sr_subtitle EN[] = { + { "a1", KCOL_JESUS "Aww hello" }, + { "a2", KCOL_JESUS "welcome to heaven." }, + { "a3", KCOL_JESUS "Not quite your time yet," }, + { "a4", KCOL_JESUS "but if you wanna take a quick look around" }, + { "a5", KCOL_JESUS "then feel free to do so." }, + { "a6", KCOL_JESUS "We've got a great grift shop on the way out!" }, + { NULL, NULL }, + }; + + return _skaterift_generic_script_template( ev, inf, + "metascenes/intro.ms", EN, 1 ); +} + static bool _skaterift_script_ch1s2( enum escript_event ev, const char *inf ) { @@ -1767,12 +1785,15 @@ struct } static _script = { .script_id = k_escript_script_id_max }; -struct script_binding +struct script_info { const char *alias; bool( *jump )( enum escript_event ev, const char *inf ); + + bool availible; + u64 viewed_time; } -_script_bindings[] = +_script_infos[] = { [k_escript_script_id_test] = { "test", _skaterift_script_test }, [k_escript_script_id_intro] = { "intro", _skaterift_script_intro }, @@ -1798,6 +1819,11 @@ _script_bindings[] = [k_escript_script_id_ch4s3] = { "ch4s3", _skaterift_script_ch4s3 }, }; +void skaterift_script_write_savedata( vg_msg *sav ) +{ + +} + static int _skaterift_script_hook( int argc, const char *argv[] ) { if( argc != 1 ) @@ -1814,7 +1840,7 @@ static int _skaterift_script_hook( int argc, const char *argv[] ) for( u32 i=0; ialias ) ) { _script.script_id = i; @@ -1833,7 +1859,7 @@ void _skaterift_script_update(void) { if( _script.script_id != k_escript_script_id_max ) { - if( _script_bindings[ _script.script_id ].jump( k_escript_event_update, + if( _script_infos[ _script.script_id ].jump( k_escript_event_update, NULL ) ) _script.script_id = k_escript_script_id_max; } @@ -1843,7 +1869,7 @@ void _skaterift_script_marker( const char *marker ) { if( _script.script_id != k_escript_script_id_max ) { - if( _script_bindings[ _script.script_id ].jump( + if( _script_infos[ _script.script_id ].jump( k_escript_event_cutscene_marker, marker) ) _script.script_id = k_escript_script_id_max; } diff --git a/src/skaterift_script.h b/src/skaterift_script.h index 2af0e98..660b2db 100644 --- a/src/skaterift_script.h +++ b/src/skaterift_script.h @@ -3,3 +3,4 @@ void _skaterift_script_update(void); void _skaterift_script_init(void); void _skaterift_script_marker( const char *marker ); +void skaterift_script_write_savedata( vg_msg *sav ); diff --git a/src/vehicle.c b/src/vehicle.c index c0a3376..6ce6d2f 100644 --- a/src/vehicle.c +++ b/src/vehicle.c @@ -14,7 +14,7 @@ int spawn_car( int argc, const char *argv[] ) v3_muladds( ra, g_render.cam.transform[2], -10.0f, rb ); float t; - if( spherecast_world( world_current_instance(), + if( spherecast_world( &_world.main, ra, rb, 1.0f, &t, rx, 0 ) != -1 ) { v3_lerp( ra, rb, t, gzoomer.rb.co ); @@ -72,7 +72,7 @@ void vehicle_wheel_force( int index ) #if 1 float t; - if( spherecast_world( world_current_instance(), pa, pb, + if( spherecast_world( &_world.main, pa, pb, k_car_wheel_radius, &t, n, 0 ) == -1 ) { t = 1.0f; } @@ -233,7 +233,7 @@ void vehicle_update_fixed(void) rb_ct manifold[64]; int len = rb_sphere__scene( rb->to_world, 1.0f, NULL, - world_current_instance()->geo_bh, + _world.main.geo_bh, manifold, 0 ); for( int j=0; j= VG_ARRAY_LEN(world_static.instances) ){ - vg_error( "Instance ID out of range (%u)\n", index ); - return; - } - - world_instance *new = &world_static.instances[ index ]; - - if( new->status != k_world_status_loaded ){ - vg_error( "Instance is not loaded (%u)\n", index ); - return; - } - - if( skaterift.demo_mode ){ - if( world_static.instance_addons[index]->flags & ADDON_REG_PREMIUM ){ - vg_error( "Can't switch to a premium world in the demo version\n" ); - return; - } - } - - world_instance *current = - &world_static.instances[ world_static.active_instance ]; - - if( index != world_static.active_instance ){ - v3_copy( localplayer.rb.co, current->player_co ); - skaterift_autosave(1); - } - - v3_copy( new->player_co, localplayer.rb.co ); - - world_static.active_instance = index; - player__reset(); -} - -static int skaterift_switch_instance_cmd( int argc, const char *argv[] ) -{ - if( argc ) - world_switch_instance( atoi(argv[0]) ); - else - vg_info( "switch_active_instance \n" ); - return 0; } -void skaterift_world_get_save_path( enum world_purpose which, char buf[128] ) +void skaterift_world_get_save_path( addon_reg *world_reg, char buf[128] ) { - addon_reg *reg = world_static.instance_addons[ which ]; - - if( !reg ) - vg_fatal_error( "Looking up addon for world without one\n" ); - char id[76]; - addon_alias_uid( ®->alias, id ); + addon_alias_uid( &world_reg->alias, id ); snprintf( buf, 128, "savedata/%s.bkv", id ); } @@ -108,3 +47,38 @@ void world_update( world_instance *world, v3f pos ) world_sfd_update( world, pos ); world_volumes_update( world, pos ); } + +bool world_set_event( enum world_event event ) +{ + if( _world.event == k_world_event_none ) + { + vg_info( "Switched to world event: %d\n", event ); + _world.event = event; + return 1; + } + else + { + vg_warn( "World event is currently: %d. " + "Switching to other event(%d) is not allowed. This is a BUG.\n", + _world.event, event ); + return 0; + } +} + +bool world_clear_event( enum world_event event ) +{ + if( _world.event == event ) + { + vg_info( "Cleared world event\n" ); + _world.event = k_world_event_none; + return 1; + } + else + { + vg_warn( "World event is currently: %d. " + "Unsetting by other event(%d) is not allowed. This is a BUG\n", + _world.event, event ); + return 0; + } +} + diff --git a/src/world.h b/src/world.h index 30d8d63..2cff650 100644 --- a/src/world.h +++ b/src/world.h @@ -11,20 +11,15 @@ /* types */ -enum world_geo_type{ +enum world_geo_type +{ k_world_geo_type_solid = 0, k_world_geo_type_nonsolid = 1, k_world_geo_type_water = 2 }; -enum world_purpose{ - k_world_purpose_invalid = -1, - k_world_purpose_hub = 0, - k_world_purpose_client = 1, - k_world_max -}; - -struct leaderboard_cache { +struct leaderboard_cache +{ enum request_status status; f64 cache_time; u8 *data; @@ -33,7 +28,7 @@ struct leaderboard_cache { typedef struct world_instance world_instance; -void skaterift_world_get_save_path( enum world_purpose which, char buf[128] ); +void skaterift_world_get_save_path( addon_reg *world_reg, char buf[128] ); /* submodule headers */ #include "world_entity.h" @@ -48,6 +43,7 @@ void skaterift_world_get_save_path( enum world_purpose which, char buf[128] ); #include "world_audio.h" #include "world_routes.h" #include "world_routes_ui.h" +#include "world_events.h" /* console variables */ @@ -60,23 +56,13 @@ static i32 k_debug_light_indices = 0, #define WORLD_SURFACE_HAS_TRAFFIC 0x1 #define WORLD_SURFACE_HAS_PROPS 0x2 -struct world_instance { - /* Fixed items - * ------------------------------------------------------- - */ - - v4f player_co; - +struct world_instance +{ + addon_reg *addon; void *heap; - enum world_status{ - k_world_status_unloaded = 0, - k_world_status_loading = 1, - k_world_status_loaded = 2, - k_world_status_unloading = 3 /* dont spawn sounds and stuff */ - } - status; - struct{ + struct + { boxf depthbounds; int depth_computed; @@ -188,8 +174,7 @@ struct world_instance { ent_miniworld, ent_prop, ent_region, - ent_glider, - ent_npc; + ent_glider; enum skybox { k_skybox_default, @@ -225,7 +210,8 @@ struct world_instance { struct route_ui *routes_ui; }; -struct world_static { +struct world_static +{ /* * Allocated as system memory * -------------------------------------------------------------------------- @@ -233,42 +219,52 @@ struct world_static { void *heap; u32 current_run_version; - double time, rewind_from, rewind_to, last_use; + double time, rewind_from, rewind_to; u32 active_trigger_volumes[8]; u32 active_trigger_volume_count; - addon_reg *instance_addons[ k_world_max ]; - world_instance instances[ k_world_max ]; + world_instance main; + addon_reg *default_hub_addon, *switch_to_addon; - enum world_purpose active_instance; - u32 focused_entity; /* like skateshop, challenge.. */ - f32 focus_strength; - vg_camera focus_cam; - - /* challenges */ - ent_objective *challenge_target; - f32 challenge_timer; - - enum world_loader_state{ + enum world_loader_state + { k_world_loader_none, - k_world_loader_preload, - k_world_loader_load + k_world_loader_saving_current, + k_world_loader_unloading_current, + k_world_loader_ready, + k_world_loader_loading, + k_world_loader_done + } + loader_state; + + enum world_event + { + k_world_event_none = 0, + k_world_event_challenge, } - load_state; + event; - bool clear_async_op_when_done; + /* World event: Challenges */ + ent_challenge *active_challenge; + bool challenge_running; + + ent_objective *challenge_target; + f32 challenge_timer; /* unused */ } -extern world_static; +extern _world; struct world_load_args { - enum world_purpose purpose; addon_reg *reg; + world_instance *instance; + void *heap; }; void world_init(void); -world_instance *world_current_instance(void); -void world_switch_instance( u32 index ); + void skaterift_world_load_thread( void *_args ); void world_update( world_instance *world, v3f pos ); + +bool world_set_event( enum world_event activity ); +bool world_clear_event( enum world_event activity ); diff --git a/src/world_audio.c b/src/world_audio.c index be9fb72..dff4993 100644 --- a/src/world_audio.c +++ b/src/world_audio.c @@ -1,24 +1,15 @@ #include "audio.h" #include "world_audio.h" -/* finds any active playing in world and fades them out, we can only do this - * while unloading */ void world_fadeout_audio( world_instance *world ) { - if( world->status != k_world_status_unloading ){ - vg_fatal_error( "World status must be set to 'unloading', to fadeout" - " audio.\n" ); - } - - u8 world_id = (world - world_static.instances) + 1; - audio_lock(); - for( u32 i=0; iallocated && (ch->world_id == world_id) ){ - ch = audio_channel_fadeout( ch, 1.0f ); - } + if( ch->allocated && (ch->flags & AUDIO_FLAG_WORLD) ) + audio_channel_fadeout( ch, 1.0f ); } audio_unlock(); } @@ -38,7 +29,7 @@ enum audio_sprite_type world_audio_sample_sprite_random(v3f origin, v3f output) ray_hit contact; contact.dist = vg_minf( 16.0f, pos[1] ); - world_instance *world = world_current_instance(); + world_instance *world = &_world.main; if( ray_world( world, pos, (v3f){0.0f,-1.0f,0.0f}, &contact, k_material_flag_ghosts ) ){ @@ -101,7 +92,7 @@ void world_audio_sample_distances( v3f co, int *index, float *value ) float dist = 200.0f; for( int i=0; i<10; i++ ){ - if( ray_world( world_current_instance(), rc, rd, &ray, + if( ray_world( &_world.main, rc, rd, &ray, k_material_flag_ghosts ) ){ dist = (float)i*5.0f + ray.dist; break; diff --git a/src/world_entity.c b/src/world_entity.c index bbc813b..3e87cef 100644 --- a/src/world_entity.c +++ b/src/world_entity.c @@ -13,7 +13,6 @@ #include "ent_traffic.h" #include "ent_glider.h" #include "ent_region.h" -#include "ent_npc.h" #include "ent_camera.h" #include "input.h" #include "player_walk.h" @@ -28,19 +27,20 @@ bh_system bh_system_entity_list = .cast_ray = NULL }; +#if 0 void world_entity_set_focus( u32 entity_id ) { - if( world_static.focused_entity ) + if( _world.focused_entity ) { vg_warn( "Entity %u#%u tried to take focus from %u#%u\n", mdl_entity_id_type( entity_id ), mdl_entity_id_id( entity_id ), - mdl_entity_id_type( world_static.focused_entity ), - mdl_entity_id_id( world_static.focused_entity ) ); + mdl_entity_id_type( _world.focused_entity ), + mdl_entity_id_id( _world.focused_entity ) ); return; } - world_static.focused_entity = entity_id; + _world.focused_entity = entity_id; } void world_entity_focus_modal(void) @@ -60,8 +60,8 @@ void world_entity_exit_modal(void) if( skaterift.activity != k_skaterift_ent_focus ) { vg_warn( "Entity %u#%u tried to exit modal when we weren't in one\n", - mdl_entity_id_type( world_static.focused_entity ), - mdl_entity_id_id( world_static.focused_entity ) ); + mdl_entity_id_type( _world.focused_entity ), + mdl_entity_id_id( _world.focused_entity ) ); return; } @@ -76,12 +76,12 @@ void world_entity_clear_focus(void) if( skaterift.activity == k_skaterift_ent_focus ) { vg_warn( "Entity %u#%u tried to clear focus before exiting modal\n", - mdl_entity_id_type( world_static.focused_entity ), - mdl_entity_id_id( world_static.focused_entity ) ); + mdl_entity_id_type( _world.focused_entity ), + mdl_entity_id_id( _world.focused_entity ) ); return; } - world_static.focused_entity = 0; + _world.focused_entity = 0; } void world_entity_focus_camera( world_instance *world, u32 uid ) @@ -90,15 +90,15 @@ void world_entity_focus_camera( world_instance *world, u32 uid ) { u32 index = mdl_entity_id_id( uid ); ent_camera *cam = af_arritm( &world->ent_camera, index ); - ent_camera_unpack( cam, &world_static.focus_cam ); + ent_camera_unpack( cam, &_world.focus_cam ); } else { - vg_camera_copy( &localplayer.cam, &world_static.focus_cam ); + vg_camera_copy( &localplayer.cam, &_world.focus_cam ); /* TODO ? */ - world_static.focus_cam.nearz = localplayer.cam.nearz; - world_static.focus_cam.farz = localplayer.cam.farz; + _world.focus_cam.nearz = localplayer.cam.nearz; + _world.focus_cam.farz = localplayer.cam.farz; } } @@ -110,14 +110,14 @@ void world_entity_focus_preupdate(void) if( skaterift.activity == k_skaterift_ent_focus ) active = 1; - vg_slewf( &world_static.focus_strength, active, + vg_slewf( &_world.focus_strength, active, vg.time_frame_delta * (1.0f/0.5f) ); - if( world_static.focused_entity == 0 ) + if( _world.focused_entity == 0 ) return; - u32 type = mdl_entity_id_type( world_static.focused_entity ), - index = mdl_entity_id_id( world_static.focused_entity ); + u32 type = mdl_entity_id_type( _world.focused_entity ), + index = mdl_entity_id_id( _world.focused_entity ); world_instance *world = world_current_instance(); @@ -150,8 +150,8 @@ void world_entity_focus_render(void) return; } - u32 type = mdl_entity_id_type( world_static.focused_entity ), - index = mdl_entity_id_id( world_static.focused_entity ); + u32 type = mdl_entity_id_type( _world.focused_entity ), + index = mdl_entity_id_id( _world.focused_entity ); if( type == k_ent_skateshop ){ ent_skateshop *skateshop = af_arritm( &world->ent_skateshop, index ); @@ -165,6 +165,7 @@ void world_entity_focus_render(void) vg_fatal_error( "Programming error\n" ); } } +#endif void world_gen_entities_init( world_instance *world ) { @@ -261,7 +262,6 @@ void world_gen_entities_init( world_instance *world ) { k_ent_volume, &world->ent_volume }, { k_ent_challenge, &world->ent_challenge }, { k_ent_glider, &world->ent_glider }, - { k_ent_npc, &world->ent_npc } }; for( u32 i=0; istatus == k_world_status_unloading ) - { - vg_warn( "cannot modify audio while unloading world\n" ); - return k_entity_call_result_invalid; - } - - u8 world_id = (world - world_static.instances) + 1; u32 index = mdl_entity_id_id( call->id ); ent_audio *audio = af_arritm( &world->ent_audio, index ); @@ -442,7 +435,8 @@ entity_call_result ent_audio_call( world_instance *world, ent_call *call ) float chance = vg_randf64(&vg.rand)*100.0f, bar = 0.0f; - for( u32 i=0; iclip_count; i++ ){ + for( u32 i=0; iclip_count; i++ ) + { ent_audio_clip *clip = af_arritm( &world->ent_audio_clip, audio->clip_start+i ); @@ -456,9 +450,16 @@ entity_call_result ent_audio_call( world_instance *world, ent_call *call ) if( audio->behaviour == k_channel_behaviour_unlimited ) { - audio_oneshot_3d( &clip->_.clip, sound_co, - audio->transform.s[0], - audio->volume ); + audio_channel *ch = audio_get_first_idle_channel(); + + if( ch ) + { + audio_channel_init( ch, &clip->_.clip, + audio->flags|AUDIO_FLAG_WORLD ); + audio_channel_set_spacial( ch, sound_co, audio->transform.s[0] ); + audio_channel_edit_volume( ch, audio->volume, 1 ); + audio_relinquish_channel( ch ); + } } else if( audio->behaviour == k_channel_behaviour_discard_if_full ) { @@ -468,9 +469,9 @@ entity_call_result ent_audio_call( world_instance *world, ent_call *call ) if( ch ) { - audio_channel_init( ch, &clip->_.clip, audio->flags ); + audio_channel_init( ch, &clip->_.clip, + audio->flags | AUDIO_FLAG_WORLD ); audio_channel_group( ch, audio->group ); - audio_channel_world( ch, world_id ); audio_channel_set_spacial( ch, sound_co, audio->transform.s[0] ); audio_channel_edit_volume( ch, audio->volume, 1 ); ch = audio_relinquish_channel( ch ); @@ -483,12 +484,15 @@ entity_call_result ent_audio_call( world_instance *world, ent_call *call ) audio->max_channels ); /* group is full */ - if( !ch ){ + if( !ch ) + { audio_channel *existing = audio_get_group_first_active_channel( audio->group ); - if( existing ){ - if( existing->source == &clip->_.clip ){ + if( existing ) + { + if( existing->source == &clip->_.clip ) + { audio_unlock(); return k_entity_call_result_OK; } @@ -502,9 +506,9 @@ entity_call_result ent_audio_call( world_instance *world, ent_call *call ) if( ch ) { - audio_channel_init( ch, &clip->_.clip, audio->flags ); + audio_channel_init( ch, &clip->_.clip, + audio->flags | AUDIO_FLAG_WORLD ); audio_channel_group( ch, audio->group ); - audio_channel_world( ch, world_id ); audio_channel_fadein( ch, audio->crossfade ); ch = audio_relinquish_channel( ch ); } @@ -592,11 +596,6 @@ void entity_bh_expand_bound( void *user, boxf bound, u32 item_index ) m4x3_expand_aabb_aabb( transform, bound, (boxf){{-1.0f,-1.0f,-1.0f},{ 1.0f, 1.0f, 1.0f}} ); } - else if( type == k_ent_npc ) - { - ent_npc *npc = af_arritm( &world->ent_npc, index ); - box_addpt( bound, npc->transform.co ); - } else{ vg_fatal_error( "Programming error\n" ); } @@ -632,11 +631,6 @@ float entity_bh_centroid( void *user, u32 item_index, int axis ) ent_glider *glider = af_arritm( &world->ent_glider, index ); return glider->transform.co[axis]; } - else if( type == k_ent_npc ) - { - ent_npc *npc = af_arritm( &world->ent_npc, index ); - return npc->transform.co[axis]; - } else { vg_fatal_error( "Programming error\n" ); @@ -705,7 +699,8 @@ void entity_bh_debug( void *user, u32 item_index ){ void update_ach_models(void) { - world_instance *hub = &world_static.instances[k_world_purpose_hub]; +#if 0 + world_instance *hub = &_world.instances[k_world_purpose_hub]; if( hub->status != k_world_status_loaded ) return; for( u32 i=0; ient_prop ); i ++ ) @@ -730,6 +725,7 @@ void update_ach_models(void) prop->flags &= ~0x1; } } +#endif } void entity_bh_closest( void *user, u32 item_index, v3f point, v3f closest ) diff --git a/src/world_entity.h b/src/world_entity.h index c954052..a03b22e 100644 --- a/src/world_entity.h +++ b/src/world_entity.h @@ -32,6 +32,7 @@ void entity_bh_debug( void *user, u32 item_index ); void entity_bh_closest( void *user, u32 item_index, v3f point, v3f closest ); +#if 0 void world_entity_set_focus( u32 entity_id ); void world_entity_focus_modal(void); @@ -41,6 +42,8 @@ void world_entity_clear_focus(void); void world_entity_focus_preupdate(void); void world_entity_focus_render(void); void world_entity_focus_camera( world_instance *world, u32 uid ); +#endif + void update_ach_models(void); extern bh_system bh_system_entity_list; diff --git a/src/world_events.c b/src/world_events.c new file mode 100644 index 0000000..5d5f46a --- /dev/null +++ b/src/world_events.c @@ -0,0 +1,32 @@ +#include "world.h" +#include "world_events.h" + +void world_events_update(void) +{ + if( _world.event == k_world_event_challenge ) + { + if( _world.challenge_running ) + { + } + else + { + ent_challenge *challenge = _world.active_challenge; + if( challenge->flags & k_ent_challenge_is_story ) + { + if( button_down( k_srbind_maccept ) ) + { + gui_helper_reset( k_gui_helper_mode_clear ); + ent_call call; + call.data = NULL; + call.function = challenge->target_event; + call.id = challenge->target; + entity_call( &_world.main, &call ); + } + } + else + { + /* activate the actual challenge blah blah */ + } + } + } +} diff --git a/src/world_events.h b/src/world_events.h new file mode 100644 index 0000000..d8a77ee --- /dev/null +++ b/src/world_events.h @@ -0,0 +1,3 @@ +#pragma once + +void world_events_update(void); diff --git a/src/world_gate.c b/src/world_gate.c index a4e33df..fb13999 100644 --- a/src/world_gate.c +++ b/src/world_gate.c @@ -237,9 +237,11 @@ static int gate_intersect_plane( ent_gate *gate, float d = v3_dot( surface, v0 ); - if( d > 0.00001f ){ + if( d > 0.00001f ) + { float t = v3_dot(delta, surface) / d; - if( t >= 0.0f && t <= l ){ + if( t >= 0.0f && t <= l ) + { v3f local, rel; v3_muladds( last, v0, t, local ); v3_sub( gate->co[0], local, rel ); @@ -264,9 +266,11 @@ int gate_intersect( ent_gate *gate, v3f pos, v3f last ) { v2f xy; - if( gate_intersect_plane( gate, pos, last, xy ) ){ + if( gate_intersect_plane( gate, pos, last, xy ) ) + { if( (fabsf(xy[0]) <= gate->dimensions[0]) && - (fabsf(xy[1]) <= gate->dimensions[1]) ){ + (fabsf(xy[1]) <= gate->dimensions[1]) ) + { return 1; } } @@ -279,17 +283,15 @@ int gate_intersect( ent_gate *gate, v3f pos, v3f last ) */ u32 world_intersect_gates( world_instance *world, v3f pos, v3f last ) { - for( u32 i=0; ient_gate); i++ ){ + for( u32 i=0; ient_gate); i++ ) + { ent_gate *gate = af_arritm( &world->ent_gate, i ); - if( !(gate->flags & k_ent_gate_linked) ) continue; - if( gate->flags & k_ent_gate_locked ) continue; + if( !(gate->flags & k_ent_gate_linked) ) + continue; - if( gate->flags & k_ent_gate_nonlocal ){ - if( world_static.instances[gate->target].status - != k_world_status_loaded ) - continue; - } + if( gate->flags & k_ent_gate_locked ) + continue; if( gate_intersect( gate, pos, last ) ) return mdl_entity_id( k_ent_gate, i ); @@ -314,23 +316,6 @@ entity_call_result ent_gate_call( world_instance *world, ent_call *call ) } } - -/* - * detatches any nonlocal gates - */ -void world_unlink_nonlocal( world_instance *world ) -{ - for( u32 j=0; jent_gate); j ++ ) - { - ent_gate *gate = af_arritm( &world->ent_gate, j ); - - if( gate->flags & k_ent_gate_nonlocal ) - { - gate->flags &= ~k_ent_gate_linked; - } - } -} - /* * This has to be synchronous because main thread looks at gate data for * rendering, and we modify gates that the main thread has ownership of. @@ -340,73 +325,10 @@ void world_link_gates_async( void *payload, u32 size ) VG_ASSERT( vg_thread_purpose() == k_thread_purpose_main ); world_instance *world = payload; - u32 world_id = world - world_static.instances; - for( u32 j=0; jent_gate); j ++ ) { ent_gate *gate = af_arritm( &world->ent_gate, j ); gate_transform_update( gate ); - - if( skaterift.demo_mode ) - if( world_static.instance_addons[world_id]->flags & ADDON_REG_PREMIUM ) - continue; - - if( !(gate->flags & k_ent_gate_nonlocal) ) continue; - if( gate->flags & k_ent_gate_linked ) continue; - - const char *key = af_str( &world->meta.af, gate->key ); - vg_info( "key: %s\n", key ); - - for( u32 i=0; istatus != k_world_status_loaded ) continue; - vg_info( "Checking world %u for key matches\n", i ); - - for( u32 k=0; kent_gate ); k++ ){ - ent_gate *gate2 = af_arritm( &other->ent_gate, k ); - - if( !(gate2->flags & k_ent_gate_nonlocal) ) continue; - if( gate2->flags & k_ent_gate_linked ) continue; - - const char *key2 = af_str( &other->meta.af, gate2->key ); - vg_info( " key2: %s\n", key2 ); - - if( strcmp( key, key2 ) ) continue; - - vg_success( "Non-local matching pair '%s' found. (%u:%u)\n", - key, world_id, i ); - - gate->flags |= k_ent_gate_linked; - gate2->flags |= k_ent_gate_linked; - gate->target = i; - gate2->target = world_id; - - v3_copy( gate->co[0], gate2->co[1] ); - v3_copy( gate2->co[0], gate->co[1] ); - v4_copy( gate->q[0], gate2->q[1] ); - v4_copy( gate2->q[0], gate->q[1] ); - - if( world->meta.version < 102 ){ - /* LEGACY BEHAVIOUR: v101 - * this would flip both the client worlds portal's entrance and - * exit. effectively the clients portal would be the opposite - * to the hub worlds one. new behaviour is to just flip the - * destinations so the rules are consistent in each world. - */ - v4f qflip; - q_axis_angle( qflip, (v3f){0.0f,1.0f,0.0f}, VG_PIf ); - q_mul( gate->q[0], qflip, gate->q[0] ); - q_mul( gate->q[1], qflip, gate->q[1] ); - q_mul( gate2->q[1], qflip, gate2->q[1] ); - } - - gate_transform_update( gate ); - gate_transform_update( gate2 ); - - goto matched; - } - } matched:; } } diff --git a/src/world_load.c b/src/world_load.c index 438f2cf..66fed1c 100644 --- a/src/world_load.c +++ b/src/world_load.c @@ -14,28 +14,16 @@ /* * load the .mdl file located in path as a world instance */ -static void world_instance_load_mdl( u32 instance_id, const char *path ){ - world_instance *world = &world_static.instances[ instance_id ]; - world_init_blank( world ); - world->status = k_world_status_loading; - - vg_info( "Loading instance[%u]: %s\n", instance_id, path ); - - void *allocator = NULL; - if( instance_id == 0 ) allocator = world_static.heap; - else allocator = world_static.instances[instance_id-1].heap; - - u32 heap_availible = vg_linear_remaining( allocator ); - u32 min_overhead = sizeof(vg_linear_allocator); - - if( heap_availible < (min_overhead+1024) ){ - vg_fatal_error( "out of memory" ); - } - - u32 size = heap_availible - min_overhead; - void *heap = vg_create_linear_allocator( allocator, size, VG_MEMORY_SYSTEM ); +static void world_instance_load_mdl( world_instance *world, const char *path, + void *heap ) +{ + vg_loader_set_user_information( "Loading world data" ); + world_init_blank( world ); world->heap = heap; + + vg_info( "Loading world model: %s\n", path ); + mdl_context *meta = &world->meta; array_file_context *af = &meta->af; @@ -86,7 +74,6 @@ static void world_instance_load_mdl( u32 instance_id, const char *path ){ AF_LOAD_ARRAY_STRUCT( af, &world->ent_prop, ent_prop, heap ); AF_LOAD_ARRAY_STRUCT( af, &world->ent_region, ent_region, heap ); AF_LOAD_ARRAY_STRUCT( af, &world->ent_glider, ent_glider, heap ); - AF_LOAD_ARRAY_STRUCT( af, &world->ent_npc, ent_npc, heap ); array_file_ptr infos; AF_LOAD_ARRAY_STRUCT( af, &infos, ent_worldinfo, vg_mem.scratch ); @@ -116,6 +103,8 @@ static void world_instance_load_mdl( u32 instance_id, const char *path ){ world->info.flags = 0; } + vg_loader_set_user_information( "Compiling world details" ); + time_t seconds = time(NULL) % ((u32)vg_maxf(1.0f,k_day_length)*60); world->time = ((f64)(seconds)/(k_day_length*60.0)); world->time += (world->info.timezone/24.0); @@ -132,7 +121,7 @@ static void world_instance_load_mdl( u32 instance_id, const char *path ){ u64 t0 = SDL_GetPerformanceCounter(); world_gen_generate_meshes( world ); u64 t1 = SDL_GetPerformanceCounter(); - world_gen_routes_generate( instance_id ); + world_gen_routes_generate( world ); u64 t2 = SDL_GetPerformanceCounter(); world_gen_compute_light_indices( world ); u64 t3 = SDL_GetPerformanceCounter(); @@ -154,10 +143,6 @@ static void world_instance_load_mdl( u32 instance_id, const char *path ){ vg_info( "wtime:mesh %.2fms route %.2fms ind %.2fms tex %.2fms ent %.2fms\n", ftime_mesh, ftime_route, ftime_ind, ftime_tex, ftime_ent ); - /* init player position. - * - this is overriden by the save state when(if) it loads */ - world_default_spawn_pos( world, world->player_co ); - /* allocate leaderboard buffers */ u32 bs = af_arrcount(&world->ent_route)*sizeof(struct leaderboard_cache); world->leaderboard_cache = vg_linear_alloc( heap, bs ); @@ -174,180 +159,249 @@ static void world_instance_load_mdl( u32 instance_id, const char *path ){ world->routes_ui = vg_linear_alloc( heap, sizeof(struct route_ui)*af_arrcount(&world->ent_route) ); + vg_loader_set_user_information( "Postprocessing world" ); vg_async_call( async_world_postprocess, world, 0 ); vg_async_stall(); -} -struct world_load_complete_data{ - savedata_file save; - enum world_purpose purpose; -}; + vg_loader_set_user_information( NULL ); +} -static void skaterift_world_load_done( void *payload, u32 size ) +static void async_world_loader_done( void *payload, u32 size ) { - struct world_load_complete_data *data = payload; - world_instance *world = &world_static.instances[ data->purpose ]; - - vg_msg sav; - vg_msg_init( &sav, data->save.buf, data->save.len ); - - if( data->purpose != k_world_purpose_hub ) - { - vg_msg player_frame = sav; - if( vg_msg_seekframe( &player_frame, "player" ) ) - { - vg_msg_getkvvecf( &player_frame, "position", k_vg_msg_v3f, - world->player_co, NULL ); - } - } - - world_entity_start( world, &sav ); - world->status = k_world_status_loaded; - world_static.load_state = k_world_loader_none; - - if( world_static.clear_async_op_when_done ) - { - g_client.loaded = 1; - world_static.clear_async_op_when_done = 0; - } + _world.loader_state = k_world_loader_done; } -/* - * Does a complete world switch using the remaining free slots - */ void skaterift_world_load_thread( void *_args ) { - struct world_load_args args = *((struct world_load_args *)_args); + vg_loader_set_user_information( "Scanning world directory" ); - addon_reg *reg = args.reg; - world_static.instance_addons[ args.purpose ] = reg; + struct world_load_args args = *((struct world_load_args *)_args); + args.instance->addon = args.reg; char uid[ADDON_UID_MAX]; - addon_alias_uid( ®->alias, uid ); - vg_info( "LOAD WORLD %s @%d\n", uid, args.purpose ); + addon_alias_uid( &args.reg->alias, uid ); + vg_info( "LOAD WORLD %s @%d\n", uid ); char path_buf[4096]; vg_str path; vg_strnull( &path, path_buf, 4096 ); - addon_get_content_folder( reg, &path, 1 ); + addon_get_content_folder( args.reg, &path, 1 ); vg_str folder = path; - if( !vg_strgood( &folder ) ) { + if( !vg_strgood( &folder ) ) + { vg_error( "Load target too long\n" ); return; } - char worlds[k_world_max-1][4096]; - u32 i=0; + char mdl_path[4096]; + + bool found_any_mdl = 0, + found_main_mdl = 0; vg_dir dir; - if( !vg_dir_open(&dir, folder.buffer) ){ + if( !vg_dir_open(&dir, folder.buffer) ) + { vg_error( "opendir('%s') failed\n", folder.buffer ); return; } - while( vg_dir_next_entry(&dir) ){ - if( vg_dir_entry_type(&dir) == k_vg_entry_type_file ){ + while( vg_dir_next_entry(&dir) ) + { + if( vg_dir_entry_type(&dir) == k_vg_entry_type_file ) + { const char *d_name = vg_dir_entry_name(&dir); - if( d_name[0] == '.' ) continue; + if( d_name[0] == '.' ) + continue; vg_str file = folder; vg_strcat( &file, "/" ); vg_strcat( &file, d_name ); - if( !vg_strgood( &file ) ) continue; + if( !vg_strgood( &file ) ) + continue; char *ext = vg_strch( &file, '.' ); - if( !ext ) continue; - if( strcmp(ext,".mdl") ) continue; + if( !ext ) + continue; + + if( strcmp(ext,".mdl") ) + continue; - if( i == k_world_max-1 ){ - vg_warn( "There are too many .mdl files in the map folder!(3)\n" ); + if( !strcmp( d_name, "main.mdl" ) ) + { + found_any_mdl = 1; + found_main_mdl = 1; + strcpy( mdl_path, file.buffer ); break; } - - strcpy( worlds[i++], file.buffer ); + else + { + if( !found_any_mdl ) + { + found_any_mdl = 1; + strcpy( mdl_path, file.buffer ); + } + } } } vg_dir_close(&dir); - if( i == 0 ){ - vg_warn( "There are no .mdl files in the map folder.\n" ); - } - - u32 first_index = 0; - for( u32 j=0; jsave.buf, data->save.len ); - struct world_load_complete_data *data = final_call->payload; - data->purpose = args.purpose; + /* start entities in the world */ + world_entity_start( data->instance, &sav ); + world_default_spawn_pos( data->instance, localplayer.rb.co ); - skaterift_world_get_save_path( args.purpose, data->save.path ); + /* start player in the world */ + vg_msg_init( &sav, data->save.buf, data->save.len ); + vg_msg player_frame = sav; + if( vg_msg_seekframe( &player_frame, "player" ) ) + { + vg_msg_getkvvecf( &player_frame, "position", k_vg_msg_v3f, + localplayer.rb.co, NULL ); + } + player__reset(); +} + +void load_player_from_world_savedata_thread( void *_args ) +{ + struct world_load_args *args = _args; + + vg_async_item *call = vg_async_alloc( sizeof(struct world_savedata_thread_data) ); + struct world_savedata_thread_data *data = call->payload; + + data->instance = args->instance; + skaterift_world_get_save_path( args->reg, data->save.path ); savedata_file_read( &data->save ); - vg_async_dispatch( final_call, skaterift_world_load_done ); + vg_async_dispatch( call, async_start_player_from_worldsave ); vg_async_stall(); } -void skaterift_change_client_world_preupdate(void) +void async_world_switcher_done( void *payload, u32 size ) { - if( world_static.load_state != k_world_loader_preload ) + _world.switch_to_addon = NULL; + g_client.unreadyness --; +} + +void world_switcher_thread( void *_ ) +{ + struct world_load_args args = + { + .reg = _world.switch_to_addon, + .instance = &_world.main, + .heap = _world.heap + }; + + skaterift_world_load_thread( &args ); + vg_async_stall(); + + load_player_from_world_savedata_thread( &args ); + vg_async_stall(); + + vg_async_call( async_world_switcher_done, NULL, 0 ); +} + +void world_switcher_update(void) +{ + if( !_world.switch_to_addon ) return; - /* holding pattern before we can start loading the new world, since we might - * be waiting for audio to stop */ - for( u32 i=1; istatus == k_world_status_unloading ) + if( skaterift_write_all_savedata(1) ) { - if( world_freeable( inst ) ) - { - world_free( inst ); - } - return; + _world.loader_state = k_world_loader_unloading_current; + vg_loader_set_user_information( "Unloading current world" ); } } - if( vg_loader_availible() ) + /* pre-load step aka waiting for audio to end. */ + if( _world.loader_state == k_world_loader_unloading_current ) { - vg_info( "worlds cleared, begining load\n" ); - world_static.load_state = k_world_loader_load; + bool all_world_audio_stopped = 1; + audio_lock(); + for( u32 i=0; iallocated && (ch->flags & AUDIO_FLAG_WORLD)) + { + if( !audio_channel_finished( ch ) ) + { + all_world_audio_stopped = 0; + break; + } + } + } + audio_unlock(); + + if( !all_world_audio_stopped ) + return; - vg_linear_clear( vg_async.buffer ); - struct world_load_args *args = - vg_linear_alloc( vg_async.buffer, sizeof(struct world_load_args) ); - args->purpose = k_world_purpose_client; - args->reg = world_static.instance_addons[ k_world_purpose_client ]; + world_instance_free_graphics_data( &_world.main ); + _world.loader_state = k_world_loader_ready; + vg_loader_set_user_information( "Waiting for loading thread" ); + } - /* this is replaces the already correct reg but we have to set it again - * TOO BAD */ + if( _world.loader_state == k_world_loader_ready ) + { + if( vg_loader_availible() ) + { + _world.loader_state = k_world_loader_loading; - /* finally can start the loader */ - vg_loader_start( skaterift_world_load_thread, args ); + vg_linear_clear( vg_async.buffer ); + vg_linear_clear( _world.heap ); + vg_loader_start( world_switcher_thread, NULL ); + } } } -/* - * places all loaded worlds into unloading state, pass NULL to reload the world - */ -void skaterift_change_world_start( addon_reg *reg ) +void skaterift_switch_world_start( addon_reg *reg ) { - if( world_static.instance_addons[ k_world_purpose_client ] == reg ) + if( g_client.unreadyness ) + { + vg_error( "Cannot start changeworld while client is not ready?\n" ); + return; + } + + if( _world.loader_state != k_world_loader_done ) + { + vg_error( "Cannot start changeworld while loader is not done?\n" ); + return; + } + + if( _world.main.addon == reg ) { vg_warn( "World is already loaded\n" ); return; @@ -355,48 +409,34 @@ void skaterift_change_world_start( addon_reg *reg ) if( !reg ) { - if( world_static.instance_addons[ k_world_purpose_client ] ) + if( _world.main.addon ) { - reg = world_static.instance_addons[ k_world_purpose_client ]; - world_static.clear_async_op_when_done = 1; + reg = _world.main.addon; } - else + else { - vg_warn( "No client world loaded\n" ); + vg_error( "Loaded world has no associated addon registration." + " Can't reload this!\n" ); return; } } - world_static.load_state = k_world_loader_preload; - - if( world_static.active_instance != 0 ) - g_client.loaded = 0; + g_client.unreadyness ++; + _world.loader_state = k_world_loader_saving_current; + vg_loader_set_user_information( "Saving current world" ); char buf[76]; addon_alias_uid( ®->alias, buf ); vg_info( "switching to: %s\n", buf ); - skaterift_autosave(1); vg_linear_clear( vg_mem.scratch ); /* ?? */ - vg_info( "unloading old worlds\n" ); + world_fadeout_audio( &_world.main ); - world_instance *client_world = - &world_static.instances[ k_world_purpose_client ]; - - if( client_world->status == k_world_status_loaded ) - { - client_world->status = k_world_status_unloading; - world_fadeout_audio( client_world ); - } - - world_static.instance_addons[ k_world_purpose_client ] = reg; - network_send_item( k_netmsg_playeritem_world1 ); - relink_all_remote_player_worlds(); - world_unlink_nonlocal( &world_static.instances[k_world_purpose_hub] ); + _world.switch_to_addon = reg; } /* console command for the above function */ -int skaterift_load_world_command( int argc, const char *argv[] ) +int skaterift_switch_world_command( int argc, const char *argv[] ) { if( !vg_loader_availible() ) { @@ -408,7 +448,7 @@ int skaterift_load_world_command( int argc, const char *argv[] ) { if( !strcmp( argv[0], "reload" ) ) { - skaterift_change_world_start( NULL ); + skaterift_switch_world_start( NULL ); return 0; } @@ -419,7 +459,7 @@ int skaterift_load_world_command( int argc, const char *argv[] ) if( reg_id != 0xffffffff ) { addon_reg *reg = get_addon_from_index( k_addon_type_world, reg_id, 0 ); - skaterift_change_world_start( reg ); + skaterift_switch_world_start( reg ); } else { @@ -447,53 +487,13 @@ int skaterift_load_world_command( int argc, const char *argv[] ) return 0; } -/* - * checks: - * 1. to see if all audios owned by the world have been stopped - * 2. that this is the least significant world - */ -int world_freeable( world_instance *world ) -{ - if( world->status != k_world_status_unloading ) return 0; - u8 world_id = (world - world_static.instances) + 1; - - for( u32 i=world_id; iallocated && (ch->world_id == world_id)){ - if( !audio_channel_finished( ch ) ){ - freeable = 0; - break; - } - } - } - audio_unlock(); - return freeable; -} - -/* - * Free all resources for world instance - */ -void world_free( world_instance *world ) +void world_instance_free_graphics_data( world_instance *world ) { - vg_info( "Free world @%p\n", world ); - /* free meshes */ mesh_free( &world->mesh_route_lines ); mesh_free( &world->mesh_geo ); mesh_free( &world->mesh_no_collide ); - /* glDeleteBuffers silently ignores 0's and names that do not correspond to - * existing buffer objects. - * */ glDeleteBuffers( 1, &world->tbo_light_entities ); glDeleteTextures( 1, &world->tex_light_entities ); glDeleteTextures( 1, &world->tex_light_cubes ); @@ -501,20 +501,13 @@ void world_free( world_instance *world ) /* delete textures and meshes */ glDeleteTextures( world->texture_count-1, world->textures+1 ); - u32 world_index = world - world_static.instances; - if( world_index ){ - vg_linear_del( world_static.instances[world_index-1].heap, - vg_linear_header(world->heap) ); - } - - for( u32 i=0; ient_cubemap); i++ ){ + for( u32 i=0; ient_cubemap); i++ ) + { ent_cubemap *cm = af_arritm(&world->ent_cubemap,i); glDeleteTextures( 1, &cm->texture_id ); glDeleteFramebuffers( 1, &cm->framebuffer_id ); glDeleteRenderbuffers( 1, &cm->renderbuffer_id ); } - - world->status = k_world_status_unloaded; } /* diff --git a/src/world_load.h b/src/world_load.h index 038233d..fbd9226 100644 --- a/src/world_load.h +++ b/src/world_load.h @@ -4,8 +4,8 @@ #include "world.h" #include "addon.h" -void world_free( world_instance *world ); -int world_freeable( world_instance *world ); -int skaterift_load_world_command( int argc, const char *argv[] ); -void skaterift_change_world_start( addon_reg *reg ); -void skaterift_change_client_world_preupdate(void); +int skaterift_switch_world_command( int argc, const char *argv[] ); +void skaterift_switch_world_start( addon_reg *reg ); +void world_switcher_update(void); +void world_switcher_thread( void *_ ); +void world_instance_free_graphics_data( world_instance *world ); diff --git a/src/world_map.c b/src/world_map.c index 5287aff..4dbacfd 100644 --- a/src/world_map.c +++ b/src/world_map.c @@ -19,10 +19,8 @@ static void world_map_get_dir( v3f dir ) static void world_map_get_plane( v4f plane ) { - world_instance *world = &world_static.instances[ world_map.world_id ]; + world_instance *world = &_world.main; f32 h = localplayer.rb.co[1]; - if( world_map.world_id != world_static.active_instance ) - h = (world->scene_geo.bbx[0][1] + world->scene_geo.bbx[1][1]) * 0.5f; v4_copy( (v4f){0.0f,1.0f,0.0f,h}, plane ); } @@ -57,7 +55,7 @@ static void respawn_map_draw_icon( vg_camera *cam, static void world_map_select_close(void) { world_map.sel_spawn = world_map.close_spawn; - gui_helper_clear(); + gui_helper_reset( k_gui_helper_mode_default ); vg_str text; if( gui_new_helper( input_button_list[k_srbind_maccept], &text ) ) @@ -73,7 +71,7 @@ void world_map_click(void) static void world_map_help_normal(void) { - gui_helper_clear(); + gui_helper_reset( k_gui_helper_mode_default ); vg_str text; if( gui_new_helper( input_joy_list[k_srjoystick_steer], &text ) ) @@ -84,13 +82,6 @@ static void world_map_help_normal(void) if( gui_new_helper( input_button_list[k_srbind_mback], &text ) ) vg_strcat( &text, "Exit" ); - - if( world_static.instances[1].status == k_world_status_loaded ) - { - if( gui_new_helper( input_button_list[k_srbind_mhub], &text ) ) - vg_strcat( &text, world_static.active_instance? - "Go to Hub": "Go to Active World" ); - } } void world_map_pre_update(void) @@ -99,12 +90,9 @@ void world_map_pre_update(void) { if( !world_map.view_ready ) { - world_map.world_id = world_static.active_instance; - - world_instance *world = &world_static.instances[ world_map.world_id ]; + world_instance *world = &_world.main; v3f *bbx = world->scene_geo.bbx; - v3_copy( localplayer.rb.co, world->player_co ); respawn_world_to_plane_pos( localplayer.rb.co, world_map.plane_pos ); world_map.boom_dist = 400.0f; world_map.home_select = 0; @@ -119,14 +107,14 @@ void world_map_pre_update(void) { if( world_map.view_ready ) { - gui_helper_clear(); + gui_helper_reset( k_gui_helper_mode_clear ); world_map.view_ready = 0; } return; } - world_instance *world = &world_static.instances[ world_map.world_id ]; + world_instance *world = &_world.main; v3f *bbx = world->scene_geo.bbx; f32 *pos = world_map.plane_pos; @@ -211,7 +199,6 @@ void world_map_pre_update(void) if( world_map.sel_spawn ) { skaterift.activity = k_skaterift_default; - world_static.active_instance = world_map.world_id; srinput.state = k_input_state_resume; player__spawn( world_map.sel_spawn ); return; diff --git a/src/world_map.h b/src/world_map.h index 3899363..fc29d78 100644 --- a/src/world_map.h +++ b/src/world_map.h @@ -7,7 +7,6 @@ struct world_map { v2f plane_pos; f32 boom_dist; - u32 world_id; u32 home_select; ent_spawn *sel_spawn, *close_spawn; diff --git a/src/world_render.c b/src/world_render.c index a5e700c..f30e97a 100644 --- a/src/world_render.c +++ b/src/world_render.c @@ -10,13 +10,12 @@ #include "ent_miniworld.h" #include "player_remote.h" #include "ent_skateshop.h" -#include "ent_npc.h" #include "shaders/model_entity.h" struct world_render world_render; static int ccmd_set_time( int argc, const char *argv[] ){ - world_instance *world = world_current_instance(); + world_instance *world = &_world.main; if( argc == 1 ) world->time = atof( argv[0] ); else @@ -27,18 +26,16 @@ static int ccmd_set_time( int argc, const char *argv[] ){ static void async_world_render_init( void *payload, u32 size ) { vg_info( "Allocate uniform buffers\n" ); - for( int i=0; iubo_bind_point = i; - glGenBuffers( 1, &world->ubo_lighting ); - glBindBuffer( GL_UNIFORM_BUFFER, world->ubo_lighting ); - glBufferData( GL_UNIFORM_BUFFER, sizeof(struct ub_world_lighting), - NULL, GL_DYNAMIC_DRAW ); + world_instance *world = &_world.main; + world->ubo_bind_point = 0; - glBindBufferBase( GL_UNIFORM_BUFFER, i, world->ubo_lighting ); - } + glGenBuffers( 1, &world->ubo_lighting ); + glBindBuffer( GL_UNIFORM_BUFFER, world->ubo_lighting ); + glBufferData( GL_UNIFORM_BUFFER, sizeof(struct ub_world_lighting), + NULL, GL_DYNAMIC_DRAW ); + + glBindBufferBase( GL_UNIFORM_BUFFER, 0, world->ubo_lighting ); } void world_render_init(void) @@ -68,24 +65,21 @@ void world_render_init(void) &world_render.tex_terrain_noise ); vg_info( "Allocate frame buffers\n" ); - for( int i=0; iheightmap = vg_framebuffer_allocate( vg_mem.rtmemory, 1, 0 ); + world->heightmap->display_name = NULL; + world->heightmap->fixed_w = 1024; + world->heightmap->fixed_h = 1024; + world->heightmap->resolution_div = 0; + world->heightmap->attachments[0] = (vg_framebuffer_attachment) { - world_instance *world = &world_static.instances[i]; - world->heightmap = vg_framebuffer_allocate( vg_mem.rtmemory, 1, 0 ); - world->heightmap->display_name = NULL; - world->heightmap->fixed_w = 1024; - world->heightmap->fixed_h = 1024; - world->heightmap->resolution_div = 0; - world->heightmap->attachments[0] = (vg_framebuffer_attachment) - { - NULL, k_framebuffer_attachment_type_texture, - .internalformat = GL_RG16F, - .format = GL_RG, - .type = GL_FLOAT, - .attachment = GL_COLOR_ATTACHMENT0 - }; - vg_framebuffer_create( world->heightmap ); - } + NULL, k_framebuffer_attachment_type_texture, + .internalformat = GL_RG16F, + .format = GL_RG, + .type = GL_FLOAT, + .attachment = GL_COLOR_ATTACHMENT0 + }; + vg_framebuffer_create( world->heightmap ); vg_async_call( async_world_render_init, NULL, 0 ); } @@ -494,9 +488,10 @@ static void render_world_foliage( world_instance *world, vg_camera *cam ) static void world_render_challenges( world_instance *world, struct world_pass *pass, v3f pos ) { +#if 0 if( !world ) return; if( skaterift.activity == k_skaterift_replay ) return; - if( world != world_current_instance() ) return; + if( world != &_world.main ) return; /* sort lists */ f32 radius = 40.0f; @@ -511,19 +506,19 @@ static void world_render_challenges( world_instance *world, ent_challenge *active_challenge = NULL; int running = 0; - if( mdl_entity_id_type( world_static.focused_entity ) == k_ent_challenge ) + if( mdl_entity_id_type( _world.focused_entity ) == k_ent_challenge ) { if( (skaterift.activity == k_skaterift_default) && - world_static.challenge_target ) + _world.challenge_target ) { running = 1; } if( !((skaterift.activity != k_skaterift_ent_focus) && - !world_static.challenge_target) ) + !_world.challenge_target) ) { - world_instance *challenge_world = world_current_instance(); - u32 index = mdl_entity_id_id( world_static.focused_entity ); + world_instance *challenge_world = &_world.main; + u32 index = mdl_entity_id_id( _world.focused_entity ); active_challenge = af_arritm(&challenge_world->ent_challenge, index); } } @@ -532,7 +527,7 @@ static void world_render_challenges( world_instance *world, { shader_scene_fxglow_uUvOffset( (v2f){ 8.0f/256.0f, 0.0f } ); challenge_list[ challenge_count ++ ] = - mdl_entity_id_id( world_static.focused_entity ); + mdl_entity_id_id( _world.focused_entity ); u32 next = active_challenge->first; while( mdl_entity_id_type(next) == k_ent_objective ) @@ -591,7 +586,7 @@ static void world_render_challenges( world_instance *world, vg_slewf(&objective->transform.s[0], target, vg.time_frame_delta*4.0f); scale = vg_smoothstepf( objective->transform.s[0] ); - if( (objective == world_static.challenge_target) || passed ) + if( (objective == _world.challenge_target) || passed ) shader_scene_fxglow_uUvOffset( (v2f){ 16.0f/256.0f, 0.0f } ); else shader_scene_fxglow_uUvOffset( (v2f){ 8.0f/256.0f, 0.0f } ); @@ -668,6 +663,7 @@ static void world_render_challenges( world_instance *world, shader_scene_font_uColourize( colour ); font3d_simple_draw( 1, buf, &g_render.cam, mmdl ); } +#endif } static void bindpoint_fxglow( world_instance *world, @@ -873,7 +869,8 @@ void render_world_gates( world_instance *world, vg_camera *cam ) float closest = INFINITY; struct ent_gate *gate = NULL; - for( u32 i=0; ient_gate); i++ ){ + for( u32 i=0; ient_gate); i++ ) + { ent_gate *gi = af_arritm( &world->ent_gate, i ); if( !(gi->flags & k_ent_gate_nonlocal) ) @@ -884,7 +881,8 @@ void render_world_gates( world_instance *world, vg_camera *cam ) vg_line_point( gi->co[0], 0.25f, VG__BLUE ); - if( dist < closest ){ + if( dist < closest ) + { closest = dist; gate = gi; } @@ -892,22 +890,16 @@ void render_world_gates( world_instance *world, vg_camera *cam ) world->rendering_gate = gate; - if( gate ){ - if( gate->flags & k_ent_gate_locked ){ + if( gate ) + { + if( gate->flags & k_ent_gate_locked ) + { world->rendering_gate = NULL; return; } - if( gate->flags & k_ent_gate_nonlocal ){ - if( !(gate->flags & k_ent_gate_linked) || - (world_static.load_state != k_world_loader_none) ){ - world->rendering_gate = NULL; - render_gate_unlinked( world, gate, cam ); - return; - } - - world_instance *dest_world = &world_static.instances[ gate->target ]; - render_gate( world, dest_world, gate, cam ); + if( gate->flags & k_ent_gate_nonlocal ) + { } else render_gate( world, world, gate, cam ); @@ -976,9 +968,7 @@ static void render_other_entities( world_instance *world, vg_camera *cam ) bh_iter_init_range( 0, &it, cam->pos, radius+10.0f ); u32 glider_list[4], - glider_count = 0, - npc_list[4], - npc_count = 0; + glider_count = 0; i32 idx; while( bh_next( world->entity_bh, &it, &idx ) ){ @@ -991,11 +981,6 @@ static void render_other_entities( world_instance *world, vg_camera *cam ) if( glider_count < VG_ARRAY_LEN(glider_list) ) glider_list[ glider_count ++ ] = index; } - else if( type == k_ent_npc ) - { - if( npc_count < VG_ARRAY_LEN(npc_list) ) - npc_list[ npc_count ++ ] = index; - } } shader_model_entity_use(); @@ -1021,14 +1006,6 @@ static void render_other_entities( world_instance *world, vg_camera *cam ) render_glider_model( cam, world, mdl, k_board_shader_entity ); } - for( u32 j=0; jent_npc, npc_list[j] ); - npc_update( npc ); - npc_render( npc, world, cam ); - } - cutscene_render( world, cam ); } @@ -1063,7 +1040,9 @@ void render_world( world_instance *world, vg_camera *cam, render_terrain( world, cam ); if( !viewing_from_gate ){ +#if 0 world_entity_focus_render(); +#endif /* Render SFD's */ u32 closest = 0; @@ -1087,8 +1066,10 @@ void render_world( world_instance *world, vg_camera *cam, if( !viewing_from_gate ){ f32 greyout = 0.0f; - if( mdl_entity_id_type(world_static.focused_entity) == k_ent_challenge ) - greyout = world_static.focus_strength; +#if 0 + if( mdl_entity_id_type(_world.focused_entity) == k_ent_challenge ) + greyout = _world.focus_strength; +#endif if( greyout > 0.0f ){ glDrawBuffers( 1, (GLenum[]){ GL_COLOR_ATTACHMENT0 } ); @@ -1212,7 +1193,7 @@ void render_world_override( world_instance *world, v4f uPlayerPos, uSpawnPos; v4_zero( uPlayerPos ); v4_zero( uSpawnPos ); - v3_copy( world->player_co, uPlayerPos ); + v3_copy( (v3f){0,0,0}, uPlayerPos ); if( dest_spawn && (v3_dist2(dest_spawn->transform.co,uPlayerPos) > 0.1f) ) v3_copy( dest_spawn->transform.co, uSpawnPos ); diff --git a/src/world_routes.c b/src/world_routes.c index 4a01773..d677a70 100644 --- a/src/world_routes.c +++ b/src/world_routes.c @@ -37,8 +37,7 @@ void world_routes_clear( world_instance *world ) rg->timing_time = 0.0; } - world_static.current_run_version += 4; - world_static.last_use = 0.0; + _world.current_run_version += 4; } static void world_routes_time_lap( world_instance *world, ent_route *route ) @@ -85,14 +84,14 @@ static void world_routes_time_lap( world_instance *world, ent_route *route ) last_cp = cp; } - if( world_static.current_run_version == last_version+1 ){ + if( _world.current_run_version == last_version+1 ){ valid_sections ++; if( route->checkpoints_count == 1 ){ - route->timing_base = world_static.time; + route->timing_base = _world.time; } - f32 section = world_static.time - last_time; + f32 section = _world.time - last_time; if( (section < last_cp->best_time) || (last_cp->best_time == 0.0f) ){ last_cp->best_time = section; } @@ -100,11 +99,11 @@ static void world_routes_time_lap( world_instance *world, ent_route *route ) else valid_sections = 0; vg_info( "%u %f [%s]\n", - world_static.current_run_version, world_static.time, + _world.current_run_version, _world.time, !localplayer.rewinded_since_last_gate? "CLEAN": " " ); if( valid_sections==route->checkpoints_count ){ - f64 lap_time = world_static.time - start_time; + f64 lap_time = _world.time - start_time; if( (route->best_laptime == 0.0) || (lap_time < route->best_laptime) ){ route->best_laptime = lap_time; @@ -123,8 +122,7 @@ static void world_routes_time_lap( world_instance *world, ent_route *route ) } } - addon_alias *alias = - &world_static.instance_addons[ world_static.active_instance ]->alias; + addon_alias *alias = &_world.main.addon->alias; char mod_uid[ ADDON_UID_MAX ]; addon_alias_uid( alias, mod_uid ); @@ -147,7 +145,6 @@ static void world_routes_time_lap( world_instance *world, ent_route *route ) */ void world_routes_activate_entry_gate( world_instance *world, ent_gate *rg ) { - world_static.last_use = world_static.time; ent_gate *dest = af_arritm( &world->ent_gate, rg->target ); for( u32 i=0; ient_route); i++ ){ @@ -175,8 +172,8 @@ void world_routes_activate_entry_gate( world_instance *world, ent_gate *rg ) } } - dest->timing_version = world_static.current_run_version; - dest->timing_time = world_static.time; + dest->timing_version = _world.current_run_version; + dest->timing_time = _world.time; if( localplayer.rewinded_since_last_gate ){ localplayer.rewinded_since_last_gate = 0; @@ -185,7 +182,7 @@ void world_routes_activate_entry_gate( world_instance *world, ent_gate *rg ) else dest->flags |= k_ent_gate_clean_pass; - world_static.current_run_version ++; + _world.current_run_version ++; } /* draw lines along the paths */ @@ -483,9 +480,8 @@ struct world_surface *world_tri_index_surface( world_instance *world, /* * Create the strips of colour that run through the world along course paths */ -void world_gen_routes_generate( u32 instance_id ) +void world_gen_routes_generate( world_instance *world ) { - world_instance *world = &world_static.instances[ instance_id ]; vg_info( "Generating route meshes\n" ); vg_async_stall(); @@ -653,14 +649,13 @@ void world_routes_recv_scoreboard( world_instance *world, void world_routes_init(void) { - world_static.current_run_version = 200; - world_static.time = 300.0; - world_static.last_use = 0.0; + _world.current_run_version = 200; + _world.time = 300.0; } void world_routes_update( world_instance *world ) { - world_static.time += vg.time_delta; + _world.time += vg.time_delta; for( u32 i=0; ient_route); i++ ){ ent_route *route = af_arritm( &world->ent_route, i ); @@ -773,7 +768,7 @@ void world_routes_update_timer_texts( world_instance *world ) if( route->valid_checkpoints >= route->checkpoints_count ) { - double lap_time = world_static.time - route->timing_base, + double lap_time = _world.time - route->timing_base, time_centiseconds = lap_time * 100.0; if( time_centiseconds > (float)0xfffe ) time_centiseconds = 0.0; diff --git a/src/world_routes.h b/src/world_routes.h index 621c28a..ae1ade0 100644 --- a/src/world_routes.h +++ b/src/world_routes.h @@ -19,7 +19,7 @@ void render_world_routes( world_instance *world, int viewing_from_gate, int viewing_from_hub ); void world_gen_routes_ent_init( world_instance *world ); -void world_gen_routes_generate( u32 instance_id ); +void world_gen_routes_generate( world_instance *world ); void world_routes_update_timer_texts( world_instance *world ); void world_routes_update( world_instance *world ); void world_routes_fixedupdate( world_instance *world ); diff --git a/src/world_routes_ui.c b/src/world_routes_ui.c index a85ca62..ed430ca 100644 --- a/src/world_routes_ui.c +++ b/src/world_routes_ui.c @@ -52,10 +52,10 @@ static void ent_route_imgui( ui_context *ctx, last_cp = cp; } - if( last_version+1 == world_static.current_run_version ){ + if( last_version+1 == _world.current_run_version ){ struct time_block *block = &blocks[ valid_sections ++ ]; block->clean = localplayer.rewinded_since_last_gate? 0: 1; - block->length = world_static.time - last_time; + block->length = _world.time - last_time; block->best = last_cp->best_time; } else diff --git a/src/world_sfd.c b/src/world_sfd.c index fcb3a5c..d3362ed 100644 --- a/src/world_sfd.c +++ b/src/world_sfd.c @@ -175,7 +175,7 @@ void world_sfd_compile_scores( struct leaderboard_cache *board, void world_sfd_compile_active_scores(void) { - world_instance *world = world_current_instance(); + world_instance *world = &_world.main; struct leaderboard_cache *board = NULL; const char *name = "Out of range"; @@ -209,13 +209,14 @@ void world_sfd_update( world_instance *world, v3f pos ) struct leaderboard_cache *board = &world->leaderboard_cache[ closest ]; /* request new board if cache expires */ - if( network_connected() ){ + if( network_connected() ) + { f64 delta = vg.time_real - board->cache_time; - if( (delta > 45.0) || (board->cache_time == 0.0) ){ + if( (delta > 45.0) || (board->cache_time == 0.0) ) + { board->cache_time = vg.time_real; ent_route *route = af_arritm( &world->ent_route, closest ); - addon_reg *world_reg = - world_static.instance_addons[ world - world_static.instances ]; + addon_reg *world_reg = _world.main.addon; char mod_uid[ ADDON_UID_MAX ]; addon_alias_uid( &world_reg->alias, mod_uid ); diff --git a/src/world_volumes.c b/src/world_volumes.c index 2123489..d4fe4c5 100644 --- a/src/world_volumes.c +++ b/src/world_volumes.c @@ -4,8 +4,8 @@ void world_volumes_update( world_instance *world, v3f pos ) { /* filter and check the existing ones */ u32 j=0; - for( u32 i=0; ient_volume, idx ); v3f local; @@ -14,7 +14,7 @@ void world_volumes_update( world_instance *world, v3f pos ) (fabsf(local[1]) <= 1.0f) && (fabsf(local[2]) <= 1.0f) ) { - world_static.active_trigger_volumes[ j ++ ] = idx; + _world.active_trigger_volumes[ j ++ ] = idx; boxf cube = {{-1.0f,-1.0f,-1.0f},{1.0f,1.0f,1.0f}}; vg_line_boxf_transformed( volume->to_world, cube, 0xff00ccff ); } @@ -32,7 +32,7 @@ void world_volumes_update( world_instance *world, v3f pos ) } } } - world_static.active_trigger_volume_count = j; + _world.active_trigger_volume_count = j; static float random_accum = 0.0f; random_accum += vg.time_delta; @@ -73,27 +73,28 @@ void world_volumes_update( world_instance *world, v3f pos ) } } else{ - for( u32 i=0; i - VG_ARRAY_LEN(world_static.active_trigger_volumes) ) continue; + if( _world.active_trigger_volume_count > + VG_ARRAY_LEN(_world.active_trigger_volumes) ) continue; v3f local; m4x3_mulv( volume->to_local, pos, local ); if( (fabsf(local[0]) <= 1.0f) && (fabsf(local[1]) <= 1.0f) && - (fabsf(local[2]) <= 1.0f) ){ + (fabsf(local[2]) <= 1.0f) ) + { ent_call basecall; basecall.function = 0; basecall.id = id; basecall.data = NULL; entity_call( world, &basecall ); - world_static.active_trigger_volumes[ - world_static.active_trigger_volume_count ++ ] = index; + _world.active_trigger_volumes[ + _world.active_trigger_volume_count ++ ] = index; } else vg_line_boxf_transformed( volume->to_world, cube, 0xffcccccc ); diff --git a/src/world_water.c b/src/world_water.c index 3d95f09..cf42136 100644 --- a/src/world_water.c +++ b/src/world_water.c @@ -145,7 +145,7 @@ void render_water_surface( world_instance *world, vg_camera *cam ) vg_framebuffer_bind_texture( g_render.fb_water_beneath, 0, 5 ); shader_scene_water_uTexBack( 5 ); - shader_scene_water_uTime( world_static.time ); + shader_scene_water_uTime( _world.time ); shader_scene_water_uCamera( cam->transform[3] ); shader_scene_water_uSurfaceY( world->water.height ); @@ -190,7 +190,7 @@ void render_water_surface( world_instance *world, vg_camera *cam ) glBindTexture( GL_TEXTURE_2D, world_water.tex_water_surf ); shader_scene_water_fast_uTexDudv( 1 ); - shader_scene_water_fast_uTime( world_static.time ); + shader_scene_water_fast_uTime( _world.time ); shader_scene_water_fast_uCamera( cam->transform[3] ); shader_scene_water_fast_uSurfaceY( world->water.height ); -- 2.25.1